diff options
304 files changed, 16805 insertions, 5762 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 9734577d1711..11a3c1682cec 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb | |||
@@ -52,3 +52,36 @@ Description: | |||
52 | facility is inherently dangerous, it is disabled by default | 52 | facility is inherently dangerous, it is disabled by default |
53 | for all devices except hubs. For more information, see | 53 | for all devices except hubs. For more information, see |
54 | Documentation/usb/persist.txt. | 54 | Documentation/usb/persist.txt. |
55 | |||
56 | What: /sys/bus/usb/device/.../power/connected_duration | ||
57 | Date: January 2008 | ||
58 | KernelVersion: 2.6.25 | ||
59 | Contact: Sarah Sharp <sarah.a.sharp@intel.com> | ||
60 | Description: | ||
61 | If CONFIG_PM and CONFIG_USB_SUSPEND are enabled, then this file | ||
62 | is present. When read, it returns the total time (in msec) | ||
63 | that the USB device has been connected to the machine. This | ||
64 | file is read-only. | ||
65 | Users: | ||
66 | PowerTOP <power@bughost.org> | ||
67 | http://www.lesswatts.org/projects/powertop/ | ||
68 | |||
69 | What: /sys/bus/usb/device/.../power/active_duration | ||
70 | Date: January 2008 | ||
71 | KernelVersion: 2.6.25 | ||
72 | Contact: Sarah Sharp <sarah.a.sharp@intel.com> | ||
73 | Description: | ||
74 | If CONFIG_PM and CONFIG_USB_SUSPEND are enabled, then this file | ||
75 | is present. When read, it returns the total time (in msec) | ||
76 | that the USB device has been active, i.e. not in a suspended | ||
77 | state. This file is read-only. | ||
78 | |||
79 | Tools can use this file and the connected_duration file to | ||
80 | compute the percentage of time that a device has been active. | ||
81 | For example, | ||
82 | echo $((100 * `cat active_duration` / `cat connected_duration`)) | ||
83 | will give an integer percentage. Note that this does not | ||
84 | account for counter wrap. | ||
85 | Users: | ||
86 | PowerTOP <power@bughost.org> | ||
87 | http://www.lesswatts.org/projects/powertop/ | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 181bff005167..a7d9d179131a 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -156,22 +156,6 @@ Who: Arjan van de Ven <arjan@linux.intel.com> | |||
156 | 156 | ||
157 | --------------------------- | 157 | --------------------------- |
158 | 158 | ||
159 | What: USB driver API moves to EXPORT_SYMBOL_GPL | ||
160 | When: February 2008 | ||
161 | Files: include/linux/usb.h, drivers/usb/core/driver.c | ||
162 | Why: The USB subsystem has changed a lot over time, and it has been | ||
163 | possible to create userspace USB drivers using usbfs/libusb/gadgetfs | ||
164 | that operate as fast as the USB bus allows. Because of this, the USB | ||
165 | subsystem will not be allowing closed source kernel drivers to | ||
166 | register with it, after this grace period is over. If anyone needs | ||
167 | any help in converting their closed source drivers over to use the | ||
168 | userspace filesystems, please contact the | ||
169 | linux-usb-devel@lists.sourceforge.net mailing list, and the developers | ||
170 | there will be glad to help you out. | ||
171 | Who: Greg Kroah-Hartman <gregkh@suse.de> | ||
172 | |||
173 | --------------------------- | ||
174 | |||
175 | What: vm_ops.nopage | 159 | What: vm_ops.nopage |
176 | When: Soon, provided in-kernel callers have been converted | 160 | When: Soon, provided in-kernel callers have been converted |
177 | Why: This interface is replaced by vm_ops.fault, but it has been around | 161 | Why: This interface is replaced by vm_ops.fault, but it has been around |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 92c40d174355..cf3868956f1e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -168,6 +168,11 @@ and is between 256 and 4096 characters. It is defined in the file | |||
168 | acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA | 168 | acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA |
169 | Format: <irq>,<irq>... | 169 | Format: <irq>,<irq>... |
170 | 170 | ||
171 | acpi_new_pts_ordering [HW,ACPI] | ||
172 | Enforce the ACPI 2.0 ordering of the _PTS control | ||
173 | method wrt putting devices into low power states | ||
174 | default: pre ACPI 2.0 ordering of _PTS | ||
175 | |||
171 | acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT | 176 | acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT |
172 | 177 | ||
173 | acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS | 178 | acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS |
diff --git a/Documentation/pci.txt b/Documentation/pci.txt index 7754f5aea4e9..72b20c639596 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt | |||
@@ -274,8 +274,6 @@ the PCI device by calling pci_enable_device(). This will: | |||
274 | o allocate an IRQ (if BIOS did not). | 274 | o allocate an IRQ (if BIOS did not). |
275 | 275 | ||
276 | NOTE: pci_enable_device() can fail! Check the return value. | 276 | NOTE: pci_enable_device() can fail! Check the return value. |
277 | NOTE2: Also see pci_enable_device_bars() below. Drivers can | ||
278 | attempt to enable only a subset of BARs they need. | ||
279 | 277 | ||
280 | [ OS BUG: we don't check resource allocations before enabling those | 278 | [ OS BUG: we don't check resource allocations before enabling those |
281 | resources. The sequence would make more sense if we called | 279 | resources. The sequence would make more sense if we called |
@@ -605,40 +603,7 @@ device lists. This is still possible but discouraged. | |||
605 | 603 | ||
606 | 604 | ||
607 | 605 | ||
608 | 10. pci_enable_device_bars() and Legacy I/O Port space | 606 | 10. MMIO Space and "Write Posting" |
609 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
610 | |||
611 | Large servers may not be able to provide I/O port resources to all PCI | ||
612 | devices. I/O Port space is only 64KB on Intel Architecture[1] and is | ||
613 | likely also fragmented since the I/O base register of PCI-to-PCI | ||
614 | bridge will usually be aligned to a 4KB boundary[2]. On such systems, | ||
615 | pci_enable_device() and pci_request_region() will fail when | ||
616 | attempting to enable I/O Port regions that don't have I/O Port | ||
617 | resources assigned. | ||
618 | |||
619 | Fortunately, many PCI devices which request I/O Port resources also | ||
620 | provide access to the same registers via MMIO BARs. These devices can | ||
621 | be handled without using I/O port space and the drivers typically | ||
622 | offer a CONFIG_ option to only use MMIO regions | ||
623 | (e.g. CONFIG_TULIP_MMIO). PCI devices typically provide I/O port | ||
624 | interface for legacy OSes and will work when I/O port resources are not | ||
625 | assigned. The "PCI Local Bus Specification Revision 3.0" discusses | ||
626 | this on p.44, "IMPLEMENTATION NOTE". | ||
627 | |||
628 | If your PCI device driver doesn't need I/O port resources assigned to | ||
629 | I/O Port BARs, you should use pci_enable_device_bars() instead of | ||
630 | pci_enable_device() in order not to enable I/O port regions for the | ||
631 | corresponding devices. In addition, you should use | ||
632 | pci_request_selected_regions() and pci_release_selected_regions() | ||
633 | instead of pci_request_regions()/pci_release_regions() in order not to | ||
634 | request/release I/O port regions for the corresponding devices. | ||
635 | |||
636 | [1] Some systems support 64KB I/O port space per PCI segment. | ||
637 | [2] Some PCI-to-PCI bridges support optional 1KB aligned I/O base. | ||
638 | |||
639 | |||
640 | |||
641 | 11. MMIO Space and "Write Posting" | ||
642 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 607 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
643 | 608 | ||
644 | Converting a driver from using I/O Port space to using MMIO space | 609 | Converting a driver from using I/O Port space to using MMIO space |
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt index 57aef2f6e0de..1555001bc733 100644 --- a/Documentation/power/basic-pm-debugging.txt +++ b/Documentation/power/basic-pm-debugging.txt | |||
@@ -1,45 +1,111 @@ | |||
1 | Debugging suspend and resume | 1 | Debugging hibernation and suspend |
2 | (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL | 2 | (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL |
3 | 3 | ||
4 | 1. Testing suspend to disk (STD) | 4 | 1. Testing hibernation (aka suspend to disk or STD) |
5 | 5 | ||
6 | To verify that the STD works, you can try to suspend in the "reboot" mode: | 6 | To check if hibernation works, you can try to hibernate in the "reboot" mode: |
7 | 7 | ||
8 | # echo reboot > /sys/power/disk | 8 | # echo reboot > /sys/power/disk |
9 | # echo disk > /sys/power/state | 9 | # echo disk > /sys/power/state |
10 | 10 | ||
11 | and the system should suspend, reboot, resume and get back to the command prompt | 11 | and the system should create a hibernation image, reboot, resume and get back to |
12 | where you have started the transition. If that happens, the STD is most likely | 12 | the command prompt where you have started the transition. If that happens, |
13 | to work correctly, but you need to repeat the test at least a couple of times in | 13 | hibernation is most likely to work correctly. Still, you need to repeat the |
14 | a row for confidence. This is necessary, because some problems only show up on | 14 | test at least a couple of times in a row for confidence. [This is necessary, |
15 | a second attempt at suspending and resuming the system. You should also test | 15 | because some problems only show up on a second attempt at suspending and |
16 | the "platform" and "shutdown" modes of suspend: | 16 | resuming the system.] Moreover, hibernating in the "reboot" and "shutdown" |
17 | modes causes the PM core to skip some platform-related callbacks which on ACPI | ||
18 | systems might be necessary to make hibernation work. Thus, if you machine fails | ||
19 | to hibernate or resume in the "reboot" mode, you should try the "platform" mode: | ||
17 | 20 | ||
18 | # echo platform > /sys/power/disk | 21 | # echo platform > /sys/power/disk |
19 | # echo disk > /sys/power/state | 22 | # echo disk > /sys/power/state |
20 | 23 | ||
21 | or | 24 | which is the default and recommended mode of hibernation. |
25 | |||
26 | Unfortunately, the "platform" mode of hibernation does not work on some systems | ||
27 | with broken BIOSes. In such cases the "shutdown" mode of hibernation might | ||
28 | work: | ||
22 | 29 | ||
23 | # echo shutdown > /sys/power/disk | 30 | # echo shutdown > /sys/power/disk |
24 | # echo disk > /sys/power/state | 31 | # echo disk > /sys/power/state |
25 | 32 | ||
26 | in which cases you will have to press the power button to make the system | 33 | (it is similar to the "reboot" mode, but it requires you to press the power |
27 | resume. If that does not work, you will need to identify what goes wrong. | 34 | button to make the system resume). |
35 | |||
36 | If neither "platform" nor "shutdown" hibernation mode works, you will need to | ||
37 | identify what goes wrong. | ||
38 | |||
39 | a) Test modes of hibernation | ||
40 | |||
41 | To find out why hibernation fails on your system, you can use a special testing | ||
42 | facility available if the kernel is compiled with CONFIG_PM_DEBUG set. Then, | ||
43 | there is the file /sys/power/pm_test that can be used to make the hibernation | ||
44 | core run in a test mode. There are 5 test modes available: | ||
45 | |||
46 | freezer | ||
47 | - test the freezing of processes | ||
48 | |||
49 | devices | ||
50 | - test the freezing of processes and suspending of devices | ||
28 | 51 | ||
29 | a) Test mode of STD | 52 | platform |
53 | - test the freezing of processes, suspending of devices and platform | ||
54 | global control methods(*) | ||
30 | 55 | ||
31 | To verify if there are any drivers that cause problems you can run the STD | 56 | processors |
32 | in the test mode: | 57 | - test the freezing of processes, suspending of devices, platform |
58 | global control methods(*) and the disabling of nonboot CPUs | ||
33 | 59 | ||
34 | # echo test > /sys/power/disk | 60 | core |
61 | - test the freezing of processes, suspending of devices, platform global | ||
62 | control methods(*), the disabling of nonboot CPUs and suspending of | ||
63 | platform/system devices | ||
64 | |||
65 | (*) the platform global control methods are only available on ACPI systems | ||
66 | and are only tested if the hibernation mode is set to "platform" | ||
67 | |||
68 | To use one of them it is necessary to write the corresponding string to | ||
69 | /sys/power/pm_test (eg. "devices" to test the freezing of processes and | ||
70 | suspending devices) and issue the standard hibernation commands. For example, | ||
71 | to use the "devices" test mode along with the "platform" mode of hibernation, | ||
72 | you should do the following: | ||
73 | |||
74 | # echo devices > /sys/power/pm_test | ||
75 | # echo platform > /sys/power/disk | ||
35 | # echo disk > /sys/power/state | 76 | # echo disk > /sys/power/state |
36 | 77 | ||
37 | in which case the system should freeze tasks, suspend devices, disable nonboot | 78 | Then, the kernel will try to freeze processes, suspend devices, wait 5 seconds, |
38 | CPUs (if any), wait for 5 seconds, enable nonboot CPUs, resume devices, thaw | 79 | resume devices and thaw processes. If "platform" is written to |
39 | tasks and return to your command prompt. If that fails, most likely there is | 80 | /sys/power/pm_test , then after suspending devices the kernel will additionally |
40 | a driver that fails to either suspend or resume (in the latter case the system | 81 | invoke the global control methods (eg. ACPI global control methods) used to |
41 | may hang or be unstable after the test, so please take that into consideration). | 82 | prepare the platform firmware for hibernation. Next, it will wait 5 seconds and |
42 | To find this driver, you can carry out a binary search according to the rules: | 83 | invoke the platform (eg. ACPI) global methods used to cancel hibernation etc. |
84 | |||
85 | Writing "none" to /sys/power/pm_test causes the kernel to switch to the normal | ||
86 | hibernation/suspend operations. Also, when open for reading, /sys/power/pm_test | ||
87 | contains a space-separated list of all available tests (including "none" that | ||
88 | represents the normal functionality) in which the current test level is | ||
89 | indicated by square brackets. | ||
90 | |||
91 | Generally, as you can see, each test level is more "invasive" than the previous | ||
92 | one and the "core" level tests the hardware and drivers as deeply as possible | ||
93 | without creating a hibernation image. Obviously, if the "devices" test fails, | ||
94 | the "platform" test will fail as well and so on. Thus, as a rule of thumb, you | ||
95 | should try the test modes starting from "freezer", through "devices", "platform" | ||
96 | and "processors" up to "core" (repeat the test on each level a couple of times | ||
97 | to make sure that any random factors are avoided). | ||
98 | |||
99 | If the "freezer" test fails, there is a task that cannot be frozen (in that case | ||
100 | it usually is possible to identify the offending task by analysing the output of | ||
101 | dmesg obtained after the failing test). Failure at this level usually means | ||
102 | that there is a problem with the tasks freezer subsystem that should be | ||
103 | reported. | ||
104 | |||
105 | If the "devices" test fails, most likely there is a driver that cannot suspend | ||
106 | or resume its device (in the latter case the system may hang or become unstable | ||
107 | after the test, so please take that into consideration). To find this driver, | ||
108 | you can carry out a binary search according to the rules: | ||
43 | - if the test fails, unload a half of the drivers currently loaded and repeat | 109 | - if the test fails, unload a half of the drivers currently loaded and repeat |
44 | (that would probably involve rebooting the system, so always note what drivers | 110 | (that would probably involve rebooting the system, so always note what drivers |
45 | have been loaded before the test), | 111 | have been loaded before the test), |
@@ -47,23 +113,46 @@ have been loaded before the test), | |||
47 | recently and repeat. | 113 | recently and repeat. |
48 | 114 | ||
49 | Once you have found the failing driver (there can be more than just one of | 115 | Once you have found the failing driver (there can be more than just one of |
50 | them), you have to unload it every time before the STD transition. In that case | 116 | them), you have to unload it every time before hibernation. In that case please |
51 | please make sure to report the problem with the driver. | 117 | make sure to report the problem with the driver. |
52 | 118 | ||
53 | It is also possible that a cycle can still fail after you have unloaded | 119 | It is also possible that the "devices" test will still fail after you have |
54 | all modules. In that case, you would want to look in your kernel configuration | 120 | unloaded all modules. In that case, you may want to look in your kernel |
55 | for the drivers that can be compiled as modules (testing again with them as | 121 | configuration for the drivers that can be compiled as modules (and test again |
56 | modules), and possibly also try boot time options such as "noapic" or "noacpi". | 122 | with these drivers compiled as modules). You may also try to use some special |
123 | kernel command line options such as "noapic", "noacpi" or even "acpi=off". | ||
124 | |||
125 | If the "platform" test fails, there is a problem with the handling of the | ||
126 | platform (eg. ACPI) firmware on your system. In that case the "platform" mode | ||
127 | of hibernation is not likely to work. You can try the "shutdown" mode, but that | ||
128 | is rather a poor man's workaround. | ||
129 | |||
130 | If the "processors" test fails, the disabling/enabling of nonboot CPUs does not | ||
131 | work (of course, this only may be an issue on SMP systems) and the problem | ||
132 | should be reported. In that case you can also try to switch the nonboot CPUs | ||
133 | off and on using the /sys/devices/system/cpu/cpu*/online sysfs attributes and | ||
134 | see if that works. | ||
135 | |||
136 | If the "core" test fails, which means that suspending of the system/platform | ||
137 | devices has failed (these devices are suspended on one CPU with interrupts off), | ||
138 | the problem is most probably hardware-related and serious, so it should be | ||
139 | reported. | ||
140 | |||
141 | A failure of any of the "platform", "processors" or "core" tests may cause your | ||
142 | system to hang or become unstable, so please beware. Such a failure usually | ||
143 | indicates a serious problem that very well may be related to the hardware, but | ||
144 | please report it anyway. | ||
57 | 145 | ||
58 | b) Testing minimal configuration | 146 | b) Testing minimal configuration |
59 | 147 | ||
60 | If the test mode of STD works, you can boot the system with "init=/bin/bash" | 148 | If all of the hibernation test modes work, you can boot the system with the |
61 | and attempt to suspend in the "reboot", "shutdown" and "platform" modes. If | 149 | "init=/bin/bash" command line parameter and attempt to hibernate in the |
62 | that does not work, there probably is a problem with a driver statically | 150 | "reboot", "shutdown" and "platform" modes. If that does not work, there |
63 | compiled into the kernel and you can try to compile more drivers as modules, | 151 | probably is a problem with a driver statically compiled into the kernel and you |
64 | so that they can be tested individually. Otherwise, there is a problem with a | 152 | can try to compile more drivers as modules, so that they can be tested |
65 | modular driver and you can find it by loading a half of the modules you normally | 153 | individually. Otherwise, there is a problem with a modular driver and you can |
66 | use and binary searching in accordance with the algorithm: | 154 | find it by loading a half of the modules you normally use and binary searching |
155 | in accordance with the algorithm: | ||
67 | - if there are n modules loaded and the attempt to suspend and resume fails, | 156 | - if there are n modules loaded and the attempt to suspend and resume fails, |
68 | unload n/2 of the modules and try again (that would probably involve rebooting | 157 | unload n/2 of the modules and try again (that would probably involve rebooting |
69 | the system), | 158 | the system), |
@@ -71,19 +160,19 @@ the system), | |||
71 | load n/2 modules more and try again. | 160 | load n/2 modules more and try again. |
72 | 161 | ||
73 | Again, if you find the offending module(s), it(they) must be unloaded every time | 162 | Again, if you find the offending module(s), it(they) must be unloaded every time |
74 | before the STD transition, and please report the problem with it(them). | 163 | before hibernation, and please report the problem with it(them). |
75 | 164 | ||
76 | c) Advanced debugging | 165 | c) Advanced debugging |
77 | 166 | ||
78 | In case the STD does not work on your system even in the minimal configuration | 167 | In case that hibernation does not work on your system even in the minimal |
79 | and compiling more drivers as modules is not practical or some modules cannot | 168 | configuration and compiling more drivers as modules is not practical or some |
80 | be unloaded, you can use one of the more advanced debugging techniques to find | 169 | modules cannot be unloaded, you can use one of the more advanced debugging |
81 | the problem. First, if there is a serial port in your box, you can boot the | 170 | techniques to find the problem. First, if there is a serial port in your box, |
82 | kernel with the 'no_console_suspend' parameter and try to log kernel | 171 | you can boot the kernel with the 'no_console_suspend' parameter and try to log |
83 | messages using the serial console. This may provide you with some information | 172 | kernel messages using the serial console. This may provide you with some |
84 | about the reasons of the suspend (resume) failure. Alternatively, it may be | 173 | information about the reasons of the suspend (resume) failure. Alternatively, |
85 | possible to use a FireWire port for debugging with firescope | 174 | it may be possible to use a FireWire port for debugging with firescope |
86 | (ftp://ftp.firstfloor.org/pub/ak/firescope/). On i386 it is also possible to | 175 | (ftp://ftp.firstfloor.org/pub/ak/firescope/). On x86 it is also possible to |
87 | use the PM_TRACE mechanism documented in Documentation/s2ram.txt . | 176 | use the PM_TRACE mechanism documented in Documentation/s2ram.txt . |
88 | 177 | ||
89 | 2. Testing suspend to RAM (STR) | 178 | 2. Testing suspend to RAM (STR) |
@@ -91,16 +180,25 @@ use the PM_TRACE mechanism documented in Documentation/s2ram.txt . | |||
91 | To verify that the STR works, it is generally more convenient to use the s2ram | 180 | To verify that the STR works, it is generally more convenient to use the s2ram |
92 | tool available from http://suspend.sf.net and documented at | 181 | tool available from http://suspend.sf.net and documented at |
93 | http://en.opensuse.org/s2ram . However, before doing that it is recommended to | 182 | http://en.opensuse.org/s2ram . However, before doing that it is recommended to |
94 | carry out the procedure described in section 1. | 183 | carry out STR testing using the facility described in section 1. |
95 | 184 | ||
96 | Assume you have resolved the problems with the STD and you have found some | 185 | Namely, after writing "freezer", "devices", "platform", "processors", or "core" |
97 | failing drivers. These drivers are also likely to fail during the STR or | 186 | into /sys/power/pm_test (available if the kernel is compiled with |
98 | during the resume, so it is better to unload them every time before the STR | 187 | CONFIG_PM_DEBUG set) the suspend code will work in the test mode corresponding |
99 | transition. Now, you can follow the instructions at | 188 | to given string. The STR test modes are defined in the same way as for |
100 | http://en.opensuse.org/s2ram to test the system, but if it does not work | 189 | hibernation, so please refer to Section 1 for more information about them. In |
101 | "out of the box", you may need to boot it with "init=/bin/bash" and test | 190 | particular, the "core" test allows you to test everything except for the actual |
102 | s2ram in the minimal configuration. In that case, you may be able to search | 191 | invocation of the platform firmware in order to put the system into the sleep |
103 | for failing drivers by following the procedure analogous to the one described in | 192 | state. |
104 | 1b). If you find some failing drivers, you will have to unload them every time | 193 | |
105 | before the STR transition (ie. before you run s2ram), and please report the | 194 | Among other things, the testing with the help of /sys/power/pm_test may allow |
106 | problems with them. | 195 | you to identify drivers that fail to suspend or resume their devices. They |
196 | should be unloaded every time before an STR transition. | ||
197 | |||
198 | Next, you can follow the instructions at http://en.opensuse.org/s2ram to test | ||
199 | the system, but if it does not work "out of the box", you may need to boot it | ||
200 | with "init=/bin/bash" and test s2ram in the minimal configuration. In that | ||
201 | case, you may be able to search for failing drivers by following the procedure | ||
202 | analogous to the one described in section 1. If you find some failing drivers, | ||
203 | you will have to unload them every time before an STR transition (ie. before | ||
204 | you run s2ram), and please report the problems with them. | ||
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index d0e79d5820a5..c53d26361919 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt | |||
@@ -502,52 +502,3 @@ If the CPU can have a "cpufreq" driver, there also may be opportunities | |||
502 | to shift to lower voltage settings and reduce the power cost of executing | 502 | to shift to lower voltage settings and reduce the power cost of executing |
503 | a given number of instructions. (Without voltage adjustment, it's rare | 503 | a given number of instructions. (Without voltage adjustment, it's rare |
504 | for cpufreq to save much power; the cost-per-instruction must go down.) | 504 | for cpufreq to save much power; the cost-per-instruction must go down.) |
505 | |||
506 | |||
507 | /sys/devices/.../power/state files | ||
508 | ================================== | ||
509 | For now you can also test some of this functionality using sysfs. | ||
510 | |||
511 | DEPRECATED: USE "power/state" ONLY FOR DRIVER TESTING, AND | ||
512 | AVOID USING dev->power.power_state IN DRIVERS. | ||
513 | |||
514 | THESE WILL BE REMOVED. IF THE "power/state" FILE GETS REPLACED, | ||
515 | IT WILL BECOME SOMETHING COUPLED TO THE BUS OR DRIVER. | ||
516 | |||
517 | In each device's directory, there is a 'power' directory, which contains | ||
518 | at least a 'state' file. The value of this field is effectively boolean, | ||
519 | PM_EVENT_ON or PM_EVENT_SUSPEND. | ||
520 | |||
521 | * Reading from this file displays a value corresponding to | ||
522 | the power.power_state.event field. All nonzero values are | ||
523 | displayed as "2", corresponding to a low power state; zero | ||
524 | is displayed as "0", corresponding to normal operation. | ||
525 | |||
526 | * Writing to this file initiates a transition using the | ||
527 | specified event code number; only '0', '2', and '3' are | ||
528 | accepted (without a newline); '2' and '3' are both | ||
529 | mapped to PM_EVENT_SUSPEND. | ||
530 | |||
531 | On writes, the PM core relies on that recorded event code and the device/bus | ||
532 | capabilities to determine whether it uses a partial suspend() or resume() | ||
533 | sequence to change things so that the recorded event corresponds to the | ||
534 | numeric parameter. | ||
535 | |||
536 | - If the bus requires the irqs-disabled suspend_late()/resume_early() | ||
537 | phases, writes fail because those operations are not supported here. | ||
538 | |||
539 | - If the recorded value is the expected value, nothing is done. | ||
540 | |||
541 | - If the recorded value is nonzero, the device is partially resumed, | ||
542 | using the bus.resume() and/or class.resume() methods. | ||
543 | |||
544 | - If the target value is nonzero, the device is partially suspended, | ||
545 | using the class.suspend() and/or bus.suspend() methods and the | ||
546 | PM_EVENT_SUSPEND message. | ||
547 | |||
548 | Drivers have no way to tell whether their suspend() and resume() calls | ||
549 | have come through the sysfs power/state file or as part of entering a | ||
550 | system sleep state, except that when accessed through sysfs the normal | ||
551 | parent/child sequencing rules are ignored. Drivers (such as bus, bridge, | ||
552 | or hub drivers) which expose child devices may need to enforce those rules | ||
553 | on their own. | ||
diff --git a/Documentation/power/drivers-testing.txt b/Documentation/power/drivers-testing.txt index e4bdcaee24e4..7f7a737f7f9f 100644 --- a/Documentation/power/drivers-testing.txt +++ b/Documentation/power/drivers-testing.txt | |||
@@ -6,9 +6,9 @@ Testing suspend and resume support in device drivers | |||
6 | Unfortunately, to effectively test the support for the system-wide suspend and | 6 | Unfortunately, to effectively test the support for the system-wide suspend and |
7 | resume transitions in a driver, it is necessary to suspend and resume a fully | 7 | resume transitions in a driver, it is necessary to suspend and resume a fully |
8 | functional system with this driver loaded. Moreover, that should be done | 8 | functional system with this driver loaded. Moreover, that should be done |
9 | several times, preferably several times in a row, and separately for the suspend | 9 | several times, preferably several times in a row, and separately for hibernation |
10 | to disk (STD) and the suspend to RAM (STR) transitions, because each of these | 10 | (aka suspend to disk or STD) and suspend to RAM (STR), because each of these |
11 | cases involves different ordering of operations and different interactions with | 11 | cases involves slightly different operations and different interactions with |
12 | the machine's BIOS. | 12 | the machine's BIOS. |
13 | 13 | ||
14 | Of course, for this purpose the test system has to be known to suspend and | 14 | Of course, for this purpose the test system has to be known to suspend and |
@@ -22,20 +22,24 @@ for more information about the debugging of suspend/resume functionality. | |||
22 | Once you have resolved the suspend/resume-related problems with your test system | 22 | Once you have resolved the suspend/resume-related problems with your test system |
23 | without the new driver, you are ready to test it: | 23 | without the new driver, you are ready to test it: |
24 | 24 | ||
25 | a) Build the driver as a module, load it and try the STD in the test mode (see: | 25 | a) Build the driver as a module, load it and try the test modes of hibernation |
26 | Documents/power/basic-pm-debugging.txt, 1a)). | 26 | (see: Documents/power/basic-pm-debugging.txt, 1). |
27 | 27 | ||
28 | b) Load the driver and attempt to suspend to disk in the "reboot", "shutdown" | 28 | b) Load the driver and attempt to hibernate in the "reboot", "shutdown" and |
29 | and "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1). | 29 | "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1). |
30 | 30 | ||
31 | c) Compile the driver directly into the kernel and try the STD in the test mode. | 31 | c) Compile the driver directly into the kernel and try the test modes of |
32 | hibernation. | ||
32 | 33 | ||
33 | d) Attempt to suspend to disk with the driver compiled directly into the kernel | 34 | d) Attempt to hibernate with the driver compiled directly into the kernel |
34 | in the "reboot", "shutdown" and "platform" modes. | 35 | in the "reboot", "shutdown" and "platform" modes. |
35 | 36 | ||
36 | e) Attempt to suspend to RAM using the s2ram tool with the driver loaded (see: | 37 | e) Try the test modes of suspend (see: Documents/power/basic-pm-debugging.txt, |
37 | Documents/power/basic-pm-debugging.txt, 2). As far as the STR tests are | 38 | 2). [As far as the STR tests are concerned, it should not matter whether or |
38 | concerned, it should not matter whether or not the driver is built as a module. | 39 | not the driver is built as a module.] |
40 | |||
41 | f) Attempt to suspend to RAM using the s2ram tool with the driver loaded | ||
42 | (see: Documents/power/basic-pm-debugging.txt, 2). | ||
39 | 43 | ||
40 | Each of the above tests should be repeated several times and the STD tests | 44 | Each of the above tests should be repeated several times and the STD tests |
41 | should be mixed with the STR tests. If any of them fails, the driver cannot be | 45 | should be mixed with the STR tests. If any of them fails, the driver cannot be |
diff --git a/Documentation/power/notifiers.txt b/Documentation/power/notifiers.txt index 9293e4bc857c..ae1b7ec07684 100644 --- a/Documentation/power/notifiers.txt +++ b/Documentation/power/notifiers.txt | |||
@@ -28,6 +28,14 @@ PM_POST_HIBERNATION The system memory state has been restored from a | |||
28 | hibernation. Device drivers' .resume() callbacks have | 28 | hibernation. Device drivers' .resume() callbacks have |
29 | been executed and tasks have been thawed. | 29 | been executed and tasks have been thawed. |
30 | 30 | ||
31 | PM_RESTORE_PREPARE The system is going to restore a hibernation image. | ||
32 | If all goes well the restored kernel will issue a | ||
33 | PM_POST_HIBERNATION notification. | ||
34 | |||
35 | PM_POST_RESTORE An error occurred during the hibernation restore. | ||
36 | Device drivers' .resume() callbacks have been executed | ||
37 | and tasks have been thawed. | ||
38 | |||
31 | PM_SUSPEND_PREPARE The system is preparing for a suspend. | 39 | PM_SUSPEND_PREPARE The system is preparing for a suspend. |
32 | 40 | ||
33 | PM_POST_SUSPEND The system has just resumed or an error occured during | 41 | PM_POST_SUSPEND The system has just resumed or an error occured during |
diff --git a/Documentation/power/userland-swsusp.txt b/Documentation/power/userland-swsusp.txt index e00c6cf09e85..7b99636564c8 100644 --- a/Documentation/power/userland-swsusp.txt +++ b/Documentation/power/userland-swsusp.txt | |||
@@ -14,7 +14,7 @@ are going to develop your own suspend/resume utilities. | |||
14 | 14 | ||
15 | The interface consists of a character device providing the open(), | 15 | The interface consists of a character device providing the open(), |
16 | release(), read(), and write() operations as well as several ioctl() | 16 | release(), read(), and write() operations as well as several ioctl() |
17 | commands defined in kernel/power/power.h. The major and minor | 17 | commands defined in include/linux/suspend_ioctls.h . The major and minor |
18 | numbers of the device are, respectively, 10 and 231, and they can | 18 | numbers of the device are, respectively, 10 and 231, and they can |
19 | be read from /sys/class/misc/snapshot/dev. | 19 | be read from /sys/class/misc/snapshot/dev. |
20 | 20 | ||
@@ -27,17 +27,17 @@ once at a time. | |||
27 | The ioctl() commands recognized by the device are: | 27 | The ioctl() commands recognized by the device are: |
28 | 28 | ||
29 | SNAPSHOT_FREEZE - freeze user space processes (the current process is | 29 | SNAPSHOT_FREEZE - freeze user space processes (the current process is |
30 | not frozen); this is required for SNAPSHOT_ATOMIC_SNAPSHOT | 30 | not frozen); this is required for SNAPSHOT_CREATE_IMAGE |
31 | and SNAPSHOT_ATOMIC_RESTORE to succeed | 31 | and SNAPSHOT_ATOMIC_RESTORE to succeed |
32 | 32 | ||
33 | SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE | 33 | SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE |
34 | 34 | ||
35 | SNAPSHOT_ATOMIC_SNAPSHOT - create a snapshot of the system memory; the | 35 | SNAPSHOT_CREATE_IMAGE - create a snapshot of the system memory; the |
36 | last argument of ioctl() should be a pointer to an int variable, | 36 | last argument of ioctl() should be a pointer to an int variable, |
37 | the value of which will indicate whether the call returned after | 37 | the value of which will indicate whether the call returned after |
38 | creating the snapshot (1) or after restoring the system memory state | 38 | creating the snapshot (1) or after restoring the system memory state |
39 | from it (0) (after resume the system finds itself finishing the | 39 | from it (0) (after resume the system finds itself finishing the |
40 | SNAPSHOT_ATOMIC_SNAPSHOT ioctl() again); after the snapshot | 40 | SNAPSHOT_CREATE_IMAGE ioctl() again); after the snapshot |
41 | has been created the read() operation can be used to transfer | 41 | has been created the read() operation can be used to transfer |
42 | it out of the kernel | 42 | it out of the kernel |
43 | 43 | ||
@@ -49,39 +49,37 @@ SNAPSHOT_ATOMIC_RESTORE - restore the system memory state from the | |||
49 | 49 | ||
50 | SNAPSHOT_FREE - free memory allocated for the snapshot image | 50 | SNAPSHOT_FREE - free memory allocated for the snapshot image |
51 | 51 | ||
52 | SNAPSHOT_SET_IMAGE_SIZE - set the preferred maximum size of the image | 52 | SNAPSHOT_PREF_IMAGE_SIZE - set the preferred maximum size of the image |
53 | (the kernel will do its best to ensure the image size will not exceed | 53 | (the kernel will do its best to ensure the image size will not exceed |
54 | this number, but if it turns out to be impossible, the kernel will | 54 | this number, but if it turns out to be impossible, the kernel will |
55 | create the smallest image possible) | 55 | create the smallest image possible) |
56 | 56 | ||
57 | SNAPSHOT_AVAIL_SWAP - return the amount of available swap in bytes (the last | 57 | SNAPSHOT_GET_IMAGE_SIZE - return the actual size of the hibernation image |
58 | argument should be a pointer to an unsigned int variable that will | 58 | |
59 | SNAPSHOT_AVAIL_SWAP_SIZE - return the amount of available swap in bytes (the | ||
60 | last argument should be a pointer to an unsigned int variable that will | ||
59 | contain the result if the call is successful). | 61 | contain the result if the call is successful). |
60 | 62 | ||
61 | SNAPSHOT_GET_SWAP_PAGE - allocate a swap page from the resume partition | 63 | SNAPSHOT_ALLOC_SWAP_PAGE - allocate a swap page from the resume partition |
62 | (the last argument should be a pointer to a loff_t variable that | 64 | (the last argument should be a pointer to a loff_t variable that |
63 | will contain the swap page offset if the call is successful) | 65 | will contain the swap page offset if the call is successful) |
64 | 66 | ||
65 | SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated with | 67 | SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated by |
66 | SNAPSHOT_GET_SWAP_PAGE | 68 | SNAPSHOT_ALLOC_SWAP_PAGE |
67 | |||
68 | SNAPSHOT_SET_SWAP_FILE - set the resume partition (the last ioctl() argument | ||
69 | should specify the device's major and minor numbers in the old | ||
70 | two-byte format, as returned by the stat() function in the .st_rdev | ||
71 | member of the stat structure) | ||
72 | 69 | ||
73 | SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in <PAGE_SIZE> | 70 | SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in <PAGE_SIZE> |
74 | units) from the beginning of the partition at which the swap header is | 71 | units) from the beginning of the partition at which the swap header is |
75 | located (the last ioctl() argument should point to a struct | 72 | located (the last ioctl() argument should point to a struct |
76 | resume_swap_area, as defined in kernel/power/power.h, containing the | 73 | resume_swap_area, as defined in kernel/power/suspend_ioctls.h, |
77 | resume device specification, as for the SNAPSHOT_SET_SWAP_FILE ioctl(), | 74 | containing the resume device specification and the offset); for swap |
78 | and the offset); for swap partitions the offset is always 0, but it is | 75 | partitions the offset is always 0, but it is different from zero for |
79 | different to zero for swap files (please see | 76 | swap files (see Documentation/swsusp-and-swap-files.txt for details). |
80 | Documentation/swsusp-and-swap-files.txt for details). | 77 | |
81 | The SNAPSHOT_SET_SWAP_AREA ioctl() is considered as a replacement for | 78 | SNAPSHOT_PLATFORM_SUPPORT - enable/disable the hibernation platform support, |
82 | SNAPSHOT_SET_SWAP_FILE which is regarded as obsolete. It is | 79 | depending on the argument value (enable, if the argument is nonzero) |
83 | recommended to always use this call, because the code to set the resume | 80 | |
84 | partition may be removed from future kernels | 81 | SNAPSHOT_POWER_OFF - make the kernel transition the system to the hibernation |
82 | state (eg. ACPI S4) using the platform (eg. ACPI) driver | ||
85 | 83 | ||
86 | SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to | 84 | SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to |
87 | immediately enter the suspend-to-RAM state, so this call must always | 85 | immediately enter the suspend-to-RAM state, so this call must always |
@@ -93,24 +91,6 @@ SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to | |||
93 | to resume the system from RAM if there's enough battery power or restore | 91 | to resume the system from RAM if there's enough battery power or restore |
94 | its state on the basis of the saved suspend image otherwise) | 92 | its state on the basis of the saved suspend image otherwise) |
95 | 93 | ||
96 | SNAPSHOT_PMOPS - enable the usage of the hibernation_ops->prepare, | ||
97 | hibernate_ops->enter and hibernation_ops->finish methods (the in-kernel | ||
98 | swsusp knows these as the "platform method") which are needed on many | ||
99 | machines to (among others) speed up the resume by letting the BIOS skip | ||
100 | some steps or to let the system recognise the correct state of the | ||
101 | hardware after the resume (in particular on many machines this ensures | ||
102 | that unplugged AC adapters get correctly detected and that kacpid does | ||
103 | not run wild after the resume). The last ioctl() argument can take one | ||
104 | of the three values, defined in kernel/power/power.h: | ||
105 | PMOPS_PREPARE - make the kernel carry out the | ||
106 | hibernation_ops->prepare() operation | ||
107 | PMOPS_ENTER - make the kernel power off the system by calling | ||
108 | hibernation_ops->enter() | ||
109 | PMOPS_FINISH - make the kernel carry out the | ||
110 | hibernation_ops->finish() operation | ||
111 | Note that the actual constants are misnamed because they surface | ||
112 | internal kernel implementation details that have changed. | ||
113 | |||
114 | The device's read() operation can be used to transfer the snapshot image from | 94 | The device's read() operation can be used to transfer the snapshot image from |
115 | the kernel. It has the following limitations: | 95 | the kernel. It has the following limitations: |
116 | - you cannot read() more than one virtual memory page at a time | 96 | - you cannot read() more than one virtual memory page at a time |
@@ -122,7 +102,7 @@ The device's write() operation is used for uploading the system memory snapshot | |||
122 | into the kernel. It has the same limitations as the read() operation. | 102 | into the kernel. It has the same limitations as the read() operation. |
123 | 103 | ||
124 | The release() operation frees all memory allocated for the snapshot image | 104 | The release() operation frees all memory allocated for the snapshot image |
125 | and all swap pages allocated with SNAPSHOT_GET_SWAP_PAGE (if any). | 105 | and all swap pages allocated with SNAPSHOT_ALLOC_SWAP_PAGE (if any). |
126 | Thus it is not necessary to use either SNAPSHOT_FREE or | 106 | Thus it is not necessary to use either SNAPSHOT_FREE or |
127 | SNAPSHOT_FREE_SWAP_PAGES before closing the device (in fact it will also | 107 | SNAPSHOT_FREE_SWAP_PAGES before closing the device (in fact it will also |
128 | unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are | 108 | unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are |
@@ -133,16 +113,12 @@ snapshot image from/to the kernel will use a swap parition, called the resume | |||
133 | partition, or a swap file as storage space (if a swap file is used, the resume | 113 | partition, or a swap file as storage space (if a swap file is used, the resume |
134 | partition is the partition that holds this file). However, this is not really | 114 | partition is the partition that holds this file). However, this is not really |
135 | required, as they can use, for example, a special (blank) suspend partition or | 115 | required, as they can use, for example, a special (blank) suspend partition or |
136 | a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and | 116 | a file on a partition that is unmounted before SNAPSHOT_CREATE_IMAGE and |
137 | mounted afterwards. | 117 | mounted afterwards. |
138 | 118 | ||
139 | These utilities SHOULD NOT make any assumptions regarding the ordering of | 119 | These utilities MUST NOT make any assumptions regarding the ordering of |
140 | data within the snapshot image, except for the image header that MAY be | 120 | data within the snapshot image. The contents of the image are entirely owned |
141 | assumed to start with an swsusp_info structure, as specified in | 121 | by the kernel and its structure may be changed in future kernel releases. |
142 | kernel/power/power.h. This structure MAY be used by the userland utilities | ||
143 | to obtain some information about the snapshot image, such as the size | ||
144 | of the snapshot image, including the metadata and the header itself, | ||
145 | contained in the .size member of swsusp_info. | ||
146 | 122 | ||
147 | The snapshot image MUST be written to the kernel unaltered (ie. all of the image | 123 | The snapshot image MUST be written to the kernel unaltered (ie. all of the image |
148 | data, metadata and header MUST be written in _exactly_ the same amount, form | 124 | data, metadata and header MUST be written in _exactly_ the same amount, form |
@@ -159,7 +135,7 @@ means, such as checksums, to ensure the integrity of the snapshot image. | |||
159 | The suspending and resuming utilities MUST lock themselves in memory, | 135 | The suspending and resuming utilities MUST lock themselves in memory, |
160 | preferrably using mlockall(), before calling SNAPSHOT_FREEZE. | 136 | preferrably using mlockall(), before calling SNAPSHOT_FREEZE. |
161 | 137 | ||
162 | The suspending utility MUST check the value stored by SNAPSHOT_ATOMIC_SNAPSHOT | 138 | The suspending utility MUST check the value stored by SNAPSHOT_CREATE_IMAGE |
163 | in the memory location pointed to by the last argument of ioctl() and proceed | 139 | in the memory location pointed to by the last argument of ioctl() and proceed |
164 | in accordance with it: | 140 | in accordance with it: |
165 | 1. If the value is 1 (ie. the system memory snapshot has just been | 141 | 1. If the value is 1 (ie. the system memory snapshot has just been |
@@ -173,7 +149,7 @@ in accordance with it: | |||
173 | image has been saved. | 149 | image has been saved. |
174 | (b) The suspending utility SHOULD NOT attempt to perform any | 150 | (b) The suspending utility SHOULD NOT attempt to perform any |
175 | file system operations (including reads) on the file systems | 151 | file system operations (including reads) on the file systems |
176 | that were mounted before SNAPSHOT_ATOMIC_SNAPSHOT has been | 152 | that were mounted before SNAPSHOT_CREATE_IMAGE has been |
177 | called. However, it MAY mount a file system that was not | 153 | called. However, it MAY mount a file system that was not |
178 | mounted at that time and perform some operations on it (eg. | 154 | mounted at that time and perform some operations on it (eg. |
179 | use it for saving the image). | 155 | use it for saving the image). |
diff --git a/Documentation/usb/gadget_printer.txt b/Documentation/usb/gadget_printer.txt new file mode 100644 index 000000000000..ad995bf0db41 --- /dev/null +++ b/Documentation/usb/gadget_printer.txt | |||
@@ -0,0 +1,510 @@ | |||
1 | |||
2 | Linux USB Printer Gadget Driver | ||
3 | 06/04/2007 | ||
4 | |||
5 | Copyright (C) 2007 Craig W. Nadler <craig@nadler.us> | ||
6 | |||
7 | |||
8 | |||
9 | GENERAL | ||
10 | ======= | ||
11 | |||
12 | This driver may be used if you are writing printer firmware using Linux as | ||
13 | the embedded OS. This driver has nothing to do with using a printer with | ||
14 | your Linux host system. | ||
15 | |||
16 | You will need a USB device controller and a Linux driver for it that accepts | ||
17 | a gadget / "device class" driver using the Linux USB Gadget API. After the | ||
18 | USB device controller driver is loaded then load the printer gadget driver. | ||
19 | This will present a printer interface to the USB Host that your USB Device | ||
20 | port is connected to. | ||
21 | |||
22 | This driver is structured for printer firmware that runs in user mode. The | ||
23 | user mode printer firmware will read and write data from the kernel mode | ||
24 | printer gadget driver using a device file. The printer returns a printer status | ||
25 | byte when the USB HOST sends a device request to get the printer status. The | ||
26 | user space firmware can read or write this status byte using a device file | ||
27 | /dev/g_printer . Both blocking and non-blocking read/write calls are supported. | ||
28 | |||
29 | |||
30 | |||
31 | |||
32 | HOWTO USE THIS DRIVER | ||
33 | ===================== | ||
34 | |||
35 | To load the USB device controller driver and the printer gadget driver. The | ||
36 | following example uses the Netchip 2280 USB device controller driver: | ||
37 | |||
38 | modprobe net2280 | ||
39 | modprobe g_printer | ||
40 | |||
41 | |||
42 | The follow command line parameter can be used when loading the printer gadget | ||
43 | (ex: modprobe g_printer idVendor=0x0525 idProduct=0xa4a8 ): | ||
44 | |||
45 | idVendor - This is the Vendor ID used in the device descriptor. The default is | ||
46 | the Netchip vendor id 0x0525. YOU MUST CHANGE TO YOUR OWN VENDOR ID | ||
47 | BEFORE RELEASING A PRODUCT. If you plan to release a product and don't | ||
48 | already have a Vendor ID please see www.usb.org for details on how to | ||
49 | get one. | ||
50 | |||
51 | idProduct - This is the Product ID used in the device descriptor. The default | ||
52 | is 0xa4a8, you should change this to an ID that's not used by any of | ||
53 | your other USB products if you have any. It would be a good idea to | ||
54 | start numbering your products starting with say 0x0001. | ||
55 | |||
56 | bcdDevice - This is the version number of your product. It would be a good idea | ||
57 | to put your firmware version here. | ||
58 | |||
59 | iManufacturer - A string containing the name of the Vendor. | ||
60 | |||
61 | iProduct - A string containing the Product Name. | ||
62 | |||
63 | iSerialNum - A string containing the Serial Number. This should be changed for | ||
64 | each unit of your product. | ||
65 | |||
66 | iPNPstring - The PNP ID string used for this printer. You will want to set | ||
67 | either on the command line or hard code the PNP ID string used for | ||
68 | your printer product. | ||
69 | |||
70 | qlen - The number of 8k buffers to use per endpoint. The default is 10, you | ||
71 | should tune this for your product. You may also want to tune the | ||
72 | size of each buffer for your product. | ||
73 | |||
74 | |||
75 | |||
76 | |||
77 | USING THE EXAMPLE CODE | ||
78 | ====================== | ||
79 | |||
80 | This example code talks to stdout, instead of a print engine. | ||
81 | |||
82 | To compile the test code below: | ||
83 | |||
84 | 1) save it to a file called prn_example.c | ||
85 | 2) compile the code with the follow command: | ||
86 | gcc prn_example.c -o prn_example | ||
87 | |||
88 | |||
89 | |||
90 | To read printer data from the host to stdout: | ||
91 | |||
92 | # prn_example -read_data | ||
93 | |||
94 | |||
95 | To write printer data from a file (data_file) to the host: | ||
96 | |||
97 | # cat data_file | prn_example -write_data | ||
98 | |||
99 | |||
100 | To get the current printer status for the gadget driver: | ||
101 | |||
102 | # prn_example -get_status | ||
103 | |||
104 | Printer status is: | ||
105 | Printer is NOT Selected | ||
106 | Paper is Out | ||
107 | Printer OK | ||
108 | |||
109 | |||
110 | To set printer to Selected/On-line: | ||
111 | |||
112 | # prn_example -selected | ||
113 | |||
114 | |||
115 | To set printer to Not Selected/Off-line: | ||
116 | |||
117 | # prn_example -not_selected | ||
118 | |||
119 | |||
120 | To set paper status to paper out: | ||
121 | |||
122 | # prn_example -paper_out | ||
123 | |||
124 | |||
125 | To set paper status to paper loaded: | ||
126 | |||
127 | # prn_example -paper_loaded | ||
128 | |||
129 | |||
130 | To set error status to printer OK: | ||
131 | |||
132 | # prn_example -no_error | ||
133 | |||
134 | |||
135 | To set error status to ERROR: | ||
136 | |||
137 | # prn_example -error | ||
138 | |||
139 | |||
140 | |||
141 | |||
142 | EXAMPLE CODE | ||
143 | ============ | ||
144 | |||
145 | |||
146 | #include <stdio.h> | ||
147 | #include <stdlib.h> | ||
148 | #include <fcntl.h> | ||
149 | #include <linux/poll.h> | ||
150 | #include <sys/ioctl.h> | ||
151 | #include <linux/usb/g_printer.h> | ||
152 | |||
153 | #define PRINTER_FILE "/dev/g_printer" | ||
154 | #define BUF_SIZE 512 | ||
155 | |||
156 | |||
157 | /* | ||
158 | * 'usage()' - Show program usage. | ||
159 | */ | ||
160 | |||
161 | static void | ||
162 | usage(const char *option) /* I - Option string or NULL */ | ||
163 | { | ||
164 | if (option) { | ||
165 | fprintf(stderr,"prn_example: Unknown option \"%s\"!\n", | ||
166 | option); | ||
167 | } | ||
168 | |||
169 | fputs("\n", stderr); | ||
170 | fputs("Usage: prn_example -[options]\n", stderr); | ||
171 | fputs("Options:\n", stderr); | ||
172 | fputs("\n", stderr); | ||
173 | fputs("-get_status Get the current printer status.\n", stderr); | ||
174 | fputs("-selected Set the selected status to selected.\n", stderr); | ||
175 | fputs("-not_selected Set the selected status to NOT selected.\n", | ||
176 | stderr); | ||
177 | fputs("-error Set the error status to error.\n", stderr); | ||
178 | fputs("-no_error Set the error status to NO error.\n", stderr); | ||
179 | fputs("-paper_out Set the paper status to paper out.\n", stderr); | ||
180 | fputs("-paper_loaded Set the paper status to paper loaded.\n", | ||
181 | stderr); | ||
182 | fputs("-read_data Read printer data from driver.\n", stderr); | ||
183 | fputs("-write_data Write printer sata to driver.\n", stderr); | ||
184 | fputs("-NB_read_data (Non-Blocking) Read printer data from driver.\n", | ||
185 | stderr); | ||
186 | fputs("\n\n", stderr); | ||
187 | |||
188 | exit(1); | ||
189 | } | ||
190 | |||
191 | |||
192 | static int | ||
193 | read_printer_data() | ||
194 | { | ||
195 | struct pollfd fd[1]; | ||
196 | |||
197 | /* Open device file for printer gadget. */ | ||
198 | fd[0].fd = open(PRINTER_FILE, O_RDWR); | ||
199 | if (fd[0].fd < 0) { | ||
200 | printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE); | ||
201 | close(fd[0].fd); | ||
202 | return(-1); | ||
203 | } | ||
204 | |||
205 | fd[0].events = POLLIN | POLLRDNORM; | ||
206 | |||
207 | while (1) { | ||
208 | static char buf[BUF_SIZE]; | ||
209 | int bytes_read; | ||
210 | int retval; | ||
211 | |||
212 | /* Wait for up to 1 second for data. */ | ||
213 | retval = poll(fd, 1, 1000); | ||
214 | |||
215 | if (retval && (fd[0].revents & POLLRDNORM)) { | ||
216 | |||
217 | /* Read data from printer gadget driver. */ | ||
218 | bytes_read = read(fd[0].fd, buf, BUF_SIZE); | ||
219 | |||
220 | if (bytes_read < 0) { | ||
221 | printf("Error %d reading from %s\n", | ||
222 | fd[0].fd, PRINTER_FILE); | ||
223 | close(fd[0].fd); | ||
224 | return(-1); | ||
225 | } else if (bytes_read > 0) { | ||
226 | /* Write data to standard OUTPUT (stdout). */ | ||
227 | fwrite(buf, 1, bytes_read, stdout); | ||
228 | fflush(stdout); | ||
229 | } | ||
230 | |||
231 | } | ||
232 | |||
233 | } | ||
234 | |||
235 | /* Close the device file. */ | ||
236 | close(fd[0].fd); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | |||
242 | static int | ||
243 | write_printer_data() | ||
244 | { | ||
245 | struct pollfd fd[1]; | ||
246 | |||
247 | /* Open device file for printer gadget. */ | ||
248 | fd[0].fd = open (PRINTER_FILE, O_RDWR); | ||
249 | if (fd[0].fd < 0) { | ||
250 | printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE); | ||
251 | close(fd[0].fd); | ||
252 | return(-1); | ||
253 | } | ||
254 | |||
255 | fd[0].events = POLLOUT | POLLWRNORM; | ||
256 | |||
257 | while (1) { | ||
258 | int retval; | ||
259 | static char buf[BUF_SIZE]; | ||
260 | /* Read data from standard INPUT (stdin). */ | ||
261 | int bytes_read = fread(buf, 1, BUF_SIZE, stdin); | ||
262 | |||
263 | if (!bytes_read) { | ||
264 | break; | ||
265 | } | ||
266 | |||
267 | while (bytes_read) { | ||
268 | |||
269 | /* Wait for up to 1 second to sent data. */ | ||
270 | retval = poll(fd, 1, 1000); | ||
271 | |||
272 | /* Write data to printer gadget driver. */ | ||
273 | if (retval && (fd[0].revents & POLLWRNORM)) { | ||
274 | retval = write(fd[0].fd, buf, bytes_read); | ||
275 | if (retval < 0) { | ||
276 | printf("Error %d writing to %s\n", | ||
277 | fd[0].fd, | ||
278 | PRINTER_FILE); | ||
279 | close(fd[0].fd); | ||
280 | return(-1); | ||
281 | } else { | ||
282 | bytes_read -= retval; | ||
283 | } | ||
284 | |||
285 | } | ||
286 | |||
287 | } | ||
288 | |||
289 | } | ||
290 | |||
291 | /* Wait until the data has been sent. */ | ||
292 | fsync(fd[0].fd); | ||
293 | |||
294 | /* Close the device file. */ | ||
295 | close(fd[0].fd); | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | |||
301 | static int | ||
302 | read_NB_printer_data() | ||
303 | { | ||
304 | int fd; | ||
305 | static char buf[BUF_SIZE]; | ||
306 | int bytes_read; | ||
307 | |||
308 | /* Open device file for printer gadget. */ | ||
309 | fd = open(PRINTER_FILE, O_RDWR|O_NONBLOCK); | ||
310 | if (fd < 0) { | ||
311 | printf("Error %d opening %s\n", fd, PRINTER_FILE); | ||
312 | close(fd); | ||
313 | return(-1); | ||
314 | } | ||
315 | |||
316 | while (1) { | ||
317 | /* Read data from printer gadget driver. */ | ||
318 | bytes_read = read(fd, buf, BUF_SIZE); | ||
319 | if (bytes_read <= 0) { | ||
320 | break; | ||
321 | } | ||
322 | |||
323 | /* Write data to standard OUTPUT (stdout). */ | ||
324 | fwrite(buf, 1, bytes_read, stdout); | ||
325 | fflush(stdout); | ||
326 | } | ||
327 | |||
328 | /* Close the device file. */ | ||
329 | close(fd); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | |||
335 | static int | ||
336 | get_printer_status() | ||
337 | { | ||
338 | int retval; | ||
339 | int fd; | ||
340 | |||
341 | /* Open device file for printer gadget. */ | ||
342 | fd = open(PRINTER_FILE, O_RDWR); | ||
343 | if (fd < 0) { | ||
344 | printf("Error %d opening %s\n", fd, PRINTER_FILE); | ||
345 | close(fd); | ||
346 | return(-1); | ||
347 | } | ||
348 | |||
349 | /* Make the IOCTL call. */ | ||
350 | retval = ioctl(fd, GADGET_GET_PRINTER_STATUS); | ||
351 | if (retval < 0) { | ||
352 | fprintf(stderr, "ERROR: Failed to set printer status\n"); | ||
353 | return(-1); | ||
354 | } | ||
355 | |||
356 | /* Close the device file. */ | ||
357 | close(fd); | ||
358 | |||
359 | return(retval); | ||
360 | } | ||
361 | |||
362 | |||
363 | static int | ||
364 | set_printer_status(unsigned char buf, int clear_printer_status_bit) | ||
365 | { | ||
366 | int retval; | ||
367 | int fd; | ||
368 | |||
369 | retval = get_printer_status(); | ||
370 | if (retval < 0) { | ||
371 | fprintf(stderr, "ERROR: Failed to get printer status\n"); | ||
372 | return(-1); | ||
373 | } | ||
374 | |||
375 | /* Open device file for printer gadget. */ | ||
376 | fd = open(PRINTER_FILE, O_RDWR); | ||
377 | |||
378 | if (fd < 0) { | ||
379 | printf("Error %d opening %s\n", fd, PRINTER_FILE); | ||
380 | close(fd); | ||
381 | return(-1); | ||
382 | } | ||
383 | |||
384 | if (clear_printer_status_bit) { | ||
385 | retval &= ~buf; | ||
386 | } else { | ||
387 | retval |= buf; | ||
388 | } | ||
389 | |||
390 | /* Make the IOCTL call. */ | ||
391 | if (ioctl(fd, GADGET_SET_PRINTER_STATUS, (unsigned char)retval)) { | ||
392 | fprintf(stderr, "ERROR: Failed to set printer status\n"); | ||
393 | return(-1); | ||
394 | } | ||
395 | |||
396 | /* Close the device file. */ | ||
397 | close(fd); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | |||
403 | static int | ||
404 | display_printer_status() | ||
405 | { | ||
406 | char printer_status; | ||
407 | |||
408 | printer_status = get_printer_status(); | ||
409 | if (printer_status < 0) { | ||
410 | fprintf(stderr, "ERROR: Failed to get printer status\n"); | ||
411 | return(-1); | ||
412 | } | ||
413 | |||
414 | printf("Printer status is:\n"); | ||
415 | if (printer_status & PRINTER_SELECTED) { | ||
416 | printf(" Printer is Selected\n"); | ||
417 | } else { | ||
418 | printf(" Printer is NOT Selected\n"); | ||
419 | } | ||
420 | if (printer_status & PRINTER_PAPER_EMPTY) { | ||
421 | printf(" Paper is Out\n"); | ||
422 | } else { | ||
423 | printf(" Paper is Loaded\n"); | ||
424 | } | ||
425 | if (printer_status & PRINTER_NOT_ERROR) { | ||
426 | printf(" Printer OK\n"); | ||
427 | } else { | ||
428 | printf(" Printer ERROR\n"); | ||
429 | } | ||
430 | |||
431 | return(0); | ||
432 | } | ||
433 | |||
434 | |||
435 | int | ||
436 | main(int argc, char *argv[]) | ||
437 | { | ||
438 | int i; /* Looping var */ | ||
439 | int retval = 0; | ||
440 | |||
441 | /* No Args */ | ||
442 | if (argc == 1) { | ||
443 | usage(0); | ||
444 | exit(0); | ||
445 | } | ||
446 | |||
447 | for (i = 1; i < argc && !retval; i ++) { | ||
448 | |||
449 | if (argv[i][0] != '-') { | ||
450 | continue; | ||
451 | } | ||
452 | |||
453 | if (!strcmp(argv[i], "-get_status")) { | ||
454 | if (display_printer_status()) { | ||
455 | retval = 1; | ||
456 | } | ||
457 | |||
458 | } else if (!strcmp(argv[i], "-paper_loaded")) { | ||
459 | if (set_printer_status(PRINTER_PAPER_EMPTY, 1)) { | ||
460 | retval = 1; | ||
461 | } | ||
462 | |||
463 | } else if (!strcmp(argv[i], "-paper_out")) { | ||
464 | if (set_printer_status(PRINTER_PAPER_EMPTY, 0)) { | ||
465 | retval = 1; | ||
466 | } | ||
467 | |||
468 | } else if (!strcmp(argv[i], "-selected")) { | ||
469 | if (set_printer_status(PRINTER_SELECTED, 0)) { | ||
470 | retval = 1; | ||
471 | } | ||
472 | |||
473 | } else if (!strcmp(argv[i], "-not_selected")) { | ||
474 | if (set_printer_status(PRINTER_SELECTED, 1)) { | ||
475 | retval = 1; | ||
476 | } | ||
477 | |||
478 | } else if (!strcmp(argv[i], "-error")) { | ||
479 | if (set_printer_status(PRINTER_NOT_ERROR, 1)) { | ||
480 | retval = 1; | ||
481 | } | ||
482 | |||
483 | } else if (!strcmp(argv[i], "-no_error")) { | ||
484 | if (set_printer_status(PRINTER_NOT_ERROR, 0)) { | ||
485 | retval = 1; | ||
486 | } | ||
487 | |||
488 | } else if (!strcmp(argv[i], "-read_data")) { | ||
489 | if (read_printer_data()) { | ||
490 | retval = 1; | ||
491 | } | ||
492 | |||
493 | } else if (!strcmp(argv[i], "-write_data")) { | ||
494 | if (write_printer_data()) { | ||
495 | retval = 1; | ||
496 | } | ||
497 | |||
498 | } else if (!strcmp(argv[i], "-NB_read_data")) { | ||
499 | if (read_NB_printer_data()) { | ||
500 | retval = 1; | ||
501 | } | ||
502 | |||
503 | } else { | ||
504 | usage(argv[i]); | ||
505 | retval = 1; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | exit(retval); | ||
510 | } | ||
diff --git a/Documentation/usb/iuu_phoenix.txt b/Documentation/usb/iuu_phoenix.txt new file mode 100644 index 000000000000..e5f048067da4 --- /dev/null +++ b/Documentation/usb/iuu_phoenix.txt | |||
@@ -0,0 +1,84 @@ | |||
1 | Infinity Usb Unlimited Readme | ||
2 | ----------------------------- | ||
3 | |||
4 | Hi all, | ||
5 | |||
6 | |||
7 | This module provide a serial interface to use your | ||
8 | IUU unit in phoenix mode. Loading this module will | ||
9 | bring a ttyUSB[0-x] interface. This driver must be | ||
10 | used by your favorite application to pilot the IUU | ||
11 | |||
12 | This driver is still in beta stage, so bugs can | ||
13 | occur and your system may freeze. As far I now, | ||
14 | I never had any problem with it, but I'm not a real | ||
15 | guru, so don't blame me if your system is unstable | ||
16 | |||
17 | You can plug more than one IUU. Every unit will | ||
18 | have his own device file(/dev/ttyUSB0,/dev/ttyUSB1,...) | ||
19 | |||
20 | |||
21 | |||
22 | How to tune the reader speed ? | ||
23 | |||
24 | A few parameters can be used at load time | ||
25 | To use parameters, just unload the module if it is | ||
26 | already loaded and use modprobe iuu_phoenix param=value. | ||
27 | In case of prebuilt module, use the command | ||
28 | insmod iuu_phoenix param=value. | ||
29 | |||
30 | Example: | ||
31 | |||
32 | modprobe iuu_phoenix clockmode=3 | ||
33 | |||
34 | The parameters are: | ||
35 | |||
36 | parm: clockmode:1=3Mhz579,2=3Mhz680,3=6Mhz (int) | ||
37 | parm: boost:overclock boost percent 100 to 500 (int) | ||
38 | parm: cdmode:Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, 4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING (int) | ||
39 | parm: xmas:xmas color enabled or not (bool) | ||
40 | parm: debug:Debug enabled or not (bool) | ||
41 | |||
42 | - clockmode will provide 3 different base settings commonly adopted by | ||
43 | different software: | ||
44 | 1. 3Mhz579 | ||
45 | 2. 3Mhz680 | ||
46 | 3. 6Mhz | ||
47 | |||
48 | - boost provide a way to overclock the reader ( my favorite :-) ) | ||
49 | For example to have best performance than a simple clockmode=3, try this: | ||
50 | |||
51 | modprobe boost=195 | ||
52 | |||
53 | This will put the reader in a base of 3Mhz579 but boosted a 195 % ! | ||
54 | the real clock will be now : 6979050 Hz ( 6Mhz979 ) and will increase | ||
55 | the speed to a score 10 to 20% better than the simple clockmode=3 !!! | ||
56 | |||
57 | |||
58 | - cdmode permit to setup the signal used to inform the userland ( ioctl answer ) | ||
59 | if the card is present or not. Eight signals are possible. | ||
60 | |||
61 | - xmas is completely useless except for your eyes. This is one of my friend who was | ||
62 | so sad to have a nice device like the iuu without seeing all color range available. | ||
63 | So I have added this option to permit him to see a lot of color ( each activity change the color | ||
64 | and the frequency randomly ) | ||
65 | |||
66 | - debug will produce a lot of debugging messages... | ||
67 | |||
68 | |||
69 | Last notes: | ||
70 | |||
71 | Don't worry about the serial settings, the serial emulation | ||
72 | is an abstraction, so use any speed or parity setting will | ||
73 | work. ( This will not change anything ).Later I will perhaps | ||
74 | use this settings to deduce de boost but is that feature | ||
75 | really necessary ? | ||
76 | The autodetect feature used is the serial CD. If that doesn't | ||
77 | work for your software, disable detection mechanism in it. | ||
78 | |||
79 | |||
80 | Have fun ! | ||
81 | |||
82 | Alain Degreffe | ||
83 | |||
84 | eczema(at)ecze.com | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 61787801244e..58b16038baea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2247,7 +2247,7 @@ P: J. Bruce Fields | |||
2247 | M: bfields@fieldses.org | 2247 | M: bfields@fieldses.org |
2248 | P: Neil Brown | 2248 | P: Neil Brown |
2249 | M: neilb@suse.de | 2249 | M: neilb@suse.de |
2250 | L: nfs@lists.sourceforge.net | 2250 | L: linux-nfs@vger.kernel.org |
2251 | W: http://nfs.sourceforge.net/ | 2251 | W: http://nfs.sourceforge.net/ |
2252 | S: Supported | 2252 | S: Supported |
2253 | 2253 | ||
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 4c002ba37e50..c613d5fb0daa 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -318,11 +318,6 @@ config PCI | |||
318 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or | 318 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or |
319 | VESA. If you have PCI, say Y, otherwise N. | 319 | VESA. If you have PCI, say Y, otherwise N. |
320 | 320 | ||
321 | The PCI-HOWTO, available from | ||
322 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
323 | information about which PCI hardware does work under Linux and which | ||
324 | doesn't. | ||
325 | |||
326 | config PCI_DOMAINS | 321 | config PCI_DOMAINS |
327 | bool | 322 | bool |
328 | default y | 323 | default y |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 77201d3f7479..4b1a8e3d292c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -577,11 +577,6 @@ config PCI | |||
577 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or | 577 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or |
578 | VESA. If you have PCI, say Y, otherwise N. | 578 | VESA. If you have PCI, say Y, otherwise N. |
579 | 579 | ||
580 | The PCI-HOWTO, available from | ||
581 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
582 | information about which PCI hardware does work under Linux and which | ||
583 | doesn't. | ||
584 | |||
585 | config PCI_SYSCALL | 580 | config PCI_SYSCALL |
586 | def_bool PCI | 581 | def_bool PCI |
587 | 582 | ||
@@ -1035,6 +1030,9 @@ menu "Power management options" | |||
1035 | 1030 | ||
1036 | source "kernel/power/Kconfig" | 1031 | source "kernel/power/Kconfig" |
1037 | 1032 | ||
1033 | config ARCH_SUSPEND_POSSIBLE | ||
1034 | def_bool y | ||
1035 | |||
1038 | endmenu | 1036 | endmenu |
1039 | 1037 | ||
1040 | source "net/Kconfig" | 1038 | source "net/Kconfig" |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 4b120cc36135..a67defd50438 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -52,7 +52,7 @@ static suspend_state_t target_state; | |||
52 | /* | 52 | /* |
53 | * Called after processes are frozen, but before we shutdown devices. | 53 | * Called after processes are frozen, but before we shutdown devices. |
54 | */ | 54 | */ |
55 | static int at91_pm_set_target(suspend_state_t state) | 55 | static int at91_pm_begin(suspend_state_t state) |
56 | { | 56 | { |
57 | target_state = state; | 57 | target_state = state; |
58 | return 0; | 58 | return 0; |
@@ -202,11 +202,20 @@ error: | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* | ||
206 | * Called right prior to thawing processes. | ||
207 | */ | ||
208 | static void at91_pm_end(void) | ||
209 | { | ||
210 | target_state = PM_SUSPEND_ON; | ||
211 | } | ||
212 | |||
205 | 213 | ||
206 | static struct platform_suspend_ops at91_pm_ops ={ | 214 | static struct platform_suspend_ops at91_pm_ops ={ |
207 | .valid = at91_pm_valid_state, | 215 | .valid = at91_pm_valid_state, |
208 | .set_target = at91_pm_set_target, | 216 | .begin = at91_pm_begin, |
209 | .enter = at91_pm_enter, | 217 | .enter = at91_pm_enter, |
218 | .end = at91_pm_end, | ||
210 | }; | 219 | }; |
211 | 220 | ||
212 | static int __init at91_pm_init(void) | 221 | static int __init at91_pm_init(void) |
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 1919756900f4..1a9c844ac7eb 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
@@ -157,15 +157,10 @@ static void tosa_udc_command(int cmd) | |||
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | static int tosa_udc_is_connected(void) | ||
161 | { | ||
162 | return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0); | ||
163 | } | ||
164 | |||
165 | |||
166 | static struct pxa2xx_udc_mach_info udc_info __initdata = { | 160 | static struct pxa2xx_udc_mach_info udc_info __initdata = { |
167 | .udc_command = tosa_udc_command, | 161 | .udc_command = tosa_udc_command, |
168 | .udc_is_connected = tosa_udc_is_connected, | 162 | .gpio_vbus = TOSA_GPIO_USB_IN, |
163 | .gpio_vbus_inverted = 1, | ||
169 | }; | 164 | }; |
170 | 165 | ||
171 | /* | 166 | /* |
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index fc7ca86ac8bf..4802eb767dc9 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -898,6 +898,10 @@ endmenu | |||
898 | menu "Power management options" | 898 | menu "Power management options" |
899 | source "kernel/power/Kconfig" | 899 | source "kernel/power/Kconfig" |
900 | 900 | ||
901 | config ARCH_SUSPEND_POSSIBLE | ||
902 | def_bool y | ||
903 | depends on !SMP | ||
904 | |||
901 | choice | 905 | choice |
902 | prompt "Select PM Wakeup Event Source" | 906 | prompt "Select PM Wakeup Event Source" |
903 | default PM_WAKEUP_GPIO_BY_SIC_IWR | 907 | default PM_WAKEUP_GPIO_BY_SIC_IWR |
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 43153e767bb1..e3f965c91e22 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig | |||
@@ -322,11 +322,6 @@ config PCI | |||
322 | onboard. If you have one of these boards and you wish to use the PCI | 322 | onboard. If you have one of these boards and you wish to use the PCI |
323 | facilities, say Y here. | 323 | facilities, say Y here. |
324 | 324 | ||
325 | The PCI-HOWTO, available from | ||
326 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
327 | information about which PCI hardware does work under Linux and which | ||
328 | doesn't. | ||
329 | |||
330 | config RESERVE_DMA_COHERENT | 325 | config RESERVE_DMA_COHERENT |
331 | bool "Reserve DMA coherent memory" | 326 | bool "Reserve DMA coherent memory" |
332 | depends on PCI && !MMU | 327 | depends on PCI && !MMU |
@@ -357,6 +352,11 @@ source "drivers/pcmcia/Kconfig" | |||
357 | # should probably wait a while. | 352 | # should probably wait a while. |
358 | 353 | ||
359 | menu "Power management options" | 354 | menu "Power management options" |
355 | |||
356 | config ARCH_SUSPEND_POSSIBLE | ||
357 | def_bool y | ||
358 | depends on !SMP | ||
359 | |||
360 | source kernel/power/Kconfig | 360 | source kernel/power/Kconfig |
361 | endmenu | 361 | endmenu |
362 | 362 | ||
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index f7237c5f531e..49326e9d4413 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig | |||
@@ -359,11 +359,6 @@ config PCI | |||
359 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or | 359 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or |
360 | VESA. If you have PCI, say Y, otherwise N. | 360 | VESA. If you have PCI, say Y, otherwise N. |
361 | 361 | ||
362 | The PCI-HOWTO, available from | ||
363 | <http://www.linuxdoc.org/docs.html#howto>, contains valuable | ||
364 | information about which PCI hardware does work under Linux and which | ||
365 | doesn't. | ||
366 | |||
367 | choice | 362 | choice |
368 | prompt "PCI access mode" | 363 | prompt "PCI access mode" |
369 | depends on PCI | 364 | depends on PCI |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 01dee84f840a..24e6bc09e7a7 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
@@ -145,11 +145,6 @@ config PCI | |||
145 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or | 145 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or |
146 | VESA. If you have PCI, say Y, otherwise N. | 146 | VESA. If you have PCI, say Y, otherwise N. |
147 | 147 | ||
148 | The PCI-HOWTO, available from | ||
149 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
150 | information about which PCI hardware does work under Linux and which | ||
151 | doesn't. | ||
152 | |||
153 | config MAC | 148 | config MAC |
154 | bool "Macintosh support" | 149 | bool "Macintosh support" |
155 | depends on !MMU_SUN3 | 150 | depends on !MMU_SUN3 |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4fad0a34b997..36a4018f71d2 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1961,11 +1961,6 @@ config PCI | |||
1961 | your box. Other bus systems are ISA, EISA, or VESA. If you have PCI, | 1961 | your box. Other bus systems are ISA, EISA, or VESA. If you have PCI, |
1962 | say Y, otherwise N. | 1962 | say Y, otherwise N. |
1963 | 1963 | ||
1964 | The PCI-HOWTO, available from | ||
1965 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
1966 | information about which PCI hardware does work under Linux and which | ||
1967 | doesn't. | ||
1968 | |||
1969 | config PCI_DOMAINS | 1964 | config PCI_DOMAINS |
1970 | bool | 1965 | bool |
1971 | 1966 | ||
@@ -2086,6 +2081,10 @@ endmenu | |||
2086 | 2081 | ||
2087 | menu "Power management options" | 2082 | menu "Power management options" |
2088 | 2083 | ||
2084 | config ARCH_SUSPEND_POSSIBLE | ||
2085 | def_bool y | ||
2086 | depends on !SMP | ||
2087 | |||
2089 | source "kernel/power/Kconfig" | 2088 | source "kernel/power/Kconfig" |
2090 | 2089 | ||
2091 | endmenu | 2090 | endmenu |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9c44af3db8d9..4a22c9928618 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -151,11 +151,25 @@ config DEFAULT_UIMAGE | |||
151 | config REDBOOT | 151 | config REDBOOT |
152 | bool | 152 | bool |
153 | 153 | ||
154 | config PPC64_SWSUSP | 154 | config HIBERNATE_32 |
155 | bool | 155 | bool |
156 | depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL)) | 156 | depends on (PPC_PMAC && !SMP) || BROKEN |
157 | default y | 157 | default y |
158 | 158 | ||
159 | config HIBERNATE_64 | ||
160 | bool | ||
161 | depends on BROKEN || (PPC_PMAC64 && EXPERIMENTAL) | ||
162 | default y | ||
163 | |||
164 | config ARCH_HIBERNATION_POSSIBLE | ||
165 | bool | ||
166 | depends on (PPC64 && HIBERNATE_64) || (PPC32 && HIBERNATE_32) | ||
167 | default y | ||
168 | |||
169 | config ARCH_SUSPEND_POSSIBLE | ||
170 | def_bool y | ||
171 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 | ||
172 | |||
159 | config PPC_DCR_NATIVE | 173 | config PPC_DCR_NATIVE |
160 | bool | 174 | bool |
161 | default n | 175 | default n |
@@ -391,6 +405,10 @@ config CMDLINE | |||
391 | most cases you will need to specify the root device here. | 405 | most cases you will need to specify the root device here. |
392 | 406 | ||
393 | if !44x || BROKEN | 407 | if !44x || BROKEN |
408 | config ARCH_WANTS_FREEZER_CONTROL | ||
409 | def_bool y | ||
410 | depends on ADB_PMU | ||
411 | |||
394 | source kernel/power/Kconfig | 412 | source kernel/power/Kconfig |
395 | endif | 413 | endif |
396 | 414 | ||
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index c0f13e8deb0b..41c7fd91e99e 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c | |||
@@ -31,7 +31,7 @@ static int lite5200_pm_valid(suspend_state_t state) | |||
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | static int lite5200_pm_set_target(suspend_state_t state) | 34 | static int lite5200_pm_begin(suspend_state_t state) |
35 | { | 35 | { |
36 | if (lite5200_pm_valid(state)) { | 36 | if (lite5200_pm_valid(state)) { |
37 | lite5200_pm_target_state = state; | 37 | lite5200_pm_target_state = state; |
@@ -219,12 +219,18 @@ static void lite5200_pm_finish(void) | |||
219 | mpc52xx_pm_finish(); | 219 | mpc52xx_pm_finish(); |
220 | } | 220 | } |
221 | 221 | ||
222 | static void lite5200_pm_end(void) | ||
223 | { | ||
224 | lite5200_pm_target_state = PM_SUSPEND_ON; | ||
225 | } | ||
226 | |||
222 | static struct platform_suspend_ops lite5200_pm_ops = { | 227 | static struct platform_suspend_ops lite5200_pm_ops = { |
223 | .valid = lite5200_pm_valid, | 228 | .valid = lite5200_pm_valid, |
224 | .set_target = lite5200_pm_set_target, | 229 | .begin = lite5200_pm_begin, |
225 | .prepare = lite5200_pm_prepare, | 230 | .prepare = lite5200_pm_prepare, |
226 | .enter = lite5200_pm_enter, | 231 | .enter = lite5200_pm_enter, |
227 | .finish = lite5200_pm_finish, | 232 | .finish = lite5200_pm_finish, |
233 | .end = lite5200_pm_end, | ||
228 | }; | 234 | }; |
229 | 235 | ||
230 | int __init lite5200_pm_init(void) | 236 | int __init lite5200_pm_init(void) |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 1cd9c8fd927d..b30c4c376a83 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -882,6 +882,10 @@ endmenu | |||
882 | menu "Power management options (EXPERIMENTAL)" | 882 | menu "Power management options (EXPERIMENTAL)" |
883 | depends on EXPERIMENTAL && SYS_SUPPORTS_PM | 883 | depends on EXPERIMENTAL && SYS_SUPPORTS_PM |
884 | 884 | ||
885 | config ARCH_SUSPEND_POSSIBLE | ||
886 | def_bool y | ||
887 | depends on !SMP | ||
888 | |||
885 | source kernel/power/Kconfig | 889 | source kernel/power/Kconfig |
886 | 890 | ||
887 | endmenu | 891 | endmenu |
diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index fbc6f2c8649f..7e816ededed7 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig | |||
@@ -6,11 +6,6 @@ config PCI | |||
6 | bus system, i.e. the way the CPU talks to the other stuff inside | 6 | bus system, i.e. the way the CPU talks to the other stuff inside |
7 | your box. If you have PCI, say Y, otherwise N. | 7 | your box. If you have PCI, say Y, otherwise N. |
8 | 8 | ||
9 | The PCI-HOWTO, available from | ||
10 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
11 | information about which PCI hardware does work under Linux and which | ||
12 | doesn't. | ||
13 | |||
14 | config SH_PCIDMA_NONCOHERENT | 9 | config SH_PCIDMA_NONCOHERENT |
15 | bool "Cache and PCI noncoherent" | 10 | bool "Cache and PCI noncoherent" |
16 | depends on PCI | 11 | depends on PCI |
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 73fc05d0bfad..158522f51d31 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -351,11 +351,6 @@ config PCI | |||
351 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or | 351 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or |
352 | VESA. If you have PCI, say Y, otherwise N. | 352 | VESA. If you have PCI, say Y, otherwise N. |
353 | 353 | ||
354 | The PCI-HOWTO, available from | ||
355 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
356 | information about which PCI hardware does work under Linux and which | ||
357 | doesn't. | ||
358 | |||
359 | config PCI_DOMAINS | 354 | config PCI_DOMAINS |
360 | def_bool PCI | 355 | def_bool PCI |
361 | 356 | ||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 93e66678e158..7109037bdf7c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -112,6 +112,14 @@ config ARCH_SUPPORTS_OPROFILE | |||
112 | 112 | ||
113 | select HAVE_KVM | 113 | select HAVE_KVM |
114 | 114 | ||
115 | config ARCH_HIBERNATION_POSSIBLE | ||
116 | def_bool y | ||
117 | depends on !SMP || !X86_VOYAGER | ||
118 | |||
119 | config ARCH_SUSPEND_POSSIBLE | ||
120 | def_bool y | ||
121 | depends on !X86_VOYAGER | ||
122 | |||
115 | config ZONE_DMA32 | 123 | config ZONE_DMA32 |
116 | bool | 124 | bool |
117 | default X86_64 | 125 | default X86_64 |
@@ -1369,11 +1377,6 @@ config PCI | |||
1369 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or | 1377 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or |
1370 | VESA. If you have PCI, say Y, otherwise N. | 1378 | VESA. If you have PCI, say Y, otherwise N. |
1371 | 1379 | ||
1372 | The PCI-HOWTO, available from | ||
1373 | <http://www.tldp.org/docs.html#howto>, contains valuable | ||
1374 | information about which PCI hardware does work under Linux and which | ||
1375 | doesn't. | ||
1376 | |||
1377 | choice | 1380 | choice |
1378 | prompt "PCI access mode" | 1381 | prompt "PCI access mode" |
1379 | depends on X86_32 && PCI && !X86_VISWS | 1382 | depends on X86_32 && PCI && !X86_VISWS |
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 150ba29a0d33..3cd7a2dcd4fe 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -30,8 +30,8 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) | |||
30 | raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); | 30 | raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); |
31 | 31 | ||
32 | if (!(word & (1 << 13))) { | 32 | if (!(word & (1 << 13))) { |
33 | printk(KERN_INFO "Intel E7520/7320/7525 detected. " | 33 | dev_info(&dev->dev, "Intel E7520/7320/7525 detected; " |
34 | "Disabling irq balancing and affinity\n"); | 34 | "disabling irq balancing and affinity\n"); |
35 | #ifdef CONFIG_IRQBALANCE | 35 | #ifdef CONFIG_IRQBALANCE |
36 | irqbalance_disable(""); | 36 | irqbalance_disable(""); |
37 | #endif | 37 | #endif |
@@ -104,14 +104,16 @@ static void ich_force_enable_hpet(struct pci_dev *dev) | |||
104 | pci_read_config_dword(dev, 0xF0, &rcba); | 104 | pci_read_config_dword(dev, 0xF0, &rcba); |
105 | rcba &= 0xFFFFC000; | 105 | rcba &= 0xFFFFC000; |
106 | if (rcba == 0) { | 106 | if (rcba == 0) { |
107 | printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n"); | 107 | dev_printk(KERN_DEBUG, &dev->dev, "RCBA disabled; " |
108 | "cannot force enable HPET\n"); | ||
108 | return; | 109 | return; |
109 | } | 110 | } |
110 | 111 | ||
111 | /* use bits 31:14, 16 kB aligned */ | 112 | /* use bits 31:14, 16 kB aligned */ |
112 | rcba_base = ioremap_nocache(rcba, 0x4000); | 113 | rcba_base = ioremap_nocache(rcba, 0x4000); |
113 | if (rcba_base == NULL) { | 114 | if (rcba_base == NULL) { |
114 | printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n"); | 115 | dev_printk(KERN_DEBUG, &dev->dev, "ioremap failed; " |
116 | "cannot force enable HPET\n"); | ||
115 | return; | 117 | return; |
116 | } | 118 | } |
117 | 119 | ||
@@ -122,8 +124,8 @@ static void ich_force_enable_hpet(struct pci_dev *dev) | |||
122 | /* HPET is enabled in HPTC. Just not reported by BIOS */ | 124 | /* HPET is enabled in HPTC. Just not reported by BIOS */ |
123 | val = val & 0x3; | 125 | val = val & 0x3; |
124 | force_hpet_address = 0xFED00000 | (val << 12); | 126 | force_hpet_address = 0xFED00000 | (val << 12); |
125 | printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", | 127 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at " |
126 | force_hpet_address); | 128 | "0x%lx\n", force_hpet_address); |
127 | iounmap(rcba_base); | 129 | iounmap(rcba_base); |
128 | return; | 130 | return; |
129 | } | 131 | } |
@@ -142,11 +144,12 @@ static void ich_force_enable_hpet(struct pci_dev *dev) | |||
142 | if (err) { | 144 | if (err) { |
143 | force_hpet_address = 0; | 145 | force_hpet_address = 0; |
144 | iounmap(rcba_base); | 146 | iounmap(rcba_base); |
145 | printk(KERN_DEBUG "Failed to force enable HPET\n"); | 147 | dev_printk(KERN_DEBUG, &dev->dev, |
148 | "Failed to force enable HPET\n"); | ||
146 | } else { | 149 | } else { |
147 | force_hpet_resume_type = ICH_FORCE_HPET_RESUME; | 150 | force_hpet_resume_type = ICH_FORCE_HPET_RESUME; |
148 | printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", | 151 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at " |
149 | force_hpet_address); | 152 | "0x%lx\n", force_hpet_address); |
150 | } | 153 | } |
151 | } | 154 | } |
152 | 155 | ||
@@ -208,8 +211,8 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev) | |||
208 | if (val & 0x4) { | 211 | if (val & 0x4) { |
209 | val &= 0x3; | 212 | val &= 0x3; |
210 | force_hpet_address = 0xFED00000 | (val << 12); | 213 | force_hpet_address = 0xFED00000 | (val << 12); |
211 | printk(KERN_DEBUG "HPET at base address 0x%lx\n", | 214 | dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n", |
212 | force_hpet_address); | 215 | force_hpet_address); |
213 | return; | 216 | return; |
214 | } | 217 | } |
215 | 218 | ||
@@ -229,14 +232,14 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev) | |||
229 | /* HPET is enabled in HPTC. Just not reported by BIOS */ | 232 | /* HPET is enabled in HPTC. Just not reported by BIOS */ |
230 | val &= 0x3; | 233 | val &= 0x3; |
231 | force_hpet_address = 0xFED00000 | (val << 12); | 234 | force_hpet_address = 0xFED00000 | (val << 12); |
232 | printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", | 235 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at " |
233 | force_hpet_address); | 236 | "0x%lx\n", force_hpet_address); |
234 | cached_dev = dev; | 237 | cached_dev = dev; |
235 | force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME; | 238 | force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME; |
236 | return; | 239 | return; |
237 | } | 240 | } |
238 | 241 | ||
239 | printk(KERN_DEBUG "Failed to force enable HPET\n"); | 242 | dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n"); |
240 | } | 243 | } |
241 | 244 | ||
242 | /* | 245 | /* |
@@ -294,8 +297,8 @@ static void vt8237_force_enable_hpet(struct pci_dev *dev) | |||
294 | */ | 297 | */ |
295 | if (val & 0x80) { | 298 | if (val & 0x80) { |
296 | force_hpet_address = (val & ~0x3ff); | 299 | force_hpet_address = (val & ~0x3ff); |
297 | printk(KERN_DEBUG "HPET at base address 0x%lx\n", | 300 | dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n", |
298 | force_hpet_address); | 301 | force_hpet_address); |
299 | return; | 302 | return; |
300 | } | 303 | } |
301 | 304 | ||
@@ -309,14 +312,14 @@ static void vt8237_force_enable_hpet(struct pci_dev *dev) | |||
309 | pci_read_config_dword(dev, 0x68, &val); | 312 | pci_read_config_dword(dev, 0x68, &val); |
310 | if (val & 0x80) { | 313 | if (val & 0x80) { |
311 | force_hpet_address = (val & ~0x3ff); | 314 | force_hpet_address = (val & ~0x3ff); |
312 | printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", | 315 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at " |
313 | force_hpet_address); | 316 | "0x%lx\n", force_hpet_address); |
314 | cached_dev = dev; | 317 | cached_dev = dev; |
315 | force_hpet_resume_type = VT8237_FORCE_HPET_RESUME; | 318 | force_hpet_resume_type = VT8237_FORCE_HPET_RESUME; |
316 | return; | 319 | return; |
317 | } | 320 | } |
318 | 321 | ||
319 | printk(KERN_DEBUG "Failed to force enable HPET\n"); | 322 | dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n"); |
320 | } | 323 | } |
321 | 324 | ||
322 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, | 325 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, |
@@ -344,7 +347,7 @@ static void nvidia_force_enable_hpet(struct pci_dev *dev) | |||
344 | pci_read_config_dword(dev, 0x44, &val); | 347 | pci_read_config_dword(dev, 0x44, &val); |
345 | force_hpet_address = val & 0xfffffffe; | 348 | force_hpet_address = val & 0xfffffffe; |
346 | force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME; | 349 | force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME; |
347 | printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", | 350 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n", |
348 | force_hpet_address); | 351 | force_hpet_address); |
349 | cached_dev = dev; | 352 | cached_dev = dev; |
350 | return; | 353 | return; |
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c index 09199511c256..7ac7130022f1 100644 --- a/arch/x86/kernel/suspend_64.c +++ b/arch/x86/kernel/suspend_64.c | |||
@@ -140,7 +140,12 @@ static void fix_processor_context(void) | |||
140 | int cpu = smp_processor_id(); | 140 | int cpu = smp_processor_id(); |
141 | struct tss_struct *t = &per_cpu(init_tss, cpu); | 141 | struct tss_struct *t = &per_cpu(init_tss, cpu); |
142 | 142 | ||
143 | set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ | 143 | /* |
144 | * This just modifies memory; should not be necessary. But... This | ||
145 | * is necessary, because 386 hardware has concept of busy TSS or some | ||
146 | * similar stupidity. | ||
147 | */ | ||
148 | set_tss_desc(cpu, t); | ||
144 | 149 | ||
145 | get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9; | 150 | get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9; |
146 | 151 | ||
@@ -160,7 +165,6 @@ static void fix_processor_context(void) | |||
160 | loaddebug(¤t->thread, 6); | 165 | loaddebug(¤t->thread, 6); |
161 | loaddebug(¤t->thread, 7); | 166 | loaddebug(¤t->thread, 7); |
162 | } | 167 | } |
163 | |||
164 | } | 168 | } |
165 | 169 | ||
166 | #ifdef CONFIG_HIBERNATION | 170 | #ifdef CONFIG_HIBERNATION |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index da524fb22422..f2f36f8dae52 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -423,23 +423,23 @@ static void __init pagetable_init(void) | |||
423 | paravirt_pagetable_setup_done(pgd_base); | 423 | paravirt_pagetable_setup_done(pgd_base); |
424 | } | 424 | } |
425 | 425 | ||
426 | #if defined(CONFIG_HIBERNATION) || defined(CONFIG_ACPI) | 426 | #ifdef CONFIG_ACPI_SLEEP |
427 | /* | 427 | /* |
428 | * Swap suspend & friends need this for resume because things like the intel-agp | 428 | * ACPI suspend needs this for resume, because things like the intel-agp |
429 | * driver might have split up a kernel 4MB mapping. | 429 | * driver might have split up a kernel 4MB mapping. |
430 | */ | 430 | */ |
431 | char __nosavedata swsusp_pg_dir[PAGE_SIZE] | 431 | char swsusp_pg_dir[PAGE_SIZE] |
432 | __attribute__ ((aligned(PAGE_SIZE))); | 432 | __attribute__ ((aligned(PAGE_SIZE))); |
433 | 433 | ||
434 | static inline void save_pg_dir(void) | 434 | static inline void save_pg_dir(void) |
435 | { | 435 | { |
436 | memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE); | 436 | memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE); |
437 | } | 437 | } |
438 | #else | 438 | #else /* !CONFIG_ACPI_SLEEP */ |
439 | static inline void save_pg_dir(void) | 439 | static inline void save_pg_dir(void) |
440 | { | 440 | { |
441 | } | 441 | } |
442 | #endif | 442 | #endif /* !CONFIG_ACPI_SLEEP */ |
443 | 443 | ||
444 | void zap_low_mappings(void) | 444 | void zap_low_mappings(void) |
445 | { | 445 | { |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index cb63007e20b2..74d30ff33c49 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -17,7 +17,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) | |||
17 | int pxb, reg; | 17 | int pxb, reg; |
18 | u8 busno, suba, subb; | 18 | u8 busno, suba, subb; |
19 | 19 | ||
20 | printk(KERN_WARNING "PCI: Searching for i450NX host bridges on %s\n", pci_name(d)); | 20 | dev_warn(&d->dev, "Searching for i450NX host bridges\n"); |
21 | reg = 0xd0; | 21 | reg = 0xd0; |
22 | for(pxb = 0; pxb < 2; pxb++) { | 22 | for(pxb = 0; pxb < 2; pxb++) { |
23 | pci_read_config_byte(d, reg++, &busno); | 23 | pci_read_config_byte(d, reg++, &busno); |
@@ -41,7 +41,7 @@ static void __devinit pci_fixup_i450gx(struct pci_dev *d) | |||
41 | */ | 41 | */ |
42 | u8 busno; | 42 | u8 busno; |
43 | pci_read_config_byte(d, 0x4a, &busno); | 43 | pci_read_config_byte(d, 0x4a, &busno); |
44 | printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno); | 44 | dev_info(&d->dev, "i440KX/GX host bridge; secondary bus %02x\n", busno); |
45 | pci_scan_bus_with_sysdata(busno); | 45 | pci_scan_bus_with_sysdata(busno); |
46 | pcibios_last_bus = -1; | 46 | pcibios_last_bus = -1; |
47 | } | 47 | } |
@@ -55,7 +55,7 @@ static void __devinit pci_fixup_umc_ide(struct pci_dev *d) | |||
55 | */ | 55 | */ |
56 | int i; | 56 | int i; |
57 | 57 | ||
58 | printk(KERN_WARNING "PCI: Fixing base address flags for device %s\n", pci_name(d)); | 58 | dev_warn(&d->dev, "Fixing base address flags\n"); |
59 | for(i = 0; i < 4; i++) | 59 | for(i = 0; i < 4; i++) |
60 | d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; | 60 | d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; |
61 | } | 61 | } |
@@ -68,7 +68,7 @@ static void __devinit pci_fixup_ncr53c810(struct pci_dev *d) | |||
68 | * Fix class to be PCI_CLASS_STORAGE_SCSI | 68 | * Fix class to be PCI_CLASS_STORAGE_SCSI |
69 | */ | 69 | */ |
70 | if (!d->class) { | 70 | if (!d->class) { |
71 | printk(KERN_WARNING "PCI: fixing NCR 53C810 class code for %s\n", pci_name(d)); | 71 | dev_warn(&d->dev, "Fixing NCR 53C810 class code\n"); |
72 | d->class = PCI_CLASS_STORAGE_SCSI << 8; | 72 | d->class = PCI_CLASS_STORAGE_SCSI << 8; |
73 | } | 73 | } |
74 | } | 74 | } |
@@ -80,7 +80,7 @@ static void __devinit pci_fixup_latency(struct pci_dev *d) | |||
80 | * SiS 5597 and 5598 chipsets require latency timer set to | 80 | * SiS 5597 and 5598 chipsets require latency timer set to |
81 | * at most 32 to avoid lockups. | 81 | * at most 32 to avoid lockups. |
82 | */ | 82 | */ |
83 | DBG("PCI: Setting max latency to 32\n"); | 83 | dev_dbg(&d->dev, "Setting max latency to 32\n"); |
84 | pcibios_max_latency = 32; | 84 | pcibios_max_latency = 32; |
85 | } | 85 | } |
86 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency); | 86 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency); |
@@ -138,7 +138,7 @@ static void pci_fixup_via_northbridge_bug(struct pci_dev *d) | |||
138 | 138 | ||
139 | pci_read_config_byte(d, where, &v); | 139 | pci_read_config_byte(d, where, &v); |
140 | if (v & ~mask) { | 140 | if (v & ~mask) { |
141 | printk(KERN_WARNING "Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x\n", \ | 141 | dev_warn(&d->dev, "Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x\n", \ |
142 | d->device, d->revision, where, v, mask, v & mask); | 142 | d->device, d->revision, where, v, mask, v & mask); |
143 | v &= mask; | 143 | v &= mask; |
144 | pci_write_config_byte(d, where, v); | 144 | pci_write_config_byte(d, where, v); |
@@ -200,7 +200,7 @@ static void pci_fixup_nforce2(struct pci_dev *dev) | |||
200 | * Apply fixup if needed, but don't touch disconnect state | 200 | * Apply fixup if needed, but don't touch disconnect state |
201 | */ | 201 | */ |
202 | if ((val & 0x00FF0000) != 0x00010000) { | 202 | if ((val & 0x00FF0000) != 0x00010000) { |
203 | printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnect fixup\n"); | 203 | dev_warn(&dev->dev, "nForce2 C1 Halt Disconnect fixup\n"); |
204 | pci_write_config_dword(dev, 0x6c, (val & 0xFF00FFFF) | 0x00010000); | 204 | pci_write_config_dword(dev, 0x6c, (val & 0xFF00FFFF) | 0x00010000); |
205 | } | 205 | } |
206 | } | 206 | } |
@@ -348,7 +348,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) | |||
348 | pci_read_config_word(pdev, PCI_COMMAND, &config); | 348 | pci_read_config_word(pdev, PCI_COMMAND, &config); |
349 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | 349 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { |
350 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | 350 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; |
351 | printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); | 351 | dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); |
352 | } | 352 | } |
353 | } | 353 | } |
354 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); | 354 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); |
@@ -388,11 +388,11 @@ static void __devinit pci_fixup_msi_k8t_onboard_sound(struct pci_dev *dev) | |||
388 | /* verify the change for status output */ | 388 | /* verify the change for status output */ |
389 | pci_read_config_byte(dev, 0x50, &val); | 389 | pci_read_config_byte(dev, 0x50, &val); |
390 | if (val & 0x40) | 390 | if (val & 0x40) |
391 | printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, " | 391 | dev_info(&dev->dev, "Detected MSI K8T Neo2-FIR; " |
392 | "can't enable onboard soundcard!\n"); | 392 | "can't enable onboard soundcard!\n"); |
393 | else | 393 | else |
394 | printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, " | 394 | dev_info(&dev->dev, "Detected MSI K8T Neo2-FIR; " |
395 | "enabled onboard soundcard.\n"); | 395 | "enabled onboard soundcard\n"); |
396 | } | 396 | } |
397 | } | 397 | } |
398 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, | 398 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index d3cb3d6af4c8..844721e8e3dd 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -174,11 +174,6 @@ config PCI | |||
174 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or | 174 | your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or |
175 | VESA. If you have PCI, say Y, otherwise N. | 175 | VESA. If you have PCI, say Y, otherwise N. |
176 | 176 | ||
177 | The PCI-HOWTO, available from | ||
178 | <http://www.linuxdoc.org/docs.html#howto>, contains valuable | ||
179 | information about which PCI hardware does work under Linux and which | ||
180 | doesn't | ||
181 | |||
182 | source "drivers/pci/Kconfig" | 177 | source "drivers/pci/Kconfig" |
183 | 178 | ||
184 | config HOTPLUG | 179 | config HOTPLUG |
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 81b248429703..fd1c4ba63367 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -192,18 +192,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | |||
192 | arg.type = ACPI_TYPE_INTEGER; | 192 | arg.type = ACPI_TYPE_INTEGER; |
193 | arg.integer.value = sleep_state; | 193 | arg.integer.value = sleep_state; |
194 | 194 | ||
195 | /* Run the _PTS and _GTS methods */ | 195 | /* Run the _PTS method */ |
196 | 196 | ||
197 | status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); | 197 | status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); |
198 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 198 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
199 | return_ACPI_STATUS(status); | 199 | return_ACPI_STATUS(status); |
200 | } | 200 | } |
201 | 201 | ||
202 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); | ||
203 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
204 | return_ACPI_STATUS(status); | ||
205 | } | ||
206 | |||
207 | /* Setup the argument to _SST */ | 202 | /* Setup the argument to _SST */ |
208 | 203 | ||
209 | switch (sleep_state) { | 204 | switch (sleep_state) { |
@@ -234,10 +229,6 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | |||
234 | "While executing method _SST")); | 229 | "While executing method _SST")); |
235 | } | 230 | } |
236 | 231 | ||
237 | /* Disable/Clear all GPEs */ | ||
238 | |||
239 | status = acpi_hw_disable_all_gpes(); | ||
240 | |||
241 | return_ACPI_STATUS(status); | 232 | return_ACPI_STATUS(status); |
242 | } | 233 | } |
243 | 234 | ||
@@ -262,6 +253,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
262 | struct acpi_bit_register_info *sleep_type_reg_info; | 253 | struct acpi_bit_register_info *sleep_type_reg_info; |
263 | struct acpi_bit_register_info *sleep_enable_reg_info; | 254 | struct acpi_bit_register_info *sleep_enable_reg_info; |
264 | u32 in_value; | 255 | u32 in_value; |
256 | struct acpi_object_list arg_list; | ||
257 | union acpi_object arg; | ||
265 | acpi_status status; | 258 | acpi_status status; |
266 | 259 | ||
267 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); | 260 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); |
@@ -307,6 +300,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
307 | return_ACPI_STATUS(status); | 300 | return_ACPI_STATUS(status); |
308 | } | 301 | } |
309 | 302 | ||
303 | /* Execute the _GTS method */ | ||
304 | |||
305 | arg_list.count = 1; | ||
306 | arg_list.pointer = &arg; | ||
307 | arg.type = ACPI_TYPE_INTEGER; | ||
308 | arg.integer.value = sleep_state; | ||
309 | |||
310 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); | ||
311 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
312 | return_ACPI_STATUS(status); | ||
313 | } | ||
314 | |||
310 | /* Get current value of PM1A control */ | 315 | /* Get current value of PM1A control */ |
311 | 316 | ||
312 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); | 317 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); |
@@ -473,17 +478,18 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) | |||
473 | 478 | ||
474 | /******************************************************************************* | 479 | /******************************************************************************* |
475 | * | 480 | * |
476 | * FUNCTION: acpi_leave_sleep_state | 481 | * FUNCTION: acpi_leave_sleep_state_prep |
477 | * | 482 | * |
478 | * PARAMETERS: sleep_state - Which sleep state we just exited | 483 | * PARAMETERS: sleep_state - Which sleep state we are exiting |
479 | * | 484 | * |
480 | * RETURN: Status | 485 | * RETURN: Status |
481 | * | 486 | * |
482 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep | 487 | * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a |
483 | * Called with interrupts ENABLED. | 488 | * sleep. |
489 | * Called with interrupts DISABLED. | ||
484 | * | 490 | * |
485 | ******************************************************************************/ | 491 | ******************************************************************************/ |
486 | acpi_status acpi_leave_sleep_state(u8 sleep_state) | 492 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) |
487 | { | 493 | { |
488 | struct acpi_object_list arg_list; | 494 | struct acpi_object_list arg_list; |
489 | union acpi_object arg; | 495 | union acpi_object arg; |
@@ -493,7 +499,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
493 | u32 PM1Acontrol; | 499 | u32 PM1Acontrol; |
494 | u32 PM1Bcontrol; | 500 | u32 PM1Bcontrol; |
495 | 501 | ||
496 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | 502 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); |
497 | 503 | ||
498 | /* | 504 | /* |
499 | * Set SLP_TYPE and SLP_EN to state S0. | 505 | * Set SLP_TYPE and SLP_EN to state S0. |
@@ -540,6 +546,41 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
540 | } | 546 | } |
541 | } | 547 | } |
542 | 548 | ||
549 | /* Execute the _BFS method */ | ||
550 | |||
551 | arg_list.count = 1; | ||
552 | arg_list.pointer = &arg; | ||
553 | arg.type = ACPI_TYPE_INTEGER; | ||
554 | arg.integer.value = sleep_state; | ||
555 | |||
556 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); | ||
557 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
558 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); | ||
559 | } | ||
560 | |||
561 | return_ACPI_STATUS(status); | ||
562 | } | ||
563 | |||
564 | /******************************************************************************* | ||
565 | * | ||
566 | * FUNCTION: acpi_leave_sleep_state | ||
567 | * | ||
568 | * PARAMETERS: sleep_state - Which sleep state we just exited | ||
569 | * | ||
570 | * RETURN: Status | ||
571 | * | ||
572 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep | ||
573 | * Called with interrupts ENABLED. | ||
574 | * | ||
575 | ******************************************************************************/ | ||
576 | acpi_status acpi_leave_sleep_state(u8 sleep_state) | ||
577 | { | ||
578 | struct acpi_object_list arg_list; | ||
579 | union acpi_object arg; | ||
580 | acpi_status status; | ||
581 | |||
582 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | ||
583 | |||
543 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ | 584 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ |
544 | 585 | ||
545 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; | 586 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; |
@@ -558,12 +599,6 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
558 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); | 599 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); |
559 | } | 600 | } |
560 | 601 | ||
561 | arg.integer.value = sleep_state; | ||
562 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); | ||
563 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
564 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); | ||
565 | } | ||
566 | |||
567 | /* | 602 | /* |
568 | * GPEs must be enabled before _WAK is called as GPEs | 603 | * GPEs must be enabled before _WAK is called as GPEs |
569 | * might get fired there | 604 | * might get fired there |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 2c0b6630f8ba..485de1347075 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -26,9 +26,24 @@ u8 sleep_states[ACPI_S_STATE_COUNT]; | |||
26 | 26 | ||
27 | #ifdef CONFIG_PM_SLEEP | 27 | #ifdef CONFIG_PM_SLEEP |
28 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 28 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
29 | static bool acpi_sleep_finish_wake_up; | ||
30 | |||
31 | /* | ||
32 | * ACPI 2.0 and later want us to execute _PTS after suspending devices, so we | ||
33 | * allow the user to request that behavior by using the 'acpi_new_pts_ordering' | ||
34 | * kernel command line option that causes the following variable to be set. | ||
35 | */ | ||
36 | static bool new_pts_ordering; | ||
37 | |||
38 | static int __init acpi_new_pts_ordering(char *str) | ||
39 | { | ||
40 | new_pts_ordering = true; | ||
41 | return 1; | ||
42 | } | ||
43 | __setup("acpi_new_pts_ordering", acpi_new_pts_ordering); | ||
29 | #endif | 44 | #endif |
30 | 45 | ||
31 | int acpi_sleep_prepare(u32 acpi_state) | 46 | static int acpi_sleep_prepare(u32 acpi_state) |
32 | { | 47 | { |
33 | #ifdef CONFIG_ACPI_SLEEP | 48 | #ifdef CONFIG_ACPI_SLEEP |
34 | /* do we have a wakeup address for S2 and S3? */ | 49 | /* do we have a wakeup address for S2 and S3? */ |
@@ -44,6 +59,8 @@ int acpi_sleep_prepare(u32 acpi_state) | |||
44 | ACPI_FLUSH_CPU_CACHE(); | 59 | ACPI_FLUSH_CPU_CACHE(); |
45 | acpi_enable_wakeup_device_prep(acpi_state); | 60 | acpi_enable_wakeup_device_prep(acpi_state); |
46 | #endif | 61 | #endif |
62 | printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", | ||
63 | acpi_state); | ||
47 | acpi_enter_sleep_state_prep(acpi_state); | 64 | acpi_enter_sleep_state_prep(acpi_state); |
48 | return 0; | 65 | return 0; |
49 | } | 66 | } |
@@ -63,17 +80,25 @@ static u32 acpi_suspend_states[] = { | |||
63 | static int init_8259A_after_S1; | 80 | static int init_8259A_after_S1; |
64 | 81 | ||
65 | /** | 82 | /** |
66 | * acpi_pm_set_target - Set the target system sleep state to the state | 83 | * acpi_pm_begin - Set the target system sleep state to the state |
67 | * associated with given @pm_state, if supported. | 84 | * associated with given @pm_state, if supported. |
68 | */ | 85 | */ |
69 | 86 | ||
70 | static int acpi_pm_set_target(suspend_state_t pm_state) | 87 | static int acpi_pm_begin(suspend_state_t pm_state) |
71 | { | 88 | { |
72 | u32 acpi_state = acpi_suspend_states[pm_state]; | 89 | u32 acpi_state = acpi_suspend_states[pm_state]; |
73 | int error = 0; | 90 | int error = 0; |
74 | 91 | ||
75 | if (sleep_states[acpi_state]) { | 92 | if (sleep_states[acpi_state]) { |
76 | acpi_target_sleep_state = acpi_state; | 93 | acpi_target_sleep_state = acpi_state; |
94 | if (new_pts_ordering) | ||
95 | return 0; | ||
96 | |||
97 | error = acpi_sleep_prepare(acpi_state); | ||
98 | if (error) | ||
99 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
100 | else | ||
101 | acpi_sleep_finish_wake_up = true; | ||
77 | } else { | 102 | } else { |
78 | printk(KERN_ERR "ACPI does not support this state: %d\n", | 103 | printk(KERN_ERR "ACPI does not support this state: %d\n", |
79 | pm_state); | 104 | pm_state); |
@@ -91,12 +116,17 @@ static int acpi_pm_set_target(suspend_state_t pm_state) | |||
91 | 116 | ||
92 | static int acpi_pm_prepare(void) | 117 | static int acpi_pm_prepare(void) |
93 | { | 118 | { |
94 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | 119 | if (new_pts_ordering) { |
120 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | ||
95 | 121 | ||
96 | if (error) | 122 | if (error) { |
97 | acpi_target_sleep_state = ACPI_STATE_S0; | 123 | acpi_target_sleep_state = ACPI_STATE_S0; |
124 | return error; | ||
125 | } | ||
126 | acpi_sleep_finish_wake_up = true; | ||
127 | } | ||
98 | 128 | ||
99 | return error; | 129 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; |
100 | } | 130 | } |
101 | 131 | ||
102 | /** | 132 | /** |
@@ -120,10 +150,8 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
120 | if (acpi_state == ACPI_STATE_S3) { | 150 | if (acpi_state == ACPI_STATE_S3) { |
121 | int error = acpi_save_state_mem(); | 151 | int error = acpi_save_state_mem(); |
122 | 152 | ||
123 | if (error) { | 153 | if (error) |
124 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
125 | return error; | 154 | return error; |
126 | } | ||
127 | } | 155 | } |
128 | 156 | ||
129 | local_irq_save(flags); | 157 | local_irq_save(flags); |
@@ -139,6 +167,9 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
139 | break; | 167 | break; |
140 | } | 168 | } |
141 | 169 | ||
170 | /* Reprogram control registers and execute _BFS */ | ||
171 | acpi_leave_sleep_state_prep(acpi_state); | ||
172 | |||
142 | /* ACPI 3.0 specs (P62) says that it's the responsabilty | 173 | /* ACPI 3.0 specs (P62) says that it's the responsabilty |
143 | * of the OSPM to clear the status bit [ implying that the | 174 | * of the OSPM to clear the status bit [ implying that the |
144 | * POWER_BUTTON event should not reach userspace ] | 175 | * POWER_BUTTON event should not reach userspace ] |
@@ -146,6 +177,13 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
146 | if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) | 177 | if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) |
147 | acpi_clear_event(ACPI_EVENT_POWER_BUTTON); | 178 | acpi_clear_event(ACPI_EVENT_POWER_BUTTON); |
148 | 179 | ||
180 | /* | ||
181 | * Disable and clear GPE status before interrupt is enabled. Some GPEs | ||
182 | * (like wakeup GPE) haven't handler, this can avoid such GPE misfire. | ||
183 | * acpi_leave_sleep_state will reenable specific GPEs later | ||
184 | */ | ||
185 | acpi_hw_disable_all_gpes(); | ||
186 | |||
149 | local_irq_restore(flags); | 187 | local_irq_restore(flags); |
150 | printk(KERN_DEBUG "Back to C!\n"); | 188 | printk(KERN_DEBUG "Back to C!\n"); |
151 | 189 | ||
@@ -157,7 +195,7 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
157 | } | 195 | } |
158 | 196 | ||
159 | /** | 197 | /** |
160 | * acpi_pm_finish - Finish up suspend sequence. | 198 | * acpi_pm_finish - Instruct the platform to leave a sleep state. |
161 | * | 199 | * |
162 | * This is called after we wake back up (or if entering the sleep state | 200 | * This is called after we wake back up (or if entering the sleep state |
163 | * failed). | 201 | * failed). |
@@ -174,6 +212,7 @@ static void acpi_pm_finish(void) | |||
174 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | 212 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); |
175 | 213 | ||
176 | acpi_target_sleep_state = ACPI_STATE_S0; | 214 | acpi_target_sleep_state = ACPI_STATE_S0; |
215 | acpi_sleep_finish_wake_up = false; | ||
177 | 216 | ||
178 | #ifdef CONFIG_X86 | 217 | #ifdef CONFIG_X86 |
179 | if (init_8259A_after_S1) { | 218 | if (init_8259A_after_S1) { |
@@ -183,6 +222,20 @@ static void acpi_pm_finish(void) | |||
183 | #endif | 222 | #endif |
184 | } | 223 | } |
185 | 224 | ||
225 | /** | ||
226 | * acpi_pm_end - Finish up suspend sequence. | ||
227 | */ | ||
228 | |||
229 | static void acpi_pm_end(void) | ||
230 | { | ||
231 | /* | ||
232 | * This is necessary in case acpi_pm_finish() is not called directly | ||
233 | * during a failing transition to a sleep state. | ||
234 | */ | ||
235 | if (acpi_sleep_finish_wake_up) | ||
236 | acpi_pm_finish(); | ||
237 | } | ||
238 | |||
186 | static int acpi_pm_state_valid(suspend_state_t pm_state) | 239 | static int acpi_pm_state_valid(suspend_state_t pm_state) |
187 | { | 240 | { |
188 | u32 acpi_state; | 241 | u32 acpi_state; |
@@ -201,10 +254,11 @@ static int acpi_pm_state_valid(suspend_state_t pm_state) | |||
201 | 254 | ||
202 | static struct platform_suspend_ops acpi_pm_ops = { | 255 | static struct platform_suspend_ops acpi_pm_ops = { |
203 | .valid = acpi_pm_state_valid, | 256 | .valid = acpi_pm_state_valid, |
204 | .set_target = acpi_pm_set_target, | 257 | .begin = acpi_pm_begin, |
205 | .prepare = acpi_pm_prepare, | 258 | .prepare = acpi_pm_prepare, |
206 | .enter = acpi_pm_enter, | 259 | .enter = acpi_pm_enter, |
207 | .finish = acpi_pm_finish, | 260 | .finish = acpi_pm_finish, |
261 | .end = acpi_pm_end, | ||
208 | }; | 262 | }; |
209 | 263 | ||
210 | /* | 264 | /* |
@@ -229,15 +283,36 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
229 | #endif /* CONFIG_SUSPEND */ | 283 | #endif /* CONFIG_SUSPEND */ |
230 | 284 | ||
231 | #ifdef CONFIG_HIBERNATION | 285 | #ifdef CONFIG_HIBERNATION |
232 | static int acpi_hibernation_start(void) | 286 | static int acpi_hibernation_begin(void) |
233 | { | 287 | { |
288 | int error; | ||
289 | |||
234 | acpi_target_sleep_state = ACPI_STATE_S4; | 290 | acpi_target_sleep_state = ACPI_STATE_S4; |
235 | return 0; | 291 | if (new_pts_ordering) |
292 | return 0; | ||
293 | |||
294 | error = acpi_sleep_prepare(ACPI_STATE_S4); | ||
295 | if (error) | ||
296 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
297 | else | ||
298 | acpi_sleep_finish_wake_up = true; | ||
299 | |||
300 | return error; | ||
236 | } | 301 | } |
237 | 302 | ||
238 | static int acpi_hibernation_prepare(void) | 303 | static int acpi_hibernation_prepare(void) |
239 | { | 304 | { |
240 | return acpi_sleep_prepare(ACPI_STATE_S4); | 305 | if (new_pts_ordering) { |
306 | int error = acpi_sleep_prepare(ACPI_STATE_S4); | ||
307 | |||
308 | if (error) { | ||
309 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
310 | return error; | ||
311 | } | ||
312 | acpi_sleep_finish_wake_up = true; | ||
313 | } | ||
314 | |||
315 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; | ||
241 | } | 316 | } |
242 | 317 | ||
243 | static int acpi_hibernation_enter(void) | 318 | static int acpi_hibernation_enter(void) |
@@ -251,6 +326,8 @@ static int acpi_hibernation_enter(void) | |||
251 | acpi_enable_wakeup_device(ACPI_STATE_S4); | 326 | acpi_enable_wakeup_device(ACPI_STATE_S4); |
252 | /* This shouldn't return. If it returns, we have a problem */ | 327 | /* This shouldn't return. If it returns, we have a problem */ |
253 | status = acpi_enter_sleep_state(ACPI_STATE_S4); | 328 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
329 | /* Reprogram control registers and execute _BFS */ | ||
330 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | ||
254 | local_irq_restore(flags); | 331 | local_irq_restore(flags); |
255 | 332 | ||
256 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 333 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
@@ -263,15 +340,12 @@ static void acpi_hibernation_leave(void) | |||
263 | * enable it here. | 340 | * enable it here. |
264 | */ | 341 | */ |
265 | acpi_enable(); | 342 | acpi_enable(); |
343 | /* Reprogram control registers and execute _BFS */ | ||
344 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | ||
266 | } | 345 | } |
267 | 346 | ||
268 | static void acpi_hibernation_finish(void) | 347 | static void acpi_hibernation_finish(void) |
269 | { | 348 | { |
270 | /* | ||
271 | * If ACPI is not enabled by the BIOS and the boot kernel, we need to | ||
272 | * enable it here. | ||
273 | */ | ||
274 | acpi_enable(); | ||
275 | acpi_disable_wakeup_device(ACPI_STATE_S4); | 349 | acpi_disable_wakeup_device(ACPI_STATE_S4); |
276 | acpi_leave_sleep_state(ACPI_STATE_S4); | 350 | acpi_leave_sleep_state(ACPI_STATE_S4); |
277 | 351 | ||
@@ -279,6 +353,17 @@ static void acpi_hibernation_finish(void) | |||
279 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | 353 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); |
280 | 354 | ||
281 | acpi_target_sleep_state = ACPI_STATE_S0; | 355 | acpi_target_sleep_state = ACPI_STATE_S0; |
356 | acpi_sleep_finish_wake_up = false; | ||
357 | } | ||
358 | |||
359 | static void acpi_hibernation_end(void) | ||
360 | { | ||
361 | /* | ||
362 | * This is necessary in case acpi_hibernation_finish() is not called | ||
363 | * directly during a failing transition to the sleep state. | ||
364 | */ | ||
365 | if (acpi_sleep_finish_wake_up) | ||
366 | acpi_hibernation_finish(); | ||
282 | } | 367 | } |
283 | 368 | ||
284 | static int acpi_hibernation_pre_restore(void) | 369 | static int acpi_hibernation_pre_restore(void) |
@@ -296,7 +381,8 @@ static void acpi_hibernation_restore_cleanup(void) | |||
296 | } | 381 | } |
297 | 382 | ||
298 | static struct platform_hibernation_ops acpi_hibernation_ops = { | 383 | static struct platform_hibernation_ops acpi_hibernation_ops = { |
299 | .start = acpi_hibernation_start, | 384 | .begin = acpi_hibernation_begin, |
385 | .end = acpi_hibernation_end, | ||
300 | .pre_snapshot = acpi_hibernation_prepare, | 386 | .pre_snapshot = acpi_hibernation_prepare, |
301 | .finish = acpi_hibernation_finish, | 387 | .finish = acpi_hibernation_finish, |
302 | .prepare = acpi_hibernation_prepare, | 388 | .prepare = acpi_hibernation_prepare, |
@@ -403,6 +489,7 @@ static void acpi_power_off_prepare(void) | |||
403 | { | 489 | { |
404 | /* Prepare to power off the system */ | 490 | /* Prepare to power off the system */ |
405 | acpi_sleep_prepare(ACPI_STATE_S5); | 491 | acpi_sleep_prepare(ACPI_STATE_S5); |
492 | acpi_hw_disable_all_gpes(); | ||
406 | } | 493 | } |
407 | 494 | ||
408 | static void acpi_power_off(void) | 495 | static void acpi_power_off(void) |
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h index a2ea125ae2d0..cfaf8f5b0a14 100644 --- a/drivers/acpi/sleep/sleep.h +++ b/drivers/acpi/sleep/sleep.h | |||
@@ -5,5 +5,3 @@ extern int acpi_suspend (u32 state); | |||
5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); | 5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); |
6 | extern void acpi_enable_wakeup_device(u8 sleep_state); | 6 | extern void acpi_enable_wakeup_device(u8 sleep_state); |
7 | extern void acpi_disable_wakeup_device(u8 sleep_state); | 7 | extern void acpi_disable_wakeup_device(u8 sleep_state); |
8 | |||
9 | extern int acpi_sleep_prepare(u32 acpi_state); | ||
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index d4590f546c49..7ed279b0a12e 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -229,7 +229,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi | |||
229 | return -ENOMEM; | 229 | return -ENOMEM; |
230 | 230 | ||
231 | /* Perform set up for DMA */ | 231 | /* Perform set up for DMA */ |
232 | if (pci_enable_device_bars(pdev, 1<<2)) { | 232 | if (pci_enable_device_io(pdev)) { |
233 | printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); | 233 | printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); |
234 | return -ENODEV; | 234 | return -ENODEV; |
235 | } | 235 | } |
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index de28dfd3b96c..911208b89259 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | obj-$(CONFIG_PM) += sysfs.o | 1 | obj-$(CONFIG_PM) += sysfs.o |
2 | obj-$(CONFIG_PM_SLEEP) += main.o | 2 | obj-$(CONFIG_PM_SLEEP) += main.o |
3 | obj-$(CONFIG_PM_TRACE) += trace.o | 3 | obj-$(CONFIG_PM_TRACE_RTC) += trace.o |
4 | 4 | ||
5 | ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG | 5 | ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG |
6 | ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG | 6 | ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index c6179d6ac6e4..a70c1c29a7aa 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -922,11 +922,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
922 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, | 922 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, |
923 | bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); | 923 | bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); |
924 | 924 | ||
925 | /* Fill what we shouldn't be filling, because usb-storage did so. */ | ||
926 | sc->work_urb.actual_length = 0; | ||
927 | sc->work_urb.error_count = 0; | ||
928 | sc->work_urb.status = 0; | ||
929 | |||
930 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 925 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
931 | /* XXX Clear stalls */ | 926 | /* XXX Clear stalls */ |
932 | ub_complete(&sc->work_done); | 927 | ub_complete(&sc->work_done); |
@@ -1313,9 +1308,6 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1313 | sc->last_pipe = pipe; | 1308 | sc->last_pipe = pipe; |
1314 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg), | 1309 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg), |
1315 | sg->length, ub_urb_complete, sc); | 1310 | sg->length, ub_urb_complete, sc); |
1316 | sc->work_urb.actual_length = 0; | ||
1317 | sc->work_urb.error_count = 0; | ||
1318 | sc->work_urb.status = 0; | ||
1319 | 1311 | ||
1320 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1312 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1321 | /* XXX Clear stalls */ | 1313 | /* XXX Clear stalls */ |
@@ -1356,9 +1348,6 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1356 | sc->last_pipe = sc->recv_bulk_pipe; | 1348 | sc->last_pipe = sc->recv_bulk_pipe; |
1357 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, | 1349 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, |
1358 | &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); | 1350 | &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); |
1359 | sc->work_urb.actual_length = 0; | ||
1360 | sc->work_urb.error_count = 0; | ||
1361 | sc->work_urb.status = 0; | ||
1362 | 1351 | ||
1363 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1352 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1364 | /* XXX Clear stalls */ | 1353 | /* XXX Clear stalls */ |
@@ -1473,9 +1462,6 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
1473 | 1462 | ||
1474 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 1463 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
1475 | (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); | 1464 | (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); |
1476 | sc->work_urb.actual_length = 0; | ||
1477 | sc->work_urb.error_count = 0; | ||
1478 | sc->work_urb.status = 0; | ||
1479 | 1465 | ||
1480 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1466 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1481 | ub_complete(&sc->work_done); | 1467 | ub_complete(&sc->work_done); |
@@ -1953,9 +1939,6 @@ static int ub_sync_reset(struct ub_dev *sc) | |||
1953 | 1939 | ||
1954 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 1940 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
1955 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); | 1941 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); |
1956 | sc->work_urb.actual_length = 0; | ||
1957 | sc->work_urb.error_count = 0; | ||
1958 | sc->work_urb.status = 0; | ||
1959 | 1942 | ||
1960 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { | 1943 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { |
1961 | printk(KERN_WARNING | 1944 | printk(KERN_WARNING |
@@ -2007,9 +1990,6 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) | |||
2007 | 1990 | ||
2008 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, | 1991 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, |
2009 | (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); | 1992 | (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); |
2010 | sc->work_urb.actual_length = 0; | ||
2011 | sc->work_urb.error_count = 0; | ||
2012 | sc->work_urb.status = 0; | ||
2013 | 1993 | ||
2014 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) | 1994 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) |
2015 | goto err_submit; | 1995 | goto err_submit; |
@@ -2077,9 +2057,6 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) | |||
2077 | 2057 | ||
2078 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 2058 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
2079 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); | 2059 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); |
2080 | sc->work_urb.actual_length = 0; | ||
2081 | sc->work_urb.error_count = 0; | ||
2082 | sc->work_urb.status = 0; | ||
2083 | 2060 | ||
2084 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { | 2061 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { |
2085 | printk(KERN_WARNING | 2062 | printk(KERN_WARNING |
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index e6c4a2b762ec..f5e7a70da831 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -492,7 +492,7 @@ static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, | |||
492 | iface->pdev = pdev; | 492 | iface->pdev = pdev; |
493 | iface->bar = bar; | 493 | iface->bar = bar; |
494 | 494 | ||
495 | rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar); | 495 | rc = pci_enable_device_io(iface->pdev); |
496 | if (rc) | 496 | if (rc) |
497 | goto errout_free; | 497 | goto errout_free; |
498 | 498 | ||
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 9e01c6dc758e..eb68a9ad0c98 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c | |||
@@ -156,8 +156,14 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic | |||
156 | ide_setup_pci_noise(dev, d); | 156 | ide_setup_pci_noise(dev, d); |
157 | 157 | ||
158 | /* We must not grab the entire device, it has 'ISA' space in its | 158 | /* We must not grab the entire device, it has 'ISA' space in its |
159 | BARS too and we will freak out other bits of the kernel */ | 159 | * BARS too and we will freak out other bits of the kernel |
160 | if (pci_enable_device_bars(dev, 1<<2)) { | 160 | * |
161 | * pci_enable_device_bars() is going away. I replaced it with | ||
162 | * IO only enable for now but I'll need confirmation this is | ||
163 | * allright for that device. If not, it will need some kind of | ||
164 | * quirk. --BenH. | ||
165 | */ | ||
166 | if (pci_enable_device_io(dev)) { | ||
161 | printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name); | 167 | printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name); |
162 | return -ENODEV; | 168 | return -ENODEV; |
163 | } | 169 | } |
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 8ff5a0ef10ad..05db429a7da8 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -228,7 +228,9 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); | |||
228 | * @d: IDE port info | 228 | * @d: IDE port info |
229 | * | 229 | * |
230 | * Enable the IDE PCI device. We attempt to enable the device in full | 230 | * Enable the IDE PCI device. We attempt to enable the device in full |
231 | * but if that fails then we only need BAR4 so we will enable that. | 231 | * but if that fails then we only need IO space. The PCI code should |
232 | * have setup the proper resources for us already for controllers in | ||
233 | * legacy mode. | ||
232 | * | 234 | * |
233 | * Returns zero on success or an error code | 235 | * Returns zero on success or an error code |
234 | */ | 236 | */ |
@@ -238,7 +240,7 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d) | |||
238 | int ret; | 240 | int ret; |
239 | 241 | ||
240 | if (pci_enable_device(dev)) { | 242 | if (pci_enable_device(dev)) { |
241 | ret = pci_enable_device_bars(dev, 1 << 4); | 243 | ret = pci_enable_device_io(dev); |
242 | if (ret < 0) { | 244 | if (ret < 0) { |
243 | printk(KERN_WARNING "%s: (ide_setup_pci_device:) " | 245 | printk(KERN_WARNING "%s: (ide_setup_pci_device:) " |
244 | "Could not enable device.\n", d->name); | 246 | "Could not enable device.\n", d->name); |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 9e5ea074ad20..ef5a6a245f5f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -108,6 +108,7 @@ int pci_bus_add_device(struct pci_dev *dev) | |||
108 | void pci_bus_add_devices(struct pci_bus *bus) | 108 | void pci_bus_add_devices(struct pci_bus *bus) |
109 | { | 109 | { |
110 | struct pci_dev *dev; | 110 | struct pci_dev *dev; |
111 | struct pci_bus *child_bus; | ||
111 | int retval; | 112 | int retval; |
112 | 113 | ||
113 | list_for_each_entry(dev, &bus->devices, bus_list) { | 114 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -138,11 +139,19 @@ void pci_bus_add_devices(struct pci_bus *bus) | |||
138 | up_write(&pci_bus_sem); | 139 | up_write(&pci_bus_sem); |
139 | } | 140 | } |
140 | pci_bus_add_devices(dev->subordinate); | 141 | pci_bus_add_devices(dev->subordinate); |
141 | retval = sysfs_create_link(&dev->subordinate->class_dev.kobj, | 142 | |
142 | &dev->dev.kobj, "bridge"); | 143 | /* register the bus with sysfs as the parent is now |
144 | * properly registered. */ | ||
145 | child_bus = dev->subordinate; | ||
146 | child_bus->dev.parent = child_bus->bridge; | ||
147 | retval = device_register(&child_bus->dev); | ||
148 | if (!retval) | ||
149 | retval = device_create_file(&child_bus->dev, | ||
150 | &dev_attr_cpuaffinity); | ||
143 | if (retval) | 151 | if (retval) |
144 | dev_err(&dev->dev, "Error creating sysfs " | 152 | dev_err(&dev->dev, "Error registering pci_bus" |
145 | "bridge symlink, continuing...\n"); | 153 | " device bridge symlink," |
154 | " continuing...\n"); | ||
146 | } | 155 | } |
147 | } | 156 | } |
148 | } | 157 | } |
@@ -204,7 +213,6 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), | |||
204 | } | 213 | } |
205 | up_read(&pci_bus_sem); | 214 | up_read(&pci_bus_sem); |
206 | } | 215 | } |
207 | EXPORT_SYMBOL_GPL(pci_walk_bus); | ||
208 | 216 | ||
209 | EXPORT_SYMBOL(pci_bus_alloc_resource); | 217 | EXPORT_SYMBOL(pci_bus_alloc_resource); |
210 | EXPORT_SYMBOL_GPL(pci_bus_add_device); | 218 | EXPORT_SYMBOL_GPL(pci_bus_add_device); |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 5dfdfdac92e1..91b2dc956be5 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/dmar.h> | 27 | #include <linux/dmar.h> |
28 | #include "iova.h" | ||
28 | 29 | ||
29 | #undef PREFIX | 30 | #undef PREFIX |
30 | #define PREFIX "DMAR:" | 31 | #define PREFIX "DMAR:" |
@@ -263,8 +264,8 @@ parse_dmar_table(void) | |||
263 | if (!dmar) | 264 | if (!dmar) |
264 | return -ENODEV; | 265 | return -ENODEV; |
265 | 266 | ||
266 | if (!dmar->width) { | 267 | if (dmar->width < PAGE_SHIFT_4K - 1) { |
267 | printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n"); | 268 | printk(KERN_WARNING PREFIX "Invalid DMAR haw\n"); |
268 | return -EINVAL; | 269 | return -EINVAL; |
269 | } | 270 | } |
270 | 271 | ||
@@ -301,11 +302,24 @@ parse_dmar_table(void) | |||
301 | int __init dmar_table_init(void) | 302 | int __init dmar_table_init(void) |
302 | { | 303 | { |
303 | 304 | ||
304 | parse_dmar_table(); | 305 | int ret; |
306 | |||
307 | ret = parse_dmar_table(); | ||
308 | if (ret) { | ||
309 | printk(KERN_INFO PREFIX "parse DMAR table failure.\n"); | ||
310 | return ret; | ||
311 | } | ||
312 | |||
305 | if (list_empty(&dmar_drhd_units)) { | 313 | if (list_empty(&dmar_drhd_units)) { |
306 | printk(KERN_INFO PREFIX "No DMAR devices found\n"); | 314 | printk(KERN_INFO PREFIX "No DMAR devices found\n"); |
307 | return -ENODEV; | 315 | return -ENODEV; |
308 | } | 316 | } |
317 | |||
318 | if (list_empty(&dmar_rmrr_units)) { | ||
319 | printk(KERN_INFO PREFIX "No RMRR found\n"); | ||
320 | return -ENODEV; | ||
321 | } | ||
322 | |||
309 | return 0; | 323 | return 0; |
310 | } | 324 | } |
311 | 325 | ||
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index a64449d489d6..2cdd8326f136 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -3,8 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menuconfig HOTPLUG_PCI | 5 | menuconfig HOTPLUG_PCI |
6 | tristate "Support for PCI Hotplug (EXPERIMENTAL)" | 6 | tristate "Support for PCI Hotplug" |
7 | depends on PCI && EXPERIMENTAL && HOTPLUG | 7 | depends on PCI && HOTPLUG |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here if you have a motherboard with a PCI Hotplug controller. | 9 | Say Y here if you have a motherboard with a PCI Hotplug controller. |
10 | This allows you to add and remove PCI cards while the machine is | 10 | This allows you to add and remove PCI cards while the machine is |
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 34a1891191fd..9bdbe1a6688f 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -3,7 +3,6 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o | 5 | obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o |
6 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o | ||
7 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o | 6 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o |
8 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o | 7 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o |
9 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | 8 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o |
@@ -16,6 +15,9 @@ obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o | |||
16 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o | 15 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o |
17 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o | 16 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o |
18 | 17 | ||
18 | # Link this last so it doesn't claim devices that have a real hotplug driver | ||
19 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o | ||
20 | |||
19 | pci_hotplug-objs := pci_hotplug_core.o | 21 | pci_hotplug-objs := pci_hotplug_core.o |
20 | 22 | ||
21 | ifdef CONFIG_HOTPLUG_PCI_CPCI | 23 | ifdef CONFIG_HOTPLUG_PCI_CPCI |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 1ef417cca2db..7a29164d4b32 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -113,7 +113,6 @@ struct acpiphp_slot { | |||
113 | u8 device; /* pci device# */ | 113 | u8 device; /* pci device# */ |
114 | 114 | ||
115 | u32 sun; /* ACPI _SUN (slot unique number) */ | 115 | u32 sun; /* ACPI _SUN (slot unique number) */ |
116 | u32 slotno; /* slot number relative to bridge */ | ||
117 | u32 flags; /* see below */ | 116 | u32 flags; /* see below */ |
118 | }; | 117 | }; |
119 | 118 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ff1b1c71291a..cf22f9e01e00 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -102,7 +102,7 @@ static int is_ejectable(acpi_handle handle) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | 104 | ||
105 | /* callback routine to check the existence of ejectable slots */ | 105 | /* callback routine to check for the existence of ejectable slots */ |
106 | static acpi_status | 106 | static acpi_status |
107 | is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | 107 | is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv) |
108 | { | 108 | { |
@@ -117,7 +117,7 @@ is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
117 | } | 117 | } |
118 | } | 118 | } |
119 | 119 | ||
120 | /* callback routine to check for the existance of a pci dock device */ | 120 | /* callback routine to check for the existence of a pci dock device */ |
121 | static acpi_status | 121 | static acpi_status |
122 | is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) | 122 | is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) |
123 | { | 123 | { |
@@ -1528,7 +1528,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
1528 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 1528 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
1529 | dbg("%s: re-enumerating slots under %s\n", | 1529 | dbg("%s: re-enumerating slots under %s\n", |
1530 | __FUNCTION__, objname); | 1530 | __FUNCTION__, objname); |
1531 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
1532 | acpiphp_check_bridge(bridge); | 1531 | acpiphp_check_bridge(bridge); |
1533 | } | 1532 | } |
1534 | return AE_OK ; | 1533 | return AE_OK ; |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index d7a293e3faf5..94b640146d44 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/workqueue.h> | ||
42 | #include "../pci.h" | 43 | #include "../pci.h" |
43 | 44 | ||
44 | #if !defined(MODULE) | 45 | #if !defined(MODULE) |
@@ -63,10 +64,16 @@ struct dummy_slot { | |||
63 | struct list_head node; | 64 | struct list_head node; |
64 | struct hotplug_slot *slot; | 65 | struct hotplug_slot *slot; |
65 | struct pci_dev *dev; | 66 | struct pci_dev *dev; |
67 | struct work_struct remove_work; | ||
68 | unsigned long removed; | ||
66 | }; | 69 | }; |
67 | 70 | ||
68 | static int debug; | 71 | static int debug; |
69 | static LIST_HEAD(slot_list); | 72 | static LIST_HEAD(slot_list); |
73 | static struct workqueue_struct *dummyphp_wq; | ||
74 | |||
75 | static void pci_rescan_worker(struct work_struct *work); | ||
76 | static DECLARE_WORK(pci_rescan_work, pci_rescan_worker); | ||
70 | 77 | ||
71 | static int enable_slot (struct hotplug_slot *slot); | 78 | static int enable_slot (struct hotplug_slot *slot); |
72 | static int disable_slot (struct hotplug_slot *slot); | 79 | static int disable_slot (struct hotplug_slot *slot); |
@@ -109,7 +116,7 @@ static int add_slot(struct pci_dev *dev) | |||
109 | slot->name = &dev->dev.bus_id[0]; | 116 | slot->name = &dev->dev.bus_id[0]; |
110 | dbg("slot->name = %s\n", slot->name); | 117 | dbg("slot->name = %s\n", slot->name); |
111 | 118 | ||
112 | dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL); | 119 | dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL); |
113 | if (!dslot) | 120 | if (!dslot) |
114 | goto error_info; | 121 | goto error_info; |
115 | 122 | ||
@@ -164,6 +171,14 @@ static void remove_slot(struct dummy_slot *dslot) | |||
164 | err("Problem unregistering a slot %s\n", dslot->slot->name); | 171 | err("Problem unregistering a slot %s\n", dslot->slot->name); |
165 | } | 172 | } |
166 | 173 | ||
174 | /* called from the single-threaded workqueue handler to remove a slot */ | ||
175 | static void remove_slot_worker(struct work_struct *work) | ||
176 | { | ||
177 | struct dummy_slot *dslot = | ||
178 | container_of(work, struct dummy_slot, remove_work); | ||
179 | remove_slot(dslot); | ||
180 | } | ||
181 | |||
167 | /** | 182 | /** |
168 | * pci_rescan_slot - Rescan slot | 183 | * pci_rescan_slot - Rescan slot |
169 | * @temp: Device template. Should be set: bus and devfn. | 184 | * @temp: Device template. Should be set: bus and devfn. |
@@ -267,11 +282,17 @@ static inline void pci_rescan(void) { | |||
267 | pci_rescan_buses(&pci_root_buses); | 282 | pci_rescan_buses(&pci_root_buses); |
268 | } | 283 | } |
269 | 284 | ||
285 | /* called from the single-threaded workqueue handler to rescan all pci buses */ | ||
286 | static void pci_rescan_worker(struct work_struct *work) | ||
287 | { | ||
288 | pci_rescan(); | ||
289 | } | ||
270 | 290 | ||
271 | static int enable_slot(struct hotplug_slot *hotplug_slot) | 291 | static int enable_slot(struct hotplug_slot *hotplug_slot) |
272 | { | 292 | { |
273 | /* mis-use enable_slot for rescanning of the pci bus */ | 293 | /* mis-use enable_slot for rescanning of the pci bus */ |
274 | pci_rescan(); | 294 | cancel_work_sync(&pci_rescan_work); |
295 | queue_work(dummyphp_wq, &pci_rescan_work); | ||
275 | return -ENODEV; | 296 | return -ENODEV; |
276 | } | 297 | } |
277 | 298 | ||
@@ -306,6 +327,10 @@ static int disable_slot(struct hotplug_slot *slot) | |||
306 | err("Can't remove PCI devices with other PCI devices behind it yet.\n"); | 327 | err("Can't remove PCI devices with other PCI devices behind it yet.\n"); |
307 | return -ENODEV; | 328 | return -ENODEV; |
308 | } | 329 | } |
330 | if (test_and_set_bit(0, &dslot->removed)) { | ||
331 | dbg("Slot already scheduled for removal\n"); | ||
332 | return -ENODEV; | ||
333 | } | ||
309 | /* search for subfunctions and disable them first */ | 334 | /* search for subfunctions and disable them first */ |
310 | if (!(dslot->dev->devfn & 7)) { | 335 | if (!(dslot->dev->devfn & 7)) { |
311 | for (func = 1; func < 8; func++) { | 336 | for (func = 1; func < 8; func++) { |
@@ -328,8 +353,9 @@ static int disable_slot(struct hotplug_slot *slot) | |||
328 | /* remove the device from the pci core */ | 353 | /* remove the device from the pci core */ |
329 | pci_remove_bus_device(dslot->dev); | 354 | pci_remove_bus_device(dslot->dev); |
330 | 355 | ||
331 | /* blow away this sysfs entry and other parts. */ | 356 | /* queue work item to blow away this sysfs entry and other parts. */ |
332 | remove_slot(dslot); | 357 | INIT_WORK(&dslot->remove_work, remove_slot_worker); |
358 | queue_work(dummyphp_wq, &dslot->remove_work); | ||
333 | 359 | ||
334 | return 0; | 360 | return 0; |
335 | } | 361 | } |
@@ -340,6 +366,7 @@ static void cleanup_slots (void) | |||
340 | struct list_head *next; | 366 | struct list_head *next; |
341 | struct dummy_slot *dslot; | 367 | struct dummy_slot *dslot; |
342 | 368 | ||
369 | destroy_workqueue(dummyphp_wq); | ||
343 | list_for_each_safe (tmp, next, &slot_list) { | 370 | list_for_each_safe (tmp, next, &slot_list) { |
344 | dslot = list_entry (tmp, struct dummy_slot, node); | 371 | dslot = list_entry (tmp, struct dummy_slot, node); |
345 | remove_slot(dslot); | 372 | remove_slot(dslot); |
@@ -351,6 +378,10 @@ static int __init dummyphp_init(void) | |||
351 | { | 378 | { |
352 | info(DRIVER_DESC "\n"); | 379 | info(DRIVER_DESC "\n"); |
353 | 380 | ||
381 | dummyphp_wq = create_singlethread_workqueue(MY_NAME); | ||
382 | if (!dummyphp_wq) | ||
383 | return -ENOMEM; | ||
384 | |||
354 | return pci_scan_buses(); | 385 | return pci_scan_buses(); |
355 | } | 386 | } |
356 | 387 | ||
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index a90c28d0c69d..87b6b8b280e6 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -761,10 +761,13 @@ static void ibm_unconfigure_device(struct pci_func *func) | |||
761 | debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0); | 761 | debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0); |
762 | 762 | ||
763 | for (j = 0; j < 0x08; j++) { | 763 | for (j = 0; j < 0x08; j++) { |
764 | temp = pci_find_slot(func->busno, (func->device << 3) | j); | 764 | temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); |
765 | if (temp) | 765 | if (temp) { |
766 | pci_remove_bus_device(temp); | 766 | pci_remove_bus_device(temp); |
767 | pci_dev_put(temp); | ||
768 | } | ||
767 | } | 769 | } |
770 | pci_dev_put(func->dev); | ||
768 | } | 771 | } |
769 | 772 | ||
770 | /* | 773 | /* |
@@ -823,7 +826,7 @@ static int ibm_configure_device(struct pci_func *func) | |||
823 | if (!(bus_structure_fixup(func->busno))) | 826 | if (!(bus_structure_fixup(func->busno))) |
824 | flag = 1; | 827 | flag = 1; |
825 | if (func->dev == NULL) | 828 | if (func->dev == NULL) |
826 | func->dev = pci_find_slot(func->busno, | 829 | func->dev = pci_get_bus_and_slot(func->busno, |
827 | PCI_DEVFN(func->device, func->function)); | 830 | PCI_DEVFN(func->device, func->function)); |
828 | 831 | ||
829 | if (func->dev == NULL) { | 832 | if (func->dev == NULL) { |
@@ -836,7 +839,7 @@ static int ibm_configure_device(struct pci_func *func) | |||
836 | if (num) | 839 | if (num) |
837 | pci_bus_add_devices(bus); | 840 | pci_bus_add_devices(bus); |
838 | 841 | ||
839 | func->dev = pci_find_slot(func->busno, | 842 | func->dev = pci_get_bus_and_slot(func->busno, |
840 | PCI_DEVFN(func->device, func->function)); | 843 | PCI_DEVFN(func->device, func->function)); |
841 | if (func->dev == NULL) { | 844 | if (func->dev == NULL) { |
842 | err("ERROR... : pci_dev still NULL\n"); | 845 | err("ERROR... : pci_dev still NULL\n"); |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 47bb0e1ff3fa..dd59a050260f 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -137,7 +137,7 @@ static int get_##name (struct hotplug_slot *slot, type *value) \ | |||
137 | int retval = 0; \ | 137 | int retval = 0; \ |
138 | if (try_module_get(ops->owner)) { \ | 138 | if (try_module_get(ops->owner)) { \ |
139 | if (ops->get_##name) \ | 139 | if (ops->get_##name) \ |
140 | retval = ops->get_##name (slot, value); \ | 140 | retval = ops->get_##name(slot, value); \ |
141 | else \ | 141 | else \ |
142 | *value = slot->info->name; \ | 142 | *value = slot->info->name; \ |
143 | module_put(ops->owner); \ | 143 | module_put(ops->owner); \ |
@@ -625,7 +625,7 @@ int pci_hp_register (struct hotplug_slot *slot) | |||
625 | if ((slot->info == NULL) || (slot->ops == NULL)) | 625 | if ((slot->info == NULL) || (slot->ops == NULL)) |
626 | return -EINVAL; | 626 | return -EINVAL; |
627 | if (slot->release == NULL) { | 627 | if (slot->release == NULL) { |
628 | dbg("Why are you trying to register a hotplug slot" | 628 | dbg("Why are you trying to register a hotplug slot " |
629 | "without a proper release function?\n"); | 629 | "without a proper release function?\n"); |
630 | return -EINVAL; | 630 | return -EINVAL; |
631 | } | 631 | } |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 7959c222dc24..ca656b27a500 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -82,24 +82,18 @@ struct event_info { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | struct controller { | 84 | struct controller { |
85 | struct controller *next; | ||
86 | struct mutex crit_sect; /* critical section mutex */ | 85 | struct mutex crit_sect; /* critical section mutex */ |
87 | struct mutex ctrl_lock; /* controller lock */ | 86 | struct mutex ctrl_lock; /* controller lock */ |
88 | int num_slots; /* Number of slots on ctlr */ | 87 | int num_slots; /* Number of slots on ctlr */ |
89 | int slot_num_inc; /* 1 or -1 */ | 88 | int slot_num_inc; /* 1 or -1 */ |
90 | struct pci_dev *pci_dev; | 89 | struct pci_dev *pci_dev; |
91 | struct list_head slot_list; | 90 | struct list_head slot_list; |
92 | struct slot *slot; | ||
93 | struct hpc_ops *hpc_ops; | 91 | struct hpc_ops *hpc_ops; |
94 | wait_queue_head_t queue; /* sleep & wake process */ | 92 | wait_queue_head_t queue; /* sleep & wake process */ |
95 | u8 bus; | ||
96 | u8 device; | ||
97 | u8 function; | ||
98 | u8 slot_device_offset; | 93 | u8 slot_device_offset; |
99 | u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ | 94 | u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ |
100 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ | 95 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ |
101 | u8 ctrlcap; | 96 | u8 ctrlcap; |
102 | u16 vendor_id; | ||
103 | u8 cap_base; | 97 | u8 cap_base; |
104 | struct timer_list poll_timer; | 98 | struct timer_list poll_timer; |
105 | volatile int cmd_busy; | 99 | volatile int cmd_busy; |
@@ -161,6 +155,9 @@ extern int pciehp_configure_device(struct slot *p_slot); | |||
161 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 155 | extern int pciehp_unconfigure_device(struct slot *p_slot); |
162 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 156 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); |
163 | int pcie_init(struct controller *ctrl, struct pcie_device *dev); | 157 | int pcie_init(struct controller *ctrl, struct pcie_device *dev); |
158 | int pciehp_enable_slot(struct slot *p_slot); | ||
159 | int pciehp_disable_slot(struct slot *p_slot); | ||
160 | int pcie_init_hardware_part2(struct controller *ctrl, struct pcie_device *dev); | ||
164 | 161 | ||
165 | static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) | 162 | static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) |
166 | { | 163 | { |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 6462ac3b405f..7f4836b8e71e 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -453,13 +453,9 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
453 | 453 | ||
454 | pci_set_drvdata(pdev, ctrl); | 454 | pci_set_drvdata(pdev, ctrl); |
455 | 455 | ||
456 | ctrl->bus = pdev->bus->number; /* ctrl bus */ | 456 | dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", |
457 | ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ | 457 | __FUNCTION__, pdev->bus->number, PCI_SLOT(pdev->devfn), |
458 | 458 | PCI_FUNC(pdev->devfn), pdev->irq); | |
459 | ctrl->device = PCI_SLOT(pdev->devfn); | ||
460 | ctrl->function = PCI_FUNC(pdev->devfn); | ||
461 | dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__, | ||
462 | ctrl->bus, ctrl->device, ctrl->function, pdev->irq); | ||
463 | 459 | ||
464 | /* Setup the slot information structures */ | 460 | /* Setup the slot information structures */ |
465 | rc = init_slots(ctrl); | 461 | rc = init_slots(ctrl); |
@@ -471,6 +467,11 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
471 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | 467 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); |
472 | 468 | ||
473 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ | 469 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ |
470 | if (value) { | ||
471 | rc = pciehp_enable_slot(t_slot); | ||
472 | if (rc) /* -ENODEV: shouldn't happen, but deal with it */ | ||
473 | value = 0; | ||
474 | } | ||
474 | if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { | 475 | if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { |
475 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ | 476 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ |
476 | if (rc) | 477 | if (rc) |
@@ -509,6 +510,24 @@ static int pciehp_suspend (struct pcie_device *dev, pm_message_t state) | |||
509 | static int pciehp_resume (struct pcie_device *dev) | 510 | static int pciehp_resume (struct pcie_device *dev) |
510 | { | 511 | { |
511 | printk("%s ENTRY\n", __FUNCTION__); | 512 | printk("%s ENTRY\n", __FUNCTION__); |
513 | if (pciehp_force) { | ||
514 | struct pci_dev *pdev = dev->port; | ||
515 | struct controller *ctrl = pci_get_drvdata(pdev); | ||
516 | struct slot *t_slot; | ||
517 | u8 status; | ||
518 | |||
519 | /* reinitialize the chipset's event detection logic */ | ||
520 | pcie_init_hardware_part2(ctrl, dev); | ||
521 | |||
522 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | ||
523 | |||
524 | /* Check if slot is occupied */ | ||
525 | t_slot->hpc_ops->get_adapter_status(t_slot, &status); | ||
526 | if (status) | ||
527 | pciehp_enable_slot(t_slot); | ||
528 | else | ||
529 | pciehp_disable_slot(t_slot); | ||
530 | } | ||
512 | return 0; | 531 | return 0; |
513 | } | 532 | } |
514 | #endif | 533 | #endif |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index f1e0966cee95..b23061c56115 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include "pciehp.h" | 37 | #include "pciehp.h" |
38 | 38 | ||
39 | static void interrupt_event_handler(struct work_struct *work); | 39 | static void interrupt_event_handler(struct work_struct *work); |
40 | static int pciehp_enable_slot(struct slot *p_slot); | ||
41 | static int pciehp_disable_slot(struct slot *p_slot); | ||
42 | 40 | ||
43 | static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | 41 | static int queue_interrupt_event(struct slot *p_slot, u32 event_type) |
44 | { | 42 | { |
@@ -197,12 +195,6 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
197 | __FUNCTION__); | 195 | __FUNCTION__); |
198 | return; | 196 | return; |
199 | } | 197 | } |
200 | /* | ||
201 | * After turning power off, we must wait for at least | ||
202 | * 1 second before taking any action that relies on | ||
203 | * power having been removed from the slot/adapter. | ||
204 | */ | ||
205 | msleep(1000); | ||
206 | } | 198 | } |
207 | } | 199 | } |
208 | 200 | ||
@@ -215,15 +207,12 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
215 | */ | 207 | */ |
216 | static int board_added(struct slot *p_slot) | 208 | static int board_added(struct slot *p_slot) |
217 | { | 209 | { |
218 | u8 hp_slot; | ||
219 | int retval = 0; | 210 | int retval = 0; |
220 | struct controller *ctrl = p_slot->ctrl; | 211 | struct controller *ctrl = p_slot->ctrl; |
221 | 212 | ||
222 | hp_slot = p_slot->device - ctrl->slot_device_offset; | ||
223 | |||
224 | dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n", | 213 | dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n", |
225 | __FUNCTION__, p_slot->device, | 214 | __FUNCTION__, p_slot->device, |
226 | ctrl->slot_device_offset, hp_slot); | 215 | ctrl->slot_device_offset, p_slot->hp_slot); |
227 | 216 | ||
228 | if (POWER_CTRL(ctrl->ctrlcap)) { | 217 | if (POWER_CTRL(ctrl->ctrlcap)) { |
229 | /* Power on slot */ | 218 | /* Power on slot */ |
@@ -281,8 +270,6 @@ err_exit: | |||
281 | */ | 270 | */ |
282 | static int remove_board(struct slot *p_slot) | 271 | static int remove_board(struct slot *p_slot) |
283 | { | 272 | { |
284 | u8 device; | ||
285 | u8 hp_slot; | ||
286 | int retval = 0; | 273 | int retval = 0; |
287 | struct controller *ctrl = p_slot->ctrl; | 274 | struct controller *ctrl = p_slot->ctrl; |
288 | 275 | ||
@@ -290,11 +277,7 @@ static int remove_board(struct slot *p_slot) | |||
290 | if (retval) | 277 | if (retval) |
291 | return retval; | 278 | return retval; |
292 | 279 | ||
293 | device = p_slot->device; | 280 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, p_slot->hp_slot); |
294 | hp_slot = p_slot->device - ctrl->slot_device_offset; | ||
295 | p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | ||
296 | |||
297 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); | ||
298 | 281 | ||
299 | if (POWER_CTRL(ctrl->ctrlcap)) { | 282 | if (POWER_CTRL(ctrl->ctrlcap)) { |
300 | /* power off slot */ | 283 | /* power off slot */ |
@@ -621,12 +604,6 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
621 | mutex_unlock(&p_slot->ctrl->crit_sect); | 604 | mutex_unlock(&p_slot->ctrl->crit_sect); |
622 | return -EINVAL; | 605 | return -EINVAL; |
623 | } | 606 | } |
624 | /* | ||
625 | * After turning power off, we must wait for at least | ||
626 | * 1 second before taking any action that relies on | ||
627 | * power having been removed from the slot/adapter. | ||
628 | */ | ||
629 | msleep(1000); | ||
630 | } | 607 | } |
631 | 608 | ||
632 | ret = remove_board(p_slot); | 609 | ret = remove_board(p_slot); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 06d025b8b13f..6eba9b2cfb90 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -636,15 +636,57 @@ static int hpc_power_on_slot(struct slot * slot) | |||
636 | return retval; | 636 | return retval; |
637 | } | 637 | } |
638 | 638 | ||
639 | static inline int pcie_mask_bad_dllp(struct controller *ctrl) | ||
640 | { | ||
641 | struct pci_dev *dev = ctrl->pci_dev; | ||
642 | int pos; | ||
643 | u32 reg; | ||
644 | |||
645 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
646 | if (!pos) | ||
647 | return 0; | ||
648 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
649 | if (reg & PCI_ERR_COR_BAD_DLLP) | ||
650 | return 0; | ||
651 | reg |= PCI_ERR_COR_BAD_DLLP; | ||
652 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
653 | return 1; | ||
654 | } | ||
655 | |||
656 | static inline void pcie_unmask_bad_dllp(struct controller *ctrl) | ||
657 | { | ||
658 | struct pci_dev *dev = ctrl->pci_dev; | ||
659 | u32 reg; | ||
660 | int pos; | ||
661 | |||
662 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
663 | if (!pos) | ||
664 | return; | ||
665 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
666 | if (!(reg & PCI_ERR_COR_BAD_DLLP)) | ||
667 | return; | ||
668 | reg &= ~PCI_ERR_COR_BAD_DLLP; | ||
669 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
670 | } | ||
671 | |||
639 | static int hpc_power_off_slot(struct slot * slot) | 672 | static int hpc_power_off_slot(struct slot * slot) |
640 | { | 673 | { |
641 | struct controller *ctrl = slot->ctrl; | 674 | struct controller *ctrl = slot->ctrl; |
642 | u16 slot_cmd; | 675 | u16 slot_cmd; |
643 | u16 cmd_mask; | 676 | u16 cmd_mask; |
644 | int retval = 0; | 677 | int retval = 0; |
678 | int changed; | ||
645 | 679 | ||
646 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); | 680 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); |
647 | 681 | ||
682 | /* | ||
683 | * Set Bad DLLP Mask bit in Correctable Error Mask | ||
684 | * Register. This is the workaround against Bad DLLP error | ||
685 | * that sometimes happens during turning power off the slot | ||
686 | * which conforms to PCI Express 1.0a spec. | ||
687 | */ | ||
688 | changed = pcie_mask_bad_dllp(ctrl); | ||
689 | |||
648 | slot_cmd = POWER_OFF; | 690 | slot_cmd = POWER_OFF; |
649 | cmd_mask = PWR_CTRL; | 691 | cmd_mask = PWR_CTRL; |
650 | /* | 692 | /* |
@@ -674,6 +716,16 @@ static int hpc_power_off_slot(struct slot * slot) | |||
674 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 716 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
675 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 717 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
676 | 718 | ||
719 | /* | ||
720 | * After turning power off, we must wait for at least 1 second | ||
721 | * before taking any action that relies on power having been | ||
722 | * removed from the slot/adapter. | ||
723 | */ | ||
724 | msleep(1000); | ||
725 | |||
726 | if (changed) | ||
727 | pcie_unmask_bad_dllp(ctrl); | ||
728 | |||
677 | return retval; | 729 | return retval; |
678 | } | 730 | } |
679 | 731 | ||
@@ -1067,13 +1119,143 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) | |||
1067 | } | 1119 | } |
1068 | #endif | 1120 | #endif |
1069 | 1121 | ||
1070 | int pcie_init(struct controller * ctrl, struct pcie_device *dev) | 1122 | static int pcie_init_hardware_part1(struct controller *ctrl, |
1123 | struct pcie_device *dev) | ||
1124 | { | ||
1125 | int rc; | ||
1126 | u16 temp_word; | ||
1127 | u32 slot_cap; | ||
1128 | u16 slot_status; | ||
1129 | |||
1130 | rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); | ||
1131 | if (rc) { | ||
1132 | err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); | ||
1133 | return -1; | ||
1134 | } | ||
1135 | |||
1136 | /* Mask Hot-plug Interrupt Enable */ | ||
1137 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | ||
1138 | if (rc) { | ||
1139 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
1140 | return -1; | ||
1141 | } | ||
1142 | |||
1143 | dbg("%s: SLOTCTRL %x value read %x\n", | ||
1144 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word); | ||
1145 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | | ||
1146 | 0x00; | ||
1147 | |||
1148 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | ||
1149 | if (rc) { | ||
1150 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | ||
1151 | return -1; | ||
1152 | } | ||
1153 | |||
1154 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
1155 | if (rc) { | ||
1156 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); | ||
1157 | return -1; | ||
1158 | } | ||
1159 | |||
1160 | temp_word = 0x1F; /* Clear all events */ | ||
1161 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); | ||
1162 | if (rc) { | ||
1163 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); | ||
1164 | return -1; | ||
1165 | } | ||
1166 | return 0; | ||
1167 | } | ||
1168 | |||
1169 | int pcie_init_hardware_part2(struct controller *ctrl, struct pcie_device *dev) | ||
1071 | { | 1170 | { |
1072 | int rc; | 1171 | int rc; |
1073 | u16 temp_word; | 1172 | u16 temp_word; |
1074 | u16 cap_reg; | ||
1075 | u16 intr_enable = 0; | 1173 | u16 intr_enable = 0; |
1076 | u32 slot_cap; | 1174 | u32 slot_cap; |
1175 | u16 slot_status; | ||
1176 | |||
1177 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | ||
1178 | if (rc) { | ||
1179 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
1180 | goto abort; | ||
1181 | } | ||
1182 | |||
1183 | intr_enable = intr_enable | PRSN_DETECT_ENABLE; | ||
1184 | |||
1185 | rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); | ||
1186 | if (rc) { | ||
1187 | err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); | ||
1188 | goto abort; | ||
1189 | } | ||
1190 | |||
1191 | if (ATTN_BUTTN(slot_cap)) | ||
1192 | intr_enable = intr_enable | ATTN_BUTTN_ENABLE; | ||
1193 | |||
1194 | if (POWER_CTRL(slot_cap)) | ||
1195 | intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE; | ||
1196 | |||
1197 | if (MRL_SENS(slot_cap)) | ||
1198 | intr_enable = intr_enable | MRL_DETECT_ENABLE; | ||
1199 | |||
1200 | temp_word = (temp_word & ~intr_enable) | intr_enable; | ||
1201 | |||
1202 | if (pciehp_poll_mode) { | ||
1203 | temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x0; | ||
1204 | } else { | ||
1205 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; | ||
1206 | } | ||
1207 | |||
1208 | /* | ||
1209 | * Unmask Hot-plug Interrupt Enable for the interrupt | ||
1210 | * notification mechanism case. | ||
1211 | */ | ||
1212 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | ||
1213 | if (rc) { | ||
1214 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | ||
1215 | goto abort; | ||
1216 | } | ||
1217 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
1218 | if (rc) { | ||
1219 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); | ||
1220 | goto abort_disable_intr; | ||
1221 | } | ||
1222 | |||
1223 | temp_word = 0x1F; /* Clear all events */ | ||
1224 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); | ||
1225 | if (rc) { | ||
1226 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); | ||
1227 | goto abort_disable_intr; | ||
1228 | } | ||
1229 | |||
1230 | if (pciehp_force) { | ||
1231 | dbg("Bypassing BIOS check for pciehp use on %s\n", | ||
1232 | pci_name(ctrl->pci_dev)); | ||
1233 | } else { | ||
1234 | rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev); | ||
1235 | if (rc) | ||
1236 | goto abort_disable_intr; | ||
1237 | } | ||
1238 | |||
1239 | return 0; | ||
1240 | |||
1241 | /* We end up here for the many possible ways to fail this API. */ | ||
1242 | abort_disable_intr: | ||
1243 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | ||
1244 | if (!rc) { | ||
1245 | temp_word &= ~(intr_enable | HP_INTR_ENABLE); | ||
1246 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | ||
1247 | } | ||
1248 | if (rc) | ||
1249 | err("%s : disabling interrupts failed\n", __FUNCTION__); | ||
1250 | abort: | ||
1251 | return -1; | ||
1252 | } | ||
1253 | |||
1254 | int pcie_init(struct controller *ctrl, struct pcie_device *dev) | ||
1255 | { | ||
1256 | int rc; | ||
1257 | u16 cap_reg; | ||
1258 | u32 slot_cap; | ||
1077 | int cap_base; | 1259 | int cap_base; |
1078 | u16 slot_status, slot_ctrl; | 1260 | u16 slot_status, slot_ctrl; |
1079 | struct pci_dev *pdev; | 1261 | struct pci_dev *pdev; |
@@ -1084,9 +1266,10 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1084 | dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", | 1266 | dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", |
1085 | __FUNCTION__, pdev->vendor, pdev->device); | 1267 | __FUNCTION__, pdev->vendor, pdev->device); |
1086 | 1268 | ||
1087 | if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) { | 1269 | cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); |
1270 | if (cap_base == 0) { | ||
1088 | dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__); | 1271 | dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__); |
1089 | goto abort_free_ctlr; | 1272 | goto abort; |
1090 | } | 1273 | } |
1091 | 1274 | ||
1092 | ctrl->cap_base = cap_base; | 1275 | ctrl->cap_base = cap_base; |
@@ -1096,7 +1279,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1096 | rc = pciehp_readw(ctrl, CAPREG, &cap_reg); | 1279 | rc = pciehp_readw(ctrl, CAPREG, &cap_reg); |
1097 | if (rc) { | 1280 | if (rc) { |
1098 | err("%s: Cannot read CAPREG register\n", __FUNCTION__); | 1281 | err("%s: Cannot read CAPREG register\n", __FUNCTION__); |
1099 | goto abort_free_ctlr; | 1282 | goto abort; |
1100 | } | 1283 | } |
1101 | dbg("%s: CAPREG offset %x cap_reg %x\n", | 1284 | dbg("%s: CAPREG offset %x cap_reg %x\n", |
1102 | __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg); | 1285 | __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg); |
@@ -1106,26 +1289,26 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1106 | && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { | 1289 | && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { |
1107 | dbg("%s : This is not a root port or the port is not " | 1290 | dbg("%s : This is not a root port or the port is not " |
1108 | "connected to a slot\n", __FUNCTION__); | 1291 | "connected to a slot\n", __FUNCTION__); |
1109 | goto abort_free_ctlr; | 1292 | goto abort; |
1110 | } | 1293 | } |
1111 | 1294 | ||
1112 | rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); | 1295 | rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); |
1113 | if (rc) { | 1296 | if (rc) { |
1114 | err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); | 1297 | err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); |
1115 | goto abort_free_ctlr; | 1298 | goto abort; |
1116 | } | 1299 | } |
1117 | dbg("%s: SLOTCAP offset %x slot_cap %x\n", | 1300 | dbg("%s: SLOTCAP offset %x slot_cap %x\n", |
1118 | __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap); | 1301 | __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap); |
1119 | 1302 | ||
1120 | if (!(slot_cap & HP_CAP)) { | 1303 | if (!(slot_cap & HP_CAP)) { |
1121 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); | 1304 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); |
1122 | goto abort_free_ctlr; | 1305 | goto abort; |
1123 | } | 1306 | } |
1124 | /* For debugging purpose */ | 1307 | /* For debugging purpose */ |
1125 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 1308 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
1126 | if (rc) { | 1309 | if (rc) { |
1127 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); | 1310 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
1128 | goto abort_free_ctlr; | 1311 | goto abort; |
1129 | } | 1312 | } |
1130 | dbg("%s: SLOTSTATUS offset %x slot_status %x\n", | 1313 | dbg("%s: SLOTSTATUS offset %x slot_status %x\n", |
1131 | __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status); | 1314 | __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status); |
@@ -1133,7 +1316,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1133 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 1316 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
1134 | if (rc) { | 1317 | if (rc) { |
1135 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 1318 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
1136 | goto abort_free_ctlr; | 1319 | goto abort; |
1137 | } | 1320 | } |
1138 | dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", | 1321 | dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", |
1139 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | 1322 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); |
@@ -1161,36 +1344,9 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1161 | ctrl->first_slot = slot_cap >> 19; | 1344 | ctrl->first_slot = slot_cap >> 19; |
1162 | ctrl->ctrlcap = slot_cap & 0x0000007f; | 1345 | ctrl->ctrlcap = slot_cap & 0x0000007f; |
1163 | 1346 | ||
1164 | /* Mask Hot-plug Interrupt Enable */ | 1347 | rc = pcie_init_hardware_part1(ctrl, dev); |
1165 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | 1348 | if (rc) |
1166 | if (rc) { | 1349 | goto abort; |
1167 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
1168 | goto abort_free_ctlr; | ||
1169 | } | ||
1170 | |||
1171 | dbg("%s: SLOTCTRL %x value read %x\n", | ||
1172 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word); | ||
1173 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | | ||
1174 | 0x00; | ||
1175 | |||
1176 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | ||
1177 | if (rc) { | ||
1178 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | ||
1179 | goto abort_free_ctlr; | ||
1180 | } | ||
1181 | |||
1182 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
1183 | if (rc) { | ||
1184 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); | ||
1185 | goto abort_free_ctlr; | ||
1186 | } | ||
1187 | |||
1188 | temp_word = 0x1F; /* Clear all events */ | ||
1189 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); | ||
1190 | if (rc) { | ||
1191 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); | ||
1192 | goto abort_free_ctlr; | ||
1193 | } | ||
1194 | 1350 | ||
1195 | if (pciehp_poll_mode) { | 1351 | if (pciehp_poll_mode) { |
1196 | /* Install interrupt polling timer. Start with 10 sec delay */ | 1352 | /* Install interrupt polling timer. Start with 10 sec delay */ |
@@ -1206,7 +1362,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1206 | if (rc) { | 1362 | if (rc) { |
1207 | err("Can't get irq %d for the hotplug controller\n", | 1363 | err("Can't get irq %d for the hotplug controller\n", |
1208 | ctrl->pci_dev->irq); | 1364 | ctrl->pci_dev->irq); |
1209 | goto abort_free_ctlr; | 1365 | goto abort; |
1210 | } | 1366 | } |
1211 | } | 1367 | } |
1212 | dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, | 1368 | dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, |
@@ -1224,82 +1380,16 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1224 | } | 1380 | } |
1225 | } | 1381 | } |
1226 | 1382 | ||
1227 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | 1383 | rc = pcie_init_hardware_part2(ctrl, dev); |
1228 | if (rc) { | 1384 | if (rc == 0) { |
1229 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 1385 | ctrl->hpc_ops = &pciehp_hpc_ops; |
1230 | goto abort_free_irq; | 1386 | return 0; |
1231 | } | 1387 | } |
1232 | |||
1233 | intr_enable = intr_enable | PRSN_DETECT_ENABLE; | ||
1234 | |||
1235 | if (ATTN_BUTTN(slot_cap)) | ||
1236 | intr_enable = intr_enable | ATTN_BUTTN_ENABLE; | ||
1237 | |||
1238 | if (POWER_CTRL(slot_cap)) | ||
1239 | intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE; | ||
1240 | |||
1241 | if (MRL_SENS(slot_cap)) | ||
1242 | intr_enable = intr_enable | MRL_DETECT_ENABLE; | ||
1243 | |||
1244 | temp_word = (temp_word & ~intr_enable) | intr_enable; | ||
1245 | |||
1246 | if (pciehp_poll_mode) { | ||
1247 | temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x0; | ||
1248 | } else { | ||
1249 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; | ||
1250 | } | ||
1251 | |||
1252 | /* | ||
1253 | * Unmask Hot-plug Interrupt Enable for the interrupt | ||
1254 | * notification mechanism case. | ||
1255 | */ | ||
1256 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | ||
1257 | if (rc) { | ||
1258 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | ||
1259 | goto abort_free_irq; | ||
1260 | } | ||
1261 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
1262 | if (rc) { | ||
1263 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); | ||
1264 | goto abort_disable_intr; | ||
1265 | } | ||
1266 | |||
1267 | temp_word = 0x1F; /* Clear all events */ | ||
1268 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); | ||
1269 | if (rc) { | ||
1270 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); | ||
1271 | goto abort_disable_intr; | ||
1272 | } | ||
1273 | |||
1274 | if (pciehp_force) { | ||
1275 | dbg("Bypassing BIOS check for pciehp use on %s\n", | ||
1276 | pci_name(ctrl->pci_dev)); | ||
1277 | } else { | ||
1278 | rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev); | ||
1279 | if (rc) | ||
1280 | goto abort_disable_intr; | ||
1281 | } | ||
1282 | |||
1283 | ctrl->hpc_ops = &pciehp_hpc_ops; | ||
1284 | |||
1285 | return 0; | ||
1286 | |||
1287 | /* We end up here for the many possible ways to fail this API. */ | ||
1288 | abort_disable_intr: | ||
1289 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | ||
1290 | if (!rc) { | ||
1291 | temp_word &= ~(intr_enable | HP_INTR_ENABLE); | ||
1292 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | ||
1293 | } | ||
1294 | if (rc) | ||
1295 | err("%s : disabling interrupts failed\n", __FUNCTION__); | ||
1296 | |||
1297 | abort_free_irq: | 1388 | abort_free_irq: |
1298 | if (pciehp_poll_mode) | 1389 | if (pciehp_poll_mode) |
1299 | del_timer_sync(&ctrl->poll_timer); | 1390 | del_timer_sync(&ctrl->poll_timer); |
1300 | else | 1391 | else |
1301 | free_irq(ctrl->pci_dev->irq, ctrl); | 1392 | free_irq(ctrl->pci_dev->irq, ctrl); |
1302 | 1393 | abort: | |
1303 | abort_free_ctlr: | ||
1304 | return -1; | 1394 | return -1; |
1305 | } | 1395 | } |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index c424aded13fb..dd50713966d1 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -105,12 +105,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | /* Find Advanced Error Reporting Enhanced Capability */ | 107 | /* Find Advanced Error Reporting Enhanced Capability */ |
108 | pos = 256; | 108 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
109 | do { | ||
110 | pci_read_config_dword(dev, pos, ®32); | ||
111 | if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR) | ||
112 | break; | ||
113 | } while ((pos = PCI_EXT_CAP_NEXT(reg32))); | ||
114 | if (!pos) | 109 | if (!pos) |
115 | return; | 110 | return; |
116 | 111 | ||
@@ -248,11 +243,15 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
248 | u8 bctl = 0; | 243 | u8 bctl = 0; |
249 | u8 presence = 0; | 244 | u8 presence = 0; |
250 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; | 245 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; |
246 | u16 command; | ||
251 | 247 | ||
252 | dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, | 248 | dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, |
253 | p_slot->device); | 249 | p_slot->device); |
250 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence); | ||
251 | if (ret) | ||
252 | presence = 0; | ||
254 | 253 | ||
255 | for (j=0; j<8 ; j++) { | 254 | for (j = 0; j < 8; j++) { |
256 | struct pci_dev* temp = pci_get_slot(parent, | 255 | struct pci_dev* temp = pci_get_slot(parent, |
257 | (p_slot->device << 3) | j); | 256 | (p_slot->device << 3) | j); |
258 | if (!temp) | 257 | if (!temp) |
@@ -263,21 +262,26 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
263 | pci_dev_put(temp); | 262 | pci_dev_put(temp); |
264 | continue; | 263 | continue; |
265 | } | 264 | } |
266 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 265 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { |
267 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, | 266 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); |
268 | &presence); | 267 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
269 | if (!ret && presence) { | 268 | err("Cannot remove display device %s\n", |
270 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, | 269 | pci_name(temp)); |
271 | &bctl); | 270 | pci_dev_put(temp); |
272 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 271 | continue; |
273 | err("Cannot remove display device %s\n", | ||
274 | pci_name(temp)); | ||
275 | pci_dev_put(temp); | ||
276 | continue; | ||
277 | } | ||
278 | } | 272 | } |
279 | } | 273 | } |
280 | pci_remove_bus_device(temp); | 274 | pci_remove_bus_device(temp); |
275 | /* | ||
276 | * Ensure that no new Requests will be generated from | ||
277 | * the device. | ||
278 | */ | ||
279 | if (presence) { | ||
280 | pci_read_config_word(temp, PCI_COMMAND, &command); | ||
281 | command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); | ||
282 | command |= PCI_COMMAND_INTX_DISABLE; | ||
283 | pci_write_config_word(temp, PCI_COMMAND, command); | ||
284 | } | ||
281 | pci_dev_put(temp); | 285 | pci_dev_put(temp); |
282 | } | 286 | } |
283 | /* | 287 | /* |
@@ -288,4 +292,3 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
288 | 292 | ||
289 | return rc; | 293 | return rc; |
290 | } | 294 | } |
291 | |||
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index c822a779653f..7d5921b1ee78 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
@@ -74,7 +74,6 @@ struct slot { | |||
74 | u32 type; | 74 | u32 type; |
75 | u32 power_domain; | 75 | u32 power_domain; |
76 | char *name; | 76 | char *name; |
77 | char *location; | ||
78 | struct device_node *dn; | 77 | struct device_node *dn; |
79 | struct pci_bus *bus; | 78 | struct pci_bus *bus; |
80 | struct list_head *pci_devs; | 79 | struct list_head *pci_devs; |
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 0de84533cd80..6571e9b4c2ec 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -64,19 +64,6 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state) | |||
64 | return rc; | 64 | return rc; |
65 | } | 65 | } |
66 | 66 | ||
67 | static void set_slot_name(struct slot *slot) | ||
68 | { | ||
69 | struct pci_bus *bus = slot->bus; | ||
70 | struct pci_dev *bridge; | ||
71 | |||
72 | bridge = bus->self; | ||
73 | if (bridge) | ||
74 | strcpy(slot->name, pci_name(bridge)); | ||
75 | else | ||
76 | sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus), | ||
77 | bus->number); | ||
78 | } | ||
79 | |||
80 | /** | 67 | /** |
81 | * rpaphp_enable_slot - record slot state, config pci device | 68 | * rpaphp_enable_slot - record slot state, config pci device |
82 | * @slot: target &slot | 69 | * @slot: target &slot |
@@ -115,7 +102,6 @@ int rpaphp_enable_slot(struct slot *slot) | |||
115 | info->adapter_status = EMPTY; | 102 | info->adapter_status = EMPTY; |
116 | slot->bus = bus; | 103 | slot->bus = bus; |
117 | slot->pci_devs = &bus->devices; | 104 | slot->pci_devs = &bus->devices; |
118 | set_slot_name(slot); | ||
119 | 105 | ||
120 | /* if there's an adapter in the slot, go add the pci devices */ | 106 | /* if there's an adapter in the slot, go add the pci devices */ |
121 | if (state == PRESENT) { | 107 | if (state == PRESENT) { |
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index d4ee8723fcb3..8ad3debb3794 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c | |||
@@ -33,23 +33,31 @@ | |||
33 | #include <asm/rtas.h> | 33 | #include <asm/rtas.h> |
34 | #include "rpaphp.h" | 34 | #include "rpaphp.h" |
35 | 35 | ||
36 | static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) | 36 | static ssize_t address_read_file (struct hotplug_slot *php_slot, char *buf) |
37 | { | 37 | { |
38 | char *value; | 38 | int retval; |
39 | int retval = -ENOENT; | ||
40 | struct slot *slot = (struct slot *)php_slot->private; | 39 | struct slot *slot = (struct slot *)php_slot->private; |
40 | struct pci_bus *bus; | ||
41 | 41 | ||
42 | if (!slot) | 42 | if (!slot) |
43 | return retval; | 43 | return -ENOENT; |
44 | |||
45 | bus = slot->bus; | ||
46 | if (!bus) | ||
47 | return -ENOENT; | ||
48 | |||
49 | if (bus->self) | ||
50 | retval = sprintf(buf, pci_name(bus->self)); | ||
51 | else | ||
52 | retval = sprintf(buf, "%04x:%02x:00.0", | ||
53 | pci_domain_nr(bus), bus->number); | ||
44 | 54 | ||
45 | value = slot->location; | ||
46 | retval = sprintf (buf, "%s\n", value); | ||
47 | return retval; | 55 | return retval; |
48 | } | 56 | } |
49 | 57 | ||
50 | static struct hotplug_slot_attribute php_attr_location = { | 58 | static struct hotplug_slot_attribute php_attr_address = { |
51 | .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, | 59 | .attr = {.name = "address", .mode = S_IFREG | S_IRUGO}, |
52 | .show = location_read_file, | 60 | .show = address_read_file, |
53 | }; | 61 | }; |
54 | 62 | ||
55 | /* free up the memory used by a slot */ | 63 | /* free up the memory used by a slot */ |
@@ -64,7 +72,6 @@ void dealloc_slot_struct(struct slot *slot) | |||
64 | kfree(slot->hotplug_slot->info); | 72 | kfree(slot->hotplug_slot->info); |
65 | kfree(slot->hotplug_slot->name); | 73 | kfree(slot->hotplug_slot->name); |
66 | kfree(slot->hotplug_slot); | 74 | kfree(slot->hotplug_slot); |
67 | kfree(slot->location); | ||
68 | kfree(slot); | 75 | kfree(slot); |
69 | } | 76 | } |
70 | 77 | ||
@@ -83,16 +90,13 @@ struct slot *alloc_slot_struct(struct device_node *dn, | |||
83 | GFP_KERNEL); | 90 | GFP_KERNEL); |
84 | if (!slot->hotplug_slot->info) | 91 | if (!slot->hotplug_slot->info) |
85 | goto error_hpslot; | 92 | goto error_hpslot; |
86 | slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL); | 93 | slot->hotplug_slot->name = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); |
87 | if (!slot->hotplug_slot->name) | 94 | if (!slot->hotplug_slot->name) |
88 | goto error_info; | 95 | goto error_info; |
89 | slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); | ||
90 | if (!slot->location) | ||
91 | goto error_name; | ||
92 | slot->name = slot->hotplug_slot->name; | 96 | slot->name = slot->hotplug_slot->name; |
97 | strcpy(slot->name, drc_name); | ||
93 | slot->dn = dn; | 98 | slot->dn = dn; |
94 | slot->index = drc_index; | 99 | slot->index = drc_index; |
95 | strcpy(slot->location, drc_name); | ||
96 | slot->power_domain = power_domain; | 100 | slot->power_domain = power_domain; |
97 | slot->hotplug_slot->private = slot; | 101 | slot->hotplug_slot->private = slot; |
98 | slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops; | 102 | slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops; |
@@ -100,8 +104,6 @@ struct slot *alloc_slot_struct(struct device_node *dn, | |||
100 | 104 | ||
101 | return (slot); | 105 | return (slot); |
102 | 106 | ||
103 | error_name: | ||
104 | kfree(slot->hotplug_slot->name); | ||
105 | error_info: | 107 | error_info: |
106 | kfree(slot->hotplug_slot->info); | 108 | kfree(slot->hotplug_slot->info); |
107 | error_hpslot: | 109 | error_hpslot: |
@@ -133,8 +135,8 @@ int rpaphp_deregister_slot(struct slot *slot) | |||
133 | 135 | ||
134 | list_del(&slot->rpaphp_slot_list); | 136 | list_del(&slot->rpaphp_slot_list); |
135 | 137 | ||
136 | /* remove "phy_location" file */ | 138 | /* remove "address" file */ |
137 | sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr); | 139 | sysfs_remove_file(&php_slot->kobj, &php_attr_address.attr); |
138 | 140 | ||
139 | retval = pci_hp_deregister(php_slot); | 141 | retval = pci_hp_deregister(php_slot); |
140 | if (retval) | 142 | if (retval) |
@@ -166,8 +168,8 @@ int rpaphp_register_slot(struct slot *slot) | |||
166 | return retval; | 168 | return retval; |
167 | } | 169 | } |
168 | 170 | ||
169 | /* create "phy_location" file */ | 171 | /* create "address" file */ |
170 | retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr); | 172 | retval = sysfs_create_file(&php_slot->kobj, &php_attr_address.attr); |
171 | if (retval) { | 173 | if (retval) { |
172 | err("sysfs_create_file failed with error %d\n", retval); | 174 | err("sysfs_create_file failed with error %d\n", retval); |
173 | goto sysfs_fail; | 175 | goto sysfs_fail; |
@@ -175,8 +177,7 @@ int rpaphp_register_slot(struct slot *slot) | |||
175 | 177 | ||
176 | /* add slot to our internal list */ | 178 | /* add slot to our internal list */ |
177 | list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); | 179 | list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); |
178 | info("Slot [%s](PCI location=%s) registered\n", slot->name, | 180 | info("Slot [%s] registered\n", slot->name); |
179 | slot->location); | ||
180 | return 0; | 181 | return 0; |
181 | 182 | ||
182 | sysfs_fail: | 183 | sysfs_fail: |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 5183a45d45b5..e8aa138128ce 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -597,7 +597,7 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
597 | cleanup_slots(ctrl); | 597 | cleanup_slots(ctrl); |
598 | 598 | ||
599 | /* | 599 | /* |
600 | * Mask SERR and System Interrut generation | 600 | * Mask SERR and System Interrupt generation |
601 | */ | 601 | */ |
602 | serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE); | 602 | serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE); |
603 | serr_int |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK | | 603 | serr_int |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK | |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index e079a5237c94..4e01df99681a 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1781,7 +1781,7 @@ __intel_alloc_iova(struct device *dev, struct dmar_domain *domain, | |||
1781 | /* | 1781 | /* |
1782 | * First try to allocate an io virtual address in | 1782 | * First try to allocate an io virtual address in |
1783 | * DMA_32BIT_MASK and if that fails then try allocating | 1783 | * DMA_32BIT_MASK and if that fails then try allocating |
1784 | * from higer range | 1784 | * from higher range |
1785 | */ | 1785 | */ |
1786 | iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK); | 1786 | iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK); |
1787 | if (!iova) | 1787 | if (!iova) |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 07c9f09c856d..26938da8f438 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -25,6 +25,51 @@ | |||
25 | 25 | ||
26 | static int pci_msi_enable = 1; | 26 | static int pci_msi_enable = 1; |
27 | 27 | ||
28 | /* Arch hooks */ | ||
29 | |||
30 | int __attribute__ ((weak)) | ||
31 | arch_msi_check_device(struct pci_dev *dev, int nvec, int type) | ||
32 | { | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | int __attribute__ ((weak)) | ||
37 | arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry) | ||
38 | { | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | int __attribute__ ((weak)) | ||
43 | arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | ||
44 | { | ||
45 | struct msi_desc *entry; | ||
46 | int ret; | ||
47 | |||
48 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
49 | ret = arch_setup_msi_irq(dev, entry); | ||
50 | if (ret) | ||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq) | ||
58 | { | ||
59 | return; | ||
60 | } | ||
61 | |||
62 | void __attribute__ ((weak)) | ||
63 | arch_teardown_msi_irqs(struct pci_dev *dev) | ||
64 | { | ||
65 | struct msi_desc *entry; | ||
66 | |||
67 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
68 | if (entry->irq != 0) | ||
69 | arch_teardown_msi_irq(entry->irq); | ||
70 | } | ||
71 | } | ||
72 | |||
28 | static void msi_set_enable(struct pci_dev *dev, int enable) | 73 | static void msi_set_enable(struct pci_dev *dev, int enable) |
29 | { | 74 | { |
30 | int pos; | 75 | int pos; |
@@ -230,7 +275,6 @@ static void pci_intx_for_msi(struct pci_dev *dev, int enable) | |||
230 | pci_intx(dev, enable); | 275 | pci_intx(dev, enable); |
231 | } | 276 | } |
232 | 277 | ||
233 | #ifdef CONFIG_PM | ||
234 | static void __pci_restore_msi_state(struct pci_dev *dev) | 278 | static void __pci_restore_msi_state(struct pci_dev *dev) |
235 | { | 279 | { |
236 | int pos; | 280 | int pos; |
@@ -288,7 +332,7 @@ void pci_restore_msi_state(struct pci_dev *dev) | |||
288 | __pci_restore_msi_state(dev); | 332 | __pci_restore_msi_state(dev); |
289 | __pci_restore_msix_state(dev); | 333 | __pci_restore_msix_state(dev); |
290 | } | 334 | } |
291 | #endif /* CONFIG_PM */ | 335 | EXPORT_SYMBOL_GPL(pci_restore_msi_state); |
292 | 336 | ||
293 | /** | 337 | /** |
294 | * msi_capability_init - configure device's MSI capability structure | 338 | * msi_capability_init - configure device's MSI capability structure |
@@ -683,49 +727,3 @@ void pci_msi_init_pci_dev(struct pci_dev *dev) | |||
683 | { | 727 | { |
684 | INIT_LIST_HEAD(&dev->msi_list); | 728 | INIT_LIST_HEAD(&dev->msi_list); |
685 | } | 729 | } |
686 | |||
687 | |||
688 | /* Arch hooks */ | ||
689 | |||
690 | int __attribute__ ((weak)) | ||
691 | arch_msi_check_device(struct pci_dev* dev, int nvec, int type) | ||
692 | { | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | int __attribute__ ((weak)) | ||
697 | arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry) | ||
698 | { | ||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | int __attribute__ ((weak)) | ||
703 | arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | ||
704 | { | ||
705 | struct msi_desc *entry; | ||
706 | int ret; | ||
707 | |||
708 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
709 | ret = arch_setup_msi_irq(dev, entry); | ||
710 | if (ret) | ||
711 | return ret; | ||
712 | } | ||
713 | |||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq) | ||
718 | { | ||
719 | return; | ||
720 | } | ||
721 | |||
722 | void __attribute__ ((weak)) | ||
723 | arch_teardown_msi_irqs(struct pci_dev *dev) | ||
724 | { | ||
725 | struct msi_desc *entry; | ||
726 | |||
727 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
728 | if (entry->irq != 0) | ||
729 | arch_teardown_msi_irq(entry->irq); | ||
730 | } | ||
731 | } | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 5c6a5d043007..e569645d59e2 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -156,13 +156,13 @@ run_osc_out: | |||
156 | } | 156 | } |
157 | 157 | ||
158 | /** | 158 | /** |
159 | * pci_osc_support_set - register OS support to Firmware | 159 | * __pci_osc_support_set - register OS support to Firmware |
160 | * @flags: OS support bits | 160 | * @flags: OS support bits |
161 | * | 161 | * |
162 | * Update OS support fields and doing a _OSC Query to obtain an update | 162 | * Update OS support fields and doing a _OSC Query to obtain an update |
163 | * from Firmware on supported control bits. | 163 | * from Firmware on supported control bits. |
164 | **/ | 164 | **/ |
165 | acpi_status pci_osc_support_set(u32 flags) | 165 | acpi_status __pci_osc_support_set(u32 flags, const char *hid) |
166 | { | 166 | { |
167 | u32 temp; | 167 | u32 temp; |
168 | acpi_status retval; | 168 | acpi_status retval; |
@@ -176,7 +176,7 @@ acpi_status pci_osc_support_set(u32 flags) | |||
176 | temp = ctrlset_buf[OSC_CONTROL_TYPE]; | 176 | temp = ctrlset_buf[OSC_CONTROL_TYPE]; |
177 | ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | 177 | ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; |
178 | ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; | 178 | ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; |
179 | acpi_get_devices ( PCI_ROOT_HID_STRING, | 179 | acpi_get_devices(hid, |
180 | acpi_query_osc, | 180 | acpi_query_osc, |
181 | ctrlset_buf, | 181 | ctrlset_buf, |
182 | (void **) &retval ); | 182 | (void **) &retval ); |
@@ -188,7 +188,6 @@ acpi_status pci_osc_support_set(u32 flags) | |||
188 | } | 188 | } |
189 | return AE_OK; | 189 | return AE_OK; |
190 | } | 190 | } |
191 | EXPORT_SYMBOL(pci_osc_support_set); | ||
192 | 191 | ||
193 | /** | 192 | /** |
194 | * pci_osc_control_set - commit requested control to Firmware | 193 | * pci_osc_control_set - commit requested control to Firmware |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index c4fa35d1dd77..e571c72e6753 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -186,13 +186,11 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | |||
186 | set_cpus_allowed(current, node_to_cpumask(node)); | 186 | set_cpus_allowed(current, node_to_cpumask(node)); |
187 | /* And set default memory allocation policy */ | 187 | /* And set default memory allocation policy */ |
188 | oldpol = current->mempolicy; | 188 | oldpol = current->mempolicy; |
189 | current->mempolicy = &default_policy; | 189 | current->mempolicy = NULL; /* fall back to system default policy */ |
190 | mpol_get(current->mempolicy); | ||
191 | #endif | 190 | #endif |
192 | error = drv->probe(dev, id); | 191 | error = drv->probe(dev, id); |
193 | #ifdef CONFIG_NUMA | 192 | #ifdef CONFIG_NUMA |
194 | set_cpus_allowed(current, oldmask); | 193 | set_cpus_allowed(current, oldmask); |
195 | mpol_free(current->mempolicy); | ||
196 | current->mempolicy = oldpol; | 194 | current->mempolicy = oldpol; |
197 | #endif | 195 | #endif |
198 | return error; | 196 | return error; |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 7d1877341aad..abf4203304e4 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/topology.h> | 21 | #include <linux/topology.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/capability.h> | 23 | #include <linux/capability.h> |
24 | #include <linux/aspm.h> | ||
24 | #include "pci.h" | 25 | #include "pci.h" |
25 | 26 | ||
26 | static int sysfs_initialized; /* = 0 */ | 27 | static int sysfs_initialized; /* = 0 */ |
@@ -358,7 +359,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
358 | char *buf, loff_t off, size_t count) | 359 | char *buf, loff_t off, size_t count) |
359 | { | 360 | { |
360 | struct pci_bus *bus = to_pci_bus(container_of(kobj, | 361 | struct pci_bus *bus = to_pci_bus(container_of(kobj, |
361 | struct class_device, | 362 | struct device, |
362 | kobj)); | 363 | kobj)); |
363 | 364 | ||
364 | /* Only support 1, 2 or 4 byte accesses */ | 365 | /* Only support 1, 2 or 4 byte accesses */ |
@@ -383,7 +384,7 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
383 | char *buf, loff_t off, size_t count) | 384 | char *buf, loff_t off, size_t count) |
384 | { | 385 | { |
385 | struct pci_bus *bus = to_pci_bus(container_of(kobj, | 386 | struct pci_bus *bus = to_pci_bus(container_of(kobj, |
386 | struct class_device, | 387 | struct device, |
387 | kobj)); | 388 | kobj)); |
388 | /* Only support 1, 2 or 4 byte accesses */ | 389 | /* Only support 1, 2 or 4 byte accesses */ |
389 | if (count != 1 && count != 2 && count != 4) | 390 | if (count != 1 && count != 2 && count != 4) |
@@ -407,7 +408,7 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, | |||
407 | struct vm_area_struct *vma) | 408 | struct vm_area_struct *vma) |
408 | { | 409 | { |
409 | struct pci_bus *bus = to_pci_bus(container_of(kobj, | 410 | struct pci_bus *bus = to_pci_bus(container_of(kobj, |
410 | struct class_device, | 411 | struct device, |
411 | kobj)); | 412 | kobj)); |
412 | 413 | ||
413 | return pci_mmap_legacy_page_range(bus, vma); | 414 | return pci_mmap_legacy_page_range(bus, vma); |
@@ -650,6 +651,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
650 | if (pcibios_add_platform_entries(pdev)) | 651 | if (pcibios_add_platform_entries(pdev)) |
651 | goto err_rom_file; | 652 | goto err_rom_file; |
652 | 653 | ||
654 | pcie_aspm_create_sysfs_dev_files(pdev); | ||
655 | |||
653 | return 0; | 656 | return 0; |
654 | 657 | ||
655 | err_rom_file: | 658 | err_rom_file: |
@@ -679,6 +682,8 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) | |||
679 | if (!sysfs_initialized) | 682 | if (!sysfs_initialized) |
680 | return; | 683 | return; |
681 | 684 | ||
685 | pcie_aspm_remove_sysfs_dev_files(pdev); | ||
686 | |||
682 | if (pdev->cfg_size < 4096) | 687 | if (pdev->cfg_size < 4096) |
683 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); | 688 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); |
684 | else | 689 | else |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7d4ce906d207..b3e9294e4a0e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/log2.h> | 20 | #include <linux/log2.h> |
21 | #include <linux/aspm.h> | ||
21 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | 22 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ |
22 | #include "pci.h" | 23 | #include "pci.h" |
23 | 24 | ||
@@ -314,6 +315,24 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap) | |||
314 | } | 315 | } |
315 | EXPORT_SYMBOL_GPL(pci_find_ht_capability); | 316 | EXPORT_SYMBOL_GPL(pci_find_ht_capability); |
316 | 317 | ||
318 | void pcie_wait_pending_transaction(struct pci_dev *dev) | ||
319 | { | ||
320 | int pos; | ||
321 | u16 reg16; | ||
322 | |||
323 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
324 | if (!pos) | ||
325 | return; | ||
326 | while (1) { | ||
327 | pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); | ||
328 | if (!(reg16 & PCI_EXP_DEVSTA_TRPND)) | ||
329 | break; | ||
330 | cpu_relax(); | ||
331 | } | ||
332 | |||
333 | } | ||
334 | EXPORT_SYMBOL_GPL(pcie_wait_pending_transaction); | ||
335 | |||
317 | /** | 336 | /** |
318 | * pci_find_parent_resource - return resource region of parent bus of given region | 337 | * pci_find_parent_resource - return resource region of parent bus of given region |
319 | * @dev: PCI device structure contains resources to be searched | 338 | * @dev: PCI device structure contains resources to be searched |
@@ -353,7 +372,7 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
353 | * Restore the BAR values for a given device, so as to make it | 372 | * Restore the BAR values for a given device, so as to make it |
354 | * accessible by its driver. | 373 | * accessible by its driver. |
355 | */ | 374 | */ |
356 | void | 375 | static void |
357 | pci_restore_bars(struct pci_dev *dev) | 376 | pci_restore_bars(struct pci_dev *dev) |
358 | { | 377 | { |
359 | int i, numres; | 378 | int i, numres; |
@@ -501,6 +520,9 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
501 | if (need_restore) | 520 | if (need_restore) |
502 | pci_restore_bars(dev); | 521 | pci_restore_bars(dev); |
503 | 522 | ||
523 | if (dev->bus->self) | ||
524 | pcie_aspm_pm_state_change(dev->bus->self); | ||
525 | |||
504 | return 0; | 526 | return 0; |
505 | } | 527 | } |
506 | 528 | ||
@@ -551,6 +573,7 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
551 | int pos, i = 0; | 573 | int pos, i = 0; |
552 | struct pci_cap_saved_state *save_state; | 574 | struct pci_cap_saved_state *save_state; |
553 | u16 *cap; | 575 | u16 *cap; |
576 | int found = 0; | ||
554 | 577 | ||
555 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 578 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); |
556 | if (pos <= 0) | 579 | if (pos <= 0) |
@@ -559,6 +582,8 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
559 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); | 582 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
560 | if (!save_state) | 583 | if (!save_state) |
561 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); | 584 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); |
585 | else | ||
586 | found = 1; | ||
562 | if (!save_state) { | 587 | if (!save_state) { |
563 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); | 588 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); |
564 | return -ENOMEM; | 589 | return -ENOMEM; |
@@ -569,7 +594,9 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
569 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); | 594 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); |
570 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); | 595 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); |
571 | pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); | 596 | pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); |
572 | pci_add_saved_cap(dev, save_state); | 597 | save_state->cap_nr = PCI_CAP_ID_EXP; |
598 | if (!found) | ||
599 | pci_add_saved_cap(dev, save_state); | ||
573 | return 0; | 600 | return 0; |
574 | } | 601 | } |
575 | 602 | ||
@@ -597,14 +624,17 @@ static int pci_save_pcix_state(struct pci_dev *dev) | |||
597 | int pos, i = 0; | 624 | int pos, i = 0; |
598 | struct pci_cap_saved_state *save_state; | 625 | struct pci_cap_saved_state *save_state; |
599 | u16 *cap; | 626 | u16 *cap; |
627 | int found = 0; | ||
600 | 628 | ||
601 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 629 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
602 | if (pos <= 0) | 630 | if (pos <= 0) |
603 | return 0; | 631 | return 0; |
604 | 632 | ||
605 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); | 633 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX); |
606 | if (!save_state) | 634 | if (!save_state) |
607 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); | 635 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); |
636 | else | ||
637 | found = 1; | ||
608 | if (!save_state) { | 638 | if (!save_state) { |
609 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); | 639 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); |
610 | return -ENOMEM; | 640 | return -ENOMEM; |
@@ -612,7 +642,9 @@ static int pci_save_pcix_state(struct pci_dev *dev) | |||
612 | cap = (u16 *)&save_state->data[0]; | 642 | cap = (u16 *)&save_state->data[0]; |
613 | 643 | ||
614 | pci_read_config_word(dev, pos + PCI_X_CMD, &cap[i++]); | 644 | pci_read_config_word(dev, pos + PCI_X_CMD, &cap[i++]); |
615 | pci_add_saved_cap(dev, save_state); | 645 | save_state->cap_nr = PCI_CAP_ID_PCIX; |
646 | if (!found) | ||
647 | pci_add_saved_cap(dev, save_state); | ||
616 | return 0; | 648 | return 0; |
617 | } | 649 | } |
618 | 650 | ||
@@ -713,23 +745,19 @@ int pci_reenable_device(struct pci_dev *dev) | |||
713 | return 0; | 745 | return 0; |
714 | } | 746 | } |
715 | 747 | ||
716 | /** | 748 | static int __pci_enable_device_flags(struct pci_dev *dev, |
717 | * pci_enable_device_bars - Initialize some of a device for use | 749 | resource_size_t flags) |
718 | * @dev: PCI device to be initialized | ||
719 | * @bars: bitmask of BAR's that must be configured | ||
720 | * | ||
721 | * Initialize device before it's used by a driver. Ask low-level code | ||
722 | * to enable selected I/O and memory resources. Wake up the device if it | ||
723 | * was suspended. Beware, this function can fail. | ||
724 | */ | ||
725 | int | ||
726 | pci_enable_device_bars(struct pci_dev *dev, int bars) | ||
727 | { | 750 | { |
728 | int err; | 751 | int err; |
752 | int i, bars = 0; | ||
729 | 753 | ||
730 | if (atomic_add_return(1, &dev->enable_cnt) > 1) | 754 | if (atomic_add_return(1, &dev->enable_cnt) > 1) |
731 | return 0; /* already enabled */ | 755 | return 0; /* already enabled */ |
732 | 756 | ||
757 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) | ||
758 | if (dev->resource[i].flags & flags) | ||
759 | bars |= (1 << i); | ||
760 | |||
733 | err = do_pci_enable_device(dev, bars); | 761 | err = do_pci_enable_device(dev, bars); |
734 | if (err < 0) | 762 | if (err < 0) |
735 | atomic_dec(&dev->enable_cnt); | 763 | atomic_dec(&dev->enable_cnt); |
@@ -737,6 +765,32 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) | |||
737 | } | 765 | } |
738 | 766 | ||
739 | /** | 767 | /** |
768 | * pci_enable_device_io - Initialize a device for use with IO space | ||
769 | * @dev: PCI device to be initialized | ||
770 | * | ||
771 | * Initialize device before it's used by a driver. Ask low-level code | ||
772 | * to enable I/O resources. Wake up the device if it was suspended. | ||
773 | * Beware, this function can fail. | ||
774 | */ | ||
775 | int pci_enable_device_io(struct pci_dev *dev) | ||
776 | { | ||
777 | return __pci_enable_device_flags(dev, IORESOURCE_IO); | ||
778 | } | ||
779 | |||
780 | /** | ||
781 | * pci_enable_device_mem - Initialize a device for use with Memory space | ||
782 | * @dev: PCI device to be initialized | ||
783 | * | ||
784 | * Initialize device before it's used by a driver. Ask low-level code | ||
785 | * to enable Memory resources. Wake up the device if it was suspended. | ||
786 | * Beware, this function can fail. | ||
787 | */ | ||
788 | int pci_enable_device_mem(struct pci_dev *dev) | ||
789 | { | ||
790 | return __pci_enable_device_flags(dev, IORESOURCE_MEM); | ||
791 | } | ||
792 | |||
793 | /** | ||
740 | * pci_enable_device - Initialize device before it's used by a driver. | 794 | * pci_enable_device - Initialize device before it's used by a driver. |
741 | * @dev: PCI device to be initialized | 795 | * @dev: PCI device to be initialized |
742 | * | 796 | * |
@@ -749,7 +803,7 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) | |||
749 | */ | 803 | */ |
750 | int pci_enable_device(struct pci_dev *dev) | 804 | int pci_enable_device(struct pci_dev *dev) |
751 | { | 805 | { |
752 | return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); | 806 | return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); |
753 | } | 807 | } |
754 | 808 | ||
755 | /* | 809 | /* |
@@ -885,6 +939,9 @@ pci_disable_device(struct pci_dev *dev) | |||
885 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) | 939 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) |
886 | return; | 940 | return; |
887 | 941 | ||
942 | /* Wait for all transactions are finished before disabling the device */ | ||
943 | pcie_wait_pending_transaction(dev); | ||
944 | |||
888 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); | 945 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); |
889 | if (pci_command & PCI_COMMAND_MASTER) { | 946 | if (pci_command & PCI_COMMAND_MASTER) { |
890 | pci_command &= ~PCI_COMMAND_MASTER; | 947 | pci_command &= ~PCI_COMMAND_MASTER; |
@@ -1619,9 +1676,9 @@ early_param("pci", pci_setup); | |||
1619 | 1676 | ||
1620 | device_initcall(pci_init); | 1677 | device_initcall(pci_init); |
1621 | 1678 | ||
1622 | EXPORT_SYMBOL_GPL(pci_restore_bars); | ||
1623 | EXPORT_SYMBOL(pci_reenable_device); | 1679 | EXPORT_SYMBOL(pci_reenable_device); |
1624 | EXPORT_SYMBOL(pci_enable_device_bars); | 1680 | EXPORT_SYMBOL(pci_enable_device_io); |
1681 | EXPORT_SYMBOL(pci_enable_device_mem); | ||
1625 | EXPORT_SYMBOL(pci_enable_device); | 1682 | EXPORT_SYMBOL(pci_enable_device); |
1626 | EXPORT_SYMBOL(pcim_enable_device); | 1683 | EXPORT_SYMBOL(pcim_enable_device); |
1627 | EXPORT_SYMBOL(pcim_pin_device); | 1684 | EXPORT_SYMBOL(pcim_pin_device); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index fc87e14b50de..eabeb1f2ec99 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -6,8 +6,10 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | |||
6 | extern void pci_cleanup_rom(struct pci_dev *dev); | 6 | extern void pci_cleanup_rom(struct pci_dev *dev); |
7 | 7 | ||
8 | /* Firmware callbacks */ | 8 | /* Firmware callbacks */ |
9 | extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); | 9 | extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, |
10 | extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); | 10 | pm_message_t state); |
11 | extern int (*platform_pci_set_power_state)(struct pci_dev *dev, | ||
12 | pci_power_t state); | ||
11 | 13 | ||
12 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); | 14 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); |
13 | extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); | 15 | extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); |
@@ -45,12 +47,6 @@ static inline void pci_no_msi(void) { } | |||
45 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 47 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
46 | #endif | 48 | #endif |
47 | 49 | ||
48 | #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) | ||
49 | void pci_restore_msi_state(struct pci_dev *dev); | ||
50 | #else | ||
51 | static inline void pci_restore_msi_state(struct pci_dev *dev) {} | ||
52 | #endif | ||
53 | |||
54 | #ifdef CONFIG_PCIEAER | 50 | #ifdef CONFIG_PCIEAER |
55 | void pci_no_aer(void); | 51 | void pci_no_aer(void); |
56 | #else | 52 | #else |
@@ -68,14 +64,14 @@ static inline int pci_no_d1d2(struct pci_dev *dev) | |||
68 | } | 64 | } |
69 | extern int pcie_mch_quirk; | 65 | extern int pcie_mch_quirk; |
70 | extern struct device_attribute pci_dev_attrs[]; | 66 | extern struct device_attribute pci_dev_attrs[]; |
71 | extern struct class_device_attribute class_device_attr_cpuaffinity; | 67 | extern struct device_attribute dev_attr_cpuaffinity; |
72 | 68 | ||
73 | /** | 69 | /** |
74 | * pci_match_one_device - Tell if a PCI device structure has a matching | 70 | * pci_match_one_device - Tell if a PCI device structure has a matching |
75 | * PCI device id structure | 71 | * PCI device id structure |
76 | * @id: single PCI device id structure to match | 72 | * @id: single PCI device id structure to match |
77 | * @dev: the PCI device structure to match against | 73 | * @dev: the PCI device structure to match against |
78 | * | 74 | * |
79 | * Returns the matching pci_device_id structure or %NULL if there is no match. | 75 | * Returns the matching pci_device_id structure or %NULL if there is no match. |
80 | */ | 76 | */ |
81 | static inline const struct pci_device_id * | 77 | static inline const struct pci_device_id * |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 287a9311716c..60104cf98796 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -26,3 +26,23 @@ config HOTPLUG_PCI_PCIE | |||
26 | When in doubt, say N. | 26 | When in doubt, say N. |
27 | 27 | ||
28 | source "drivers/pci/pcie/aer/Kconfig" | 28 | source "drivers/pci/pcie/aer/Kconfig" |
29 | |||
30 | # | ||
31 | # PCI Express ASPM | ||
32 | # | ||
33 | config PCIEASPM | ||
34 | bool "PCI Express ASPM support(Experimental)" | ||
35 | depends on PCI && EXPERIMENTAL | ||
36 | default y | ||
37 | help | ||
38 | This enables PCI Express ASPM (Active State Power Management) and | ||
39 | Clock Power Management. ASPM supports state L0/L0s/L1. | ||
40 | |||
41 | When in doubt, say N. | ||
42 | config PCIEASPM_DEBUG | ||
43 | bool "Debug PCI Express ASPM" | ||
44 | depends on PCIEASPM | ||
45 | default n | ||
46 | help | ||
47 | This enables PCI Express ASPM debug support. It will add per-device | ||
48 | interface to control ASPM. | ||
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index e00fb99acf44..11f6bb1eae24 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile | |||
@@ -2,6 +2,9 @@ | |||
2 | # Makefile for PCI-Express PORT Driver | 2 | # Makefile for PCI-Express PORT Driver |
3 | # | 3 | # |
4 | 4 | ||
5 | # Build PCI Express ASPM if needed | ||
6 | obj-$(CONFIG_PCIEASPM) += aspm.o | ||
7 | |||
5 | pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o | 8 | pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o |
6 | 9 | ||
7 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o | 10 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 1a1eb45a779e..8c199ae84f6d 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -31,26 +31,16 @@ int aer_osc_setup(struct pcie_device *pciedev) | |||
31 | { | 31 | { |
32 | acpi_status status = AE_NOT_FOUND; | 32 | acpi_status status = AE_NOT_FOUND; |
33 | struct pci_dev *pdev = pciedev->port; | 33 | struct pci_dev *pdev = pciedev->port; |
34 | acpi_handle handle = DEVICE_ACPI_HANDLE(&pdev->dev); | 34 | acpi_handle handle = 0; |
35 | struct pci_bus *parent; | ||
36 | 35 | ||
37 | while (!handle) { | 36 | /* Find root host bridge */ |
38 | if (!pdev || !pdev->bus->parent) | 37 | while (pdev->bus && pdev->bus->self) |
39 | break; | 38 | pdev = pdev->bus->self; |
40 | parent = pdev->bus->parent; | 39 | handle = acpi_get_pci_rootbridge_handle( |
41 | if (!parent->self) | 40 | pci_domain_nr(pdev->bus), pdev->bus->number); |
42 | /* Parent must be a host bridge */ | ||
43 | handle = acpi_get_pci_rootbridge_handle( | ||
44 | pci_domain_nr(parent), | ||
45 | parent->number); | ||
46 | else | ||
47 | handle = DEVICE_ACPI_HANDLE( | ||
48 | &(parent->self->dev)); | ||
49 | pdev = parent->self; | ||
50 | } | ||
51 | 41 | ||
52 | if (handle) { | 42 | if (handle) { |
53 | pci_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); | 43 | pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); |
54 | status = pci_osc_control_set(handle, | 44 | status = pci_osc_control_set(handle, |
55 | OSC_PCI_EXPRESS_AER_CONTROL | | 45 | OSC_PCI_EXPRESS_AER_CONTROL | |
56 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | 46 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c new file mode 100644 index 000000000000..1a5adeb10c95 --- /dev/null +++ b/drivers/pci/pcie/aspm.c | |||
@@ -0,0 +1,802 @@ | |||
1 | /* | ||
2 | * File: drivers/pci/pcie/aspm.c | ||
3 | * Enabling PCIE link L0s/L1 state and Clock Power Management | ||
4 | * | ||
5 | * Copyright (C) 2007 Intel | ||
6 | * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) | ||
7 | * Copyright (C) Shaohua Li (shaohua.li@intel.com) | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/moduleparam.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/pci_regs.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/aspm.h> | ||
20 | #include <acpi/acpi_bus.h> | ||
21 | #include <linux/pci-acpi.h> | ||
22 | #include "../pci.h" | ||
23 | |||
24 | #ifdef MODULE_PARAM_PREFIX | ||
25 | #undef MODULE_PARAM_PREFIX | ||
26 | #endif | ||
27 | #define MODULE_PARAM_PREFIX "pcie_aspm." | ||
28 | |||
29 | struct endpoint_state { | ||
30 | unsigned int l0s_acceptable_latency; | ||
31 | unsigned int l1_acceptable_latency; | ||
32 | }; | ||
33 | |||
34 | struct pcie_link_state { | ||
35 | struct list_head sibiling; | ||
36 | struct pci_dev *pdev; | ||
37 | |||
38 | /* ASPM state */ | ||
39 | unsigned int support_state; | ||
40 | unsigned int enabled_state; | ||
41 | unsigned int bios_aspm_state; | ||
42 | /* upstream component */ | ||
43 | unsigned int l0s_upper_latency; | ||
44 | unsigned int l1_upper_latency; | ||
45 | /* downstream component */ | ||
46 | unsigned int l0s_down_latency; | ||
47 | unsigned int l1_down_latency; | ||
48 | /* Clock PM state*/ | ||
49 | unsigned int clk_pm_capable; | ||
50 | unsigned int clk_pm_enabled; | ||
51 | unsigned int bios_clk_state; | ||
52 | |||
53 | /* | ||
54 | * A pcie downstream port only has one slot under it, so at most there | ||
55 | * are 8 functions | ||
56 | */ | ||
57 | struct endpoint_state endpoints[8]; | ||
58 | }; | ||
59 | |||
60 | static int aspm_disabled; | ||
61 | static DEFINE_MUTEX(aspm_lock); | ||
62 | static LIST_HEAD(link_list); | ||
63 | |||
64 | #define POLICY_DEFAULT 0 /* BIOS default setting */ | ||
65 | #define POLICY_PERFORMANCE 1 /* high performance */ | ||
66 | #define POLICY_POWERSAVE 2 /* high power saving */ | ||
67 | static int aspm_policy; | ||
68 | static const char *policy_str[] = { | ||
69 | [POLICY_DEFAULT] = "default", | ||
70 | [POLICY_PERFORMANCE] = "performance", | ||
71 | [POLICY_POWERSAVE] = "powersave" | ||
72 | }; | ||
73 | |||
74 | static int policy_to_aspm_state(struct pci_dev *pdev) | ||
75 | { | ||
76 | struct pcie_link_state *link_state = pdev->link_state; | ||
77 | |||
78 | switch (aspm_policy) { | ||
79 | case POLICY_PERFORMANCE: | ||
80 | /* Disable ASPM and Clock PM */ | ||
81 | return 0; | ||
82 | case POLICY_POWERSAVE: | ||
83 | /* Enable ASPM L0s/L1 */ | ||
84 | return PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; | ||
85 | case POLICY_DEFAULT: | ||
86 | return link_state->bios_aspm_state; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int policy_to_clkpm_state(struct pci_dev *pdev) | ||
92 | { | ||
93 | struct pcie_link_state *link_state = pdev->link_state; | ||
94 | |||
95 | switch (aspm_policy) { | ||
96 | case POLICY_PERFORMANCE: | ||
97 | /* Disable ASPM and Clock PM */ | ||
98 | return 0; | ||
99 | case POLICY_POWERSAVE: | ||
100 | /* Disable Clock PM */ | ||
101 | return 1; | ||
102 | case POLICY_DEFAULT: | ||
103 | return link_state->bios_clk_state; | ||
104 | } | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static void pcie_set_clock_pm(struct pci_dev *pdev, int enable) | ||
109 | { | ||
110 | struct pci_dev *child_dev; | ||
111 | int pos; | ||
112 | u16 reg16; | ||
113 | struct pcie_link_state *link_state = pdev->link_state; | ||
114 | |||
115 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
116 | pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | ||
117 | if (!pos) | ||
118 | return; | ||
119 | pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, ®16); | ||
120 | if (enable) | ||
121 | reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN; | ||
122 | else | ||
123 | reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN; | ||
124 | pci_write_config_word(child_dev, pos + PCI_EXP_LNKCTL, reg16); | ||
125 | } | ||
126 | link_state->clk_pm_enabled = !!enable; | ||
127 | } | ||
128 | |||
129 | static void pcie_check_clock_pm(struct pci_dev *pdev) | ||
130 | { | ||
131 | int pos; | ||
132 | u32 reg32; | ||
133 | u16 reg16; | ||
134 | int capable = 1, enabled = 1; | ||
135 | struct pci_dev *child_dev; | ||
136 | struct pcie_link_state *link_state = pdev->link_state; | ||
137 | |||
138 | /* All functions should have the same cap and state, take the worst */ | ||
139 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
140 | pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | ||
141 | if (!pos) | ||
142 | return; | ||
143 | pci_read_config_dword(child_dev, pos + PCI_EXP_LNKCAP, ®32); | ||
144 | if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) { | ||
145 | capable = 0; | ||
146 | enabled = 0; | ||
147 | break; | ||
148 | } | ||
149 | pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, ®16); | ||
150 | if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) | ||
151 | enabled = 0; | ||
152 | } | ||
153 | link_state->clk_pm_capable = capable; | ||
154 | link_state->clk_pm_enabled = enabled; | ||
155 | link_state->bios_clk_state = enabled; | ||
156 | pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * pcie_aspm_configure_common_clock: check if the 2 ends of a link | ||
161 | * could use common clock. If they are, configure them to use the | ||
162 | * common clock. That will reduce the ASPM state exit latency. | ||
163 | */ | ||
164 | static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | ||
165 | { | ||
166 | int pos, child_pos; | ||
167 | u16 reg16 = 0; | ||
168 | struct pci_dev *child_dev; | ||
169 | int same_clock = 1; | ||
170 | |||
171 | /* | ||
172 | * all functions of a slot should have the same Slot Clock | ||
173 | * Configuration, so just check one function | ||
174 | * */ | ||
175 | child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev, | ||
176 | bus_list); | ||
177 | BUG_ON(!child_dev->is_pcie); | ||
178 | |||
179 | /* Check downstream component if bit Slot Clock Configuration is 1 */ | ||
180 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | ||
181 | pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKSTA, ®16); | ||
182 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | ||
183 | same_clock = 0; | ||
184 | |||
185 | /* Check upstream component if bit Slot Clock Configuration is 1 */ | ||
186 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
187 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); | ||
188 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | ||
189 | same_clock = 0; | ||
190 | |||
191 | /* Configure downstream component, all functions */ | ||
192 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
193 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | ||
194 | pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, | ||
195 | ®16); | ||
196 | if (same_clock) | ||
197 | reg16 |= PCI_EXP_LNKCTL_CCC; | ||
198 | else | ||
199 | reg16 &= ~PCI_EXP_LNKCTL_CCC; | ||
200 | pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, | ||
201 | reg16); | ||
202 | } | ||
203 | |||
204 | /* Configure upstream component */ | ||
205 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | ||
206 | if (same_clock) | ||
207 | reg16 |= PCI_EXP_LNKCTL_CCC; | ||
208 | else | ||
209 | reg16 &= ~PCI_EXP_LNKCTL_CCC; | ||
210 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); | ||
211 | |||
212 | /* retrain link */ | ||
213 | reg16 |= PCI_EXP_LNKCTL_RL; | ||
214 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); | ||
215 | |||
216 | /* Wait for link training end */ | ||
217 | while (1) { | ||
218 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); | ||
219 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) | ||
220 | break; | ||
221 | cpu_relax(); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * calc_L0S_latency: Convert L0s latency encoding to ns | ||
227 | */ | ||
228 | static unsigned int calc_L0S_latency(unsigned int latency_encoding, int ac) | ||
229 | { | ||
230 | unsigned int ns = 64; | ||
231 | |||
232 | if (latency_encoding == 0x7) { | ||
233 | if (ac) | ||
234 | ns = -1U; | ||
235 | else | ||
236 | ns = 5*1000; /* > 4us */ | ||
237 | } else | ||
238 | ns *= (1 << latency_encoding); | ||
239 | return ns; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * calc_L1_latency: Convert L1 latency encoding to ns | ||
244 | */ | ||
245 | static unsigned int calc_L1_latency(unsigned int latency_encoding, int ac) | ||
246 | { | ||
247 | unsigned int ns = 1000; | ||
248 | |||
249 | if (latency_encoding == 0x7) { | ||
250 | if (ac) | ||
251 | ns = -1U; | ||
252 | else | ||
253 | ns = 65*1000; /* > 64us */ | ||
254 | } else | ||
255 | ns *= (1 << latency_encoding); | ||
256 | return ns; | ||
257 | } | ||
258 | |||
259 | static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state, | ||
260 | unsigned int *l0s, unsigned int *l1, unsigned int *enabled) | ||
261 | { | ||
262 | int pos; | ||
263 | u16 reg16; | ||
264 | u32 reg32; | ||
265 | unsigned int latency; | ||
266 | |||
267 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
268 | pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); | ||
269 | *state = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; | ||
270 | if (*state != PCIE_LINK_STATE_L0S && | ||
271 | *state != (PCIE_LINK_STATE_L1|PCIE_LINK_STATE_L0S)) | ||
272 | * state = 0; | ||
273 | if (*state == 0) | ||
274 | return; | ||
275 | |||
276 | latency = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; | ||
277 | *l0s = calc_L0S_latency(latency, 0); | ||
278 | if (*state & PCIE_LINK_STATE_L1) { | ||
279 | latency = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15; | ||
280 | *l1 = calc_L1_latency(latency, 0); | ||
281 | } | ||
282 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | ||
283 | *enabled = reg16 & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1); | ||
284 | } | ||
285 | |||
286 | static void pcie_aspm_cap_init(struct pci_dev *pdev) | ||
287 | { | ||
288 | struct pci_dev *child_dev; | ||
289 | u32 state, tmp; | ||
290 | struct pcie_link_state *link_state = pdev->link_state; | ||
291 | |||
292 | /* upstream component states */ | ||
293 | pcie_aspm_get_cap_device(pdev, &link_state->support_state, | ||
294 | &link_state->l0s_upper_latency, | ||
295 | &link_state->l1_upper_latency, | ||
296 | &link_state->enabled_state); | ||
297 | /* downstream component states, all functions have the same setting */ | ||
298 | child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev, | ||
299 | bus_list); | ||
300 | pcie_aspm_get_cap_device(child_dev, &state, | ||
301 | &link_state->l0s_down_latency, | ||
302 | &link_state->l1_down_latency, | ||
303 | &tmp); | ||
304 | link_state->support_state &= state; | ||
305 | if (!link_state->support_state) | ||
306 | return; | ||
307 | link_state->enabled_state &= link_state->support_state; | ||
308 | link_state->bios_aspm_state = link_state->enabled_state; | ||
309 | |||
310 | /* ENDPOINT states*/ | ||
311 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
312 | int pos; | ||
313 | u32 reg32; | ||
314 | unsigned int latency; | ||
315 | struct endpoint_state *ep_state = | ||
316 | &link_state->endpoints[PCI_FUNC(child_dev->devfn)]; | ||
317 | |||
318 | if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT && | ||
319 | child_dev->pcie_type != PCI_EXP_TYPE_LEG_END) | ||
320 | continue; | ||
321 | |||
322 | pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | ||
323 | pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, ®32); | ||
324 | latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; | ||
325 | latency = calc_L0S_latency(latency, 1); | ||
326 | ep_state->l0s_acceptable_latency = latency; | ||
327 | if (link_state->support_state & PCIE_LINK_STATE_L1) { | ||
328 | latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9; | ||
329 | latency = calc_L1_latency(latency, 1); | ||
330 | ep_state->l1_acceptable_latency = latency; | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev, | ||
336 | unsigned int state) | ||
337 | { | ||
338 | struct pci_dev *parent_dev, *tmp_dev; | ||
339 | unsigned int latency, l1_latency = 0; | ||
340 | struct pcie_link_state *link_state; | ||
341 | struct endpoint_state *ep_state; | ||
342 | |||
343 | parent_dev = pdev->bus->self; | ||
344 | link_state = parent_dev->link_state; | ||
345 | state &= link_state->support_state; | ||
346 | if (state == 0) | ||
347 | return 0; | ||
348 | ep_state = &link_state->endpoints[PCI_FUNC(pdev->devfn)]; | ||
349 | |||
350 | /* | ||
351 | * Check latency for endpoint device. | ||
352 | * TBD: The latency from the endpoint to root complex vary per | ||
353 | * switch's upstream link state above the device. Here we just do a | ||
354 | * simple check which assumes all links above the device can be in L1 | ||
355 | * state, that is we just consider the worst case. If switch's upstream | ||
356 | * link can't be put into L0S/L1, then our check is too strictly. | ||
357 | */ | ||
358 | tmp_dev = pdev; | ||
359 | while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { | ||
360 | parent_dev = tmp_dev->bus->self; | ||
361 | link_state = parent_dev->link_state; | ||
362 | if (state & PCIE_LINK_STATE_L0S) { | ||
363 | latency = max_t(unsigned int, | ||
364 | link_state->l0s_upper_latency, | ||
365 | link_state->l0s_down_latency); | ||
366 | if (latency > ep_state->l0s_acceptable_latency) | ||
367 | state &= ~PCIE_LINK_STATE_L0S; | ||
368 | } | ||
369 | if (state & PCIE_LINK_STATE_L1) { | ||
370 | latency = max_t(unsigned int, | ||
371 | link_state->l1_upper_latency, | ||
372 | link_state->l1_down_latency); | ||
373 | if (latency + l1_latency > | ||
374 | ep_state->l1_acceptable_latency) | ||
375 | state &= ~PCIE_LINK_STATE_L1; | ||
376 | } | ||
377 | if (!parent_dev->bus->self) /* parent_dev is a root port */ | ||
378 | break; | ||
379 | else { | ||
380 | /* | ||
381 | * parent_dev is the downstream port of a switch, make | ||
382 | * tmp_dev the upstream port of the switch | ||
383 | */ | ||
384 | tmp_dev = parent_dev->bus->self; | ||
385 | /* | ||
386 | * every switch on the path to root complex need 1 more | ||
387 | * microsecond for L1. Spec doesn't mention L0S. | ||
388 | */ | ||
389 | if (state & PCIE_LINK_STATE_L1) | ||
390 | l1_latency += 1000; | ||
391 | } | ||
392 | } | ||
393 | return state; | ||
394 | } | ||
395 | |||
396 | static unsigned int pcie_aspm_check_state(struct pci_dev *pdev, | ||
397 | unsigned int state) | ||
398 | { | ||
399 | struct pci_dev *child_dev; | ||
400 | |||
401 | /* If no child, disable the link */ | ||
402 | if (list_empty(&pdev->subordinate->devices)) | ||
403 | return 0; | ||
404 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
405 | if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { | ||
406 | /* | ||
407 | * If downstream component of a link is pci bridge, we | ||
408 | * disable ASPM for now for the link | ||
409 | * */ | ||
410 | state = 0; | ||
411 | break; | ||
412 | } | ||
413 | if ((child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT && | ||
414 | child_dev->pcie_type != PCI_EXP_TYPE_LEG_END)) | ||
415 | continue; | ||
416 | /* Device not in D0 doesn't need check latency */ | ||
417 | if (child_dev->current_state == PCI_D1 || | ||
418 | child_dev->current_state == PCI_D2 || | ||
419 | child_dev->current_state == PCI_D3hot || | ||
420 | child_dev->current_state == PCI_D3cold) | ||
421 | continue; | ||
422 | state = __pcie_aspm_check_state_one(child_dev, state); | ||
423 | } | ||
424 | return state; | ||
425 | } | ||
426 | |||
427 | static void __pcie_aspm_config_one_dev(struct pci_dev *pdev, unsigned int state) | ||
428 | { | ||
429 | u16 reg16; | ||
430 | int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
431 | |||
432 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | ||
433 | reg16 &= ~0x3; | ||
434 | reg16 |= state; | ||
435 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); | ||
436 | } | ||
437 | |||
438 | static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state) | ||
439 | { | ||
440 | struct pci_dev *child_dev; | ||
441 | int valid = 1; | ||
442 | struct pcie_link_state *link_state = pdev->link_state; | ||
443 | |||
444 | /* | ||
445 | * if the downstream component has pci bridge function, don't do ASPM | ||
446 | * now | ||
447 | */ | ||
448 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
449 | if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { | ||
450 | valid = 0; | ||
451 | break; | ||
452 | } | ||
453 | } | ||
454 | if (!valid) | ||
455 | return; | ||
456 | |||
457 | /* | ||
458 | * spec 2.0 suggests all functions should be configured the same | ||
459 | * setting for ASPM. Enabling ASPM L1 should be done in upstream | ||
460 | * component first and then downstream, and vice versa for disabling | ||
461 | * ASPM L1. Spec doesn't mention L0S. | ||
462 | */ | ||
463 | if (state & PCIE_LINK_STATE_L1) | ||
464 | __pcie_aspm_config_one_dev(pdev, state); | ||
465 | |||
466 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) | ||
467 | __pcie_aspm_config_one_dev(child_dev, state); | ||
468 | |||
469 | if (!(state & PCIE_LINK_STATE_L1)) | ||
470 | __pcie_aspm_config_one_dev(pdev, state); | ||
471 | |||
472 | link_state->enabled_state = state; | ||
473 | } | ||
474 | |||
475 | static void __pcie_aspm_configure_link_state(struct pci_dev *pdev, | ||
476 | unsigned int state) | ||
477 | { | ||
478 | struct pcie_link_state *link_state = pdev->link_state; | ||
479 | |||
480 | if (link_state->support_state == 0) | ||
481 | return; | ||
482 | state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; | ||
483 | |||
484 | /* state 0 means disabling aspm */ | ||
485 | state = pcie_aspm_check_state(pdev, state); | ||
486 | if (link_state->enabled_state == state) | ||
487 | return; | ||
488 | __pcie_aspm_config_link(pdev, state); | ||
489 | } | ||
490 | |||
491 | /* | ||
492 | * pcie_aspm_configure_link_state: enable/disable PCI express link state | ||
493 | * @pdev: the root port or switch downstream port | ||
494 | */ | ||
495 | static void pcie_aspm_configure_link_state(struct pci_dev *pdev, | ||
496 | unsigned int state) | ||
497 | { | ||
498 | down_read(&pci_bus_sem); | ||
499 | mutex_lock(&aspm_lock); | ||
500 | __pcie_aspm_configure_link_state(pdev, state); | ||
501 | mutex_unlock(&aspm_lock); | ||
502 | up_read(&pci_bus_sem); | ||
503 | } | ||
504 | |||
505 | static void free_link_state(struct pci_dev *pdev) | ||
506 | { | ||
507 | kfree(pdev->link_state); | ||
508 | pdev->link_state = NULL; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * pcie_aspm_init_link_state: Initiate PCI express link state. | ||
513 | * It is called after the pcie and its children devices are scaned. | ||
514 | * @pdev: the root port or switch downstream port | ||
515 | */ | ||
516 | void pcie_aspm_init_link_state(struct pci_dev *pdev) | ||
517 | { | ||
518 | unsigned int state; | ||
519 | struct pcie_link_state *link_state; | ||
520 | int error = 0; | ||
521 | |||
522 | if (aspm_disabled || !pdev->is_pcie || pdev->link_state) | ||
523 | return; | ||
524 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
525 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | ||
526 | return; | ||
527 | down_read(&pci_bus_sem); | ||
528 | if (list_empty(&pdev->subordinate->devices)) | ||
529 | goto out; | ||
530 | |||
531 | mutex_lock(&aspm_lock); | ||
532 | |||
533 | link_state = kzalloc(sizeof(*link_state), GFP_KERNEL); | ||
534 | if (!link_state) | ||
535 | goto unlock_out; | ||
536 | pdev->link_state = link_state; | ||
537 | |||
538 | pcie_aspm_configure_common_clock(pdev); | ||
539 | |||
540 | pcie_aspm_cap_init(pdev); | ||
541 | |||
542 | /* config link state to avoid BIOS error */ | ||
543 | state = pcie_aspm_check_state(pdev, policy_to_aspm_state(pdev)); | ||
544 | __pcie_aspm_config_link(pdev, state); | ||
545 | |||
546 | pcie_check_clock_pm(pdev); | ||
547 | |||
548 | link_state->pdev = pdev; | ||
549 | list_add(&link_state->sibiling, &link_list); | ||
550 | |||
551 | unlock_out: | ||
552 | if (error) | ||
553 | free_link_state(pdev); | ||
554 | mutex_unlock(&aspm_lock); | ||
555 | out: | ||
556 | up_read(&pci_bus_sem); | ||
557 | } | ||
558 | |||
559 | /* @pdev: the endpoint device */ | ||
560 | void pcie_aspm_exit_link_state(struct pci_dev *pdev) | ||
561 | { | ||
562 | struct pci_dev *parent = pdev->bus->self; | ||
563 | struct pcie_link_state *link_state = parent->link_state; | ||
564 | |||
565 | if (aspm_disabled || !pdev->is_pcie || !parent || !link_state) | ||
566 | return; | ||
567 | if (parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
568 | parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | ||
569 | return; | ||
570 | down_read(&pci_bus_sem); | ||
571 | mutex_lock(&aspm_lock); | ||
572 | |||
573 | /* | ||
574 | * All PCIe functions are in one slot, remove one function will remove | ||
575 | * the the whole slot, so just wait | ||
576 | */ | ||
577 | if (!list_empty(&parent->subordinate->devices)) | ||
578 | goto out; | ||
579 | |||
580 | /* All functions are removed, so just disable ASPM for the link */ | ||
581 | __pcie_aspm_config_one_dev(parent, 0); | ||
582 | list_del(&link_state->sibiling); | ||
583 | /* Clock PM is for endpoint device */ | ||
584 | |||
585 | free_link_state(parent); | ||
586 | out: | ||
587 | mutex_unlock(&aspm_lock); | ||
588 | up_read(&pci_bus_sem); | ||
589 | } | ||
590 | |||
591 | /* @pdev: the root port or switch downstream port */ | ||
592 | void pcie_aspm_pm_state_change(struct pci_dev *pdev) | ||
593 | { | ||
594 | struct pcie_link_state *link_state = pdev->link_state; | ||
595 | |||
596 | if (aspm_disabled || !pdev->is_pcie || !pdev->link_state) | ||
597 | return; | ||
598 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
599 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | ||
600 | return; | ||
601 | /* | ||
602 | * devices changed PM state, we should recheck if latency meets all | ||
603 | * functions' requirement | ||
604 | */ | ||
605 | pcie_aspm_configure_link_state(pdev, link_state->enabled_state); | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * pci_disable_link_state - disable pci device's link state, so the link will | ||
610 | * never enter specific states | ||
611 | */ | ||
612 | void pci_disable_link_state(struct pci_dev *pdev, int state) | ||
613 | { | ||
614 | struct pci_dev *parent = pdev->bus->self; | ||
615 | struct pcie_link_state *link_state; | ||
616 | |||
617 | if (aspm_disabled || !pdev->is_pcie) | ||
618 | return; | ||
619 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | ||
620 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | ||
621 | parent = pdev; | ||
622 | if (!parent) | ||
623 | return; | ||
624 | |||
625 | down_read(&pci_bus_sem); | ||
626 | mutex_lock(&aspm_lock); | ||
627 | link_state = parent->link_state; | ||
628 | link_state->support_state &= | ||
629 | ~(state & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1)); | ||
630 | if (state & PCIE_LINK_STATE_CLKPM) | ||
631 | link_state->clk_pm_capable = 0; | ||
632 | |||
633 | __pcie_aspm_configure_link_state(parent, link_state->enabled_state); | ||
634 | if (!link_state->clk_pm_capable && link_state->clk_pm_enabled) | ||
635 | pcie_set_clock_pm(parent, 0); | ||
636 | mutex_unlock(&aspm_lock); | ||
637 | up_read(&pci_bus_sem); | ||
638 | } | ||
639 | EXPORT_SYMBOL(pci_disable_link_state); | ||
640 | |||
641 | static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) | ||
642 | { | ||
643 | int i; | ||
644 | struct pci_dev *pdev; | ||
645 | struct pcie_link_state *link_state; | ||
646 | |||
647 | for (i = 0; i < ARRAY_SIZE(policy_str); i++) | ||
648 | if (!strncmp(val, policy_str[i], strlen(policy_str[i]))) | ||
649 | break; | ||
650 | if (i >= ARRAY_SIZE(policy_str)) | ||
651 | return -EINVAL; | ||
652 | if (i == aspm_policy) | ||
653 | return 0; | ||
654 | |||
655 | down_read(&pci_bus_sem); | ||
656 | mutex_lock(&aspm_lock); | ||
657 | aspm_policy = i; | ||
658 | list_for_each_entry(link_state, &link_list, sibiling) { | ||
659 | pdev = link_state->pdev; | ||
660 | __pcie_aspm_configure_link_state(pdev, | ||
661 | policy_to_aspm_state(pdev)); | ||
662 | if (link_state->clk_pm_capable && | ||
663 | link_state->clk_pm_enabled != policy_to_clkpm_state(pdev)) | ||
664 | pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); | ||
665 | |||
666 | } | ||
667 | mutex_unlock(&aspm_lock); | ||
668 | up_read(&pci_bus_sem); | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static int pcie_aspm_get_policy(char *buffer, struct kernel_param *kp) | ||
673 | { | ||
674 | int i, cnt = 0; | ||
675 | for (i = 0; i < ARRAY_SIZE(policy_str); i++) | ||
676 | if (i == aspm_policy) | ||
677 | cnt += sprintf(buffer + cnt, "[%s] ", policy_str[i]); | ||
678 | else | ||
679 | cnt += sprintf(buffer + cnt, "%s ", policy_str[i]); | ||
680 | return cnt; | ||
681 | } | ||
682 | |||
683 | module_param_call(policy, pcie_aspm_set_policy, pcie_aspm_get_policy, | ||
684 | NULL, 0644); | ||
685 | |||
686 | #ifdef CONFIG_PCIEASPM_DEBUG | ||
687 | static ssize_t link_state_show(struct device *dev, | ||
688 | struct device_attribute *attr, | ||
689 | char *buf) | ||
690 | { | ||
691 | struct pci_dev *pci_device = to_pci_dev(dev); | ||
692 | struct pcie_link_state *link_state = pci_device->link_state; | ||
693 | |||
694 | return sprintf(buf, "%d\n", link_state->enabled_state); | ||
695 | } | ||
696 | |||
697 | static ssize_t link_state_store(struct device *dev, | ||
698 | struct device_attribute *attr, | ||
699 | const char *buf, | ||
700 | size_t n) | ||
701 | { | ||
702 | struct pci_dev *pci_device = to_pci_dev(dev); | ||
703 | int state; | ||
704 | |||
705 | if (n < 1) | ||
706 | return -EINVAL; | ||
707 | state = buf[0]-'0'; | ||
708 | if (state >= 0 && state <= 3) { | ||
709 | /* setup link aspm state */ | ||
710 | pcie_aspm_configure_link_state(pci_device, state); | ||
711 | return n; | ||
712 | } | ||
713 | |||
714 | return -EINVAL; | ||
715 | } | ||
716 | |||
717 | static ssize_t clk_ctl_show(struct device *dev, | ||
718 | struct device_attribute *attr, | ||
719 | char *buf) | ||
720 | { | ||
721 | struct pci_dev *pci_device = to_pci_dev(dev); | ||
722 | struct pcie_link_state *link_state = pci_device->link_state; | ||
723 | |||
724 | return sprintf(buf, "%d\n", link_state->clk_pm_enabled); | ||
725 | } | ||
726 | |||
727 | static ssize_t clk_ctl_store(struct device *dev, | ||
728 | struct device_attribute *attr, | ||
729 | const char *buf, | ||
730 | size_t n) | ||
731 | { | ||
732 | struct pci_dev *pci_device = to_pci_dev(dev); | ||
733 | int state; | ||
734 | |||
735 | if (n < 1) | ||
736 | return -EINVAL; | ||
737 | state = buf[0]-'0'; | ||
738 | |||
739 | down_read(&pci_bus_sem); | ||
740 | mutex_lock(&aspm_lock); | ||
741 | pcie_set_clock_pm(pci_device, !!state); | ||
742 | mutex_unlock(&aspm_lock); | ||
743 | up_read(&pci_bus_sem); | ||
744 | |||
745 | return n; | ||
746 | } | ||
747 | |||
748 | static DEVICE_ATTR(link_state, 0644, link_state_show, link_state_store); | ||
749 | static DEVICE_ATTR(clk_ctl, 0644, clk_ctl_show, clk_ctl_store); | ||
750 | |||
751 | static char power_group[] = "power"; | ||
752 | void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) | ||
753 | { | ||
754 | struct pcie_link_state *link_state = pdev->link_state; | ||
755 | |||
756 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
757 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | ||
758 | return; | ||
759 | |||
760 | if (link_state->support_state) | ||
761 | sysfs_add_file_to_group(&pdev->dev.kobj, | ||
762 | &dev_attr_link_state.attr, power_group); | ||
763 | if (link_state->clk_pm_capable) | ||
764 | sysfs_add_file_to_group(&pdev->dev.kobj, | ||
765 | &dev_attr_clk_ctl.attr, power_group); | ||
766 | } | ||
767 | |||
768 | void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) | ||
769 | { | ||
770 | struct pcie_link_state *link_state = pdev->link_state; | ||
771 | |||
772 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
773 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | ||
774 | return; | ||
775 | |||
776 | if (link_state->support_state) | ||
777 | sysfs_remove_file_from_group(&pdev->dev.kobj, | ||
778 | &dev_attr_link_state.attr, power_group); | ||
779 | if (link_state->clk_pm_capable) | ||
780 | sysfs_remove_file_from_group(&pdev->dev.kobj, | ||
781 | &dev_attr_clk_ctl.attr, power_group); | ||
782 | } | ||
783 | #endif | ||
784 | |||
785 | static int __init pcie_aspm_disable(char *str) | ||
786 | { | ||
787 | aspm_disabled = 1; | ||
788 | return 1; | ||
789 | } | ||
790 | |||
791 | __setup("pcie_noaspm", pcie_aspm_disable); | ||
792 | |||
793 | static int __init pcie_aspm_init(void) | ||
794 | { | ||
795 | if (aspm_disabled) | ||
796 | return 0; | ||
797 | pci_osc_support_set(OSC_ACTIVE_STATE_PWR_SUPPORT| | ||
798 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT); | ||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | fs_initcall(pcie_aspm_init); | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index b20a9b81dae2..23d9eb073296 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -192,9 +192,8 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
192 | if (reg32 & SLOT_HP_CAPABLE_MASK) | 192 | if (reg32 & SLOT_HP_CAPABLE_MASK) |
193 | services |= PCIE_PORT_SERVICE_HP; | 193 | services |= PCIE_PORT_SERVICE_HP; |
194 | } | 194 | } |
195 | /* PME Capable */ | 195 | /* PME Capable - root port capability */ |
196 | pos = pci_find_capability(dev, PCI_CAP_ID_PME); | 196 | if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT) |
197 | if (pos) | ||
198 | services |= PCIE_PORT_SERVICE_PME; | 197 | services |= PCIE_PORT_SERVICE_PME; |
199 | 198 | ||
200 | pos = PCI_CFG_SPACE_SIZE; | 199 | pos = PCI_CFG_SPACE_SIZE; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5fd585293e79..8b505bd925aa 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/cpumask.h> | 11 | #include <linux/cpumask.h> |
12 | #include <linux/aspm.h> | ||
12 | #include "pci.h" | 13 | #include "pci.h" |
13 | 14 | ||
14 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -53,7 +54,7 @@ static void pci_create_legacy_files(struct pci_bus *b) | |||
53 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | 54 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; |
54 | b->legacy_io->read = pci_read_legacy_io; | 55 | b->legacy_io->read = pci_read_legacy_io; |
55 | b->legacy_io->write = pci_write_legacy_io; | 56 | b->legacy_io->write = pci_write_legacy_io; |
56 | class_device_create_bin_file(&b->class_dev, b->legacy_io); | 57 | device_create_bin_file(&b->dev, b->legacy_io); |
57 | 58 | ||
58 | /* Allocated above after the legacy_io struct */ | 59 | /* Allocated above after the legacy_io struct */ |
59 | b->legacy_mem = b->legacy_io + 1; | 60 | b->legacy_mem = b->legacy_io + 1; |
@@ -61,15 +62,15 @@ static void pci_create_legacy_files(struct pci_bus *b) | |||
61 | b->legacy_mem->size = 1024*1024; | 62 | b->legacy_mem->size = 1024*1024; |
62 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; | 63 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; |
63 | b->legacy_mem->mmap = pci_mmap_legacy_mem; | 64 | b->legacy_mem->mmap = pci_mmap_legacy_mem; |
64 | class_device_create_bin_file(&b->class_dev, b->legacy_mem); | 65 | device_create_bin_file(&b->dev, b->legacy_mem); |
65 | } | 66 | } |
66 | } | 67 | } |
67 | 68 | ||
68 | void pci_remove_legacy_files(struct pci_bus *b) | 69 | void pci_remove_legacy_files(struct pci_bus *b) |
69 | { | 70 | { |
70 | if (b->legacy_io) { | 71 | if (b->legacy_io) { |
71 | class_device_remove_bin_file(&b->class_dev, b->legacy_io); | 72 | device_remove_bin_file(&b->dev, b->legacy_io); |
72 | class_device_remove_bin_file(&b->class_dev, b->legacy_mem); | 73 | device_remove_bin_file(&b->dev, b->legacy_mem); |
73 | kfree(b->legacy_io); /* both are allocated here */ | 74 | kfree(b->legacy_io); /* both are allocated here */ |
74 | } | 75 | } |
75 | } | 76 | } |
@@ -81,26 +82,27 @@ void pci_remove_legacy_files(struct pci_bus *bus) { return; } | |||
81 | /* | 82 | /* |
82 | * PCI Bus Class Devices | 83 | * PCI Bus Class Devices |
83 | */ | 84 | */ |
84 | static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, | 85 | static ssize_t pci_bus_show_cpuaffinity(struct device *dev, |
86 | struct device_attribute *attr, | ||
85 | char *buf) | 87 | char *buf) |
86 | { | 88 | { |
87 | int ret; | 89 | int ret; |
88 | cpumask_t cpumask; | 90 | cpumask_t cpumask; |
89 | 91 | ||
90 | cpumask = pcibus_to_cpumask(to_pci_bus(class_dev)); | 92 | cpumask = pcibus_to_cpumask(to_pci_bus(dev)); |
91 | ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); | 93 | ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); |
92 | if (ret < PAGE_SIZE) | 94 | if (ret < PAGE_SIZE) |
93 | buf[ret++] = '\n'; | 95 | buf[ret++] = '\n'; |
94 | return ret; | 96 | return ret; |
95 | } | 97 | } |
96 | CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); | 98 | DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); |
97 | 99 | ||
98 | /* | 100 | /* |
99 | * PCI Bus Class | 101 | * PCI Bus Class |
100 | */ | 102 | */ |
101 | static void release_pcibus_dev(struct class_device *class_dev) | 103 | static void release_pcibus_dev(struct device *dev) |
102 | { | 104 | { |
103 | struct pci_bus *pci_bus = to_pci_bus(class_dev); | 105 | struct pci_bus *pci_bus = to_pci_bus(dev); |
104 | 106 | ||
105 | if (pci_bus->bridge) | 107 | if (pci_bus->bridge) |
106 | put_device(pci_bus->bridge); | 108 | put_device(pci_bus->bridge); |
@@ -109,7 +111,7 @@ static void release_pcibus_dev(struct class_device *class_dev) | |||
109 | 111 | ||
110 | static struct class pcibus_class = { | 112 | static struct class pcibus_class = { |
111 | .name = "pci_bus", | 113 | .name = "pci_bus", |
112 | .release = &release_pcibus_dev, | 114 | .dev_release = &release_pcibus_dev, |
113 | }; | 115 | }; |
114 | 116 | ||
115 | static int __init pcibus_class_init(void) | 117 | static int __init pcibus_class_init(void) |
@@ -392,7 +394,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) | |||
392 | { | 394 | { |
393 | struct pci_bus *child; | 395 | struct pci_bus *child; |
394 | int i; | 396 | int i; |
395 | int retval; | ||
396 | 397 | ||
397 | /* | 398 | /* |
398 | * Allocate a new bus, and inherit stuff from the parent.. | 399 | * Allocate a new bus, and inherit stuff from the parent.. |
@@ -408,15 +409,12 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) | |||
408 | child->bus_flags = parent->bus_flags; | 409 | child->bus_flags = parent->bus_flags; |
409 | child->bridge = get_device(&bridge->dev); | 410 | child->bridge = get_device(&bridge->dev); |
410 | 411 | ||
411 | child->class_dev.class = &pcibus_class; | 412 | /* initialize some portions of the bus device, but don't register it |
412 | sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), busnr); | 413 | * now as the parent is not properly set up yet. This device will get |
413 | retval = class_device_register(&child->class_dev); | 414 | * registered later in pci_bus_add_devices() |
414 | if (retval) | 415 | */ |
415 | goto error_register; | 416 | child->dev.class = &pcibus_class; |
416 | retval = class_device_create_file(&child->class_dev, | 417 | sprintf(child->dev.bus_id, "%04x:%02x", pci_domain_nr(child), busnr); |
417 | &class_device_attr_cpuaffinity); | ||
418 | if (retval) | ||
419 | goto error_file_create; | ||
420 | 418 | ||
421 | /* | 419 | /* |
422 | * Set up the primary, secondary and subordinate | 420 | * Set up the primary, secondary and subordinate |
@@ -434,12 +432,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) | |||
434 | bridge->subordinate = child; | 432 | bridge->subordinate = child; |
435 | 433 | ||
436 | return child; | 434 | return child; |
437 | |||
438 | error_file_create: | ||
439 | class_device_unregister(&child->class_dev); | ||
440 | error_register: | ||
441 | kfree(child); | ||
442 | return NULL; | ||
443 | } | 435 | } |
444 | 436 | ||
445 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) | 437 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) |
@@ -471,8 +463,6 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) | |||
471 | } | 463 | } |
472 | } | 464 | } |
473 | 465 | ||
474 | unsigned int pci_scan_child_bus(struct pci_bus *bus); | ||
475 | |||
476 | /* | 466 | /* |
477 | * If it's a bridge, configure it and scan the bus behind it. | 467 | * If it's a bridge, configure it and scan the bus behind it. |
478 | * For CardBus bridges, we don't scan behind as the devices will | 468 | * For CardBus bridges, we don't scan behind as the devices will |
@@ -641,13 +631,13 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass | |||
641 | (child->number > bus->subordinate) || | 631 | (child->number > bus->subordinate) || |
642 | (child->number < bus->number) || | 632 | (child->number < bus->number) || |
643 | (child->subordinate < bus->number)) { | 633 | (child->subordinate < bus->number)) { |
644 | pr_debug("PCI: Bus #%02x (-#%02x) is %s" | 634 | pr_debug("PCI: Bus #%02x (-#%02x) is %s " |
645 | "hidden behind%s bridge #%02x (-#%02x)\n", | 635 | "hidden behind%s bridge #%02x (-#%02x)\n", |
646 | child->number, child->subordinate, | 636 | child->number, child->subordinate, |
647 | (bus->number > child->subordinate && | 637 | (bus->number > child->subordinate && |
648 | bus->subordinate < child->number) ? | 638 | bus->subordinate < child->number) ? |
649 | "wholly " : " partially", | 639 | "wholly" : "partially", |
650 | bus->self->transparent ? " transparent" : " ", | 640 | bus->self->transparent ? " transparent" : "", |
651 | bus->number, bus->subordinate); | 641 | bus->number, bus->subordinate); |
652 | } | 642 | } |
653 | bus = bus->parent; | 643 | bus = bus->parent; |
@@ -971,6 +961,7 @@ struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
971 | 961 | ||
972 | return dev; | 962 | return dev; |
973 | } | 963 | } |
964 | EXPORT_SYMBOL(pci_scan_single_device); | ||
974 | 965 | ||
975 | /** | 966 | /** |
976 | * pci_scan_slot - scan a PCI slot on a bus for devices. | 967 | * pci_scan_slot - scan a PCI slot on a bus for devices. |
@@ -1011,6 +1002,10 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1011 | break; | 1002 | break; |
1012 | } | 1003 | } |
1013 | } | 1004 | } |
1005 | |||
1006 | if (bus->self) | ||
1007 | pcie_aspm_init_link_state(bus->self); | ||
1008 | |||
1014 | return nr; | 1009 | return nr; |
1015 | } | 1010 | } |
1016 | 1011 | ||
@@ -1103,32 +1098,27 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1103 | goto dev_reg_err; | 1098 | goto dev_reg_err; |
1104 | b->bridge = get_device(dev); | 1099 | b->bridge = get_device(dev); |
1105 | 1100 | ||
1106 | b->class_dev.class = &pcibus_class; | 1101 | b->dev.class = &pcibus_class; |
1107 | sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus); | 1102 | b->dev.parent = b->bridge; |
1108 | error = class_device_register(&b->class_dev); | 1103 | sprintf(b->dev.bus_id, "%04x:%02x", pci_domain_nr(b), bus); |
1104 | error = device_register(&b->dev); | ||
1109 | if (error) | 1105 | if (error) |
1110 | goto class_dev_reg_err; | 1106 | goto class_dev_reg_err; |
1111 | error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); | 1107 | error = device_create_file(&b->dev, &dev_attr_cpuaffinity); |
1112 | if (error) | 1108 | if (error) |
1113 | goto class_dev_create_file_err; | 1109 | goto dev_create_file_err; |
1114 | 1110 | ||
1115 | /* Create legacy_io and legacy_mem files for this bus */ | 1111 | /* Create legacy_io and legacy_mem files for this bus */ |
1116 | pci_create_legacy_files(b); | 1112 | pci_create_legacy_files(b); |
1117 | 1113 | ||
1118 | error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); | ||
1119 | if (error) | ||
1120 | goto sys_create_link_err; | ||
1121 | |||
1122 | b->number = b->secondary = bus; | 1114 | b->number = b->secondary = bus; |
1123 | b->resource[0] = &ioport_resource; | 1115 | b->resource[0] = &ioport_resource; |
1124 | b->resource[1] = &iomem_resource; | 1116 | b->resource[1] = &iomem_resource; |
1125 | 1117 | ||
1126 | return b; | 1118 | return b; |
1127 | 1119 | ||
1128 | sys_create_link_err: | 1120 | dev_create_file_err: |
1129 | class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity); | 1121 | device_unregister(&b->dev); |
1130 | class_dev_create_file_err: | ||
1131 | class_device_unregister(&b->class_dev); | ||
1132 | class_dev_reg_err: | 1122 | class_dev_reg_err: |
1133 | device_unregister(dev); | 1123 | device_unregister(dev); |
1134 | dev_reg_err: | 1124 | dev_reg_err: |
@@ -1140,7 +1130,6 @@ err_out: | |||
1140 | kfree(b); | 1130 | kfree(b); |
1141 | return NULL; | 1131 | return NULL; |
1142 | } | 1132 | } |
1143 | EXPORT_SYMBOL_GPL(pci_create_bus); | ||
1144 | 1133 | ||
1145 | struct pci_bus *pci_scan_bus_parented(struct device *parent, | 1134 | struct pci_bus *pci_scan_bus_parented(struct device *parent, |
1146 | int bus, struct pci_ops *ops, void *sysdata) | 1135 | int bus, struct pci_ops *ops, void *sysdata) |
@@ -1159,7 +1148,6 @@ EXPORT_SYMBOL(pci_add_new_bus); | |||
1159 | EXPORT_SYMBOL(pci_do_scan_bus); | 1148 | EXPORT_SYMBOL(pci_do_scan_bus); |
1160 | EXPORT_SYMBOL(pci_scan_slot); | 1149 | EXPORT_SYMBOL(pci_scan_slot); |
1161 | EXPORT_SYMBOL(pci_scan_bridge); | 1150 | EXPORT_SYMBOL(pci_scan_bridge); |
1162 | EXPORT_SYMBOL(pci_scan_single_device); | ||
1163 | EXPORT_SYMBOL_GPL(pci_scan_child_bus); | 1151 | EXPORT_SYMBOL_GPL(pci_scan_child_bus); |
1164 | #endif | 1152 | #endif |
1165 | 1153 | ||
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 716439e25dd2..68aeeb7206de 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/proc_fs.h> | 12 | #include <linux/proc_fs.h> |
13 | #include <linux/seq_file.h> | 13 | #include <linux/seq_file.h> |
14 | #include <linux/smp_lock.h> | ||
14 | #include <linux/capability.h> | 15 | #include <linux/capability.h> |
15 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
16 | #include <asm/byteorder.h> | 17 | #include <asm/byteorder.h> |
@@ -202,15 +203,18 @@ struct pci_filp_private { | |||
202 | int write_combine; | 203 | int write_combine; |
203 | }; | 204 | }; |
204 | 205 | ||
205 | static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 206 | static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, |
207 | unsigned long arg) | ||
206 | { | 208 | { |
207 | const struct proc_dir_entry *dp = PDE(inode); | 209 | const struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); |
208 | struct pci_dev *dev = dp->data; | 210 | struct pci_dev *dev = dp->data; |
209 | #ifdef HAVE_PCI_MMAP | 211 | #ifdef HAVE_PCI_MMAP |
210 | struct pci_filp_private *fpriv = file->private_data; | 212 | struct pci_filp_private *fpriv = file->private_data; |
211 | #endif /* HAVE_PCI_MMAP */ | 213 | #endif /* HAVE_PCI_MMAP */ |
212 | int ret = 0; | 214 | int ret = 0; |
213 | 215 | ||
216 | lock_kernel(); | ||
217 | |||
214 | switch (cmd) { | 218 | switch (cmd) { |
215 | case PCIIOC_CONTROLLER: | 219 | case PCIIOC_CONTROLLER: |
216 | ret = pci_domain_nr(dev->bus); | 220 | ret = pci_domain_nr(dev->bus); |
@@ -239,6 +243,7 @@ static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned i | |||
239 | break; | 243 | break; |
240 | }; | 244 | }; |
241 | 245 | ||
246 | unlock_kernel(); | ||
242 | return ret; | 247 | return ret; |
243 | } | 248 | } |
244 | 249 | ||
@@ -291,7 +296,7 @@ static const struct file_operations proc_bus_pci_operations = { | |||
291 | .llseek = proc_bus_pci_lseek, | 296 | .llseek = proc_bus_pci_lseek, |
292 | .read = proc_bus_pci_read, | 297 | .read = proc_bus_pci_read, |
293 | .write = proc_bus_pci_write, | 298 | .write = proc_bus_pci_write, |
294 | .ioctl = proc_bus_pci_ioctl, | 299 | .unlocked_ioctl = proc_bus_pci_ioctl, |
295 | #ifdef HAVE_PCI_MMAP | 300 | #ifdef HAVE_PCI_MMAP |
296 | .open = proc_bus_pci_open, | 301 | .open = proc_bus_pci_open, |
297 | .release = proc_bus_pci_release, | 302 | .release = proc_bus_pci_release, |
@@ -370,7 +375,7 @@ static int show_device(struct seq_file *m, void *v) | |||
370 | return 0; | 375 | return 0; |
371 | } | 376 | } |
372 | 377 | ||
373 | static struct seq_operations proc_bus_pci_devices_op = { | 378 | static const struct seq_operations proc_bus_pci_devices_op = { |
374 | .start = pci_seq_start, | 379 | .start = pci_seq_start, |
375 | .next = pci_seq_next, | 380 | .next = pci_seq_next, |
376 | .stop = pci_seq_stop, | 381 | .stop = pci_seq_stop, |
@@ -480,7 +485,3 @@ static int __init pci_proc_init(void) | |||
480 | 485 | ||
481 | __initcall(pci_proc_init); | 486 | __initcall(pci_proc_init); |
482 | 487 | ||
483 | #ifdef CONFIG_HOTPLUG | ||
484 | EXPORT_SYMBOL(pci_proc_detach_bus); | ||
485 | #endif | ||
486 | |||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 72e0bd5d80ac..0a953d43b9a2 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/acpi.h> | 23 | #include <linux/acpi.h> |
24 | #include <linux/kallsyms.h> | ||
24 | #include "pci.h" | 25 | #include "pci.h" |
25 | 26 | ||
26 | /* The Mellanox Tavor device gives false positive parity errors | 27 | /* The Mellanox Tavor device gives false positive parity errors |
@@ -46,14 +47,14 @@ static void quirk_passive_release(struct pci_dev *dev) | |||
46 | while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) { | 47 | while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) { |
47 | pci_read_config_byte(d, 0x82, &dlc); | 48 | pci_read_config_byte(d, 0x82, &dlc); |
48 | if (!(dlc & 1<<1)) { | 49 | if (!(dlc & 1<<1)) { |
49 | printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d)); | 50 | dev_err(&d->dev, "PIIX3: Enabling Passive Release\n"); |
50 | dlc |= 1<<1; | 51 | dlc |= 1<<1; |
51 | pci_write_config_byte(d, 0x82, dlc); | 52 | pci_write_config_byte(d, 0x82, dlc); |
52 | } | 53 | } |
53 | } | 54 | } |
54 | } | 55 | } |
55 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); | 56 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release); |
56 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); | 57 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release); |
57 | 58 | ||
58 | /* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround | 59 | /* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround |
59 | but VIA don't answer queries. If you happen to have good contacts at VIA | 60 | but VIA don't answer queries. If you happen to have good contacts at VIA |
@@ -68,20 +69,20 @@ static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev) | |||
68 | { | 69 | { |
69 | if (!isa_dma_bridge_buggy) { | 70 | if (!isa_dma_bridge_buggy) { |
70 | isa_dma_bridge_buggy=1; | 71 | isa_dma_bridge_buggy=1; |
71 | printk(KERN_INFO "Activating ISA DMA hang workarounds.\n"); | 72 | dev_info(&dev->dev, "Activating ISA DMA hang workarounds\n"); |
72 | } | 73 | } |
73 | } | 74 | } |
74 | /* | 75 | /* |
75 | * Its not totally clear which chipsets are the problematic ones | 76 | * Its not totally clear which chipsets are the problematic ones |
76 | * We know 82C586 and 82C596 variants are affected. | 77 | * We know 82C586 and 82C596 variants are affected. |
77 | */ | 78 | */ |
78 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_isa_dma_hangs ); | 79 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_isa_dma_hangs); |
79 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, quirk_isa_dma_hangs ); | 80 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, quirk_isa_dma_hangs); |
80 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, quirk_isa_dma_hangs ); | 81 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, quirk_isa_dma_hangs); |
81 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, quirk_isa_dma_hangs ); | 82 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, quirk_isa_dma_hangs); |
82 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_dma_hangs ); | 83 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_dma_hangs); |
83 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs ); | 84 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs); |
84 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs ); | 85 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); |
85 | 86 | ||
86 | int pci_pci_problems; | 87 | int pci_pci_problems; |
87 | EXPORT_SYMBOL(pci_pci_problems); | 88 | EXPORT_SYMBOL(pci_pci_problems); |
@@ -92,12 +93,12 @@ EXPORT_SYMBOL(pci_pci_problems); | |||
92 | static void __devinit quirk_nopcipci(struct pci_dev *dev) | 93 | static void __devinit quirk_nopcipci(struct pci_dev *dev) |
93 | { | 94 | { |
94 | if ((pci_pci_problems & PCIPCI_FAIL)==0) { | 95 | if ((pci_pci_problems & PCIPCI_FAIL)==0) { |
95 | printk(KERN_INFO "Disabling direct PCI/PCI transfers.\n"); | 96 | dev_info(&dev->dev, "Disabling direct PCI/PCI transfers\n"); |
96 | pci_pci_problems |= PCIPCI_FAIL; | 97 | pci_pci_problems |= PCIPCI_FAIL; |
97 | } | 98 | } |
98 | } | 99 | } |
99 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci ); | 100 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci); |
100 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci ); | 101 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci); |
101 | 102 | ||
102 | static void __devinit quirk_nopciamd(struct pci_dev *dev) | 103 | static void __devinit quirk_nopciamd(struct pci_dev *dev) |
103 | { | 104 | { |
@@ -105,11 +106,11 @@ static void __devinit quirk_nopciamd(struct pci_dev *dev) | |||
105 | pci_read_config_byte(dev, 0x08, &rev); | 106 | pci_read_config_byte(dev, 0x08, &rev); |
106 | if (rev == 0x13) { | 107 | if (rev == 0x13) { |
107 | /* Erratum 24 */ | 108 | /* Erratum 24 */ |
108 | printk(KERN_INFO "Chipset erratum: Disabling direct PCI/AGP transfers.\n"); | 109 | dev_info(&dev->dev, "Chipset erratum: Disabling direct PCI/AGP transfers\n"); |
109 | pci_pci_problems |= PCIAGP_FAIL; | 110 | pci_pci_problems |= PCIAGP_FAIL; |
110 | } | 111 | } |
111 | } | 112 | } |
112 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopciamd ); | 113 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopciamd); |
113 | 114 | ||
114 | /* | 115 | /* |
115 | * Triton requires workarounds to be used by the drivers | 116 | * Triton requires workarounds to be used by the drivers |
@@ -117,14 +118,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopci | |||
117 | static void __devinit quirk_triton(struct pci_dev *dev) | 118 | static void __devinit quirk_triton(struct pci_dev *dev) |
118 | { | 119 | { |
119 | if ((pci_pci_problems&PCIPCI_TRITON)==0) { | 120 | if ((pci_pci_problems&PCIPCI_TRITON)==0) { |
120 | printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); | 121 | dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n"); |
121 | pci_pci_problems |= PCIPCI_TRITON; | 122 | pci_pci_problems |= PCIPCI_TRITON; |
122 | } | 123 | } |
123 | } | 124 | } |
124 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, quirk_triton ); | 125 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, quirk_triton); |
125 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX, quirk_triton ); | 126 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX, quirk_triton); |
126 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439, quirk_triton ); | 127 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439, quirk_triton); |
127 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quirk_triton ); | 128 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quirk_triton); |
128 | 129 | ||
129 | /* | 130 | /* |
130 | * VIA Apollo KT133 needs PCI latency patch | 131 | * VIA Apollo KT133 needs PCI latency patch |
@@ -139,25 +140,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quir | |||
139 | static void quirk_vialatency(struct pci_dev *dev) | 140 | static void quirk_vialatency(struct pci_dev *dev) |
140 | { | 141 | { |
141 | struct pci_dev *p; | 142 | struct pci_dev *p; |
142 | u8 rev; | ||
143 | u8 busarb; | 143 | u8 busarb; |
144 | /* Ok we have a potential problem chipset here. Now see if we have | 144 | /* Ok we have a potential problem chipset here. Now see if we have |
145 | a buggy southbridge */ | 145 | a buggy southbridge */ |
146 | 146 | ||
147 | p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL); | 147 | p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL); |
148 | if (p!=NULL) { | 148 | if (p!=NULL) { |
149 | pci_read_config_byte(p, PCI_CLASS_REVISION, &rev); | ||
150 | /* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */ | 149 | /* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */ |
151 | /* Check for buggy part revisions */ | 150 | /* Check for buggy part revisions */ |
152 | if (rev < 0x40 || rev > 0x42) | 151 | if (p->revision < 0x40 || p->revision > 0x42) |
153 | goto exit; | 152 | goto exit; |
154 | } else { | 153 | } else { |
155 | p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL); | 154 | p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL); |
156 | if (p==NULL) /* No problem parts */ | 155 | if (p==NULL) /* No problem parts */ |
157 | goto exit; | 156 | goto exit; |
158 | pci_read_config_byte(p, PCI_CLASS_REVISION, &rev); | ||
159 | /* Check for buggy part revisions */ | 157 | /* Check for buggy part revisions */ |
160 | if (rev < 0x10 || rev > 0x12) | 158 | if (p->revision < 0x10 || p->revision > 0x12) |
161 | goto exit; | 159 | goto exit; |
162 | } | 160 | } |
163 | 161 | ||
@@ -180,17 +178,17 @@ static void quirk_vialatency(struct pci_dev *dev) | |||
180 | busarb &= ~(1<<5); | 178 | busarb &= ~(1<<5); |
181 | busarb |= (1<<4); | 179 | busarb |= (1<<4); |
182 | pci_write_config_byte(dev, 0x76, busarb); | 180 | pci_write_config_byte(dev, 0x76, busarb); |
183 | printk(KERN_INFO "Applying VIA southbridge workaround.\n"); | 181 | dev_info(&dev->dev, "Applying VIA southbridge workaround\n"); |
184 | exit: | 182 | exit: |
185 | pci_dev_put(p); | 183 | pci_dev_put(p); |
186 | } | 184 | } |
187 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); | 185 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency); |
188 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); | 186 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency); |
189 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); | 187 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency); |
190 | /* Must restore this on a resume from RAM */ | 188 | /* Must restore this on a resume from RAM */ |
191 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); | 189 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency); |
192 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); | 190 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency); |
193 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); | 191 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency); |
194 | 192 | ||
195 | /* | 193 | /* |
196 | * VIA Apollo VP3 needs ETBF on BT848/878 | 194 | * VIA Apollo VP3 needs ETBF on BT848/878 |
@@ -198,20 +196,20 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_viala | |||
198 | static void __devinit quirk_viaetbf(struct pci_dev *dev) | 196 | static void __devinit quirk_viaetbf(struct pci_dev *dev) |
199 | { | 197 | { |
200 | if ((pci_pci_problems&PCIPCI_VIAETBF)==0) { | 198 | if ((pci_pci_problems&PCIPCI_VIAETBF)==0) { |
201 | printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); | 199 | dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n"); |
202 | pci_pci_problems |= PCIPCI_VIAETBF; | 200 | pci_pci_problems |= PCIPCI_VIAETBF; |
203 | } | 201 | } |
204 | } | 202 | } |
205 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_viaetbf ); | 203 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_viaetbf); |
206 | 204 | ||
207 | static void __devinit quirk_vsfx(struct pci_dev *dev) | 205 | static void __devinit quirk_vsfx(struct pci_dev *dev) |
208 | { | 206 | { |
209 | if ((pci_pci_problems&PCIPCI_VSFX)==0) { | 207 | if ((pci_pci_problems&PCIPCI_VSFX)==0) { |
210 | printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); | 208 | dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n"); |
211 | pci_pci_problems |= PCIPCI_VSFX; | 209 | pci_pci_problems |= PCIPCI_VSFX; |
212 | } | 210 | } |
213 | } | 211 | } |
214 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx ); | 212 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx); |
215 | 213 | ||
216 | /* | 214 | /* |
217 | * Ali Magik requires workarounds to be used by the drivers | 215 | * Ali Magik requires workarounds to be used by the drivers |
@@ -222,12 +220,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx | |||
222 | static void __init quirk_alimagik(struct pci_dev *dev) | 220 | static void __init quirk_alimagik(struct pci_dev *dev) |
223 | { | 221 | { |
224 | if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) { | 222 | if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) { |
225 | printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); | 223 | dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n"); |
226 | pci_pci_problems |= PCIPCI_ALIMAGIK|PCIPCI_TRITON; | 224 | pci_pci_problems |= PCIPCI_ALIMAGIK|PCIPCI_TRITON; |
227 | } | 225 | } |
228 | } | 226 | } |
229 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1647, quirk_alimagik ); | 227 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1647, quirk_alimagik); |
230 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, quirk_alimagik ); | 228 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, quirk_alimagik); |
231 | 229 | ||
232 | /* | 230 | /* |
233 | * Natoma has some interesting boundary conditions with Zoran stuff | 231 | * Natoma has some interesting boundary conditions with Zoran stuff |
@@ -236,16 +234,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, quirk_alimag | |||
236 | static void __devinit quirk_natoma(struct pci_dev *dev) | 234 | static void __devinit quirk_natoma(struct pci_dev *dev) |
237 | { | 235 | { |
238 | if ((pci_pci_problems&PCIPCI_NATOMA)==0) { | 236 | if ((pci_pci_problems&PCIPCI_NATOMA)==0) { |
239 | printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); | 237 | dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n"); |
240 | pci_pci_problems |= PCIPCI_NATOMA; | 238 | pci_pci_problems |= PCIPCI_NATOMA; |
241 | } | 239 | } |
242 | } | 240 | } |
243 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_natoma ); | 241 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_natoma); |
244 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_0, quirk_natoma ); | 242 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_0, quirk_natoma); |
245 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_1, quirk_natoma ); | 243 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_1, quirk_natoma); |
246 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0, quirk_natoma ); | 244 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0, quirk_natoma); |
247 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_1, quirk_natoma ); | 245 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_1, quirk_natoma); |
248 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma ); | 246 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma); |
249 | 247 | ||
250 | /* | 248 | /* |
251 | * This chip can cause PCI parity errors if config register 0xA0 is read | 249 | * This chip can cause PCI parity errors if config register 0xA0 is read |
@@ -255,7 +253,7 @@ static void __devinit quirk_citrine(struct pci_dev *dev) | |||
255 | { | 253 | { |
256 | dev->cfg_size = 0xA0; | 254 | dev->cfg_size = 0xA0; |
257 | } | 255 | } |
258 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine ); | 256 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine); |
259 | 257 | ||
260 | /* | 258 | /* |
261 | * S3 868 and 968 chips report region size equal to 32M, but they decode 64M. | 259 | * S3 868 and 968 chips report region size equal to 32M, but they decode 64M. |
@@ -270,8 +268,8 @@ static void __devinit quirk_s3_64M(struct pci_dev *dev) | |||
270 | r->end = 0x3ffffff; | 268 | r->end = 0x3ffffff; |
271 | } | 269 | } |
272 | } | 270 | } |
273 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M ); | 271 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M); |
274 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M ); | 272 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M); |
275 | 273 | ||
276 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | 274 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, |
277 | unsigned size, int nr, const char *name) | 275 | unsigned size, int nr, const char *name) |
@@ -292,7 +290,7 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | |||
292 | pcibios_bus_to_resource(dev, res, &bus_region); | 290 | pcibios_bus_to_resource(dev, res, &bus_region); |
293 | 291 | ||
294 | pci_claim_resource(dev, nr); | 292 | pci_claim_resource(dev, nr); |
295 | printk("PCI quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name); | 293 | dev_info(&dev->dev, "quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name); |
296 | } | 294 | } |
297 | } | 295 | } |
298 | 296 | ||
@@ -302,12 +300,12 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | |||
302 | */ | 300 | */ |
303 | static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev) | 301 | static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev) |
304 | { | 302 | { |
305 | printk(KERN_INFO "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb.\n"); | 303 | dev_info(&dev->dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n"); |
306 | /* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */ | 304 | /* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */ |
307 | request_region(0x3b0, 0x0C, "RadeonIGP"); | 305 | request_region(0x3b0, 0x0C, "RadeonIGP"); |
308 | request_region(0x3d3, 0x01, "RadeonIGP"); | 306 | request_region(0x3d3, 0x01, "RadeonIGP"); |
309 | } | 307 | } |
310 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_exploding_mce ); | 308 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_exploding_mce); |
311 | 309 | ||
312 | /* | 310 | /* |
313 | * Let's make the southbridge information explicit instead | 311 | * Let's make the southbridge information explicit instead |
@@ -329,7 +327,7 @@ static void __devinit quirk_ali7101_acpi(struct pci_dev *dev) | |||
329 | pci_read_config_word(dev, 0xE2, ®ion); | 327 | pci_read_config_word(dev, 0xE2, ®ion); |
330 | quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); | 328 | quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); |
331 | } | 329 | } |
332 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi ); | 330 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi); |
333 | 331 | ||
334 | static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable) | 332 | static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable) |
335 | { | 333 | { |
@@ -354,7 +352,7 @@ static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int p | |||
354 | * let's get enough confirmation reports first. | 352 | * let's get enough confirmation reports first. |
355 | */ | 353 | */ |
356 | base &= -size; | 354 | base &= -size; |
357 | printk("%s PIO at %04x-%04x\n", name, base, base + size - 1); | 355 | dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base, base + size - 1); |
358 | } | 356 | } |
359 | 357 | ||
360 | static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable) | 358 | static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable) |
@@ -379,7 +377,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int | |||
379 | * reserve it, but let's get enough confirmation reports first. | 377 | * reserve it, but let's get enough confirmation reports first. |
380 | */ | 378 | */ |
381 | base &= -size; | 379 | base &= -size; |
382 | printk("%s MMIO at %04x-%04x\n", name, base, base + size - 1); | 380 | dev_info(&dev->dev, "%s MMIO at %04x-%04x\n", name, base, base + size - 1); |
383 | } | 381 | } |
384 | 382 | ||
385 | /* | 383 | /* |
@@ -418,8 +416,8 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev) | |||
418 | piix4_io_quirk(dev, "PIIX4 devres I", 0x78, 1 << 20); | 416 | piix4_io_quirk(dev, "PIIX4 devres I", 0x78, 1 << 20); |
419 | piix4_io_quirk(dev, "PIIX4 devres J", 0x7c, 1 << 20); | 417 | piix4_io_quirk(dev, "PIIX4 devres J", 0x7c, 1 << 20); |
420 | } | 418 | } |
421 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi ); | 419 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi); |
422 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, quirk_piix4_acpi ); | 420 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, quirk_piix4_acpi); |
423 | 421 | ||
424 | /* | 422 | /* |
425 | * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at | 423 | * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at |
@@ -436,16 +434,16 @@ static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev) | |||
436 | pci_read_config_dword(dev, 0x58, ®ion); | 434 | pci_read_config_dword(dev, 0x58, ®ion); |
437 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH4 GPIO"); | 435 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH4 GPIO"); |
438 | } | 436 | } |
439 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi ); | 437 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); |
440 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi ); | 438 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); |
441 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, quirk_ich4_lpc_acpi ); | 439 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, quirk_ich4_lpc_acpi); |
442 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, quirk_ich4_lpc_acpi ); | 440 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, quirk_ich4_lpc_acpi); |
443 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, quirk_ich4_lpc_acpi ); | 441 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, quirk_ich4_lpc_acpi); |
444 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, quirk_ich4_lpc_acpi ); | 442 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, quirk_ich4_lpc_acpi); |
445 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, quirk_ich4_lpc_acpi ); | 443 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, quirk_ich4_lpc_acpi); |
446 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, quirk_ich4_lpc_acpi ); | 444 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, quirk_ich4_lpc_acpi); |
447 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi ); | 445 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi); |
448 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi ); | 446 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi); |
449 | 447 | ||
450 | static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | 448 | static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) |
451 | { | 449 | { |
@@ -457,20 +455,20 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | |||
457 | pci_read_config_dword(dev, 0x48, ®ion); | 455 | pci_read_config_dword(dev, 0x48, ®ion); |
458 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); | 456 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); |
459 | } | 457 | } |
460 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); | 458 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi); |
461 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); | 459 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi); |
462 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi ); | 460 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi); |
463 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi ); | 461 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi); |
464 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi ); | 462 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi); |
465 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi ); | 463 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi); |
466 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi ); | 464 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi); |
467 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi ); | 465 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi); |
468 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, quirk_ich6_lpc_acpi ); | 466 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, quirk_ich6_lpc_acpi); |
469 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, quirk_ich6_lpc_acpi ); | 467 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, quirk_ich6_lpc_acpi); |
470 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, quirk_ich6_lpc_acpi ); | 468 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, quirk_ich6_lpc_acpi); |
471 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_4, quirk_ich6_lpc_acpi ); | 469 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_4, quirk_ich6_lpc_acpi); |
472 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, quirk_ich6_lpc_acpi ); | 470 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, quirk_ich6_lpc_acpi); |
473 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_8, quirk_ich6_lpc_acpi ); | 471 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_8, quirk_ich6_lpc_acpi); |
474 | 472 | ||
475 | /* | 473 | /* |
476 | * VIA ACPI: One IO region pointed to by longword at | 474 | * VIA ACPI: One IO region pointed to by longword at |
@@ -486,7 +484,7 @@ static void __devinit quirk_vt82c586_acpi(struct pci_dev *dev) | |||
486 | quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); | 484 | quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); |
487 | } | 485 | } |
488 | } | 486 | } |
489 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi ); | 487 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi); |
490 | 488 | ||
491 | /* | 489 | /* |
492 | * VIA VT82C686 ACPI: Three IO region pointed to by (long)words at | 490 | * VIA VT82C686 ACPI: Three IO region pointed to by (long)words at |
@@ -509,7 +507,7 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev) | |||
509 | smb &= PCI_BASE_ADDRESS_IO_MASK; | 507 | smb &= PCI_BASE_ADDRESS_IO_MASK; |
510 | quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); | 508 | quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); |
511 | } | 509 | } |
512 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi ); | 510 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi); |
513 | 511 | ||
514 | /* | 512 | /* |
515 | * VIA VT8235 ISA Bridge: Two IO regions pointed to by words at | 513 | * VIA VT8235 ISA Bridge: Two IO regions pointed to by words at |
@@ -551,14 +549,14 @@ static void quirk_via_ioapic(struct pci_dev *dev) | |||
551 | else | 549 | else |
552 | tmp = 0x1f; /* all known bits (4-0) routed to external APIC */ | 550 | tmp = 0x1f; /* all known bits (4-0) routed to external APIC */ |
553 | 551 | ||
554 | printk(KERN_INFO "PCI: %sbling Via external APIC routing\n", | 552 | dev_info(&dev->dev, "%sbling VIA external APIC routing\n", |
555 | tmp == 0 ? "Disa" : "Ena"); | 553 | tmp == 0 ? "Disa" : "Ena"); |
556 | 554 | ||
557 | /* Offset 0x58: External APIC IRQ output control */ | 555 | /* Offset 0x58: External APIC IRQ output control */ |
558 | pci_write_config_byte (dev, 0x58, tmp); | 556 | pci_write_config_byte (dev, 0x58, tmp); |
559 | } | 557 | } |
560 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); | 558 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic); |
561 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); | 559 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic); |
562 | 560 | ||
563 | /* | 561 | /* |
564 | * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. | 562 | * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. |
@@ -573,7 +571,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) | |||
573 | 571 | ||
574 | pci_read_config_byte(dev, 0x5B, &misc_control2); | 572 | pci_read_config_byte(dev, 0x5B, &misc_control2); |
575 | if (!(misc_control2 & BYPASS_APIC_DEASSERT)) { | 573 | if (!(misc_control2 & BYPASS_APIC_DEASSERT)) { |
576 | printk(KERN_INFO "PCI: Bypassing VIA 8237 APIC De-Assert Message\n"); | 574 | dev_info(&dev->dev, "Bypassing VIA 8237 APIC De-Assert Message\n"); |
577 | pci_write_config_byte(dev, 0x5B, misc_control2|BYPASS_APIC_DEASSERT); | 575 | pci_write_config_byte(dev, 0x5B, misc_control2|BYPASS_APIC_DEASSERT); |
578 | } | 576 | } |
579 | } | 577 | } |
@@ -592,18 +590,18 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_v | |||
592 | static void __devinit quirk_amd_ioapic(struct pci_dev *dev) | 590 | static void __devinit quirk_amd_ioapic(struct pci_dev *dev) |
593 | { | 591 | { |
594 | if (dev->revision >= 0x02) { | 592 | if (dev->revision >= 0x02) { |
595 | printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n"); | 593 | dev_warn(&dev->dev, "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n"); |
596 | printk(KERN_WARNING " : booting with the \"noapic\" option.\n"); | 594 | dev_warn(&dev->dev, " : booting with the \"noapic\" option\n"); |
597 | } | 595 | } |
598 | } | 596 | } |
599 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic ); | 597 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic); |
600 | 598 | ||
601 | static void __init quirk_ioapic_rmw(struct pci_dev *dev) | 599 | static void __init quirk_ioapic_rmw(struct pci_dev *dev) |
602 | { | 600 | { |
603 | if (dev->devfn == 0 && dev->bus->number == 0) | 601 | if (dev->devfn == 0 && dev->bus->number == 0) |
604 | sis_apic_bug = 1; | 602 | sis_apic_bug = 1; |
605 | } | 603 | } |
606 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw ); | 604 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw); |
607 | 605 | ||
608 | #define AMD8131_revA0 0x01 | 606 | #define AMD8131_revA0 0x01 |
609 | #define AMD8131_revB0 0x11 | 607 | #define AMD8131_revB0 0x11 |
@@ -617,7 +615,7 @@ static void quirk_amd_8131_ioapic(struct pci_dev *dev) | |||
617 | return; | 615 | return; |
618 | 616 | ||
619 | if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) { | 617 | if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) { |
620 | printk(KERN_INFO "Fixing up AMD8131 IOAPIC mode\n"); | 618 | dev_info(&dev->dev, "Fixing up AMD8131 IOAPIC mode\n"); |
621 | pci_read_config_byte( dev, AMD8131_MISC, &tmp); | 619 | pci_read_config_byte( dev, AMD8131_MISC, &tmp); |
622 | tmp &= ~(1 << AMD8131_NIOAMODE_BIT); | 620 | tmp &= ~(1 << AMD8131_NIOAMODE_BIT); |
623 | pci_write_config_byte( dev, AMD8131_MISC, tmp); | 621 | pci_write_config_byte( dev, AMD8131_MISC, tmp); |
@@ -634,8 +632,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk | |||
634 | static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev) | 632 | static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev) |
635 | { | 633 | { |
636 | if (dev->subordinate && dev->revision <= 0x12) { | 634 | if (dev->subordinate && dev->revision <= 0x12) { |
637 | printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X " | 635 | dev_info(&dev->dev, "AMD8131 rev %x detected; " |
638 | "MMRBC\n", dev->revision); | 636 | "disabling PCI-X MMRBC\n", dev->revision); |
639 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC; | 637 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC; |
640 | } | 638 | } |
641 | } | 639 | } |
@@ -660,8 +658,8 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) | |||
660 | if (irq && (irq != 2)) | 658 | if (irq && (irq != 2)) |
661 | d->irq = irq; | 659 | d->irq = irq; |
662 | } | 660 | } |
663 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); | 661 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi); |
664 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); | 662 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi); |
665 | 663 | ||
666 | 664 | ||
667 | /* | 665 | /* |
@@ -742,8 +740,8 @@ static void quirk_via_vlink(struct pci_dev *dev) | |||
742 | 740 | ||
743 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 741 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
744 | if (new_irq != irq) { | 742 | if (new_irq != irq) { |
745 | printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n", | 743 | dev_info(&dev->dev, "VIA VLink IRQ fixup, from %d to %d\n", |
746 | pci_name(dev), irq, new_irq); | 744 | irq, new_irq); |
747 | udelay(15); /* unknown if delay really needed */ | 745 | udelay(15); /* unknown if delay really needed */ |
748 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); | 746 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); |
749 | } | 747 | } |
@@ -761,7 +759,7 @@ static void __devinit quirk_vt82c598_id(struct pci_dev *dev) | |||
761 | pci_write_config_byte(dev, 0xfc, 0); | 759 | pci_write_config_byte(dev, 0xfc, 0); |
762 | pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device); | 760 | pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device); |
763 | } | 761 | } |
764 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id ); | 762 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id); |
765 | 763 | ||
766 | /* | 764 | /* |
767 | * CardBus controllers have a legacy base address that enables them | 765 | * CardBus controllers have a legacy base address that enables them |
@@ -791,15 +789,15 @@ static void quirk_amd_ordering(struct pci_dev *dev) | |||
791 | pci_read_config_dword(dev, 0x4C, &pcic); | 789 | pci_read_config_dword(dev, 0x4C, &pcic); |
792 | if ((pcic&6)!=6) { | 790 | if ((pcic&6)!=6) { |
793 | pcic |= 6; | 791 | pcic |= 6; |
794 | printk(KERN_WARNING "BIOS failed to enable PCI standards compliance, fixing this error.\n"); | 792 | dev_warn(&dev->dev, "BIOS failed to enable PCI standards compliance; fixing this error\n"); |
795 | pci_write_config_dword(dev, 0x4C, pcic); | 793 | pci_write_config_dword(dev, 0x4C, pcic); |
796 | pci_read_config_dword(dev, 0x84, &pcic); | 794 | pci_read_config_dword(dev, 0x84, &pcic); |
797 | pcic |= (1<<23); /* Required in this mode */ | 795 | pcic |= (1<<23); /* Required in this mode */ |
798 | pci_write_config_dword(dev, 0x84, pcic); | 796 | pci_write_config_dword(dev, 0x84, pcic); |
799 | } | 797 | } |
800 | } | 798 | } |
801 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); | 799 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering); |
802 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); | 800 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering); |
803 | 801 | ||
804 | /* | 802 | /* |
805 | * DreamWorks provided workaround for Dunord I-3000 problem | 803 | * DreamWorks provided workaround for Dunord I-3000 problem |
@@ -814,7 +812,7 @@ static void __devinit quirk_dunord ( struct pci_dev * dev ) | |||
814 | r->start = 0; | 812 | r->start = 0; |
815 | r->end = 0xffffff; | 813 | r->end = 0xffffff; |
816 | } | 814 | } |
817 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DUNORD, PCI_DEVICE_ID_DUNORD_I3000, quirk_dunord ); | 815 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DUNORD, PCI_DEVICE_ID_DUNORD_I3000, quirk_dunord); |
818 | 816 | ||
819 | /* | 817 | /* |
820 | * i82380FB mobile docking controller: its PCI-to-PCI bridge | 818 | * i82380FB mobile docking controller: its PCI-to-PCI bridge |
@@ -826,8 +824,8 @@ static void __devinit quirk_transparent_bridge(struct pci_dev *dev) | |||
826 | { | 824 | { |
827 | dev->transparent = 1; | 825 | dev->transparent = 1; |
828 | } | 826 | } |
829 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge ); | 827 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge); |
830 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge ); | 828 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge); |
831 | 829 | ||
832 | /* | 830 | /* |
833 | * Common misconfiguration of the MediaGX/Geode PCI master that will | 831 | * Common misconfiguration of the MediaGX/Geode PCI master that will |
@@ -841,12 +839,12 @@ static void quirk_mediagx_master(struct pci_dev *dev) | |||
841 | pci_read_config_byte(dev, 0x41, ®); | 839 | pci_read_config_byte(dev, 0x41, ®); |
842 | if (reg & 2) { | 840 | if (reg & 2) { |
843 | reg &= ~2; | 841 | reg &= ~2; |
844 | printk(KERN_INFO "PCI: Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n", reg); | 842 | dev_info(&dev->dev, "Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n", reg); |
845 | pci_write_config_byte(dev, 0x41, reg); | 843 | pci_write_config_byte(dev, 0x41, reg); |
846 | } | 844 | } |
847 | } | 845 | } |
848 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); | 846 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master); |
849 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); | 847 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master); |
850 | 848 | ||
851 | /* | 849 | /* |
852 | * Ensure C0 rev restreaming is off. This is normally done by | 850 | * Ensure C0 rev restreaming is off. This is normally done by |
@@ -863,11 +861,11 @@ static void quirk_disable_pxb(struct pci_dev *pdev) | |||
863 | if (config & (1<<6)) { | 861 | if (config & (1<<6)) { |
864 | config &= ~(1<<6); | 862 | config &= ~(1<<6); |
865 | pci_write_config_word(pdev, 0x40, config); | 863 | pci_write_config_word(pdev, 0x40, config); |
866 | printk(KERN_INFO "PCI: C0 revision 450NX. Disabling PCI restreaming.\n"); | 864 | dev_info(&pdev->dev, "C0 revision 450NX. Disabling PCI restreaming\n"); |
867 | } | 865 | } |
868 | } | 866 | } |
869 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); | 867 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); |
870 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); | 868 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); |
871 | 869 | ||
872 | 870 | ||
873 | static void __devinit quirk_sb600_sata(struct pci_dev *pdev) | 871 | static void __devinit quirk_sb600_sata(struct pci_dev *pdev) |
@@ -902,7 +900,7 @@ static void __devinit quirk_svwks_csb5ide(struct pci_dev *pdev) | |||
902 | /* PCI layer will sort out resources */ | 900 | /* PCI layer will sort out resources */ |
903 | } | 901 | } |
904 | } | 902 | } |
905 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide ); | 903 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide); |
906 | 904 | ||
907 | /* | 905 | /* |
908 | * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same | 906 | * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same |
@@ -914,7 +912,7 @@ static void __init quirk_ide_samemode(struct pci_dev *pdev) | |||
914 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog); | 912 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog); |
915 | 913 | ||
916 | if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) { | 914 | if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) { |
917 | printk(KERN_INFO "PCI: IDE mode mismatch; forcing legacy mode\n"); | 915 | dev_info(&pdev->dev, "IDE mode mismatch; forcing legacy mode\n"); |
918 | prog &= ~5; | 916 | prog &= ~5; |
919 | pdev->class &= ~5; | 917 | pdev->class &= ~5; |
920 | pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); | 918 | pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); |
@@ -929,7 +927,7 @@ static void __init quirk_eisa_bridge(struct pci_dev *dev) | |||
929 | { | 927 | { |
930 | dev->class = PCI_CLASS_BRIDGE_EISA << 8; | 928 | dev->class = PCI_CLASS_BRIDGE_EISA << 8; |
931 | } | 929 | } |
932 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge ); | 930 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge); |
933 | 931 | ||
934 | 932 | ||
935 | /* | 933 | /* |
@@ -1022,6 +1020,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
1022 | case 0x12bd: /* HP D530 */ | 1020 | case 0x12bd: /* HP D530 */ |
1023 | asus_hides_smbus = 1; | 1021 | asus_hides_smbus = 1; |
1024 | } | 1022 | } |
1023 | else if (dev->device == PCI_DEVICE_ID_INTEL_82875_HB) | ||
1024 | switch (dev->subsystem_device) { | ||
1025 | case 0x12bf: /* HP xw4100 */ | ||
1026 | asus_hides_smbus = 1; | ||
1027 | } | ||
1025 | else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) | 1028 | else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) |
1026 | switch (dev->subsystem_device) { | 1029 | switch (dev->subsystem_device) { |
1027 | case 0x099c: /* HP Compaq nx6110 */ | 1030 | case 0x099c: /* HP Compaq nx6110 */ |
@@ -1049,17 +1052,18 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
1049 | } | 1052 | } |
1050 | } | 1053 | } |
1051 | } | 1054 | } |
1052 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge ); | 1055 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge); |
1053 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asus_hides_smbus_hostbridge ); | 1056 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asus_hides_smbus_hostbridge); |
1054 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge ); | 1057 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge); |
1055 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge ); | 1058 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge); |
1056 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); | 1059 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, asus_hides_smbus_hostbridge); |
1057 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge ); | 1060 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge); |
1058 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); | 1061 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge); |
1059 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); | 1062 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge); |
1060 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); | 1063 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge); |
1064 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge); | ||
1061 | 1065 | ||
1062 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, asus_hides_smbus_hostbridge ); | 1066 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, asus_hides_smbus_hostbridge); |
1063 | 1067 | ||
1064 | static void asus_hides_smbus_lpc(struct pci_dev *dev) | 1068 | static void asus_hides_smbus_lpc(struct pci_dev *dev) |
1065 | { | 1069 | { |
@@ -1073,25 +1077,25 @@ static void asus_hides_smbus_lpc(struct pci_dev *dev) | |||
1073 | pci_write_config_word(dev, 0xF2, val & (~0x8)); | 1077 | pci_write_config_word(dev, 0xF2, val & (~0x8)); |
1074 | pci_read_config_word(dev, 0xF2, &val); | 1078 | pci_read_config_word(dev, 0xF2, &val); |
1075 | if (val & 0x8) | 1079 | if (val & 0x8) |
1076 | printk(KERN_INFO "PCI: i801 SMBus device continues to play 'hide and seek'! 0x%x\n", val); | 1080 | dev_info(&dev->dev, "i801 SMBus device continues to play 'hide and seek'! 0x%x\n", val); |
1077 | else | 1081 | else |
1078 | printk(KERN_INFO "PCI: Enabled i801 SMBus device\n"); | 1082 | dev_info(&dev->dev, "Enabled i801 SMBus device\n"); |
1079 | } | 1083 | } |
1080 | } | 1084 | } |
1081 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc ); | 1085 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc); |
1082 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); | 1086 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc); |
1083 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); | 1087 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc); |
1084 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); | 1088 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc); |
1085 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | 1089 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc); |
1086 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 1090 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc); |
1087 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 1091 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc); |
1088 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc ); | 1092 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc); |
1089 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); | 1093 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc); |
1090 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); | 1094 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc); |
1091 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); | 1095 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc); |
1092 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | 1096 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc); |
1093 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 1097 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc); |
1094 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 1098 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc); |
1095 | 1099 | ||
1096 | static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | 1100 | static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) |
1097 | { | 1101 | { |
@@ -1106,10 +1110,10 @@ static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | |||
1106 | val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */ | 1110 | val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */ |
1107 | writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */ | 1111 | writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */ |
1108 | iounmap(base); | 1112 | iounmap(base); |
1109 | printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); | 1113 | dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n"); |
1110 | } | 1114 | } |
1111 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); | 1115 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6); |
1112 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); | 1116 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6); |
1113 | 1117 | ||
1114 | /* | 1118 | /* |
1115 | * SiS 96x south bridge: BIOS typically hides SMBus device... | 1119 | * SiS 96x south bridge: BIOS typically hides SMBus device... |
@@ -1119,18 +1123,18 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev) | |||
1119 | u8 val = 0; | 1123 | u8 val = 0; |
1120 | pci_read_config_byte(dev, 0x77, &val); | 1124 | pci_read_config_byte(dev, 0x77, &val); |
1121 | if (val & 0x10) { | 1125 | if (val & 0x10) { |
1122 | printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); | 1126 | dev_info(&dev->dev, "Enabling SiS 96x SMBus\n"); |
1123 | pci_write_config_byte(dev, 0x77, val & ~0x10); | 1127 | pci_write_config_byte(dev, 0x77, val & ~0x10); |
1124 | } | 1128 | } |
1125 | } | 1129 | } |
1126 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); | 1130 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus); |
1127 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); | 1131 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus); |
1128 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); | 1132 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus); |
1129 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); | 1133 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus); |
1130 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); | 1134 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus); |
1131 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); | 1135 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus); |
1132 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); | 1136 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus); |
1133 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); | 1137 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus); |
1134 | 1138 | ||
1135 | /* | 1139 | /* |
1136 | * ... This is further complicated by the fact that some SiS96x south | 1140 | * ... This is further complicated by the fact that some SiS96x south |
@@ -1163,8 +1167,8 @@ static void quirk_sis_503(struct pci_dev *dev) | |||
1163 | dev->device = devid; | 1167 | dev->device = devid; |
1164 | quirk_sis_96x_smbus(dev); | 1168 | quirk_sis_96x_smbus(dev); |
1165 | } | 1169 | } |
1166 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); | 1170 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503); |
1167 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); | 1171 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503); |
1168 | 1172 | ||
1169 | 1173 | ||
1170 | /* | 1174 | /* |
@@ -1191,13 +1195,13 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev) | |||
1191 | pci_write_config_byte(dev, 0x50, val & (~0xc0)); | 1195 | pci_write_config_byte(dev, 0x50, val & (~0xc0)); |
1192 | pci_read_config_byte(dev, 0x50, &val); | 1196 | pci_read_config_byte(dev, 0x50, &val); |
1193 | if (val & 0xc0) | 1197 | if (val & 0xc0) |
1194 | printk(KERN_INFO "PCI: onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n", val); | 1198 | dev_info(&dev->dev, "Onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n", val); |
1195 | else | 1199 | else |
1196 | printk(KERN_INFO "PCI: enabled onboard AC97/MC97 devices\n"); | 1200 | dev_info(&dev->dev, "Enabled onboard AC97/MC97 devices\n"); |
1197 | } | 1201 | } |
1198 | } | 1202 | } |
1199 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); | 1203 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc); |
1200 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); | 1204 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc); |
1201 | 1205 | ||
1202 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) | 1206 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) |
1203 | 1207 | ||
@@ -1292,7 +1296,7 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev) | |||
1292 | } | 1296 | } |
1293 | 1297 | ||
1294 | } | 1298 | } |
1295 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic ); | 1299 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic); |
1296 | #endif | 1300 | #endif |
1297 | 1301 | ||
1298 | int pcie_mch_quirk; | 1302 | int pcie_mch_quirk; |
@@ -1302,9 +1306,9 @@ static void __devinit quirk_pcie_mch(struct pci_dev *pdev) | |||
1302 | { | 1306 | { |
1303 | pcie_mch_quirk = 1; | 1307 | pcie_mch_quirk = 1; |
1304 | } | 1308 | } |
1305 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch ); | 1309 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch); |
1306 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch ); | 1310 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch); |
1307 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch ); | 1311 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch); |
1308 | 1312 | ||
1309 | 1313 | ||
1310 | /* | 1314 | /* |
@@ -1314,11 +1318,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quir | |||
1314 | static void __devinit quirk_pcie_pxh(struct pci_dev *dev) | 1318 | static void __devinit quirk_pcie_pxh(struct pci_dev *dev) |
1315 | { | 1319 | { |
1316 | pci_msi_off(dev); | 1320 | pci_msi_off(dev); |
1317 | |||
1318 | dev->no_msi = 1; | 1321 | dev->no_msi = 1; |
1319 | 1322 | dev_warn(&dev->dev, "PXH quirk detected; SHPC device MSI disabled\n"); | |
1320 | printk(KERN_WARNING "PCI: PXH quirk detected, " | ||
1321 | "disabling MSI for SHPC device\n"); | ||
1322 | } | 1323 | } |
1323 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_0, quirk_pcie_pxh); | 1324 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_0, quirk_pcie_pxh); |
1324 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_1, quirk_pcie_pxh); | 1325 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_1, quirk_pcie_pxh); |
@@ -1399,7 +1400,7 @@ static void __devinit quirk_netmos(struct pci_dev *dev) | |||
1399 | case PCI_DEVICE_ID_NETMOS_9855: | 1400 | case PCI_DEVICE_ID_NETMOS_9855: |
1400 | if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL && | 1401 | if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL && |
1401 | num_parallel) { | 1402 | num_parallel) { |
1402 | printk(KERN_INFO "PCI: Netmos %04x (%u parallel, " | 1403 | dev_info(&dev->dev, "Netmos %04x (%u parallel, " |
1403 | "%u serial); changing class SERIAL to OTHER " | 1404 | "%u serial); changing class SERIAL to OTHER " |
1404 | "(use parport_serial)\n", | 1405 | "(use parport_serial)\n", |
1405 | dev->device, num_parallel, num_serial); | 1406 | dev->device, num_parallel, num_serial); |
@@ -1412,9 +1413,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); | |||
1412 | 1413 | ||
1413 | static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | 1414 | static void __devinit quirk_e100_interrupt(struct pci_dev *dev) |
1414 | { | 1415 | { |
1415 | u16 command; | 1416 | u16 command, pmcsr; |
1416 | u8 __iomem *csr; | 1417 | u8 __iomem *csr; |
1417 | u8 cmd_hi; | 1418 | u8 cmd_hi; |
1419 | int pm; | ||
1418 | 1420 | ||
1419 | switch (dev->device) { | 1421 | switch (dev->device) { |
1420 | /* PCI IDs taken from drivers/net/e100.c */ | 1422 | /* PCI IDs taken from drivers/net/e100.c */ |
@@ -1448,18 +1450,28 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | |||
1448 | if (!(command & PCI_COMMAND_MEMORY) || !pci_resource_start(dev, 0)) | 1450 | if (!(command & PCI_COMMAND_MEMORY) || !pci_resource_start(dev, 0)) |
1449 | return; | 1451 | return; |
1450 | 1452 | ||
1453 | /* | ||
1454 | * Check that the device is in the D0 power state. If it's not, | ||
1455 | * there is no point to look any further. | ||
1456 | */ | ||
1457 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | ||
1458 | if (pm) { | ||
1459 | pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); | ||
1460 | if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) | ||
1461 | return; | ||
1462 | } | ||
1463 | |||
1451 | /* Convert from PCI bus to resource space. */ | 1464 | /* Convert from PCI bus to resource space. */ |
1452 | csr = ioremap(pci_resource_start(dev, 0), 8); | 1465 | csr = ioremap(pci_resource_start(dev, 0), 8); |
1453 | if (!csr) { | 1466 | if (!csr) { |
1454 | printk(KERN_WARNING "PCI: Can't map %s e100 registers\n", | 1467 | dev_warn(&dev->dev, "Can't map e100 registers\n"); |
1455 | pci_name(dev)); | ||
1456 | return; | 1468 | return; |
1457 | } | 1469 | } |
1458 | 1470 | ||
1459 | cmd_hi = readb(csr + 3); | 1471 | cmd_hi = readb(csr + 3); |
1460 | if (cmd_hi == 0) { | 1472 | if (cmd_hi == 0) { |
1461 | printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts " | 1473 | dev_warn(&dev->dev, "Firmware left e100 interrupts enabled; " |
1462 | "enabled, disabling\n", pci_name(dev)); | 1474 | "disabling\n"); |
1463 | writeb(1, csr + 3); | 1475 | writeb(1, csr + 3); |
1464 | } | 1476 | } |
1465 | 1477 | ||
@@ -1474,7 +1486,7 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) | |||
1474 | */ | 1486 | */ |
1475 | 1487 | ||
1476 | if (dev->class == PCI_CLASS_NOT_DEFINED) { | 1488 | if (dev->class == PCI_CLASS_NOT_DEFINED) { |
1477 | printk(KERN_INFO "NCR 53c810 rev 1 detected, setting PCI class.\n"); | 1489 | dev_info(&dev->dev, "NCR 53c810 rev 1 detected; setting PCI class\n"); |
1478 | dev->class = PCI_CLASS_STORAGE_SCSI; | 1490 | dev->class = PCI_CLASS_STORAGE_SCSI; |
1479 | } | 1491 | } |
1480 | } | 1492 | } |
@@ -1485,7 +1497,11 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_f | |||
1485 | while (f < end) { | 1497 | while (f < end) { |
1486 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && | 1498 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && |
1487 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { | 1499 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { |
1488 | pr_debug("PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev)); | 1500 | #ifdef DEBUG |
1501 | dev_dbg(&dev->dev, "calling quirk 0x%p", f->hook); | ||
1502 | print_fn_descriptor_symbol(": %s()\n", | ||
1503 | (unsigned long) f->hook); | ||
1504 | #endif | ||
1489 | f->hook(dev); | 1505 | f->hook(dev); |
1490 | } | 1506 | } |
1491 | f++; | 1507 | f++; |
@@ -1553,7 +1569,7 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) | |||
1553 | pci_read_config_word(dev, 0x40, &en1k); | 1569 | pci_read_config_word(dev, 0x40, &en1k); |
1554 | 1570 | ||
1555 | if (en1k & 0x200) { | 1571 | if (en1k & 0x200) { |
1556 | printk(KERN_INFO "PCI: Enable I/O Space to 1 KB Granularity\n"); | 1572 | dev_info(&dev->dev, "Enable I/O Space to 1KB granularity\n"); |
1557 | 1573 | ||
1558 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | 1574 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); |
1559 | pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); | 1575 | pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); |
@@ -1585,7 +1601,7 @@ static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev) | |||
1585 | iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00); | 1601 | iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00); |
1586 | 1602 | ||
1587 | if (iobl_adr != iobl_adr_1k) { | 1603 | if (iobl_adr != iobl_adr_1k) { |
1588 | printk(KERN_INFO "PCI: Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1 KB Granularity\n", | 1604 | dev_info(&dev->dev, "Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1KB granularity\n", |
1589 | iobl_adr,iobl_adr_1k); | 1605 | iobl_adr,iobl_adr_1k); |
1590 | pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k); | 1606 | pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k); |
1591 | } | 1607 | } |
@@ -1603,9 +1619,8 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) | |||
1603 | if (pci_read_config_byte(dev, 0xf41, &b) == 0) { | 1619 | if (pci_read_config_byte(dev, 0xf41, &b) == 0) { |
1604 | if (!(b & 0x20)) { | 1620 | if (!(b & 0x20)) { |
1605 | pci_write_config_byte(dev, 0xf41, b | 0x20); | 1621 | pci_write_config_byte(dev, 0xf41, b | 0x20); |
1606 | printk(KERN_INFO | 1622 | dev_info(&dev->dev, |
1607 | "PCI: Linking AER extended capability on %s\n", | 1623 | "Linking AER extended capability\n"); |
1608 | pci_name(dev)); | ||
1609 | } | 1624 | } |
1610 | } | 1625 | } |
1611 | } | 1626 | } |
@@ -1614,6 +1629,34 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | |||
1614 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1629 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1615 | quirk_nvidia_ck804_pcie_aer_ext_cap); | 1630 | quirk_nvidia_ck804_pcie_aer_ext_cap); |
1616 | 1631 | ||
1632 | static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | ||
1633 | { | ||
1634 | /* | ||
1635 | * Disable PCI Bus Parking and PCI Master read caching on CX700 | ||
1636 | * which causes unspecified timing errors with a VT6212L on the PCI | ||
1637 | * bus leading to USB2.0 packet loss. The defaults are that these | ||
1638 | * features are turned off but some BIOSes turn them on. | ||
1639 | */ | ||
1640 | |||
1641 | uint8_t b; | ||
1642 | if (pci_read_config_byte(dev, 0x76, &b) == 0) { | ||
1643 | if (b & 0x40) { | ||
1644 | /* Turn off PCI Bus Parking */ | ||
1645 | pci_write_config_byte(dev, 0x76, b ^ 0x40); | ||
1646 | |||
1647 | /* Turn off PCI Master read caching */ | ||
1648 | pci_write_config_byte(dev, 0x72, 0x0); | ||
1649 | pci_write_config_byte(dev, 0x75, 0x1); | ||
1650 | pci_write_config_byte(dev, 0x77, 0x0); | ||
1651 | |||
1652 | printk(KERN_INFO | ||
1653 | "PCI: VIA CX700 PCI parking/caching fixup on %s\n", | ||
1654 | pci_name(dev)); | ||
1655 | } | ||
1656 | } | ||
1657 | } | ||
1658 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); | ||
1659 | |||
1617 | #ifdef CONFIG_PCI_MSI | 1660 | #ifdef CONFIG_PCI_MSI |
1618 | /* Some chipsets do not support MSI. We cannot easily rely on setting | 1661 | /* Some chipsets do not support MSI. We cannot easily rely on setting |
1619 | * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually | 1662 | * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually |
@@ -1624,7 +1667,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | |||
1624 | static void __init quirk_disable_all_msi(struct pci_dev *dev) | 1667 | static void __init quirk_disable_all_msi(struct pci_dev *dev) |
1625 | { | 1668 | { |
1626 | pci_no_msi(); | 1669 | pci_no_msi(); |
1627 | printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n"); | 1670 | dev_warn(&dev->dev, "MSI quirk detected; MSI disabled\n"); |
1628 | } | 1671 | } |
1629 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi); | 1672 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi); |
1630 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); | 1673 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); |
@@ -1635,9 +1678,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disab | |||
1635 | static void __devinit quirk_disable_msi(struct pci_dev *dev) | 1678 | static void __devinit quirk_disable_msi(struct pci_dev *dev) |
1636 | { | 1679 | { |
1637 | if (dev->subordinate) { | 1680 | if (dev->subordinate) { |
1638 | printk(KERN_WARNING "PCI: MSI quirk detected. " | 1681 | dev_warn(&dev->dev, "MSI quirk detected; " |
1639 | "PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n", | 1682 | "subordinate MSI disabled\n"); |
1640 | pci_name(dev)); | ||
1641 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | 1683 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; |
1642 | } | 1684 | } |
1643 | } | 1685 | } |
@@ -1656,9 +1698,9 @@ static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) | |||
1656 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | 1698 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, |
1657 | &flags) == 0) | 1699 | &flags) == 0) |
1658 | { | 1700 | { |
1659 | printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n", | 1701 | dev_info(&dev->dev, "Found %s HT MSI Mapping\n", |
1660 | flags & HT_MSI_FLAGS_ENABLE ? | 1702 | flags & HT_MSI_FLAGS_ENABLE ? |
1661 | "enabled" : "disabled", pci_name(dev)); | 1703 | "enabled" : "disabled"); |
1662 | return (flags & HT_MSI_FLAGS_ENABLE) != 0; | 1704 | return (flags & HT_MSI_FLAGS_ENABLE) != 0; |
1663 | } | 1705 | } |
1664 | 1706 | ||
@@ -1672,17 +1714,40 @@ static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) | |||
1672 | static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) | 1714 | static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) |
1673 | { | 1715 | { |
1674 | if (dev->subordinate && !msi_ht_cap_enabled(dev)) { | 1716 | if (dev->subordinate && !msi_ht_cap_enabled(dev)) { |
1675 | printk(KERN_WARNING "PCI: MSI quirk detected. " | 1717 | dev_warn(&dev->dev, "MSI quirk detected; " |
1676 | "MSI disabled on chipset %s.\n", | 1718 | "subordinate MSI disabled\n"); |
1677 | pci_name(dev)); | ||
1678 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | 1719 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; |
1679 | } | 1720 | } |
1680 | } | 1721 | } |
1681 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, | 1722 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, |
1682 | quirk_msi_ht_cap); | 1723 | quirk_msi_ht_cap); |
1683 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, | 1724 | |
1684 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | 1725 | |
1685 | quirk_msi_ht_cap); | 1726 | /* |
1727 | * Force enable MSI mapping capability on HT bridges | ||
1728 | */ | ||
1729 | static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev) | ||
1730 | { | ||
1731 | int pos, ttl = 48; | ||
1732 | |||
1733 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | ||
1734 | while (pos && ttl--) { | ||
1735 | u8 flags; | ||
1736 | |||
1737 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) { | ||
1738 | printk(KERN_INFO "PCI: Enabling HT MSI Mapping on %s\n", | ||
1739 | pci_name(dev)); | ||
1740 | |||
1741 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, | ||
1742 | flags | HT_MSI_FLAGS_ENABLE); | ||
1743 | } | ||
1744 | pos = pci_find_next_ht_capability(dev, pos, | ||
1745 | HT_CAPTYPE_MSI_MAPPING); | ||
1746 | } | ||
1747 | } | ||
1748 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | ||
1749 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | ||
1750 | quirk_msi_ht_cap_enable); | ||
1686 | 1751 | ||
1687 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. | 1752 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. |
1688 | * MSI are supported if the MSI capability set in any of these mappings. | 1753 | * MSI are supported if the MSI capability set in any of these mappings. |
@@ -1701,9 +1766,8 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1701 | if (!pdev) | 1766 | if (!pdev) |
1702 | return; | 1767 | return; |
1703 | if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { | 1768 | if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { |
1704 | printk(KERN_WARNING "PCI: MSI quirk detected. " | 1769 | dev_warn(&dev->dev, "MSI quirk detected; " |
1705 | "MSI disabled on chipset %s.\n", | 1770 | "subordinate MSI disabled\n"); |
1706 | pci_name(dev)); | ||
1707 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | 1771 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; |
1708 | } | 1772 | } |
1709 | pci_dev_put(pdev); | 1773 | pci_dev_put(pdev); |
@@ -1715,6 +1779,23 @@ static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) | |||
1715 | { | 1779 | { |
1716 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | 1780 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; |
1717 | } | 1781 | } |
1782 | static void __devinit quirk_msi_intx_disable_ati_bug(struct pci_dev *dev) | ||
1783 | { | ||
1784 | struct pci_dev *p; | ||
1785 | |||
1786 | /* SB700 MSI issue will be fixed at HW level from revision A21, | ||
1787 | * we need check PCI REVISION ID of SMBus controller to get SB700 | ||
1788 | * revision. | ||
1789 | */ | ||
1790 | p = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, | ||
1791 | NULL); | ||
1792 | if (!p) | ||
1793 | return; | ||
1794 | |||
1795 | if ((p->revision < 0x3B) && (p->revision >= 0x30)) | ||
1796 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | ||
1797 | pci_dev_put(p); | ||
1798 | } | ||
1718 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | 1799 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
1719 | PCI_DEVICE_ID_TIGON3_5780, | 1800 | PCI_DEVICE_ID_TIGON3_5780, |
1720 | quirk_msi_intx_disable_bug); | 1801 | quirk_msi_intx_disable_bug); |
@@ -1735,17 +1816,15 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | |||
1735 | quirk_msi_intx_disable_bug); | 1816 | quirk_msi_intx_disable_bug); |
1736 | 1817 | ||
1737 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4390, | 1818 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4390, |
1738 | quirk_msi_intx_disable_bug); | 1819 | quirk_msi_intx_disable_ati_bug); |
1739 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4391, | 1820 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4391, |
1740 | quirk_msi_intx_disable_bug); | 1821 | quirk_msi_intx_disable_ati_bug); |
1741 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4392, | 1822 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4392, |
1742 | quirk_msi_intx_disable_bug); | 1823 | quirk_msi_intx_disable_ati_bug); |
1743 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4393, | 1824 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4393, |
1744 | quirk_msi_intx_disable_bug); | 1825 | quirk_msi_intx_disable_ati_bug); |
1745 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4394, | 1826 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4394, |
1746 | quirk_msi_intx_disable_bug); | 1827 | quirk_msi_intx_disable_ati_bug); |
1747 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4395, | ||
1748 | quirk_msi_intx_disable_bug); | ||
1749 | 1828 | ||
1750 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4373, | 1829 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4373, |
1751 | quirk_msi_intx_disable_bug); | 1830 | quirk_msi_intx_disable_bug); |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 430281b2e921..ec4a82ba29a8 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/pci.h> | 1 | #include <linux/pci.h> |
2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
3 | #include <linux/aspm.h> | ||
3 | #include "pci.h" | 4 | #include "pci.h" |
4 | 5 | ||
5 | static void pci_free_resources(struct pci_dev *dev) | 6 | static void pci_free_resources(struct pci_dev *dev) |
@@ -30,6 +31,9 @@ static void pci_stop_dev(struct pci_dev *dev) | |||
30 | dev->global_list.next = dev->global_list.prev = NULL; | 31 | dev->global_list.next = dev->global_list.prev = NULL; |
31 | up_write(&pci_bus_sem); | 32 | up_write(&pci_bus_sem); |
32 | } | 33 | } |
34 | |||
35 | if (dev->bus->self) | ||
36 | pcie_aspm_exit_link_state(dev); | ||
33 | } | 37 | } |
34 | 38 | ||
35 | static void pci_destroy_dev(struct pci_dev *dev) | 39 | static void pci_destroy_dev(struct pci_dev *dev) |
@@ -74,10 +78,8 @@ void pci_remove_bus(struct pci_bus *pci_bus) | |||
74 | list_del(&pci_bus->node); | 78 | list_del(&pci_bus->node); |
75 | up_write(&pci_bus_sem); | 79 | up_write(&pci_bus_sem); |
76 | pci_remove_legacy_files(pci_bus); | 80 | pci_remove_legacy_files(pci_bus); |
77 | class_device_remove_file(&pci_bus->class_dev, | 81 | device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity); |
78 | &class_device_attr_cpuaffinity); | 82 | device_unregister(&pci_bus->dev); |
79 | sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge"); | ||
80 | class_device_unregister(&pci_bus->class_dev); | ||
81 | } | 83 | } |
82 | EXPORT_SYMBOL(pci_remove_bus); | 84 | EXPORT_SYMBOL(pci_remove_bus); |
83 | 85 | ||
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index dbbcc04abd1a..a98b2470b9ea 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -162,6 +162,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
162 | return rom; | 162 | return rom; |
163 | } | 163 | } |
164 | 164 | ||
165 | #if 0 | ||
165 | /** | 166 | /** |
166 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy | 167 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy |
167 | * @pdev: pointer to pci device struct | 168 | * @pdev: pointer to pci device struct |
@@ -196,6 +197,7 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) | |||
196 | 197 | ||
197 | return (void __iomem *)(unsigned long)res->start; | 198 | return (void __iomem *)(unsigned long)res->start; |
198 | } | 199 | } |
200 | #endif /* 0 */ | ||
199 | 201 | ||
200 | /** | 202 | /** |
201 | * pci_unmap_rom - unmap the ROM from kernel space | 203 | * pci_unmap_rom - unmap the ROM from kernel space |
@@ -218,6 +220,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) | |||
218 | pci_disable_rom(pdev); | 220 | pci_disable_rom(pdev); |
219 | } | 221 | } |
220 | 222 | ||
223 | #if 0 | ||
221 | /** | 224 | /** |
222 | * pci_remove_rom - disable the ROM and remove its sysfs attribute | 225 | * pci_remove_rom - disable the ROM and remove its sysfs attribute |
223 | * @pdev: pointer to pci device struct | 226 | * @pdev: pointer to pci device struct |
@@ -236,6 +239,7 @@ void pci_remove_rom(struct pci_dev *pdev) | |||
236 | IORESOURCE_ROM_COPY))) | 239 | IORESOURCE_ROM_COPY))) |
237 | pci_disable_rom(pdev); | 240 | pci_disable_rom(pdev); |
238 | } | 241 | } |
242 | #endif /* 0 */ | ||
239 | 243 | ||
240 | /** | 244 | /** |
241 | * pci_cleanup_rom - internal routine for freeing the ROM copy created | 245 | * pci_cleanup_rom - internal routine for freeing the ROM copy created |
@@ -256,6 +260,4 @@ void pci_cleanup_rom(struct pci_dev *pdev) | |||
256 | } | 260 | } |
257 | 261 | ||
258 | EXPORT_SYMBOL(pci_map_rom); | 262 | EXPORT_SYMBOL(pci_map_rom); |
259 | EXPORT_SYMBOL(pci_map_rom_copy); | ||
260 | EXPORT_SYMBOL(pci_unmap_rom); | 263 | EXPORT_SYMBOL(pci_unmap_rom); |
261 | EXPORT_SYMBOL(pci_remove_rom); | ||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 401e03c920bd..8a7232feb553 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -89,8 +89,9 @@ void pci_setup_cardbus(struct pci_bus *bus) | |||
89 | * The IO resource is allocated a range twice as large as it | 89 | * The IO resource is allocated a range twice as large as it |
90 | * would normally need. This allows us to set both IO regs. | 90 | * would normally need. This allows us to set both IO regs. |
91 | */ | 91 | */ |
92 | printk(" IO window: %08lx-%08lx\n", | 92 | printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n", |
93 | region.start, region.end); | 93 | (unsigned long)region.start, |
94 | (unsigned long)region.end); | ||
94 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, | 95 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, |
95 | region.start); | 96 | region.start); |
96 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, | 97 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, |
@@ -99,8 +100,9 @@ void pci_setup_cardbus(struct pci_bus *bus) | |||
99 | 100 | ||
100 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | 101 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); |
101 | if (bus->resource[1]->flags & IORESOURCE_IO) { | 102 | if (bus->resource[1]->flags & IORESOURCE_IO) { |
102 | printk(" IO window: %08lx-%08lx\n", | 103 | printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n", |
103 | region.start, region.end); | 104 | (unsigned long)region.start, |
105 | (unsigned long)region.end); | ||
104 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, | 106 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, |
105 | region.start); | 107 | region.start); |
106 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, | 108 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, |
@@ -109,8 +111,9 @@ void pci_setup_cardbus(struct pci_bus *bus) | |||
109 | 111 | ||
110 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 112 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); |
111 | if (bus->resource[2]->flags & IORESOURCE_MEM) { | 113 | if (bus->resource[2]->flags & IORESOURCE_MEM) { |
112 | printk(" PREFETCH window: %08lx-%08lx\n", | 114 | printk(KERN_INFO " PREFETCH window: 0x%08lx-0x%08lx\n", |
113 | region.start, region.end); | 115 | (unsigned long)region.start, |
116 | (unsigned long)region.end); | ||
114 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, | 117 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, |
115 | region.start); | 118 | region.start); |
116 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, | 119 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, |
@@ -119,8 +122,9 @@ void pci_setup_cardbus(struct pci_bus *bus) | |||
119 | 122 | ||
120 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); | 123 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); |
121 | if (bus->resource[3]->flags & IORESOURCE_MEM) { | 124 | if (bus->resource[3]->flags & IORESOURCE_MEM) { |
122 | printk(" MEM window: %08lx-%08lx\n", | 125 | printk(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n", |
123 | region.start, region.end); | 126 | (unsigned long)region.start, |
127 | (unsigned long)region.end); | ||
124 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, | 128 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, |
125 | region.start); | 129 | region.start); |
126 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, | 130 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, |
@@ -145,7 +149,7 @@ pci_setup_bridge(struct pci_bus *bus) | |||
145 | { | 149 | { |
146 | struct pci_dev *bridge = bus->self; | 150 | struct pci_dev *bridge = bus->self; |
147 | struct pci_bus_region region; | 151 | struct pci_bus_region region; |
148 | u32 l, io_upper16; | 152 | u32 l, bu, lu, io_upper16; |
149 | 153 | ||
150 | DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge)); | 154 | DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge)); |
151 | 155 | ||
@@ -159,7 +163,8 @@ pci_setup_bridge(struct pci_bus *bus) | |||
159 | /* Set up upper 16 bits of I/O base/limit. */ | 163 | /* Set up upper 16 bits of I/O base/limit. */ |
160 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); | 164 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); |
161 | DBG(KERN_INFO " IO window: %04lx-%04lx\n", | 165 | DBG(KERN_INFO " IO window: %04lx-%04lx\n", |
162 | region.start, region.end); | 166 | (unsigned long)region.start, |
167 | (unsigned long)region.end); | ||
163 | } | 168 | } |
164 | else { | 169 | else { |
165 | /* Clear upper 16 bits of I/O base/limit. */ | 170 | /* Clear upper 16 bits of I/O base/limit. */ |
@@ -180,8 +185,9 @@ pci_setup_bridge(struct pci_bus *bus) | |||
180 | if (bus->resource[1]->flags & IORESOURCE_MEM) { | 185 | if (bus->resource[1]->flags & IORESOURCE_MEM) { |
181 | l = (region.start >> 16) & 0xfff0; | 186 | l = (region.start >> 16) & 0xfff0; |
182 | l |= region.end & 0xfff00000; | 187 | l |= region.end & 0xfff00000; |
183 | DBG(KERN_INFO " MEM window: %08lx-%08lx\n", | 188 | DBG(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n", |
184 | region.start, region.end); | 189 | (unsigned long)region.start, |
190 | (unsigned long)region.end); | ||
185 | } | 191 | } |
186 | else { | 192 | else { |
187 | l = 0x0000fff0; | 193 | l = 0x0000fff0; |
@@ -195,12 +201,18 @@ pci_setup_bridge(struct pci_bus *bus) | |||
195 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); | 201 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); |
196 | 202 | ||
197 | /* Set up PREF base/limit. */ | 203 | /* Set up PREF base/limit. */ |
204 | bu = lu = 0; | ||
198 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 205 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); |
199 | if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { | 206 | if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { |
200 | l = (region.start >> 16) & 0xfff0; | 207 | l = (region.start >> 16) & 0xfff0; |
201 | l |= region.end & 0xfff00000; | 208 | l |= region.end & 0xfff00000; |
202 | DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n", | 209 | #ifdef CONFIG_RESOURCES_64BIT |
203 | region.start, region.end); | 210 | bu = region.start >> 32; |
211 | lu = region.end >> 32; | ||
212 | #endif | ||
213 | DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n", | ||
214 | (unsigned long long)region.start, | ||
215 | (unsigned long long)region.end); | ||
204 | } | 216 | } |
205 | else { | 217 | else { |
206 | l = 0x0000fff0; | 218 | l = 0x0000fff0; |
@@ -208,8 +220,9 @@ pci_setup_bridge(struct pci_bus *bus) | |||
208 | } | 220 | } |
209 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); | 221 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); |
210 | 222 | ||
211 | /* Clear out the upper 32 bits of PREF base. */ | 223 | /* Set the upper 32 bits of PREF base & limit. */ |
212 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0); | 224 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); |
225 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); | ||
213 | 226 | ||
214 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); | 227 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); |
215 | } | 228 | } |
@@ -323,8 +336,8 @@ static void pbus_size_io(struct pci_bus *bus) | |||
323 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) | 336 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) |
324 | { | 337 | { |
325 | struct pci_dev *dev; | 338 | struct pci_dev *dev; |
326 | unsigned long min_align, align, size; | 339 | resource_size_t min_align, align, size; |
327 | unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */ | 340 | resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ |
328 | int order, max_order; | 341 | int order, max_order; |
329 | struct resource *b_res = find_free_bus_resource(bus, type); | 342 | struct resource *b_res = find_free_bus_resource(bus, type); |
330 | 343 | ||
@@ -340,7 +353,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long | |||
340 | 353 | ||
341 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 354 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
342 | struct resource *r = &dev->resource[i]; | 355 | struct resource *r = &dev->resource[i]; |
343 | unsigned long r_size; | 356 | resource_size_t r_size; |
344 | 357 | ||
345 | if (r->parent || (r->flags & mask) != type) | 358 | if (r->parent || (r->flags & mask) != type) |
346 | continue; | 359 | continue; |
@@ -350,10 +363,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long | |||
350 | order = __ffs(align) - 20; | 363 | order = __ffs(align) - 20; |
351 | if (order > 11) { | 364 | if (order > 11) { |
352 | printk(KERN_WARNING "PCI: region %s/%d " | 365 | printk(KERN_WARNING "PCI: region %s/%d " |
353 | "too large: %llx-%llx\n", | 366 | "too large: 0x%016llx-0x%016llx\n", |
354 | pci_name(dev), i, | 367 | pci_name(dev), i, |
355 | (unsigned long long)r->start, | 368 | (unsigned long long)r->start, |
356 | (unsigned long long)r->end); | 369 | (unsigned long long)r->end); |
357 | r->flags = 0; | 370 | r->flags = 0; |
358 | continue; | 371 | continue; |
359 | } | 372 | } |
@@ -372,8 +385,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long | |||
372 | align = 0; | 385 | align = 0; |
373 | min_align = 0; | 386 | min_align = 0; |
374 | for (order = 0; order <= max_order; order++) { | 387 | for (order = 0; order <= max_order; order++) { |
375 | unsigned long align1 = 1UL << (order + 20); | 388 | #ifdef CONFIG_RESOURCES_64BIT |
376 | 389 | resource_size_t align1 = 1ULL << (order + 20); | |
390 | #else | ||
391 | resource_size_t align1 = 1U << (order + 20); | ||
392 | #endif | ||
377 | if (!align) | 393 | if (!align) |
378 | min_align = align1; | 394 | min_align = align1; |
379 | else if (ALIGN(align + min_align, min_align) < align1) | 395 | else if (ALIGN(align + min_align, min_align) < align1) |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 6dfd86167e39..4be7ccf7e3ae 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -51,10 +51,12 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
51 | 51 | ||
52 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
53 | 53 | ||
54 | pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " | 54 | pr_debug(" got res [%llx:%llx] bus [%llx:%llx] flags %lx for " |
55 | "BAR %d of %s\n", (unsigned long long)res->start, | 55 | "BAR %d of %s\n", (unsigned long long)res->start, |
56 | (unsigned long long)res->end, | 56 | (unsigned long long)res->end, |
57 | region.start, region.end, res->flags, resno, pci_name(dev)); | 57 | (unsigned long long)region.start, |
58 | (unsigned long long)region.end, | ||
59 | (unsigned long)res->flags, resno, pci_name(dev)); | ||
58 | 60 | ||
59 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 61 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); |
60 | if (res->flags & IORESOURCE_IO) | 62 | if (res->flags & IORESOURCE_IO) |
@@ -125,7 +127,6 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
125 | 127 | ||
126 | return err; | 128 | return err; |
127 | } | 129 | } |
128 | EXPORT_SYMBOL_GPL(pci_claim_resource); | ||
129 | 130 | ||
130 | int pci_assign_resource(struct pci_dev *dev, int resno) | 131 | int pci_assign_resource(struct pci_dev *dev, int resno) |
131 | { | 132 | { |
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index 2ac050d7f8cf..645d7a60e412 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c | |||
@@ -34,7 +34,6 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn, | |||
34 | if (!dev) | 34 | if (!dev) |
35 | goto error; | 35 | goto error; |
36 | 36 | ||
37 | lock_kernel(); | ||
38 | switch (len) { | 37 | switch (len) { |
39 | case 1: | 38 | case 1: |
40 | cfg_ret = pci_user_read_config_byte(dev, off, &byte); | 39 | cfg_ret = pci_user_read_config_byte(dev, off, &byte); |
@@ -47,10 +46,8 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn, | |||
47 | break; | 46 | break; |
48 | default: | 47 | default: |
49 | err = -EINVAL; | 48 | err = -EINVAL; |
50 | unlock_kernel(); | ||
51 | goto error; | 49 | goto error; |
52 | }; | 50 | }; |
53 | unlock_kernel(); | ||
54 | 51 | ||
55 | err = -EIO; | 52 | err = -EIO; |
56 | if (cfg_ret != PCIBIOS_SUCCESSFUL) | 53 | if (cfg_ret != PCIBIOS_SUCCESSFUL) |
@@ -107,7 +104,6 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, | |||
107 | if (!dev) | 104 | if (!dev) |
108 | return -ENODEV; | 105 | return -ENODEV; |
109 | 106 | ||
110 | lock_kernel(); | ||
111 | switch(len) { | 107 | switch(len) { |
112 | case 1: | 108 | case 1: |
113 | err = get_user(byte, (u8 __user *)buf); | 109 | err = get_user(byte, (u8 __user *)buf); |
@@ -140,7 +136,6 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, | |||
140 | err = -EINVAL; | 136 | err = -EINVAL; |
141 | break; | 137 | break; |
142 | } | 138 | } |
143 | unlock_kernel(); | ||
144 | pci_dev_put(dev); | 139 | pci_dev_put(dev); |
145 | return err; | 140 | return err; |
146 | } | 141 | } |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 3205f7488d1c..29b4cf9e059b 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -2296,10 +2296,9 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
2296 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2296 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
2297 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2297 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2298 | struct lpfc_sli *psli = &phba->sli; | 2298 | struct lpfc_sli *psli = &phba->sli; |
2299 | int bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
2300 | 2299 | ||
2301 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); | 2300 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); |
2302 | if (pci_enable_device_bars(pdev, bars)) { | 2301 | if (pci_enable_device_mem(pdev)) { |
2303 | printk(KERN_ERR "lpfc: Cannot re-enable " | 2302 | printk(KERN_ERR "lpfc: Cannot re-enable " |
2304 | "PCI device after reset.\n"); | 2303 | "PCI device after reset.\n"); |
2305 | return PCI_ERS_RESULT_DISCONNECT; | 2304 | return PCI_ERS_RESULT_DISCONNECT; |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6f129da37589..b72c7f170854 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2268,6 +2268,7 @@ typedef struct scsi_qla_host { | |||
2268 | spinlock_t hardware_lock ____cacheline_aligned; | 2268 | spinlock_t hardware_lock ____cacheline_aligned; |
2269 | 2269 | ||
2270 | int bars; | 2270 | int bars; |
2271 | int mem_only; | ||
2271 | device_reg_t __iomem *iobase; /* Base I/O address */ | 2272 | device_reg_t __iomem *iobase; /* Base I/O address */ |
2272 | resource_size_t pio_address; | 2273 | resource_size_t pio_address; |
2273 | #define MIN_IOBASE_LEN 0x100 | 2274 | #define MIN_IOBASE_LEN 0x100 |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3954ed2d7b51..8f69caf83272 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1564,7 +1564,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1564 | char pci_info[30]; | 1564 | char pci_info[30]; |
1565 | char fw_str[30]; | 1565 | char fw_str[30]; |
1566 | struct scsi_host_template *sht; | 1566 | struct scsi_host_template *sht; |
1567 | int bars; | 1567 | int bars, mem_only = 0; |
1568 | 1568 | ||
1569 | bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); | 1569 | bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); |
1570 | sht = &qla2x00_driver_template; | 1570 | sht = &qla2x00_driver_template; |
@@ -1575,10 +1575,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1575 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { | 1575 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { |
1576 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 1576 | bars = pci_select_bars(pdev, IORESOURCE_MEM); |
1577 | sht = &qla24xx_driver_template; | 1577 | sht = &qla24xx_driver_template; |
1578 | mem_only = 1; | ||
1578 | } | 1579 | } |
1579 | 1580 | ||
1580 | if (pci_enable_device_bars(pdev, bars)) | 1581 | if (mem_only) { |
1581 | goto probe_out; | 1582 | if (pci_enable_device_mem(pdev)) |
1583 | goto probe_out; | ||
1584 | } else { | ||
1585 | if (pci_enable_device(pdev)) | ||
1586 | goto probe_out; | ||
1587 | } | ||
1582 | 1588 | ||
1583 | if (pci_find_aer_capability(pdev)) | 1589 | if (pci_find_aer_capability(pdev)) |
1584 | if (pci_enable_pcie_error_reporting(pdev)) | 1590 | if (pci_enable_pcie_error_reporting(pdev)) |
@@ -1601,6 +1607,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1601 | sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); | 1607 | sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); |
1602 | ha->parent = NULL; | 1608 | ha->parent = NULL; |
1603 | ha->bars = bars; | 1609 | ha->bars = bars; |
1610 | ha->mem_only = mem_only; | ||
1604 | 1611 | ||
1605 | /* Set ISP-type information. */ | 1612 | /* Set ISP-type information. */ |
1606 | qla2x00_set_isp_flags(ha); | 1613 | qla2x00_set_isp_flags(ha); |
@@ -2875,8 +2882,14 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
2875 | { | 2882 | { |
2876 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; | 2883 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; |
2877 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | 2884 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); |
2885 | int rc; | ||
2886 | |||
2887 | if (ha->mem_only) | ||
2888 | rc = pci_enable_device_mem(pdev); | ||
2889 | else | ||
2890 | rc = pci_enable_device(pdev); | ||
2878 | 2891 | ||
2879 | if (pci_enable_device_bars(pdev, ha->bars)) { | 2892 | if (rc) { |
2880 | qla_printk(KERN_WARNING, ha, | 2893 | qla_printk(KERN_WARNING, ha, |
2881 | "Can't re-enable PCI device after reset.\n"); | 2894 | "Can't re-enable PCI device after reset.\n"); |
2882 | 2895 | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7a6499008b89..755823cdf62a 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -42,6 +42,10 @@ config USB_ARCH_HAS_OHCI | |||
42 | default y if PPC_MPC52xx | 42 | default y if PPC_MPC52xx |
43 | # MIPS: | 43 | # MIPS: |
44 | default y if SOC_AU1X00 | 44 | default y if SOC_AU1X00 |
45 | # SH: | ||
46 | default y if CPU_SUBTYPE_SH7720 | ||
47 | default y if CPU_SUBTYPE_SH7721 | ||
48 | default y if CPU_SUBTYPE_SH7763 | ||
45 | # more: | 49 | # more: |
46 | default PCI | 50 | default PCI |
47 | 51 | ||
@@ -50,6 +54,7 @@ config USB_ARCH_HAS_EHCI | |||
50 | boolean | 54 | boolean |
51 | default y if PPC_83xx | 55 | default y if PPC_83xx |
52 | default y if SOC_AU1200 | 56 | default y if SOC_AU1200 |
57 | default y if ARCH_IXP4XX | ||
53 | default PCI | 58 | default PCI |
54 | 59 | ||
55 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. | 60 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. |
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig index b450cbaa3a0b..86e64035edb0 100644 --- a/drivers/usb/atm/Kconfig +++ b/drivers/usb/atm/Kconfig | |||
@@ -2,10 +2,7 @@ | |||
2 | # USB/ATM DSL configuration | 2 | # USB/ATM DSL configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "USB DSL modem support" | 5 | menuconfig USB_ATM |
6 | depends on USB | ||
7 | |||
8 | config USB_ATM | ||
9 | tristate "USB DSL modem support" | 6 | tristate "USB DSL modem support" |
10 | depends on USB && ATM | 7 | depends on USB && ATM |
11 | select CRC32 | 8 | select CRC32 |
@@ -18,6 +15,8 @@ config USB_ATM | |||
18 | To compile this driver as a module, choose M here: the | 15 | To compile this driver as a module, choose M here: the |
19 | module will be called usbatm. | 16 | module will be called usbatm. |
20 | 17 | ||
18 | if USB_ATM | ||
19 | |||
21 | config USB_SPEEDTOUCH | 20 | config USB_SPEEDTOUCH |
22 | tristate "Speedtouch USB support" | 21 | tristate "Speedtouch USB support" |
23 | depends on USB_ATM | 22 | depends on USB_ATM |
@@ -70,4 +69,4 @@ config USB_XUSBATM | |||
70 | To compile this driver as a module, choose M here: the | 69 | To compile this driver as a module, choose M here: the |
71 | module will be called xusbatm. | 70 | module will be called xusbatm. |
72 | 71 | ||
73 | endmenu | 72 | endif # USB_ATM |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 389c5b164eb2..c5ec1a55eee3 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -999,7 +999,7 @@ static void __uea_load_page_e4(struct uea_softc *sc, u8 pageno, int boot) | |||
999 | bi.dwAddress = swab32(blockidx->PageAddress); | 999 | bi.dwAddress = swab32(blockidx->PageAddress); |
1000 | 1000 | ||
1001 | uea_dbg(INS_TO_USBDEV(sc), | 1001 | uea_dbg(INS_TO_USBDEV(sc), |
1002 | "sending block %u for DSP page %u size %u adress %x\n", | 1002 | "sending block %u for DSP page %u size %u address %x\n", |
1003 | blockno, pageno, blocksize, le32_to_cpu(blockidx->PageAddress)); | 1003 | blockno, pageno, blocksize, le32_to_cpu(blockidx->PageAddress)); |
1004 | 1004 | ||
1005 | /* send block info through the IDMA pipe */ | 1005 | /* send block info through the IDMA pipe */ |
@@ -1990,7 +1990,7 @@ static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr) | |||
1990 | return; | 1990 | return; |
1991 | 1991 | ||
1992 | bad2: | 1992 | bad2: |
1993 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | 1993 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received, " |
1994 | "Function : %d, Subfunction : %d\n", | 1994 | "Function : %d, Subfunction : %d\n", |
1995 | E1_FUNCTION_TYPE(cmv->bFunction), | 1995 | E1_FUNCTION_TYPE(cmv->bFunction), |
1996 | E1_FUNCTION_SUBTYPE(cmv->bFunction)); | 1996 | E1_FUNCTION_SUBTYPE(cmv->bFunction)); |
@@ -2038,7 +2038,7 @@ static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr) | |||
2038 | return; | 2038 | return; |
2039 | 2039 | ||
2040 | bad2: | 2040 | bad2: |
2041 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | 2041 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received, " |
2042 | "Function : %d, Subfunction : %d\n", | 2042 | "Function : %d, Subfunction : %d\n", |
2043 | E4_FUNCTION_TYPE(cmv->wFunction), | 2043 | E4_FUNCTION_TYPE(cmv->wFunction), |
2044 | E4_FUNCTION_SUBTYPE(cmv->wFunction)); | 2044 | E4_FUNCTION_SUBTYPE(cmv->wFunction)); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 912d97aaf9bf..bcc42136c93f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -496,10 +496,19 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
496 | otherwise it is scheduled, and with high data rates data can get lost. */ | 496 | otherwise it is scheduled, and with high data rates data can get lost. */ |
497 | tty->low_latency = 1; | 497 | tty->low_latency = 1; |
498 | 498 | ||
499 | if (usb_autopm_get_interface(acm->control)) { | ||
500 | mutex_unlock(&open_mutex); | ||
501 | return -EIO; | ||
502 | } | ||
503 | |||
504 | mutex_lock(&acm->mutex); | ||
505 | mutex_unlock(&open_mutex); | ||
499 | if (acm->used++) { | 506 | if (acm->used++) { |
507 | usb_autopm_put_interface(acm->control); | ||
500 | goto done; | 508 | goto done; |
501 | } | 509 | } |
502 | 510 | ||
511 | |||
503 | acm->ctrlurb->dev = acm->dev; | 512 | acm->ctrlurb->dev = acm->dev; |
504 | if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { | 513 | if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { |
505 | dbg("usb_submit_urb(ctrl irq) failed"); | 514 | dbg("usb_submit_urb(ctrl irq) failed"); |
@@ -526,14 +535,15 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
526 | 535 | ||
527 | done: | 536 | done: |
528 | err_out: | 537 | err_out: |
529 | mutex_unlock(&open_mutex); | 538 | mutex_unlock(&acm->mutex); |
530 | return rv; | 539 | return rv; |
531 | 540 | ||
532 | full_bailout: | 541 | full_bailout: |
533 | usb_kill_urb(acm->ctrlurb); | 542 | usb_kill_urb(acm->ctrlurb); |
534 | bail_out: | 543 | bail_out: |
544 | usb_autopm_put_interface(acm->control); | ||
535 | acm->used--; | 545 | acm->used--; |
536 | mutex_unlock(&open_mutex); | 546 | mutex_unlock(&acm->mutex); |
537 | return -EIO; | 547 | return -EIO; |
538 | } | 548 | } |
539 | 549 | ||
@@ -570,6 +580,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
570 | usb_kill_urb(acm->writeurb); | 580 | usb_kill_urb(acm->writeurb); |
571 | for (i = 0; i < nr; i++) | 581 | for (i = 0; i < nr; i++) |
572 | usb_kill_urb(acm->ru[i].urb); | 582 | usb_kill_urb(acm->ru[i].urb); |
583 | usb_autopm_put_interface(acm->control); | ||
573 | } else | 584 | } else |
574 | acm_tty_unregister(acm); | 585 | acm_tty_unregister(acm); |
575 | } | 586 | } |
@@ -904,7 +915,7 @@ next_desc: | |||
904 | } | 915 | } |
905 | 916 | ||
906 | if (data_interface_num != call_interface_num) | 917 | if (data_interface_num != call_interface_num) |
907 | dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n"); | 918 | dev_dbg(&intf->dev,"Separate call control interface. That is not fully supported.\n"); |
908 | 919 | ||
909 | skip_normal_probe: | 920 | skip_normal_probe: |
910 | 921 | ||
@@ -980,6 +991,7 @@ skip_normal_probe: | |||
980 | spin_lock_init(&acm->throttle_lock); | 991 | spin_lock_init(&acm->throttle_lock); |
981 | spin_lock_init(&acm->write_lock); | 992 | spin_lock_init(&acm->write_lock); |
982 | spin_lock_init(&acm->read_lock); | 993 | spin_lock_init(&acm->read_lock); |
994 | mutex_init(&acm->mutex); | ||
983 | acm->write_ready = 1; | 995 | acm->write_ready = 1; |
984 | acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); | 996 | acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); |
985 | 997 | ||
@@ -1096,6 +1108,25 @@ alloc_fail: | |||
1096 | return -ENOMEM; | 1108 | return -ENOMEM; |
1097 | } | 1109 | } |
1098 | 1110 | ||
1111 | static void stop_data_traffic(struct acm *acm) | ||
1112 | { | ||
1113 | int i; | ||
1114 | |||
1115 | tasklet_disable(&acm->urb_task); | ||
1116 | |||
1117 | usb_kill_urb(acm->ctrlurb); | ||
1118 | usb_kill_urb(acm->writeurb); | ||
1119 | for (i = 0; i < acm->rx_buflimit; i++) | ||
1120 | usb_kill_urb(acm->ru[i].urb); | ||
1121 | |||
1122 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
1123 | INIT_LIST_HEAD(&acm->spare_read_bufs); | ||
1124 | |||
1125 | tasklet_enable(&acm->urb_task); | ||
1126 | |||
1127 | cancel_work_sync(&acm->work); | ||
1128 | } | ||
1129 | |||
1099 | static void acm_disconnect(struct usb_interface *intf) | 1130 | static void acm_disconnect(struct usb_interface *intf) |
1100 | { | 1131 | { |
1101 | struct acm *acm = usb_get_intfdata(intf); | 1132 | struct acm *acm = usb_get_intfdata(intf); |
@@ -1123,19 +1154,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
1123 | usb_set_intfdata(acm->control, NULL); | 1154 | usb_set_intfdata(acm->control, NULL); |
1124 | usb_set_intfdata(acm->data, NULL); | 1155 | usb_set_intfdata(acm->data, NULL); |
1125 | 1156 | ||
1126 | tasklet_disable(&acm->urb_task); | 1157 | stop_data_traffic(acm); |
1127 | |||
1128 | usb_kill_urb(acm->ctrlurb); | ||
1129 | usb_kill_urb(acm->writeurb); | ||
1130 | for (i = 0; i < acm->rx_buflimit; i++) | ||
1131 | usb_kill_urb(acm->ru[i].urb); | ||
1132 | |||
1133 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
1134 | INIT_LIST_HEAD(&acm->spare_read_bufs); | ||
1135 | |||
1136 | tasklet_enable(&acm->urb_task); | ||
1137 | |||
1138 | flush_scheduled_work(); /* wait for acm_softint */ | ||
1139 | 1158 | ||
1140 | acm_write_buffers_free(acm); | 1159 | acm_write_buffers_free(acm); |
1141 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1160 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
@@ -1156,6 +1175,46 @@ static void acm_disconnect(struct usb_interface *intf) | |||
1156 | tty_hangup(acm->tty); | 1175 | tty_hangup(acm->tty); |
1157 | } | 1176 | } |
1158 | 1177 | ||
1178 | static int acm_suspend(struct usb_interface *intf, pm_message_t message) | ||
1179 | { | ||
1180 | struct acm *acm = usb_get_intfdata(intf); | ||
1181 | |||
1182 | if (acm->susp_count++) | ||
1183 | return 0; | ||
1184 | /* | ||
1185 | we treat opened interfaces differently, | ||
1186 | we must guard against open | ||
1187 | */ | ||
1188 | mutex_lock(&acm->mutex); | ||
1189 | |||
1190 | if (acm->used) | ||
1191 | stop_data_traffic(acm); | ||
1192 | |||
1193 | mutex_unlock(&acm->mutex); | ||
1194 | return 0; | ||
1195 | } | ||
1196 | |||
1197 | static int acm_resume(struct usb_interface *intf) | ||
1198 | { | ||
1199 | struct acm *acm = usb_get_intfdata(intf); | ||
1200 | int rv = 0; | ||
1201 | |||
1202 | if (--acm->susp_count) | ||
1203 | return 0; | ||
1204 | |||
1205 | mutex_lock(&acm->mutex); | ||
1206 | if (acm->used) { | ||
1207 | rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); | ||
1208 | if (rv < 0) | ||
1209 | goto err_out; | ||
1210 | |||
1211 | tasklet_schedule(&acm->urb_task); | ||
1212 | } | ||
1213 | |||
1214 | err_out: | ||
1215 | mutex_unlock(&acm->mutex); | ||
1216 | return rv; | ||
1217 | } | ||
1159 | /* | 1218 | /* |
1160 | * USB driver structure. | 1219 | * USB driver structure. |
1161 | */ | 1220 | */ |
@@ -1208,7 +1267,10 @@ static struct usb_driver acm_driver = { | |||
1208 | .name = "cdc_acm", | 1267 | .name = "cdc_acm", |
1209 | .probe = acm_probe, | 1268 | .probe = acm_probe, |
1210 | .disconnect = acm_disconnect, | 1269 | .disconnect = acm_disconnect, |
1270 | .suspend = acm_suspend, | ||
1271 | .resume = acm_resume, | ||
1211 | .id_table = acm_ids, | 1272 | .id_table = acm_ids, |
1273 | .supports_autosuspend = 1, | ||
1212 | }; | 1274 | }; |
1213 | 1275 | ||
1214 | /* | 1276 | /* |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 09f7765dbf8d..8df6a57dcf9e 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
@@ -107,6 +107,7 @@ struct acm { | |||
107 | int write_used; /* number of non-empty write buffers */ | 107 | int write_used; /* number of non-empty write buffers */ |
108 | int write_ready; /* write urb is not running */ | 108 | int write_ready; /* write urb is not running */ |
109 | spinlock_t write_lock; | 109 | spinlock_t write_lock; |
110 | struct mutex mutex; | ||
110 | struct usb_cdc_line_coding line; /* bits, stop, parity */ | 111 | struct usb_cdc_line_coding line; /* bits, stop, parity */ |
111 | struct work_struct work; /* work queue entry for line discipline waking up */ | 112 | struct work_struct work; /* work queue entry for line discipline waking up */ |
112 | struct tasklet_struct urb_task; /* rx processing */ | 113 | struct tasklet_struct urb_task; /* rx processing */ |
@@ -120,6 +121,7 @@ struct acm { | |||
120 | unsigned char throttle; /* throttled by tty layer */ | 121 | unsigned char throttle; /* throttled by tty layer */ |
121 | unsigned char clocal; /* termios CLOCAL */ | 122 | unsigned char clocal; /* termios CLOCAL */ |
122 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ | 123 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ |
124 | unsigned int susp_count; /* number of suspended interfaces */ | ||
123 | }; | 125 | }; |
124 | 126 | ||
125 | #define CDC_DATA_INTERFACE_TYPE 0x0a | 127 | #define CDC_DATA_INTERFACE_TYPE 0x0a |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 97b09f282705..5c33cdb9cac7 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -9,6 +9,21 @@ config USB_DEBUG | |||
9 | of debug messages to the system log. Select this if you are having a | 9 | of debug messages to the system log. Select this if you are having a |
10 | problem with USB support and want to see more of what is going on. | 10 | problem with USB support and want to see more of what is going on. |
11 | 11 | ||
12 | config USB_ANNOUNCE_NEW_DEVICES | ||
13 | bool "USB announce new devices" | ||
14 | depends on USB | ||
15 | default N | ||
16 | help | ||
17 | Say Y here if you want the USB core to always announce the | ||
18 | idVendor, idProduct, Manufacturer, Product, and SerialNumber | ||
19 | strings for every new USB device to the syslog. This option is | ||
20 | usually used by distro vendors to help with debugging and to | ||
21 | let users know what specific device was added to the machine | ||
22 | in what location. | ||
23 | |||
24 | If you do not want this kind of information sent to the system | ||
25 | log, or have any doubts about this, say N here. | ||
26 | |||
12 | comment "Miscellaneous USB options" | 27 | comment "Miscellaneous USB options" |
13 | depends on USB | 28 | depends on USB |
14 | 29 | ||
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 28d4972f7ad5..cadb2dc1d28a 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -53,11 +53,13 @@ int hcd_buffer_create(struct usb_hcd *hcd) | |||
53 | char name[16]; | 53 | char name[16]; |
54 | int i, size; | 54 | int i, size; |
55 | 55 | ||
56 | if (!hcd->self.controller->dma_mask) | 56 | if (!hcd->self.controller->dma_mask && |
57 | !(hcd->driver->flags & HCD_LOCAL_MEM)) | ||
57 | return 0; | 58 | return 0; |
58 | 59 | ||
59 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 60 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
60 | if (!(size = pool_max [i])) | 61 | size = pool_max[i]; |
62 | if (!size) | ||
61 | continue; | 63 | continue; |
62 | snprintf(name, sizeof name, "buffer-%d", size); | 64 | snprintf(name, sizeof name, "buffer-%d", size); |
63 | hcd->pool[i] = dma_pool_create(name, hcd->self.controller, | 65 | hcd->pool[i] = dma_pool_create(name, hcd->self.controller, |
@@ -80,10 +82,10 @@ int hcd_buffer_create(struct usb_hcd *hcd) | |||
80 | */ | 82 | */ |
81 | void hcd_buffer_destroy(struct usb_hcd *hcd) | 83 | void hcd_buffer_destroy(struct usb_hcd *hcd) |
82 | { | 84 | { |
83 | int i; | 85 | int i; |
84 | 86 | ||
85 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 87 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
86 | struct dma_pool *pool = hcd->pool[i]; | 88 | struct dma_pool *pool = hcd->pool[i]; |
87 | if (pool) { | 89 | if (pool) { |
88 | dma_pool_destroy(pool); | 90 | dma_pool_destroy(pool); |
89 | hcd->pool[i] = NULL; | 91 | hcd->pool[i] = NULL; |
@@ -107,7 +109,8 @@ void *hcd_buffer_alloc( | |||
107 | int i; | 109 | int i; |
108 | 110 | ||
109 | /* some USB hosts just use PIO */ | 111 | /* some USB hosts just use PIO */ |
110 | if (!bus->controller->dma_mask) { | 112 | if (!bus->controller->dma_mask && |
113 | !(hcd->driver->flags & HCD_LOCAL_MEM)) { | ||
111 | *dma = ~(dma_addr_t) 0; | 114 | *dma = ~(dma_addr_t) 0; |
112 | return kmalloc(size, mem_flags); | 115 | return kmalloc(size, mem_flags); |
113 | } | 116 | } |
@@ -132,7 +135,8 @@ void hcd_buffer_free( | |||
132 | if (!addr) | 135 | if (!addr) |
133 | return; | 136 | return; |
134 | 137 | ||
135 | if (!bus->controller->dma_mask) { | 138 | if (!bus->controller->dma_mask && |
139 | !(hcd->driver->flags & HCD_LOCAL_MEM)) { | ||
136 | kfree(addr); | 140 | kfree(addr); |
137 | return; | 141 | return; |
138 | } | 142 | } |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 1a8edcee7f30..a92122a216bc 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -238,7 +238,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno, | |||
238 | 238 | ||
239 | /* Allocate space for the right(?) number of endpoints */ | 239 | /* Allocate space for the right(?) number of endpoints */ |
240 | num_ep = num_ep_orig = alt->desc.bNumEndpoints; | 240 | num_ep = num_ep_orig = alt->desc.bNumEndpoints; |
241 | alt->desc.bNumEndpoints = 0; // Use as a counter | 241 | alt->desc.bNumEndpoints = 0; /* Use as a counter */ |
242 | if (num_ep > USB_MAXENDPOINTS) { | 242 | if (num_ep > USB_MAXENDPOINTS) { |
243 | dev_warn(ddev, "too many endpoints for config %d interface %d " | 243 | dev_warn(ddev, "too many endpoints for config %d interface %d " |
244 | "altsetting %d: %d, using maximum allowed: %d\n", | 244 | "altsetting %d: %d, using maximum allowed: %d\n", |
@@ -246,7 +246,8 @@ static int usb_parse_interface(struct device *ddev, int cfgno, | |||
246 | num_ep = USB_MAXENDPOINTS; | 246 | num_ep = USB_MAXENDPOINTS; |
247 | } | 247 | } |
248 | 248 | ||
249 | if (num_ep > 0) { /* Can't allocate 0 bytes */ | 249 | if (num_ep > 0) { |
250 | /* Can't allocate 0 bytes */ | ||
250 | len = sizeof(struct usb_host_endpoint) * num_ep; | 251 | len = sizeof(struct usb_host_endpoint) * num_ep; |
251 | alt->endpoint = kzalloc(len, GFP_KERNEL); | 252 | alt->endpoint = kzalloc(len, GFP_KERNEL); |
252 | if (!alt->endpoint) | 253 | if (!alt->endpoint) |
@@ -475,8 +476,9 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx, | |||
475 | return 0; | 476 | return 0; |
476 | } | 477 | } |
477 | 478 | ||
478 | // hub-only!! ... and only exported for reset/reinit path. | 479 | /* hub-only!! ... and only exported for reset/reinit path. |
479 | // otherwise used internally on disconnect/destroy path | 480 | * otherwise used internally on disconnect/destroy path |
481 | */ | ||
480 | void usb_destroy_configuration(struct usb_device *dev) | 482 | void usb_destroy_configuration(struct usb_device *dev) |
481 | { | 483 | { |
482 | int c, i; | 484 | int c, i; |
@@ -498,7 +500,7 @@ void usb_destroy_configuration(struct usb_device *dev) | |||
498 | kfree(cf->string); | 500 | kfree(cf->string); |
499 | for (i = 0; i < cf->desc.bNumInterfaces; i++) { | 501 | for (i = 0; i < cf->desc.bNumInterfaces; i++) { |
500 | if (cf->intf_cache[i]) | 502 | if (cf->intf_cache[i]) |
501 | kref_put(&cf->intf_cache[i]->ref, | 503 | kref_put(&cf->intf_cache[i]->ref, |
502 | usb_release_interface_cache); | 504 | usb_release_interface_cache); |
503 | } | 505 | } |
504 | } | 506 | } |
@@ -525,7 +527,7 @@ int usb_get_configuration(struct usb_device *dev) | |||
525 | unsigned int cfgno, length; | 527 | unsigned int cfgno, length; |
526 | unsigned char *buffer; | 528 | unsigned char *buffer; |
527 | unsigned char *bigbuffer; | 529 | unsigned char *bigbuffer; |
528 | struct usb_config_descriptor *desc; | 530 | struct usb_config_descriptor *desc; |
529 | 531 | ||
530 | cfgno = 0; | 532 | cfgno = 0; |
531 | if (dev->authorized == 0) /* Not really an error */ | 533 | if (dev->authorized == 0) /* Not really an error */ |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 87c794d60aa0..83d9dc379d96 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -89,7 +89,7 @@ static const char *format_string_serialnumber = | |||
89 | static const char *format_bandwidth = | 89 | static const char *format_bandwidth = |
90 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ | 90 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ |
91 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; | 91 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; |
92 | 92 | ||
93 | static const char *format_device1 = | 93 | static const char *format_device1 = |
94 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ | 94 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ |
95 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; | 95 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; |
@@ -101,7 +101,7 @@ static const char *format_device2 = | |||
101 | static const char *format_config = | 101 | static const char *format_config = |
102 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ | 102 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ |
103 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; | 103 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; |
104 | 104 | ||
105 | static const char *format_iad = | 105 | static const char *format_iad = |
106 | /* A: FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */ | 106 | /* A: FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */ |
107 | "A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; | 107 | "A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; |
@@ -122,7 +122,7 @@ static const char *format_endpt = | |||
122 | */ | 122 | */ |
123 | 123 | ||
124 | static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq); | 124 | static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq); |
125 | static unsigned int conndiscevcnt = 0; | 125 | static unsigned int conndiscevcnt; |
126 | 126 | ||
127 | /* this struct stores the poll state for <mountpoint>/devices pollers */ | 127 | /* this struct stores the poll state for <mountpoint>/devices pollers */ |
128 | struct usb_device_status { | 128 | struct usb_device_status { |
@@ -172,12 +172,8 @@ static const char *class_decode(const int class) | |||
172 | return clas_info[ix].class_name; | 172 | return clas_info[ix].class_name; |
173 | } | 173 | } |
174 | 174 | ||
175 | static char *usb_dump_endpoint_descriptor( | 175 | static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, |
176 | int speed, | 176 | const struct usb_endpoint_descriptor *desc) |
177 | char *start, | ||
178 | char *end, | ||
179 | const struct usb_endpoint_descriptor *desc | ||
180 | ) | ||
181 | { | 177 | { |
182 | char dir, unit, *type; | 178 | char dir, unit, *type; |
183 | unsigned interval, bandwidth = 1; | 179 | unsigned interval, bandwidth = 1; |
@@ -235,22 +231,24 @@ static char *usb_dump_endpoint_descriptor( | |||
235 | 231 | ||
236 | start += sprintf(start, format_endpt, desc->bEndpointAddress, dir, | 232 | start += sprintf(start, format_endpt, desc->bEndpointAddress, dir, |
237 | desc->bmAttributes, type, | 233 | desc->bmAttributes, type, |
238 | (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * bandwidth, | 234 | (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * |
235 | bandwidth, | ||
239 | interval, unit); | 236 | interval, unit); |
240 | return start; | 237 | return start; |
241 | } | 238 | } |
242 | 239 | ||
243 | static char *usb_dump_interface_descriptor(char *start, char *end, | 240 | static char *usb_dump_interface_descriptor(char *start, char *end, |
244 | const struct usb_interface_cache *intfc, | 241 | const struct usb_interface_cache *intfc, |
245 | const struct usb_interface *iface, | 242 | const struct usb_interface *iface, |
246 | int setno) | 243 | int setno) |
247 | { | 244 | { |
248 | const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; | 245 | const struct usb_interface_descriptor *desc; |
249 | const char *driver_name = ""; | 246 | const char *driver_name = ""; |
250 | int active = 0; | 247 | int active = 0; |
251 | 248 | ||
252 | if (start > end) | 249 | if (start > end) |
253 | return start; | 250 | return start; |
251 | desc = &intfc->altsetting[setno].desc; | ||
254 | if (iface) { | 252 | if (iface) { |
255 | driver_name = (iface->dev.driver | 253 | driver_name = (iface->dev.driver |
256 | ? iface->dev.driver->name | 254 | ? iface->dev.driver->name |
@@ -270,14 +268,10 @@ static char *usb_dump_interface_descriptor(char *start, char *end, | |||
270 | return start; | 268 | return start; |
271 | } | 269 | } |
272 | 270 | ||
273 | static char *usb_dump_interface( | 271 | static char *usb_dump_interface(int speed, char *start, char *end, |
274 | int speed, | 272 | const struct usb_interface_cache *intfc, |
275 | char *start, | 273 | const struct usb_interface *iface, int setno) |
276 | char *end, | 274 | { |
277 | const struct usb_interface_cache *intfc, | ||
278 | const struct usb_interface *iface, | ||
279 | int setno | ||
280 | ) { | ||
281 | const struct usb_host_interface *desc = &intfc->altsetting[setno]; | 275 | const struct usb_host_interface *desc = &intfc->altsetting[setno]; |
282 | int i; | 276 | int i; |
283 | 277 | ||
@@ -292,7 +286,7 @@ static char *usb_dump_interface( | |||
292 | } | 286 | } |
293 | 287 | ||
294 | static char *usb_dump_iad_descriptor(char *start, char *end, | 288 | static char *usb_dump_iad_descriptor(char *start, char *end, |
295 | const struct usb_interface_assoc_descriptor *iad) | 289 | const struct usb_interface_assoc_descriptor *iad) |
296 | { | 290 | { |
297 | if (start > end) | 291 | if (start > end) |
298 | return start; | 292 | return start; |
@@ -311,13 +305,15 @@ static char *usb_dump_iad_descriptor(char *start, char *end, | |||
311 | * 1. marking active interface altsettings (code lists all, but should mark | 305 | * 1. marking active interface altsettings (code lists all, but should mark |
312 | * which ones are active, if any) | 306 | * which ones are active, if any) |
313 | */ | 307 | */ |
314 | 308 | static char *usb_dump_config_descriptor(char *start, char *end, | |
315 | static char *usb_dump_config_descriptor(char *start, char *end, const struct usb_config_descriptor *desc, int active) | 309 | const struct usb_config_descriptor *desc, |
310 | int active) | ||
316 | { | 311 | { |
317 | if (start > end) | 312 | if (start > end) |
318 | return start; | 313 | return start; |
319 | start += sprintf(start, format_config, | 314 | start += sprintf(start, format_config, |
320 | active ? '*' : ' ', /* mark active/actual/current cfg. */ | 315 | /* mark active/actual/current cfg. */ |
316 | active ? '*' : ' ', | ||
321 | desc->bNumInterfaces, | 317 | desc->bNumInterfaces, |
322 | desc->bConfigurationValue, | 318 | desc->bConfigurationValue, |
323 | desc->bmAttributes, | 319 | desc->bmAttributes, |
@@ -325,13 +321,8 @@ static char *usb_dump_config_descriptor(char *start, char *end, const struct usb | |||
325 | return start; | 321 | return start; |
326 | } | 322 | } |
327 | 323 | ||
328 | static char *usb_dump_config ( | 324 | static char *usb_dump_config(int speed, char *start, char *end, |
329 | int speed, | 325 | const struct usb_host_config *config, int active) |
330 | char *start, | ||
331 | char *end, | ||
332 | const struct usb_host_config *config, | ||
333 | int active | ||
334 | ) | ||
335 | { | 326 | { |
336 | int i, j; | 327 | int i, j; |
337 | struct usb_interface_cache *intfc; | 328 | struct usb_interface_cache *intfc; |
@@ -339,7 +330,8 @@ static char *usb_dump_config ( | |||
339 | 330 | ||
340 | if (start > end) | 331 | if (start > end) |
341 | return start; | 332 | return start; |
342 | if (!config) /* getting these some in 2.3.7; none in 2.3.6 */ | 333 | if (!config) |
334 | /* getting these some in 2.3.7; none in 2.3.6 */ | ||
343 | return start + sprintf(start, "(null Cfg. desc.)\n"); | 335 | return start + sprintf(start, "(null Cfg. desc.)\n"); |
344 | start = usb_dump_config_descriptor(start, end, &config->desc, active); | 336 | start = usb_dump_config_descriptor(start, end, &config->desc, active); |
345 | for (i = 0; i < USB_MAXIADS; i++) { | 337 | for (i = 0; i < USB_MAXIADS; i++) { |
@@ -364,7 +356,8 @@ static char *usb_dump_config ( | |||
364 | /* | 356 | /* |
365 | * Dump the different USB descriptors. | 357 | * Dump the different USB descriptors. |
366 | */ | 358 | */ |
367 | static char *usb_dump_device_descriptor(char *start, char *end, const struct usb_device_descriptor *desc) | 359 | static char *usb_dump_device_descriptor(char *start, char *end, |
360 | const struct usb_device_descriptor *desc) | ||
368 | { | 361 | { |
369 | u16 bcdUSB = le16_to_cpu(desc->bcdUSB); | 362 | u16 bcdUSB = le16_to_cpu(desc->bcdUSB); |
370 | u16 bcdDevice = le16_to_cpu(desc->bcdDevice); | 363 | u16 bcdDevice = le16_to_cpu(desc->bcdDevice); |
@@ -374,7 +367,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb | |||
374 | start += sprintf(start, format_device1, | 367 | start += sprintf(start, format_device1, |
375 | bcdUSB >> 8, bcdUSB & 0xff, | 368 | bcdUSB >> 8, bcdUSB & 0xff, |
376 | desc->bDeviceClass, | 369 | desc->bDeviceClass, |
377 | class_decode (desc->bDeviceClass), | 370 | class_decode(desc->bDeviceClass), |
378 | desc->bDeviceSubClass, | 371 | desc->bDeviceSubClass, |
379 | desc->bDeviceProtocol, | 372 | desc->bDeviceProtocol, |
380 | desc->bMaxPacketSize0, | 373 | desc->bMaxPacketSize0, |
@@ -391,12 +384,14 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb | |||
391 | /* | 384 | /* |
392 | * Dump the different strings that this device holds. | 385 | * Dump the different strings that this device holds. |
393 | */ | 386 | */ |
394 | static char *usb_dump_device_strings(char *start, char *end, struct usb_device *dev) | 387 | static char *usb_dump_device_strings(char *start, char *end, |
388 | struct usb_device *dev) | ||
395 | { | 389 | { |
396 | if (start > end) | 390 | if (start > end) |
397 | return start; | 391 | return start; |
398 | if (dev->manufacturer) | 392 | if (dev->manufacturer) |
399 | start += sprintf(start, format_string_manufacturer, dev->manufacturer); | 393 | start += sprintf(start, format_string_manufacturer, |
394 | dev->manufacturer); | ||
400 | if (start > end) | 395 | if (start > end) |
401 | goto out; | 396 | goto out; |
402 | if (dev->product) | 397 | if (dev->product) |
@@ -405,7 +400,8 @@ static char *usb_dump_device_strings(char *start, char *end, struct usb_device * | |||
405 | goto out; | 400 | goto out; |
406 | #ifdef ALLOW_SERIAL_NUMBER | 401 | #ifdef ALLOW_SERIAL_NUMBER |
407 | if (dev->serial) | 402 | if (dev->serial) |
408 | start += sprintf(start, format_string_serialnumber, dev->serial); | 403 | start += sprintf(start, format_string_serialnumber, |
404 | dev->serial); | ||
409 | #endif | 405 | #endif |
410 | out: | 406 | out: |
411 | return start; | 407 | return start; |
@@ -417,12 +413,12 @@ static char *usb_dump_desc(char *start, char *end, struct usb_device *dev) | |||
417 | 413 | ||
418 | if (start > end) | 414 | if (start > end) |
419 | return start; | 415 | return start; |
420 | 416 | ||
421 | start = usb_dump_device_descriptor(start, end, &dev->descriptor); | 417 | start = usb_dump_device_descriptor(start, end, &dev->descriptor); |
422 | 418 | ||
423 | if (start > end) | 419 | if (start > end) |
424 | return start; | 420 | return start; |
425 | 421 | ||
426 | start = usb_dump_device_strings(start, end, dev); | 422 | start = usb_dump_device_strings(start, end, dev); |
427 | 423 | ||
428 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { | 424 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { |
@@ -439,7 +435,8 @@ static char *usb_dump_desc(char *start, char *end, struct usb_device *dev) | |||
439 | 435 | ||
440 | #ifdef PROC_EXTRA /* TBD: may want to add this code later */ | 436 | #ifdef PROC_EXTRA /* TBD: may want to add this code later */ |
441 | 437 | ||
442 | static char *usb_dump_hub_descriptor(char *start, char *end, const struct usb_hub_descriptor * desc) | 438 | static char *usb_dump_hub_descriptor(char *start, char *end, |
439 | const struct usb_hub_descriptor *desc) | ||
443 | { | 440 | { |
444 | int leng = USB_DT_HUB_NONVAR_SIZE; | 441 | int leng = USB_DT_HUB_NONVAR_SIZE; |
445 | unsigned char *ptr = (unsigned char *)desc; | 442 | unsigned char *ptr = (unsigned char *)desc; |
@@ -455,13 +452,16 @@ static char *usb_dump_hub_descriptor(char *start, char *end, const struct usb_hu | |||
455 | return start; | 452 | return start; |
456 | } | 453 | } |
457 | 454 | ||
458 | static char *usb_dump_string(char *start, char *end, const struct usb_device *dev, char *id, int index) | 455 | static char *usb_dump_string(char *start, char *end, |
456 | const struct usb_device *dev, char *id, int index) | ||
459 | { | 457 | { |
460 | if (start > end) | 458 | if (start > end) |
461 | return start; | 459 | return start; |
462 | start += sprintf(start, "Interface:"); | 460 | start += sprintf(start, "Interface:"); |
463 | if (index <= dev->maxstring && dev->stringindex && dev->stringindex[index]) | 461 | if (index <= dev->maxstring && dev->stringindex && |
464 | start += sprintf(start, "%s: %.100s ", id, dev->stringindex[index]); | 462 | dev->stringindex[index]) |
463 | start += sprintf(start, "%s: %.100s ", id, | ||
464 | dev->stringindex[index]); | ||
465 | return start; | 465 | return start; |
466 | } | 466 | } |
467 | 467 | ||
@@ -476,8 +476,10 @@ static char *usb_dump_string(char *start, char *end, const struct usb_device *de | |||
476 | * file_offset - the offset into the devices file on completion | 476 | * file_offset - the offset into the devices file on completion |
477 | * The caller must own the device lock. | 477 | * The caller must own the device lock. |
478 | */ | 478 | */ |
479 | static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset, | 479 | static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, |
480 | struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count) | 480 | loff_t *skip_bytes, loff_t *file_offset, |
481 | struct usb_device *usbdev, struct usb_bus *bus, | ||
482 | int level, int index, int count) | ||
481 | { | 483 | { |
482 | int chix; | 484 | int chix; |
483 | int ret, cnt = 0; | 485 | int ret, cnt = 0; |
@@ -485,17 +487,19 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
485 | char *pages_start, *data_end, *speed; | 487 | char *pages_start, *data_end, *speed; |
486 | unsigned int length; | 488 | unsigned int length; |
487 | ssize_t total_written = 0; | 489 | ssize_t total_written = 0; |
488 | 490 | ||
489 | /* don't bother with anything else if we're not writing any data */ | 491 | /* don't bother with anything else if we're not writing any data */ |
490 | if (*nbytes <= 0) | 492 | if (*nbytes <= 0) |
491 | return 0; | 493 | return 0; |
492 | 494 | ||
493 | if (level > MAX_TOPO_LEVEL) | 495 | if (level > MAX_TOPO_LEVEL) |
494 | return 0; | 496 | return 0; |
495 | /* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */ | 497 | /* allocate 2^1 pages = 8K (on i386); |
496 | if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1))) | 498 | * should be more than enough for one device */ |
497 | return -ENOMEM; | 499 | pages_start = (char *)__get_free_pages(GFP_KERNEL, 1); |
498 | 500 | if (!pages_start) | |
501 | return -ENOMEM; | ||
502 | |||
499 | if (usbdev->parent && usbdev->parent->devnum != -1) | 503 | if (usbdev->parent && usbdev->parent->devnum != -1) |
500 | parent_devnum = usbdev->parent->devnum; | 504 | parent_devnum = usbdev->parent->devnum; |
501 | /* | 505 | /* |
@@ -541,15 +545,16 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
541 | bus->bandwidth_allocated, max, | 545 | bus->bandwidth_allocated, max, |
542 | (100 * bus->bandwidth_allocated + max / 2) | 546 | (100 * bus->bandwidth_allocated + max / 2) |
543 | / max, | 547 | / max, |
544 | bus->bandwidth_int_reqs, | 548 | bus->bandwidth_int_reqs, |
545 | bus->bandwidth_isoc_reqs); | 549 | bus->bandwidth_isoc_reqs); |
546 | 550 | ||
547 | } | 551 | } |
548 | data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev); | 552 | data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, |
549 | 553 | usbdev); | |
554 | |||
550 | if (data_end > (pages_start + (2 * PAGE_SIZE) - 256)) | 555 | if (data_end > (pages_start + (2 * PAGE_SIZE) - 256)) |
551 | data_end += sprintf(data_end, "(truncated)\n"); | 556 | data_end += sprintf(data_end, "(truncated)\n"); |
552 | 557 | ||
553 | length = data_end - pages_start; | 558 | length = data_end - pages_start; |
554 | /* if we can start copying some data to the user */ | 559 | /* if we can start copying some data to the user */ |
555 | if (length > *skip_bytes) { | 560 | if (length > *skip_bytes) { |
@@ -567,17 +572,18 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
567 | *skip_bytes = 0; | 572 | *skip_bytes = 0; |
568 | } else | 573 | } else |
569 | *skip_bytes -= length; | 574 | *skip_bytes -= length; |
570 | 575 | ||
571 | free_pages((unsigned long)pages_start, 1); | 576 | free_pages((unsigned long)pages_start, 1); |
572 | 577 | ||
573 | /* Now look at all of this device's children. */ | 578 | /* Now look at all of this device's children. */ |
574 | for (chix = 0; chix < usbdev->maxchild; chix++) { | 579 | for (chix = 0; chix < usbdev->maxchild; chix++) { |
575 | struct usb_device *childdev = usbdev->children[chix]; | 580 | struct usb_device *childdev = usbdev->children[chix]; |
576 | 581 | ||
577 | if (childdev) { | 582 | if (childdev) { |
578 | usb_lock_device(childdev); | 583 | usb_lock_device(childdev); |
579 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, | 584 | ret = usb_device_dump(buffer, nbytes, skip_bytes, |
580 | bus, level + 1, chix, ++cnt); | 585 | file_offset, childdev, bus, |
586 | level + 1, chix, ++cnt); | ||
581 | usb_unlock_device(childdev); | 587 | usb_unlock_device(childdev); |
582 | if (ret == -EFAULT) | 588 | if (ret == -EFAULT) |
583 | return total_written; | 589 | return total_written; |
@@ -587,7 +593,8 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
587 | return total_written; | 593 | return total_written; |
588 | } | 594 | } |
589 | 595 | ||
590 | static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 596 | static ssize_t usb_device_read(struct file *file, char __user *buf, |
597 | size_t nbytes, loff_t *ppos) | ||
591 | { | 598 | { |
592 | struct usb_bus *bus; | 599 | struct usb_bus *bus; |
593 | ssize_t ret, total_written = 0; | 600 | ssize_t ret, total_written = 0; |
@@ -607,7 +614,8 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte | |||
607 | if (!bus->root_hub) | 614 | if (!bus->root_hub) |
608 | continue; | 615 | continue; |
609 | usb_lock_device(bus->root_hub); | 616 | usb_lock_device(bus->root_hub); |
610 | ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0); | 617 | ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, |
618 | bus->root_hub, bus, 0, 0, 0); | ||
611 | usb_unlock_device(bus->root_hub); | 619 | usb_unlock_device(bus->root_hub); |
612 | if (ret < 0) { | 620 | if (ret < 0) { |
613 | mutex_unlock(&usb_bus_list_lock); | 621 | mutex_unlock(&usb_bus_list_lock); |
@@ -620,7 +628,8 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte | |||
620 | } | 628 | } |
621 | 629 | ||
622 | /* Kernel lock for "lastev" protection */ | 630 | /* Kernel lock for "lastev" protection */ |
623 | static unsigned int usb_device_poll(struct file *file, struct poll_table_struct *wait) | 631 | static unsigned int usb_device_poll(struct file *file, |
632 | struct poll_table_struct *wait) | ||
624 | { | 633 | { |
625 | struct usb_device_status *st = file->private_data; | 634 | struct usb_device_status *st = file->private_data; |
626 | unsigned int mask = 0; | 635 | unsigned int mask = 0; |
@@ -629,7 +638,8 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct | |||
629 | if (!st) { | 638 | if (!st) { |
630 | st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL); | 639 | st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL); |
631 | 640 | ||
632 | /* we may have dropped BKL - need to check for having lost the race */ | 641 | /* we may have dropped BKL - |
642 | * need to check for having lost the race */ | ||
633 | if (file->private_data) { | 643 | if (file->private_data) { |
634 | kfree(st); | 644 | kfree(st); |
635 | st = file->private_data; | 645 | st = file->private_data; |
@@ -652,7 +662,7 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct | |||
652 | } | 662 | } |
653 | lost_race: | 663 | lost_race: |
654 | if (file->f_mode & FMODE_READ) | 664 | if (file->f_mode & FMODE_READ) |
655 | poll_wait(file, &deviceconndiscwq, wait); | 665 | poll_wait(file, &deviceconndiscwq, wait); |
656 | if (st->lastev != conndiscevcnt) | 666 | if (st->lastev != conndiscevcnt) |
657 | mask |= POLLIN; | 667 | mask |= POLLIN; |
658 | st->lastev = conndiscevcnt; | 668 | st->lastev = conndiscevcnt; |
@@ -662,18 +672,18 @@ lost_race: | |||
662 | 672 | ||
663 | static int usb_device_open(struct inode *inode, struct file *file) | 673 | static int usb_device_open(struct inode *inode, struct file *file) |
664 | { | 674 | { |
665 | file->private_data = NULL; | 675 | file->private_data = NULL; |
666 | return 0; | 676 | return 0; |
667 | } | 677 | } |
668 | 678 | ||
669 | static int usb_device_release(struct inode *inode, struct file *file) | 679 | static int usb_device_release(struct inode *inode, struct file *file) |
670 | { | 680 | { |
671 | kfree(file->private_data); | 681 | kfree(file->private_data); |
672 | file->private_data = NULL; | 682 | file->private_data = NULL; |
673 | return 0; | 683 | return 0; |
674 | } | 684 | } |
675 | 685 | ||
676 | static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig) | 686 | static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig) |
677 | { | 687 | { |
678 | loff_t ret; | 688 | loff_t ret; |
679 | 689 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 1f4f6d02fe25..ae94176c64e4 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -75,14 +75,14 @@ struct async { | |||
75 | u32 secid; | 75 | u32 secid; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static int usbfs_snoop = 0; | 78 | static int usbfs_snoop; |
79 | module_param (usbfs_snoop, bool, S_IRUGO | S_IWUSR); | 79 | module_param(usbfs_snoop, bool, S_IRUGO | S_IWUSR); |
80 | MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic"); | 80 | MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); |
81 | 81 | ||
82 | #define snoop(dev, format, arg...) \ | 82 | #define snoop(dev, format, arg...) \ |
83 | do { \ | 83 | do { \ |
84 | if (usbfs_snoop) \ | 84 | if (usbfs_snoop) \ |
85 | dev_info( dev , format , ## arg); \ | 85 | dev_info(dev , format , ## arg); \ |
86 | } while (0) | 86 | } while (0) |
87 | 87 | ||
88 | #define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0) | 88 | #define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0) |
@@ -90,7 +90,7 @@ MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic"); | |||
90 | 90 | ||
91 | #define MAX_USBFS_BUFFER_SIZE 16384 | 91 | #define MAX_USBFS_BUFFER_SIZE 16384 |
92 | 92 | ||
93 | static inline int connected (struct dev_state *ps) | 93 | static inline int connected(struct dev_state *ps) |
94 | { | 94 | { |
95 | return (!list_empty(&ps->list) && | 95 | return (!list_empty(&ps->list) && |
96 | ps->dev->state != USB_STATE_NOTATTACHED); | 96 | ps->dev->state != USB_STATE_NOTATTACHED); |
@@ -120,7 +120,8 @@ static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) | |||
120 | return ret; | 120 | return ret; |
121 | } | 121 | } |
122 | 122 | ||
123 | static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 123 | static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, |
124 | loff_t *ppos) | ||
124 | { | 125 | { |
125 | struct dev_state *ps = file->private_data; | 126 | struct dev_state *ps = file->private_data; |
126 | struct usb_device *dev = ps->dev; | 127 | struct usb_device *dev = ps->dev; |
@@ -140,7 +141,8 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l | |||
140 | } | 141 | } |
141 | 142 | ||
142 | if (pos < sizeof(struct usb_device_descriptor)) { | 143 | if (pos < sizeof(struct usb_device_descriptor)) { |
143 | struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */ | 144 | /* 18 bytes - fits on the stack */ |
145 | struct usb_device_descriptor temp_desc; | ||
144 | 146 | ||
145 | memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor)); | 147 | memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor)); |
146 | le16_to_cpus(&temp_desc.bcdUSB); | 148 | le16_to_cpus(&temp_desc.bcdUSB); |
@@ -210,17 +212,17 @@ err: | |||
210 | 212 | ||
211 | static struct async *alloc_async(unsigned int numisoframes) | 213 | static struct async *alloc_async(unsigned int numisoframes) |
212 | { | 214 | { |
213 | unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor); | 215 | struct async *as; |
214 | struct async *as = kzalloc(assize, GFP_KERNEL); | ||
215 | 216 | ||
216 | if (!as) | 217 | as = kzalloc(sizeof(struct async), GFP_KERNEL); |
217 | return NULL; | 218 | if (!as) |
219 | return NULL; | ||
218 | as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); | 220 | as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); |
219 | if (!as->urb) { | 221 | if (!as->urb) { |
220 | kfree(as); | 222 | kfree(as); |
221 | return NULL; | 223 | return NULL; |
222 | } | 224 | } |
223 | return as; | 225 | return as; |
224 | } | 226 | } |
225 | 227 | ||
226 | static void free_async(struct async *as) | 228 | static void free_async(struct async *as) |
@@ -234,52 +236,54 @@ static void free_async(struct async *as) | |||
234 | 236 | ||
235 | static inline void async_newpending(struct async *as) | 237 | static inline void async_newpending(struct async *as) |
236 | { | 238 | { |
237 | struct dev_state *ps = as->ps; | 239 | struct dev_state *ps = as->ps; |
238 | unsigned long flags; | 240 | unsigned long flags; |
239 | 241 | ||
240 | spin_lock_irqsave(&ps->lock, flags); | 242 | spin_lock_irqsave(&ps->lock, flags); |
241 | list_add_tail(&as->asynclist, &ps->async_pending); | 243 | list_add_tail(&as->asynclist, &ps->async_pending); |
242 | spin_unlock_irqrestore(&ps->lock, flags); | 244 | spin_unlock_irqrestore(&ps->lock, flags); |
243 | } | 245 | } |
244 | 246 | ||
245 | static inline void async_removepending(struct async *as) | 247 | static inline void async_removepending(struct async *as) |
246 | { | 248 | { |
247 | struct dev_state *ps = as->ps; | 249 | struct dev_state *ps = as->ps; |
248 | unsigned long flags; | 250 | unsigned long flags; |
249 | 251 | ||
250 | spin_lock_irqsave(&ps->lock, flags); | 252 | spin_lock_irqsave(&ps->lock, flags); |
251 | list_del_init(&as->asynclist); | 253 | list_del_init(&as->asynclist); |
252 | spin_unlock_irqrestore(&ps->lock, flags); | 254 | spin_unlock_irqrestore(&ps->lock, flags); |
253 | } | 255 | } |
254 | 256 | ||
255 | static inline struct async *async_getcompleted(struct dev_state *ps) | 257 | static inline struct async *async_getcompleted(struct dev_state *ps) |
256 | { | 258 | { |
257 | unsigned long flags; | 259 | unsigned long flags; |
258 | struct async *as = NULL; | 260 | struct async *as = NULL; |
259 | 261 | ||
260 | spin_lock_irqsave(&ps->lock, flags); | 262 | spin_lock_irqsave(&ps->lock, flags); |
261 | if (!list_empty(&ps->async_completed)) { | 263 | if (!list_empty(&ps->async_completed)) { |
262 | as = list_entry(ps->async_completed.next, struct async, asynclist); | 264 | as = list_entry(ps->async_completed.next, struct async, |
263 | list_del_init(&as->asynclist); | 265 | asynclist); |
264 | } | 266 | list_del_init(&as->asynclist); |
265 | spin_unlock_irqrestore(&ps->lock, flags); | 267 | } |
266 | return as; | 268 | spin_unlock_irqrestore(&ps->lock, flags); |
269 | return as; | ||
267 | } | 270 | } |
268 | 271 | ||
269 | static inline struct async *async_getpending(struct dev_state *ps, void __user *userurb) | 272 | static inline struct async *async_getpending(struct dev_state *ps, |
273 | void __user *userurb) | ||
270 | { | 274 | { |
271 | unsigned long flags; | 275 | unsigned long flags; |
272 | struct async *as; | 276 | struct async *as; |
273 | 277 | ||
274 | spin_lock_irqsave(&ps->lock, flags); | 278 | spin_lock_irqsave(&ps->lock, flags); |
275 | list_for_each_entry(as, &ps->async_pending, asynclist) | 279 | list_for_each_entry(as, &ps->async_pending, asynclist) |
276 | if (as->userurb == userurb) { | 280 | if (as->userurb == userurb) { |
277 | list_del_init(&as->asynclist); | 281 | list_del_init(&as->asynclist); |
278 | spin_unlock_irqrestore(&ps->lock, flags); | 282 | spin_unlock_irqrestore(&ps->lock, flags); |
279 | return as; | 283 | return as; |
280 | } | 284 | } |
281 | spin_unlock_irqrestore(&ps->lock, flags); | 285 | spin_unlock_irqrestore(&ps->lock, flags); |
282 | return NULL; | 286 | return NULL; |
283 | } | 287 | } |
284 | 288 | ||
285 | static void snoop_urb(struct urb *urb, void __user *userurb) | 289 | static void snoop_urb(struct urb *urb, void __user *userurb) |
@@ -298,19 +302,19 @@ static void snoop_urb(struct urb *urb, void __user *userurb) | |||
298 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); | 302 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); |
299 | dev_info(&urb->dev->dev, "data: "); | 303 | dev_info(&urb->dev->dev, "data: "); |
300 | for (j = 0; j < urb->transfer_buffer_length; ++j) | 304 | for (j = 0; j < urb->transfer_buffer_length; ++j) |
301 | printk ("%02x ", data[j]); | 305 | printk("%02x ", data[j]); |
302 | printk("\n"); | 306 | printk("\n"); |
303 | } | 307 | } |
304 | 308 | ||
305 | static void async_completed(struct urb *urb) | 309 | static void async_completed(struct urb *urb) |
306 | { | 310 | { |
307 | struct async *as = urb->context; | 311 | struct async *as = urb->context; |
308 | struct dev_state *ps = as->ps; | 312 | struct dev_state *ps = as->ps; |
309 | struct siginfo sinfo; | 313 | struct siginfo sinfo; |
310 | 314 | ||
311 | spin_lock(&ps->lock); | 315 | spin_lock(&ps->lock); |
312 | list_move_tail(&as->asynclist, &ps->async_completed); | 316 | list_move_tail(&as->asynclist, &ps->async_completed); |
313 | spin_unlock(&ps->lock); | 317 | spin_unlock(&ps->lock); |
314 | as->status = urb->status; | 318 | as->status = urb->status; |
315 | if (as->signr) { | 319 | if (as->signr) { |
316 | sinfo.si_signo = as->signr; | 320 | sinfo.si_signo = as->signr; |
@@ -325,7 +329,7 @@ static void async_completed(struct urb *urb) | |||
325 | wake_up(&ps->wait); | 329 | wake_up(&ps->wait); |
326 | } | 330 | } |
327 | 331 | ||
328 | static void destroy_async (struct dev_state *ps, struct list_head *list) | 332 | static void destroy_async(struct dev_state *ps, struct list_head *list) |
329 | { | 333 | { |
330 | struct async *as; | 334 | struct async *as; |
331 | unsigned long flags; | 335 | unsigned long flags; |
@@ -348,7 +352,8 @@ static void destroy_async (struct dev_state *ps, struct list_head *list) | |||
348 | } | 352 | } |
349 | } | 353 | } |
350 | 354 | ||
351 | static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum) | 355 | static void destroy_async_on_interface(struct dev_state *ps, |
356 | unsigned int ifnum) | ||
352 | { | 357 | { |
353 | struct list_head *p, *q, hitlist; | 358 | struct list_head *p, *q, hitlist; |
354 | unsigned long flags; | 359 | unsigned long flags; |
@@ -364,7 +369,7 @@ static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum | |||
364 | 369 | ||
365 | static inline void destroy_all_async(struct dev_state *ps) | 370 | static inline void destroy_all_async(struct dev_state *ps) |
366 | { | 371 | { |
367 | destroy_async(ps, &ps->async_pending); | 372 | destroy_async(ps, &ps->async_pending); |
368 | } | 373 | } |
369 | 374 | ||
370 | /* | 375 | /* |
@@ -373,15 +378,15 @@ static inline void destroy_all_async(struct dev_state *ps) | |||
373 | * they're also undone when devices disconnect. | 378 | * they're also undone when devices disconnect. |
374 | */ | 379 | */ |
375 | 380 | ||
376 | static int driver_probe (struct usb_interface *intf, | 381 | static int driver_probe(struct usb_interface *intf, |
377 | const struct usb_device_id *id) | 382 | const struct usb_device_id *id) |
378 | { | 383 | { |
379 | return -ENODEV; | 384 | return -ENODEV; |
380 | } | 385 | } |
381 | 386 | ||
382 | static void driver_disconnect(struct usb_interface *intf) | 387 | static void driver_disconnect(struct usb_interface *intf) |
383 | { | 388 | { |
384 | struct dev_state *ps = usb_get_intfdata (intf); | 389 | struct dev_state *ps = usb_get_intfdata(intf); |
385 | unsigned int ifnum = intf->altsetting->desc.bInterfaceNumber; | 390 | unsigned int ifnum = intf->altsetting->desc.bInterfaceNumber; |
386 | 391 | ||
387 | if (!ps) | 392 | if (!ps) |
@@ -396,16 +401,31 @@ static void driver_disconnect(struct usb_interface *intf) | |||
396 | else | 401 | else |
397 | warn("interface number %u out of range", ifnum); | 402 | warn("interface number %u out of range", ifnum); |
398 | 403 | ||
399 | usb_set_intfdata (intf, NULL); | 404 | usb_set_intfdata(intf, NULL); |
400 | 405 | ||
401 | /* force async requests to complete */ | 406 | /* force async requests to complete */ |
402 | destroy_async_on_interface(ps, ifnum); | 407 | destroy_async_on_interface(ps, ifnum); |
403 | } | 408 | } |
404 | 409 | ||
410 | /* The following routines are merely placeholders. There is no way | ||
411 | * to inform a user task about suspend or resumes. | ||
412 | */ | ||
413 | static int driver_suspend(struct usb_interface *intf, pm_message_t msg) | ||
414 | { | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | static int driver_resume(struct usb_interface *intf) | ||
419 | { | ||
420 | return 0; | ||
421 | } | ||
422 | |||
405 | struct usb_driver usbfs_driver = { | 423 | struct usb_driver usbfs_driver = { |
406 | .name = "usbfs", | 424 | .name = "usbfs", |
407 | .probe = driver_probe, | 425 | .probe = driver_probe, |
408 | .disconnect = driver_disconnect, | 426 | .disconnect = driver_disconnect, |
427 | .suspend = driver_suspend, | ||
428 | .resume = driver_resume, | ||
409 | }; | 429 | }; |
410 | 430 | ||
411 | static int claimintf(struct dev_state *ps, unsigned int ifnum) | 431 | static int claimintf(struct dev_state *ps, unsigned int ifnum) |
@@ -459,15 +479,16 @@ static int checkintf(struct dev_state *ps, unsigned int ifnum) | |||
459 | if (test_bit(ifnum, &ps->ifclaimed)) | 479 | if (test_bit(ifnum, &ps->ifclaimed)) |
460 | return 0; | 480 | return 0; |
461 | /* if not yet claimed, claim it for the driver */ | 481 | /* if not yet claimed, claim it for the driver */ |
462 | dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim interface %u before use\n", | 482 | dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim " |
463 | task_pid_nr(current), current->comm, ifnum); | 483 | "interface %u before use\n", task_pid_nr(current), |
484 | current->comm, ifnum); | ||
464 | return claimintf(ps, ifnum); | 485 | return claimintf(ps, ifnum); |
465 | } | 486 | } |
466 | 487 | ||
467 | static int findintfep(struct usb_device *dev, unsigned int ep) | 488 | static int findintfep(struct usb_device *dev, unsigned int ep) |
468 | { | 489 | { |
469 | unsigned int i, j, e; | 490 | unsigned int i, j, e; |
470 | struct usb_interface *intf; | 491 | struct usb_interface *intf; |
471 | struct usb_host_interface *alts; | 492 | struct usb_host_interface *alts; |
472 | struct usb_endpoint_descriptor *endpt; | 493 | struct usb_endpoint_descriptor *endpt; |
473 | 494 | ||
@@ -478,7 +499,7 @@ static int findintfep(struct usb_device *dev, unsigned int ep) | |||
478 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { | 499 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { |
479 | intf = dev->actconfig->interface[i]; | 500 | intf = dev->actconfig->interface[i]; |
480 | for (j = 0; j < intf->num_altsetting; j++) { | 501 | for (j = 0; j < intf->num_altsetting; j++) { |
481 | alts = &intf->altsetting[j]; | 502 | alts = &intf->altsetting[j]; |
482 | for (e = 0; e < alts->desc.bNumEndpoints; e++) { | 503 | for (e = 0; e < alts->desc.bNumEndpoints; e++) { |
483 | endpt = &alts->endpoint[e].desc; | 504 | endpt = &alts->endpoint[e].desc; |
484 | if (endpt->bEndpointAddress == ep) | 505 | if (endpt->bEndpointAddress == ep) |
@@ -486,10 +507,11 @@ static int findintfep(struct usb_device *dev, unsigned int ep) | |||
486 | } | 507 | } |
487 | } | 508 | } |
488 | } | 509 | } |
489 | return -ENOENT; | 510 | return -ENOENT; |
490 | } | 511 | } |
491 | 512 | ||
492 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned int index) | 513 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, |
514 | unsigned int index) | ||
493 | { | 515 | { |
494 | int ret = 0; | 516 | int ret = 0; |
495 | 517 | ||
@@ -502,7 +524,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
502 | index &= 0xff; | 524 | index &= 0xff; |
503 | switch (requesttype & USB_RECIP_MASK) { | 525 | switch (requesttype & USB_RECIP_MASK) { |
504 | case USB_RECIP_ENDPOINT: | 526 | case USB_RECIP_ENDPOINT: |
505 | if ((ret = findintfep(ps->dev, index)) >= 0) | 527 | ret = findintfep(ps->dev, index); |
528 | if (ret >= 0) | ||
506 | ret = checkintf(ps, ret); | 529 | ret = checkintf(ps, ret); |
507 | break; | 530 | break; |
508 | 531 | ||
@@ -546,7 +569,8 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
546 | mutex_lock(&usbfs_mutex); | 569 | mutex_lock(&usbfs_mutex); |
547 | 570 | ||
548 | ret = -ENOMEM; | 571 | ret = -ENOMEM; |
549 | if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL))) | 572 | ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL); |
573 | if (!ps) | ||
550 | goto out; | 574 | goto out; |
551 | 575 | ||
552 | ret = -ENOENT; | 576 | ret = -ENOENT; |
@@ -627,15 +651,18 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
627 | 651 | ||
628 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 652 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
629 | return -EFAULT; | 653 | return -EFAULT; |
630 | if ((ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex))) | 654 | ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); |
655 | if (ret) | ||
631 | return ret; | 656 | return ret; |
632 | if (ctrl.wLength > PAGE_SIZE) | 657 | if (ctrl.wLength > PAGE_SIZE) |
633 | return -EINVAL; | 658 | return -EINVAL; |
634 | if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL))) | 659 | tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); |
660 | if (!tbuf) | ||
635 | return -ENOMEM; | 661 | return -ENOMEM; |
636 | tmo = ctrl.timeout; | 662 | tmo = ctrl.timeout; |
637 | if (ctrl.bRequestType & 0x80) { | 663 | if (ctrl.bRequestType & 0x80) { |
638 | if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, ctrl.wLength)) { | 664 | if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, |
665 | ctrl.wLength)) { | ||
639 | free_page((unsigned long)tbuf); | 666 | free_page((unsigned long)tbuf); |
640 | return -EINVAL; | 667 | return -EINVAL; |
641 | } | 668 | } |
@@ -646,14 +673,15 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
646 | ctrl.wIndex, ctrl.wLength); | 673 | ctrl.wIndex, ctrl.wLength); |
647 | 674 | ||
648 | usb_unlock_device(dev); | 675 | usb_unlock_device(dev); |
649 | i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, | 676 | i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, |
650 | ctrl.wValue, ctrl.wIndex, tbuf, ctrl.wLength, tmo); | 677 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
678 | tbuf, ctrl.wLength, tmo); | ||
651 | usb_lock_device(dev); | 679 | usb_lock_device(dev); |
652 | if ((i > 0) && ctrl.wLength) { | 680 | if ((i > 0) && ctrl.wLength) { |
653 | if (usbfs_snoop) { | 681 | if (usbfs_snoop) { |
654 | dev_info(&dev->dev, "control read: data "); | 682 | dev_info(&dev->dev, "control read: data "); |
655 | for (j = 0; j < i; ++j) | 683 | for (j = 0; j < i; ++j) |
656 | printk("%02x ", (unsigned char)(tbuf)[j]); | 684 | printk("%02x ", (u8)(tbuf)[j]); |
657 | printk("\n"); | 685 | printk("\n"); |
658 | } | 686 | } |
659 | if (copy_to_user(ctrl.data, tbuf, i)) { | 687 | if (copy_to_user(ctrl.data, tbuf, i)) { |
@@ -680,12 +708,13 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
680 | printk("\n"); | 708 | printk("\n"); |
681 | } | 709 | } |
682 | usb_unlock_device(dev); | 710 | usb_unlock_device(dev); |
683 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, | 711 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, |
684 | ctrl.wValue, ctrl.wIndex, tbuf, ctrl.wLength, tmo); | 712 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
713 | tbuf, ctrl.wLength, tmo); | ||
685 | usb_lock_device(dev); | 714 | usb_lock_device(dev); |
686 | } | 715 | } |
687 | free_page((unsigned long)tbuf); | 716 | free_page((unsigned long)tbuf); |
688 | if (i<0 && i != -EPIPE) { | 717 | if (i < 0 && i != -EPIPE) { |
689 | dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " | 718 | dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " |
690 | "failed cmd %s rqt %u rq %u len %u ret %d\n", | 719 | "failed cmd %s rqt %u rq %u len %u ret %d\n", |
691 | current->comm, ctrl.bRequestType, ctrl.bRequest, | 720 | current->comm, ctrl.bRequestType, ctrl.bRequest, |
@@ -705,9 +734,11 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
705 | 734 | ||
706 | if (copy_from_user(&bulk, arg, sizeof(bulk))) | 735 | if (copy_from_user(&bulk, arg, sizeof(bulk))) |
707 | return -EFAULT; | 736 | return -EFAULT; |
708 | if ((ret = findintfep(ps->dev, bulk.ep)) < 0) | 737 | ret = findintfep(ps->dev, bulk.ep); |
738 | if (ret < 0) | ||
709 | return ret; | 739 | return ret; |
710 | if ((ret = checkintf(ps, ret))) | 740 | ret = checkintf(ps, ret); |
741 | if (ret) | ||
711 | return ret; | 742 | return ret; |
712 | if (bulk.ep & USB_DIR_IN) | 743 | if (bulk.ep & USB_DIR_IN) |
713 | pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f); | 744 | pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f); |
@@ -735,7 +766,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
735 | if (usbfs_snoop) { | 766 | if (usbfs_snoop) { |
736 | dev_info(&dev->dev, "bulk read: data "); | 767 | dev_info(&dev->dev, "bulk read: data "); |
737 | for (j = 0; j < len2; ++j) | 768 | for (j = 0; j < len2; ++j) |
738 | printk("%02x ", (unsigned char)(tbuf)[j]); | 769 | printk("%02x ", (u8)(tbuf)[j]); |
739 | printk("\n"); | 770 | printk("\n"); |
740 | } | 771 | } |
741 | if (copy_to_user(bulk.data, tbuf, len2)) { | 772 | if (copy_to_user(bulk.data, tbuf, len2)) { |
@@ -775,9 +806,11 @@ static int proc_resetep(struct dev_state *ps, void __user *arg) | |||
775 | 806 | ||
776 | if (get_user(ep, (unsigned int __user *)arg)) | 807 | if (get_user(ep, (unsigned int __user *)arg)) |
777 | return -EFAULT; | 808 | return -EFAULT; |
778 | if ((ret = findintfep(ps->dev, ep)) < 0) | 809 | ret = findintfep(ps->dev, ep); |
810 | if (ret < 0) | ||
779 | return ret; | 811 | return ret; |
780 | if ((ret = checkintf(ps, ret))) | 812 | ret = checkintf(ps, ret); |
813 | if (ret) | ||
781 | return ret; | 814 | return ret; |
782 | usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0); | 815 | usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0); |
783 | return 0; | 816 | return 0; |
@@ -791,18 +824,19 @@ static int proc_clearhalt(struct dev_state *ps, void __user *arg) | |||
791 | 824 | ||
792 | if (get_user(ep, (unsigned int __user *)arg)) | 825 | if (get_user(ep, (unsigned int __user *)arg)) |
793 | return -EFAULT; | 826 | return -EFAULT; |
794 | if ((ret = findintfep(ps->dev, ep)) < 0) | 827 | ret = findintfep(ps->dev, ep); |
828 | if (ret < 0) | ||
795 | return ret; | 829 | return ret; |
796 | if ((ret = checkintf(ps, ret))) | 830 | ret = checkintf(ps, ret); |
831 | if (ret) | ||
797 | return ret; | 832 | return ret; |
798 | if (ep & USB_DIR_IN) | 833 | if (ep & USB_DIR_IN) |
799 | pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f); | 834 | pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f); |
800 | else | 835 | else |
801 | pipe = usb_sndbulkpipe(ps->dev, ep & 0x7f); | 836 | pipe = usb_sndbulkpipe(ps->dev, ep & 0x7f); |
802 | 837 | ||
803 | return usb_clear_halt(ps->dev, pipe); | 838 | return usb_clear_halt(ps->dev, pipe); |
804 | } | 839 | } |
805 | |||
806 | 840 | ||
807 | static int proc_getdriver(struct dev_state *ps, void __user *arg) | 841 | static int proc_getdriver(struct dev_state *ps, void __user *arg) |
808 | { | 842 | { |
@@ -856,23 +890,23 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) | |||
856 | { | 890 | { |
857 | int u; | 891 | int u; |
858 | int status = 0; | 892 | int status = 0; |
859 | struct usb_host_config *actconfig; | 893 | struct usb_host_config *actconfig; |
860 | 894 | ||
861 | if (get_user(u, (int __user *)arg)) | 895 | if (get_user(u, (int __user *)arg)) |
862 | return -EFAULT; | 896 | return -EFAULT; |
863 | 897 | ||
864 | actconfig = ps->dev->actconfig; | 898 | actconfig = ps->dev->actconfig; |
865 | 899 | ||
866 | /* Don't touch the device if any interfaces are claimed. | 900 | /* Don't touch the device if any interfaces are claimed. |
867 | * It could interfere with other drivers' operations, and if | 901 | * It could interfere with other drivers' operations, and if |
868 | * an interface is claimed by usbfs it could easily deadlock. | 902 | * an interface is claimed by usbfs it could easily deadlock. |
869 | */ | 903 | */ |
870 | if (actconfig) { | 904 | if (actconfig) { |
871 | int i; | 905 | int i; |
872 | 906 | ||
873 | for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) { | 907 | for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) { |
874 | if (usb_interface_claimed(actconfig->interface[i])) { | 908 | if (usb_interface_claimed(actconfig->interface[i])) { |
875 | dev_warn (&ps->dev->dev, | 909 | dev_warn(&ps->dev->dev, |
876 | "usbfs: interface %d claimed by %s " | 910 | "usbfs: interface %d claimed by %s " |
877 | "while '%s' sets config #%d\n", | 911 | "while '%s' sets config #%d\n", |
878 | actconfig->interface[i] | 912 | actconfig->interface[i] |
@@ -881,11 +915,11 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) | |||
881 | actconfig->interface[i] | 915 | actconfig->interface[i] |
882 | ->dev.driver->name, | 916 | ->dev.driver->name, |
883 | current->comm, u); | 917 | current->comm, u); |
884 | status = -EBUSY; | 918 | status = -EBUSY; |
885 | break; | 919 | break; |
886 | } | 920 | } |
887 | } | 921 | } |
888 | } | 922 | } |
889 | 923 | ||
890 | /* SET_CONFIGURATION is often abused as a "cheap" driver reset, | 924 | /* SET_CONFIGURATION is often abused as a "cheap" driver reset, |
891 | * so avoid usb_set_configuration()'s kick to sysfs | 925 | * so avoid usb_set_configuration()'s kick to sysfs |
@@ -901,8 +935,8 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) | |||
901 | } | 935 | } |
902 | 936 | ||
903 | static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | 937 | static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, |
904 | struct usbdevfs_iso_packet_desc __user *iso_frame_desc, | 938 | struct usbdevfs_iso_packet_desc __user *iso_frame_desc, |
905 | void __user *arg) | 939 | void __user *arg) |
906 | { | 940 | { |
907 | struct usbdevfs_iso_packet_desc *isopkt = NULL; | 941 | struct usbdevfs_iso_packet_desc *isopkt = NULL; |
908 | struct usb_host_endpoint *ep; | 942 | struct usb_host_endpoint *ep; |
@@ -917,12 +951,16 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
917 | return -EINVAL; | 951 | return -EINVAL; |
918 | if (!uurb->buffer) | 952 | if (!uurb->buffer) |
919 | return -EINVAL; | 953 | return -EINVAL; |
920 | if (uurb->signr != 0 && (uurb->signr < SIGRTMIN || uurb->signr > SIGRTMAX)) | 954 | if (uurb->signr != 0 && (uurb->signr < SIGRTMIN || |
955 | uurb->signr > SIGRTMAX)) | ||
921 | return -EINVAL; | 956 | return -EINVAL; |
922 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { | 957 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && |
923 | if ((ifnum = findintfep(ps->dev, uurb->endpoint)) < 0) | 958 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { |
959 | ifnum = findintfep(ps->dev, uurb->endpoint); | ||
960 | if (ifnum < 0) | ||
924 | return ifnum; | 961 | return ifnum; |
925 | if ((ret = checkintf(ps, ifnum))) | 962 | ret = checkintf(ps, ifnum); |
963 | if (ret) | ||
926 | return ret; | 964 | return ret; |
927 | } | 965 | } |
928 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { | 966 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { |
@@ -938,10 +976,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
938 | case USBDEVFS_URB_TYPE_CONTROL: | 976 | case USBDEVFS_URB_TYPE_CONTROL: |
939 | if (!usb_endpoint_xfer_control(&ep->desc)) | 977 | if (!usb_endpoint_xfer_control(&ep->desc)) |
940 | return -EINVAL; | 978 | return -EINVAL; |
941 | /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ | 979 | /* min 8 byte setup packet, |
942 | if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) | 980 | * max 8 byte setup plus an arbitrary data stage */ |
981 | if (uurb->buffer_length < 8 || | ||
982 | uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) | ||
943 | return -EINVAL; | 983 | return -EINVAL; |
944 | if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) | 984 | dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); |
985 | if (!dr) | ||
945 | return -ENOMEM; | 986 | return -ENOMEM; |
946 | if (copy_from_user(dr, uurb->buffer, 8)) { | 987 | if (copy_from_user(dr, uurb->buffer, 8)) { |
947 | kfree(dr); | 988 | kfree(dr); |
@@ -951,7 +992,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
951 | kfree(dr); | 992 | kfree(dr); |
952 | return -EINVAL; | 993 | return -EINVAL; |
953 | } | 994 | } |
954 | if ((ret = check_ctrlrecip(ps, dr->bRequestType, le16_to_cpup(&dr->wIndex)))) { | 995 | ret = check_ctrlrecip(ps, dr->bRequestType, |
996 | le16_to_cpup(&dr->wIndex)); | ||
997 | if (ret) { | ||
955 | kfree(dr); | 998 | kfree(dr); |
956 | return ret; | 999 | return ret; |
957 | } | 1000 | } |
@@ -997,11 +1040,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
997 | 1040 | ||
998 | case USBDEVFS_URB_TYPE_ISO: | 1041 | case USBDEVFS_URB_TYPE_ISO: |
999 | /* arbitrary limit */ | 1042 | /* arbitrary limit */ |
1000 | if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128) | 1043 | if (uurb->number_of_packets < 1 || |
1044 | uurb->number_of_packets > 128) | ||
1001 | return -EINVAL; | 1045 | return -EINVAL; |
1002 | if (!usb_endpoint_xfer_isoc(&ep->desc)) | 1046 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
1003 | return -EINVAL; | 1047 | return -EINVAL; |
1004 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; | 1048 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * |
1049 | uurb->number_of_packets; | ||
1005 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) | 1050 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) |
1006 | return -ENOMEM; | 1051 | return -ENOMEM; |
1007 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { | 1052 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { |
@@ -1009,7 +1054,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1009 | return -EFAULT; | 1054 | return -EFAULT; |
1010 | } | 1055 | } |
1011 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1056 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { |
1012 | /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */ | 1057 | /* arbitrary limit, |
1058 | * sufficient for USB 2.0 high-bandwidth iso */ | ||
1013 | if (isopkt[u].length > 8192) { | 1059 | if (isopkt[u].length > 8192) { |
1014 | kfree(isopkt); | 1060 | kfree(isopkt); |
1015 | return -EINVAL; | 1061 | return -EINVAL; |
@@ -1039,25 +1085,27 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1039 | default: | 1085 | default: |
1040 | return -EINVAL; | 1086 | return -EINVAL; |
1041 | } | 1087 | } |
1042 | if (!(as = alloc_async(uurb->number_of_packets))) { | 1088 | as = alloc_async(uurb->number_of_packets); |
1089 | if (!as) { | ||
1043 | kfree(isopkt); | 1090 | kfree(isopkt); |
1044 | kfree(dr); | 1091 | kfree(dr); |
1045 | return -ENOMEM; | 1092 | return -ENOMEM; |
1046 | } | 1093 | } |
1047 | if (!(as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL))) { | 1094 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL); |
1095 | if (!as->urb->transfer_buffer) { | ||
1048 | kfree(isopkt); | 1096 | kfree(isopkt); |
1049 | kfree(dr); | 1097 | kfree(dr); |
1050 | free_async(as); | 1098 | free_async(as); |
1051 | return -ENOMEM; | 1099 | return -ENOMEM; |
1052 | } | 1100 | } |
1053 | as->urb->dev = ps->dev; | 1101 | as->urb->dev = ps->dev; |
1054 | as->urb->pipe = (uurb->type << 30) | | 1102 | as->urb->pipe = (uurb->type << 30) | |
1055 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | | 1103 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | |
1056 | (uurb->endpoint & USB_DIR_IN); | 1104 | (uurb->endpoint & USB_DIR_IN); |
1057 | as->urb->transfer_flags = uurb->flags | | 1105 | as->urb->transfer_flags = uurb->flags | |
1058 | (is_in ? URB_DIR_IN : URB_DIR_OUT); | 1106 | (is_in ? URB_DIR_IN : URB_DIR_OUT); |
1059 | as->urb->transfer_buffer_length = uurb->buffer_length; | 1107 | as->urb->transfer_buffer_length = uurb->buffer_length; |
1060 | as->urb->setup_packet = (unsigned char*)dr; | 1108 | as->urb->setup_packet = (unsigned char *)dr; |
1061 | as->urb->start_frame = uurb->start_frame; | 1109 | as->urb->start_frame = uurb->start_frame; |
1062 | as->urb->number_of_packets = uurb->number_of_packets; | 1110 | as->urb->number_of_packets = uurb->number_of_packets; |
1063 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || | 1111 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || |
@@ -1065,8 +1113,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1065 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); | 1113 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); |
1066 | else | 1114 | else |
1067 | as->urb->interval = ep->desc.bInterval; | 1115 | as->urb->interval = ep->desc.bInterval; |
1068 | as->urb->context = as; | 1116 | as->urb->context = as; |
1069 | as->urb->complete = async_completed; | 1117 | as->urb->complete = async_completed; |
1070 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1118 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { |
1071 | as->urb->iso_frame_desc[u].offset = totlen; | 1119 | as->urb->iso_frame_desc[u].offset = totlen; |
1072 | as->urb->iso_frame_desc[u].length = isopkt[u].length; | 1120 | as->urb->iso_frame_desc[u].length = isopkt[u].length; |
@@ -1074,7 +1122,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1074 | } | 1122 | } |
1075 | kfree(isopkt); | 1123 | kfree(isopkt); |
1076 | as->ps = ps; | 1124 | as->ps = ps; |
1077 | as->userurb = arg; | 1125 | as->userurb = arg; |
1078 | if (uurb->endpoint & USB_DIR_IN) | 1126 | if (uurb->endpoint & USB_DIR_IN) |
1079 | as->userbuffer = uurb->buffer; | 1127 | as->userbuffer = uurb->buffer; |
1080 | else | 1128 | else |
@@ -1093,14 +1141,15 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1093 | } | 1141 | } |
1094 | } | 1142 | } |
1095 | snoop_urb(as->urb, as->userurb); | 1143 | snoop_urb(as->urb, as->userurb); |
1096 | async_newpending(as); | 1144 | async_newpending(as); |
1097 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { | 1145 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { |
1098 | dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret); | 1146 | dev_printk(KERN_DEBUG, &ps->dev->dev, |
1099 | async_removepending(as); | 1147 | "usbfs: usb_submit_urb returned %d\n", ret); |
1100 | free_async(as); | 1148 | async_removepending(as); |
1101 | return ret; | 1149 | free_async(as); |
1102 | } | 1150 | return ret; |
1103 | return 0; | 1151 | } |
1152 | return 0; | ||
1104 | } | 1153 | } |
1105 | 1154 | ||
1106 | static int proc_submiturb(struct dev_state *ps, void __user *arg) | 1155 | static int proc_submiturb(struct dev_state *ps, void __user *arg) |
@@ -1110,7 +1159,9 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg) | |||
1110 | if (copy_from_user(&uurb, arg, sizeof(uurb))) | 1159 | if (copy_from_user(&uurb, arg, sizeof(uurb))) |
1111 | return -EFAULT; | 1160 | return -EFAULT; |
1112 | 1161 | ||
1113 | return proc_do_submiturb(ps, &uurb, (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), arg); | 1162 | return proc_do_submiturb(ps, &uurb, |
1163 | (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), | ||
1164 | arg); | ||
1114 | } | 1165 | } |
1115 | 1166 | ||
1116 | static int proc_unlinkurb(struct dev_state *ps, void __user *arg) | 1167 | static int proc_unlinkurb(struct dev_state *ps, void __user *arg) |
@@ -1132,7 +1183,8 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1132 | unsigned int i; | 1183 | unsigned int i; |
1133 | 1184 | ||
1134 | if (as->userbuffer) | 1185 | if (as->userbuffer) |
1135 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1186 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1187 | urb->transfer_buffer_length)) | ||
1136 | return -EFAULT; | 1188 | return -EFAULT; |
1137 | if (put_user(as->status, &userurb->status)) | 1189 | if (put_user(as->status, &userurb->status)) |
1138 | return -EFAULT; | 1190 | return -EFAULT; |
@@ -1159,16 +1211,17 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1159 | return 0; | 1211 | return 0; |
1160 | } | 1212 | } |
1161 | 1213 | ||
1162 | static struct async* reap_as(struct dev_state *ps) | 1214 | static struct async *reap_as(struct dev_state *ps) |
1163 | { | 1215 | { |
1164 | DECLARE_WAITQUEUE(wait, current); | 1216 | DECLARE_WAITQUEUE(wait, current); |
1165 | struct async *as = NULL; | 1217 | struct async *as = NULL; |
1166 | struct usb_device *dev = ps->dev; | 1218 | struct usb_device *dev = ps->dev; |
1167 | 1219 | ||
1168 | add_wait_queue(&ps->wait, &wait); | 1220 | add_wait_queue(&ps->wait, &wait); |
1169 | for (;;) { | 1221 | for (;;) { |
1170 | __set_current_state(TASK_INTERRUPTIBLE); | 1222 | __set_current_state(TASK_INTERRUPTIBLE); |
1171 | if ((as = async_getcompleted(ps))) | 1223 | as = async_getcompleted(ps); |
1224 | if (as) | ||
1172 | break; | 1225 | break; |
1173 | if (signal_pending(current)) | 1226 | if (signal_pending(current)) |
1174 | break; | 1227 | break; |
@@ -1232,10 +1285,12 @@ static int proc_submiturb_compat(struct dev_state *ps, void __user *arg) | |||
1232 | { | 1285 | { |
1233 | struct usbdevfs_urb uurb; | 1286 | struct usbdevfs_urb uurb; |
1234 | 1287 | ||
1235 | if (get_urb32(&uurb,(struct usbdevfs_urb32 __user *)arg)) | 1288 | if (get_urb32(&uurb, (struct usbdevfs_urb32 __user *)arg)) |
1236 | return -EFAULT; | 1289 | return -EFAULT; |
1237 | 1290 | ||
1238 | return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg); | 1291 | return proc_do_submiturb(ps, &uurb, |
1292 | ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, | ||
1293 | arg); | ||
1239 | } | 1294 | } |
1240 | 1295 | ||
1241 | static int processcompl_compat(struct async *as, void __user * __user *arg) | 1296 | static int processcompl_compat(struct async *as, void __user * __user *arg) |
@@ -1246,7 +1301,8 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
1246 | unsigned int i; | 1301 | unsigned int i; |
1247 | 1302 | ||
1248 | if (as->userbuffer) | 1303 | if (as->userbuffer) |
1249 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1304 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1305 | urb->transfer_buffer_length)) | ||
1250 | return -EFAULT; | 1306 | return -EFAULT; |
1251 | if (put_user(as->status, &userurb->status)) | 1307 | if (put_user(as->status, &userurb->status)) |
1252 | return -EFAULT; | 1308 | return -EFAULT; |
@@ -1337,16 +1393,16 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1337 | struct usb_driver *driver = NULL; | 1393 | struct usb_driver *driver = NULL; |
1338 | 1394 | ||
1339 | /* alloc buffer */ | 1395 | /* alloc buffer */ |
1340 | if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) { | 1396 | if ((size = _IOC_SIZE(ctl->ioctl_code)) > 0) { |
1341 | if ((buf = kmalloc (size, GFP_KERNEL)) == NULL) | 1397 | if ((buf = kmalloc(size, GFP_KERNEL)) == NULL) |
1342 | return -ENOMEM; | 1398 | return -ENOMEM; |
1343 | if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { | 1399 | if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { |
1344 | if (copy_from_user (buf, ctl->data, size)) { | 1400 | if (copy_from_user(buf, ctl->data, size)) { |
1345 | kfree(buf); | 1401 | kfree(buf); |
1346 | return -EFAULT; | 1402 | return -EFAULT; |
1347 | } | 1403 | } |
1348 | } else { | 1404 | } else { |
1349 | memset (buf, 0, size); | 1405 | memset(buf, 0, size); |
1350 | } | 1406 | } |
1351 | } | 1407 | } |
1352 | 1408 | ||
@@ -1357,15 +1413,15 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1357 | 1413 | ||
1358 | if (ps->dev->state != USB_STATE_CONFIGURED) | 1414 | if (ps->dev->state != USB_STATE_CONFIGURED) |
1359 | retval = -EHOSTUNREACH; | 1415 | retval = -EHOSTUNREACH; |
1360 | else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno))) | 1416 | else if (!(intf = usb_ifnum_to_if(ps->dev, ctl->ifno))) |
1361 | retval = -EINVAL; | 1417 | retval = -EINVAL; |
1362 | else switch (ctl->ioctl_code) { | 1418 | else switch (ctl->ioctl_code) { |
1363 | 1419 | ||
1364 | /* disconnect kernel driver from interface */ | 1420 | /* disconnect kernel driver from interface */ |
1365 | case USBDEVFS_DISCONNECT: | 1421 | case USBDEVFS_DISCONNECT: |
1366 | if (intf->dev.driver) { | 1422 | if (intf->dev.driver) { |
1367 | driver = to_usb_driver(intf->dev.driver); | 1423 | driver = to_usb_driver(intf->dev.driver); |
1368 | dev_dbg (&intf->dev, "disconnect by usbfs\n"); | 1424 | dev_dbg(&intf->dev, "disconnect by usbfs\n"); |
1369 | usb_driver_release_interface(driver, intf); | 1425 | usb_driver_release_interface(driver, intf); |
1370 | } else | 1426 | } else |
1371 | retval = -ENODATA; | 1427 | retval = -ENODATA; |
@@ -1373,9 +1429,10 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1373 | 1429 | ||
1374 | /* let kernel drivers try to (re)bind to the interface */ | 1430 | /* let kernel drivers try to (re)bind to the interface */ |
1375 | case USBDEVFS_CONNECT: | 1431 | case USBDEVFS_CONNECT: |
1376 | usb_unlock_device(ps->dev); | 1432 | if (!intf->dev.driver) |
1377 | retval = bus_rescan_devices(intf->dev.bus); | 1433 | retval = device_attach(&intf->dev); |
1378 | usb_lock_device(ps->dev); | 1434 | else |
1435 | retval = -EBUSY; | ||
1379 | break; | 1436 | break; |
1380 | 1437 | ||
1381 | /* talk directly to the interface's driver */ | 1438 | /* talk directly to the interface's driver */ |
@@ -1385,7 +1442,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1385 | if (driver == NULL || driver->ioctl == NULL) { | 1442 | if (driver == NULL || driver->ioctl == NULL) { |
1386 | retval = -ENOTTY; | 1443 | retval = -ENOTTY; |
1387 | } else { | 1444 | } else { |
1388 | retval = driver->ioctl (intf, ctl->ioctl_code, buf); | 1445 | retval = driver->ioctl(intf, ctl->ioctl_code, buf); |
1389 | if (retval == -ENOIOCTLCMD) | 1446 | if (retval == -ENOIOCTLCMD) |
1390 | retval = -ENOTTY; | 1447 | retval = -ENOTTY; |
1391 | } | 1448 | } |
@@ -1393,9 +1450,9 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1393 | 1450 | ||
1394 | /* cleanup and return */ | 1451 | /* cleanup and return */ |
1395 | if (retval >= 0 | 1452 | if (retval >= 0 |
1396 | && (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0 | 1453 | && (_IOC_DIR(ctl->ioctl_code) & _IOC_READ) != 0 |
1397 | && size > 0 | 1454 | && size > 0 |
1398 | && copy_to_user (ctl->data, buf, size) != 0) | 1455 | && copy_to_user(ctl->data, buf, size) != 0) |
1399 | retval = -EFAULT; | 1456 | retval = -EFAULT; |
1400 | 1457 | ||
1401 | kfree(buf); | 1458 | kfree(buf); |
@@ -1406,7 +1463,7 @@ static int proc_ioctl_default(struct dev_state *ps, void __user *arg) | |||
1406 | { | 1463 | { |
1407 | struct usbdevfs_ioctl ctrl; | 1464 | struct usbdevfs_ioctl ctrl; |
1408 | 1465 | ||
1409 | if (copy_from_user(&ctrl, arg, sizeof (ctrl))) | 1466 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
1410 | return -EFAULT; | 1467 | return -EFAULT; |
1411 | return proc_ioctl(ps, &ctrl); | 1468 | return proc_ioctl(ps, &ctrl); |
1412 | } | 1469 | } |
@@ -1434,7 +1491,8 @@ static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg) | |||
1434 | * are assuming that somehow the configuration has been prevented from | 1491 | * are assuming that somehow the configuration has been prevented from |
1435 | * changing. But there's no mechanism to ensure that... | 1492 | * changing. But there's no mechanism to ensure that... |
1436 | */ | 1493 | */ |
1437 | static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 1494 | static int usbdev_ioctl(struct inode *inode, struct file *file, |
1495 | unsigned int cmd, unsigned long arg) | ||
1438 | { | 1496 | { |
1439 | struct dev_state *ps = file->private_data; | 1497 | struct dev_state *ps = file->private_data; |
1440 | struct usb_device *dev = ps->dev; | 1498 | struct usb_device *dev = ps->dev; |
@@ -1577,7 +1635,8 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
1577 | } | 1635 | } |
1578 | 1636 | ||
1579 | /* No kernel lock - fine */ | 1637 | /* No kernel lock - fine */ |
1580 | static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wait) | 1638 | static unsigned int usbdev_poll(struct file *file, |
1639 | struct poll_table_struct *wait) | ||
1581 | { | 1640 | { |
1582 | struct dev_state *ps = file->private_data; | 1641 | struct dev_state *ps = file->private_data; |
1583 | unsigned int mask = 0; | 1642 | unsigned int mask = 0; |
@@ -1648,7 +1707,7 @@ int __init usb_devio_init(void) | |||
1648 | int retval; | 1707 | int retval; |
1649 | 1708 | ||
1650 | retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX, | 1709 | retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX, |
1651 | "usb_device"); | 1710 | "usb_device"); |
1652 | if (retval) { | 1711 | if (retval) { |
1653 | err("unable to register minors for usb_device"); | 1712 | err("unable to register minors for usb_device"); |
1654 | goto out; | 1713 | goto out; |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 7c3aaa9c5402..801b6f142fa7 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -202,10 +202,10 @@ static int usb_probe_interface(struct device *dev) | |||
202 | intf = to_usb_interface(dev); | 202 | intf = to_usb_interface(dev); |
203 | udev = interface_to_usbdev(intf); | 203 | udev = interface_to_usbdev(intf); |
204 | 204 | ||
205 | if (udev->authorized == 0) { | 205 | if (udev->authorized == 0) { |
206 | dev_err(&intf->dev, "Device is not authorized for usage\n"); | 206 | dev_err(&intf->dev, "Device is not authorized for usage\n"); |
207 | return -ENODEV; | 207 | return -ENODEV; |
208 | } | 208 | } |
209 | 209 | ||
210 | id = usb_match_id(intf, driver->id_table); | 210 | id = usb_match_id(intf, driver->id_table); |
211 | if (!id) | 211 | if (!id) |
@@ -299,7 +299,7 @@ static int usb_unbind_interface(struct device *dev) | |||
299 | * lock. | 299 | * lock. |
300 | */ | 300 | */ |
301 | int usb_driver_claim_interface(struct usb_driver *driver, | 301 | int usb_driver_claim_interface(struct usb_driver *driver, |
302 | struct usb_interface *iface, void* priv) | 302 | struct usb_interface *iface, void *priv) |
303 | { | 303 | { |
304 | struct device *dev = &iface->dev; | 304 | struct device *dev = &iface->dev; |
305 | struct usb_device *udev = interface_to_usbdev(iface); | 305 | struct usb_device *udev = interface_to_usbdev(iface); |
@@ -325,7 +325,7 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
325 | 325 | ||
326 | return retval; | 326 | return retval; |
327 | } | 327 | } |
328 | EXPORT_SYMBOL(usb_driver_claim_interface); | 328 | EXPORT_SYMBOL_GPL(usb_driver_claim_interface); |
329 | 329 | ||
330 | /** | 330 | /** |
331 | * usb_driver_release_interface - unbind a driver from an interface | 331 | * usb_driver_release_interface - unbind a driver from an interface |
@@ -370,7 +370,7 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
370 | iface->needs_remote_wakeup = 0; | 370 | iface->needs_remote_wakeup = 0; |
371 | usb_pm_unlock(udev); | 371 | usb_pm_unlock(udev); |
372 | } | 372 | } |
373 | EXPORT_SYMBOL(usb_driver_release_interface); | 373 | EXPORT_SYMBOL_GPL(usb_driver_release_interface); |
374 | 374 | ||
375 | /* returns 0 if no match, 1 if match */ | 375 | /* returns 0 if no match, 1 if match */ |
376 | int usb_match_device(struct usb_device *dev, const struct usb_device_id *id) | 376 | int usb_match_device(struct usb_device *dev, const struct usb_device_id *id) |
@@ -398,7 +398,7 @@ int usb_match_device(struct usb_device *dev, const struct usb_device_id *id) | |||
398 | return 0; | 398 | return 0; |
399 | 399 | ||
400 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | 400 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && |
401 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | 401 | (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass)) |
402 | return 0; | 402 | return 0; |
403 | 403 | ||
404 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | 404 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && |
@@ -534,15 +534,15 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface, | |||
534 | id->driver_info is the way to create an entry that | 534 | id->driver_info is the way to create an entry that |
535 | indicates that the driver want to examine every | 535 | indicates that the driver want to examine every |
536 | device and interface. */ | 536 | device and interface. */ |
537 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | 537 | for (; id->idVendor || id->idProduct || id->bDeviceClass || |
538 | id->driver_info; id++) { | 538 | id->bInterfaceClass || id->driver_info; id++) { |
539 | if (usb_match_one_id(interface, id)) | 539 | if (usb_match_one_id(interface, id)) |
540 | return id; | 540 | return id; |
541 | } | 541 | } |
542 | 542 | ||
543 | return NULL; | 543 | return NULL; |
544 | } | 544 | } |
545 | EXPORT_SYMBOL_GPL_FUTURE(usb_match_id); | 545 | EXPORT_SYMBOL_GPL(usb_match_id); |
546 | 546 | ||
547 | static int usb_device_match(struct device *dev, struct device_driver *drv) | 547 | static int usb_device_match(struct device *dev, struct device_driver *drv) |
548 | { | 548 | { |
@@ -586,7 +586,7 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
586 | struct usb_device *usb_dev; | 586 | struct usb_device *usb_dev; |
587 | 587 | ||
588 | /* driver is often null here; dev_dbg() would oops */ | 588 | /* driver is often null here; dev_dbg() would oops */ |
589 | pr_debug ("usb %s: uevent\n", dev->bus_id); | 589 | pr_debug("usb %s: uevent\n", dev->bus_id); |
590 | 590 | ||
591 | if (is_usb_device(dev)) | 591 | if (is_usb_device(dev)) |
592 | usb_dev = to_usb_device(dev); | 592 | usb_dev = to_usb_device(dev); |
@@ -596,11 +596,11 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
596 | } | 596 | } |
597 | 597 | ||
598 | if (usb_dev->devnum < 0) { | 598 | if (usb_dev->devnum < 0) { |
599 | pr_debug ("usb %s: already deleted?\n", dev->bus_id); | 599 | pr_debug("usb %s: already deleted?\n", dev->bus_id); |
600 | return -ENODEV; | 600 | return -ENODEV; |
601 | } | 601 | } |
602 | if (!usb_dev->bus) { | 602 | if (!usb_dev->bus) { |
603 | pr_debug ("usb %s: bus removed?\n", dev->bus_id); | 603 | pr_debug("usb %s: bus removed?\n", dev->bus_id); |
604 | return -ENODEV; | 604 | return -ENODEV; |
605 | } | 605 | } |
606 | 606 | ||
@@ -745,7 +745,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, | |||
745 | 745 | ||
746 | return retval; | 746 | return retval; |
747 | } | 747 | } |
748 | EXPORT_SYMBOL_GPL_FUTURE(usb_register_driver); | 748 | EXPORT_SYMBOL_GPL(usb_register_driver); |
749 | 749 | ||
750 | /** | 750 | /** |
751 | * usb_deregister - unregister a USB interface driver | 751 | * usb_deregister - unregister a USB interface driver |
@@ -769,7 +769,7 @@ void usb_deregister(struct usb_driver *driver) | |||
769 | 769 | ||
770 | usbfs_update_special(); | 770 | usbfs_update_special(); |
771 | } | 771 | } |
772 | EXPORT_SYMBOL_GPL_FUTURE(usb_deregister); | 772 | EXPORT_SYMBOL_GPL(usb_deregister); |
773 | 773 | ||
774 | #ifdef CONFIG_PM | 774 | #ifdef CONFIG_PM |
775 | 775 | ||
@@ -854,8 +854,10 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg) | |||
854 | dev_err(&intf->dev, "%s error %d\n", | 854 | dev_err(&intf->dev, "%s error %d\n", |
855 | "suspend", status); | 855 | "suspend", status); |
856 | } else { | 856 | } else { |
857 | // FIXME else if there's no suspend method, disconnect... | 857 | /* |
858 | // Not possible if auto_pm is set... | 858 | * FIXME else if there's no suspend method, disconnect... |
859 | * Not possible if auto_pm is set... | ||
860 | */ | ||
859 | dev_warn(&intf->dev, "no suspend for driver %s?\n", | 861 | dev_warn(&intf->dev, "no suspend for driver %s?\n", |
860 | driver->name); | 862 | driver->name); |
861 | mark_quiesced(intf); | 863 | mark_quiesced(intf); |
@@ -894,7 +896,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume) | |||
894 | dev_err(&intf->dev, "%s error %d\n", | 896 | dev_err(&intf->dev, "%s error %d\n", |
895 | "reset_resume", status); | 897 | "reset_resume", status); |
896 | } else { | 898 | } else { |
897 | // status = -EOPNOTSUPP; | 899 | /* status = -EOPNOTSUPP; */ |
898 | dev_warn(&intf->dev, "no %s for driver %s?\n", | 900 | dev_warn(&intf->dev, "no %s for driver %s?\n", |
899 | "reset_resume", driver->name); | 901 | "reset_resume", driver->name); |
900 | } | 902 | } |
@@ -905,7 +907,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume) | |||
905 | dev_err(&intf->dev, "%s error %d\n", | 907 | dev_err(&intf->dev, "%s error %d\n", |
906 | "resume", status); | 908 | "resume", status); |
907 | } else { | 909 | } else { |
908 | // status = -EOPNOTSUPP; | 910 | /* status = -EOPNOTSUPP; */ |
909 | dev_warn(&intf->dev, "no %s for driver %s?\n", | 911 | dev_warn(&intf->dev, "no %s for driver %s?\n", |
910 | "resume", driver->name); | 912 | "resume", driver->name); |
911 | } | 913 | } |
@@ -1175,7 +1177,7 @@ static int usb_resume_both(struct usb_device *udev) | |||
1175 | * so if a root hub's controller is suspended | 1177 | * so if a root hub's controller is suspended |
1176 | * then we're stuck. */ | 1178 | * then we're stuck. */ |
1177 | status = usb_resume_device(udev); | 1179 | status = usb_resume_device(udev); |
1178 | } | 1180 | } |
1179 | } else { | 1181 | } else { |
1180 | 1182 | ||
1181 | /* Needed for setting udev->dev.power.power_state.event, | 1183 | /* Needed for setting udev->dev.power.power_state.event, |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 5d860bc9b421..8133c99c6c5c 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -204,7 +204,7 @@ int usb_register_dev(struct usb_interface *intf, | |||
204 | exit: | 204 | exit: |
205 | return retval; | 205 | return retval; |
206 | } | 206 | } |
207 | EXPORT_SYMBOL(usb_register_dev); | 207 | EXPORT_SYMBOL_GPL(usb_register_dev); |
208 | 208 | ||
209 | /** | 209 | /** |
210 | * usb_deregister_dev - deregister a USB device's dynamic minor. | 210 | * usb_deregister_dev - deregister a USB device's dynamic minor. |
@@ -245,4 +245,4 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
245 | intf->minor = -1; | 245 | intf->minor = -1; |
246 | destroy_usb_class(); | 246 | destroy_usb_class(); |
247 | } | 247 | } |
248 | EXPORT_SYMBOL(usb_deregister_dev); | 248 | EXPORT_SYMBOL_GPL(usb_deregister_dev); |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 3fb9af80cbf4..84760ddbc332 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * (C) Copyright David Brownell 2000-2002 | 2 | * (C) Copyright David Brownell 2000-2002 |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the | 5 | * under the terms of the GNU General Public License as published by the |
6 | * Free Software Foundation; either version 2 of the License, or (at your | 6 | * Free Software Foundation; either version 2 of the License, or (at your |
@@ -55,7 +55,7 @@ | |||
55 | * | 55 | * |
56 | * Store this function in the HCD's struct pci_driver as probe(). | 56 | * Store this function in the HCD's struct pci_driver as probe(). |
57 | */ | 57 | */ |
58 | int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) | 58 | int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
59 | { | 59 | { |
60 | struct hc_driver *driver; | 60 | struct hc_driver *driver; |
61 | struct usb_hcd *hcd; | 61 | struct usb_hcd *hcd; |
@@ -64,66 +64,71 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
64 | if (usb_disabled()) | 64 | if (usb_disabled()) |
65 | return -ENODEV; | 65 | return -ENODEV; |
66 | 66 | ||
67 | if (!id || !(driver = (struct hc_driver *) id->driver_data)) | 67 | if (!id) |
68 | return -EINVAL; | ||
69 | driver = (struct hc_driver *)id->driver_data; | ||
70 | if (!driver) | ||
68 | return -EINVAL; | 71 | return -EINVAL; |
69 | 72 | ||
70 | if (pci_enable_device (dev) < 0) | 73 | if (pci_enable_device(dev) < 0) |
71 | return -ENODEV; | 74 | return -ENODEV; |
72 | dev->current_state = PCI_D0; | 75 | dev->current_state = PCI_D0; |
73 | dev->dev.power.power_state = PMSG_ON; | 76 | dev->dev.power.power_state = PMSG_ON; |
74 | 77 | ||
75 | if (!dev->irq) { | 78 | if (!dev->irq) { |
76 | dev_err (&dev->dev, | 79 | dev_err(&dev->dev, |
77 | "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", | 80 | "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", |
78 | pci_name(dev)); | 81 | pci_name(dev)); |
79 | retval = -ENODEV; | 82 | retval = -ENODEV; |
80 | goto err1; | 83 | goto err1; |
81 | } | 84 | } |
82 | 85 | ||
83 | hcd = usb_create_hcd (driver, &dev->dev, pci_name(dev)); | 86 | hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev)); |
84 | if (!hcd) { | 87 | if (!hcd) { |
85 | retval = -ENOMEM; | 88 | retval = -ENOMEM; |
86 | goto err1; | 89 | goto err1; |
87 | } | 90 | } |
88 | 91 | ||
89 | if (driver->flags & HCD_MEMORY) { // EHCI, OHCI | 92 | if (driver->flags & HCD_MEMORY) { |
90 | hcd->rsrc_start = pci_resource_start (dev, 0); | 93 | /* EHCI, OHCI */ |
91 | hcd->rsrc_len = pci_resource_len (dev, 0); | 94 | hcd->rsrc_start = pci_resource_start(dev, 0); |
92 | if (!request_mem_region (hcd->rsrc_start, hcd->rsrc_len, | 95 | hcd->rsrc_len = pci_resource_len(dev, 0); |
96 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
93 | driver->description)) { | 97 | driver->description)) { |
94 | dev_dbg (&dev->dev, "controller already in use\n"); | 98 | dev_dbg(&dev->dev, "controller already in use\n"); |
95 | retval = -EBUSY; | 99 | retval = -EBUSY; |
96 | goto err2; | 100 | goto err2; |
97 | } | 101 | } |
98 | hcd->regs = ioremap_nocache (hcd->rsrc_start, hcd->rsrc_len); | 102 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); |
99 | if (hcd->regs == NULL) { | 103 | if (hcd->regs == NULL) { |
100 | dev_dbg (&dev->dev, "error mapping memory\n"); | 104 | dev_dbg(&dev->dev, "error mapping memory\n"); |
101 | retval = -EFAULT; | 105 | retval = -EFAULT; |
102 | goto err3; | 106 | goto err3; |
103 | } | 107 | } |
104 | 108 | ||
105 | } else { // UHCI | 109 | } else { |
110 | /* UHCI */ | ||
106 | int region; | 111 | int region; |
107 | 112 | ||
108 | for (region = 0; region < PCI_ROM_RESOURCE; region++) { | 113 | for (region = 0; region < PCI_ROM_RESOURCE; region++) { |
109 | if (!(pci_resource_flags (dev, region) & | 114 | if (!(pci_resource_flags(dev, region) & |
110 | IORESOURCE_IO)) | 115 | IORESOURCE_IO)) |
111 | continue; | 116 | continue; |
112 | 117 | ||
113 | hcd->rsrc_start = pci_resource_start (dev, region); | 118 | hcd->rsrc_start = pci_resource_start(dev, region); |
114 | hcd->rsrc_len = pci_resource_len (dev, region); | 119 | hcd->rsrc_len = pci_resource_len(dev, region); |
115 | if (request_region (hcd->rsrc_start, hcd->rsrc_len, | 120 | if (request_region(hcd->rsrc_start, hcd->rsrc_len, |
116 | driver->description)) | 121 | driver->description)) |
117 | break; | 122 | break; |
118 | } | 123 | } |
119 | if (region == PCI_ROM_RESOURCE) { | 124 | if (region == PCI_ROM_RESOURCE) { |
120 | dev_dbg (&dev->dev, "no i/o regions available\n"); | 125 | dev_dbg(&dev->dev, "no i/o regions available\n"); |
121 | retval = -EBUSY; | 126 | retval = -EBUSY; |
122 | goto err1; | 127 | goto err1; |
123 | } | 128 | } |
124 | } | 129 | } |
125 | 130 | ||
126 | pci_set_master (dev); | 131 | pci_set_master(dev); |
127 | 132 | ||
128 | retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); | 133 | retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); |
129 | if (retval != 0) | 134 | if (retval != 0) |
@@ -132,19 +137,19 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
132 | 137 | ||
133 | err4: | 138 | err4: |
134 | if (driver->flags & HCD_MEMORY) { | 139 | if (driver->flags & HCD_MEMORY) { |
135 | iounmap (hcd->regs); | 140 | iounmap(hcd->regs); |
136 | err3: | 141 | err3: |
137 | release_mem_region (hcd->rsrc_start, hcd->rsrc_len); | 142 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
138 | } else | 143 | } else |
139 | release_region (hcd->rsrc_start, hcd->rsrc_len); | 144 | release_region(hcd->rsrc_start, hcd->rsrc_len); |
140 | err2: | 145 | err2: |
141 | usb_put_hcd (hcd); | 146 | usb_put_hcd(hcd); |
142 | err1: | 147 | err1: |
143 | pci_disable_device (dev); | 148 | pci_disable_device(dev); |
144 | dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); | 149 | dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); |
145 | return retval; | 150 | return retval; |
146 | } | 151 | } |
147 | EXPORT_SYMBOL (usb_hcd_pci_probe); | 152 | EXPORT_SYMBOL_GPL(usb_hcd_pci_probe); |
148 | 153 | ||
149 | 154 | ||
150 | /* may be called without controller electrically present */ | 155 | /* may be called without controller electrically present */ |
@@ -161,7 +166,7 @@ EXPORT_SYMBOL (usb_hcd_pci_probe); | |||
161 | * | 166 | * |
162 | * Store this function in the HCD's struct pci_driver as remove(). | 167 | * Store this function in the HCD's struct pci_driver as remove(). |
163 | */ | 168 | */ |
164 | void usb_hcd_pci_remove (struct pci_dev *dev) | 169 | void usb_hcd_pci_remove(struct pci_dev *dev) |
165 | { | 170 | { |
166 | struct usb_hcd *hcd; | 171 | struct usb_hcd *hcd; |
167 | 172 | ||
@@ -169,17 +174,17 @@ void usb_hcd_pci_remove (struct pci_dev *dev) | |||
169 | if (!hcd) | 174 | if (!hcd) |
170 | return; | 175 | return; |
171 | 176 | ||
172 | usb_remove_hcd (hcd); | 177 | usb_remove_hcd(hcd); |
173 | if (hcd->driver->flags & HCD_MEMORY) { | 178 | if (hcd->driver->flags & HCD_MEMORY) { |
174 | iounmap (hcd->regs); | 179 | iounmap(hcd->regs); |
175 | release_mem_region (hcd->rsrc_start, hcd->rsrc_len); | 180 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
176 | } else { | 181 | } else { |
177 | release_region (hcd->rsrc_start, hcd->rsrc_len); | 182 | release_region(hcd->rsrc_start, hcd->rsrc_len); |
178 | } | 183 | } |
179 | usb_put_hcd (hcd); | 184 | usb_put_hcd(hcd); |
180 | pci_disable_device(dev); | 185 | pci_disable_device(dev); |
181 | } | 186 | } |
182 | EXPORT_SYMBOL (usb_hcd_pci_remove); | 187 | EXPORT_SYMBOL_GPL(usb_hcd_pci_remove); |
183 | 188 | ||
184 | 189 | ||
185 | #ifdef CONFIG_PM | 190 | #ifdef CONFIG_PM |
@@ -191,7 +196,7 @@ EXPORT_SYMBOL (usb_hcd_pci_remove); | |||
191 | * | 196 | * |
192 | * Store this function in the HCD's struct pci_driver as suspend(). | 197 | * Store this function in the HCD's struct pci_driver as suspend(). |
193 | */ | 198 | */ |
194 | int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | 199 | int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) |
195 | { | 200 | { |
196 | struct usb_hcd *hcd; | 201 | struct usb_hcd *hcd; |
197 | int retval = 0; | 202 | int retval = 0; |
@@ -246,12 +251,18 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
246 | 251 | ||
247 | /* no DMA or IRQs except when HC is active */ | 252 | /* no DMA or IRQs except when HC is active */ |
248 | if (dev->current_state == PCI_D0) { | 253 | if (dev->current_state == PCI_D0) { |
249 | pci_save_state (dev); | 254 | pci_save_state(dev); |
250 | pci_disable_device (dev); | 255 | pci_disable_device(dev); |
256 | } | ||
257 | |||
258 | if (message.event == PM_EVENT_FREEZE || | ||
259 | message.event == PM_EVENT_PRETHAW) { | ||
260 | dev_dbg(hcd->self.controller, "--> no state change\n"); | ||
261 | goto done; | ||
251 | } | 262 | } |
252 | 263 | ||
253 | if (!has_pci_pm) { | 264 | if (!has_pci_pm) { |
254 | dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n"); | 265 | dev_dbg(hcd->self.controller, "--> PCI D0/legacy\n"); |
255 | goto done; | 266 | goto done; |
256 | } | 267 | } |
257 | 268 | ||
@@ -260,30 +271,30 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
260 | * PCI_D3 (but not PCI_D1 or PCI_D2) is allowed to reset | 271 | * PCI_D3 (but not PCI_D1 or PCI_D2) is allowed to reset |
261 | * some device state (e.g. as part of clock reinit). | 272 | * some device state (e.g. as part of clock reinit). |
262 | */ | 273 | */ |
263 | retval = pci_set_power_state (dev, PCI_D3hot); | 274 | retval = pci_set_power_state(dev, PCI_D3hot); |
264 | suspend_report_result(pci_set_power_state, retval); | 275 | suspend_report_result(pci_set_power_state, retval); |
265 | if (retval == 0) { | 276 | if (retval == 0) { |
266 | int wake = device_can_wakeup(&hcd->self.root_hub->dev); | 277 | int wake = device_can_wakeup(&hcd->self.root_hub->dev); |
267 | 278 | ||
268 | wake = wake && device_may_wakeup(hcd->self.controller); | 279 | wake = wake && device_may_wakeup(hcd->self.controller); |
269 | 280 | ||
270 | dev_dbg (hcd->self.controller, "--> PCI D3%s\n", | 281 | dev_dbg(hcd->self.controller, "--> PCI D3%s\n", |
271 | wake ? "/wakeup" : ""); | 282 | wake ? "/wakeup" : ""); |
272 | 283 | ||
273 | /* Ignore these return values. We rely on pci code to | 284 | /* Ignore these return values. We rely on pci code to |
274 | * reject requests the hardware can't implement, rather | 285 | * reject requests the hardware can't implement, rather |
275 | * than coding the same thing. | 286 | * than coding the same thing. |
276 | */ | 287 | */ |
277 | (void) pci_enable_wake (dev, PCI_D3hot, wake); | 288 | (void) pci_enable_wake(dev, PCI_D3hot, wake); |
278 | (void) pci_enable_wake (dev, PCI_D3cold, wake); | 289 | (void) pci_enable_wake(dev, PCI_D3cold, wake); |
279 | } else { | 290 | } else { |
280 | dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", | 291 | dev_dbg(&dev->dev, "PCI D3 suspend fail, %d\n", |
281 | retval); | 292 | retval); |
282 | (void) usb_hcd_pci_resume (dev); | 293 | (void) usb_hcd_pci_resume(dev); |
283 | } | 294 | } |
284 | 295 | ||
285 | } else if (hcd->state != HC_STATE_HALT) { | 296 | } else if (hcd->state != HC_STATE_HALT) { |
286 | dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", | 297 | dev_dbg(hcd->self.controller, "hcd state %d; not suspended\n", |
287 | hcd->state); | 298 | hcd->state); |
288 | WARN_ON(1); | 299 | WARN_ON(1); |
289 | retval = -EINVAL; | 300 | retval = -EINVAL; |
@@ -298,7 +309,7 @@ done: | |||
298 | if (machine_is(powermac)) { | 309 | if (machine_is(powermac)) { |
299 | struct device_node *of_node; | 310 | struct device_node *of_node; |
300 | 311 | ||
301 | of_node = pci_device_to_OF_node (dev); | 312 | of_node = pci_device_to_OF_node(dev); |
302 | if (of_node) | 313 | if (of_node) |
303 | pmac_call_feature(PMAC_FTR_USB_ENABLE, | 314 | pmac_call_feature(PMAC_FTR_USB_ENABLE, |
304 | of_node, 0, 0); | 315 | of_node, 0, 0); |
@@ -308,7 +319,7 @@ done: | |||
308 | 319 | ||
309 | return retval; | 320 | return retval; |
310 | } | 321 | } |
311 | EXPORT_SYMBOL (usb_hcd_pci_suspend); | 322 | EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); |
312 | 323 | ||
313 | /** | 324 | /** |
314 | * usb_hcd_pci_resume - power management resume of a PCI-based HCD | 325 | * usb_hcd_pci_resume - power management resume of a PCI-based HCD |
@@ -316,14 +327,14 @@ EXPORT_SYMBOL (usb_hcd_pci_suspend); | |||
316 | * | 327 | * |
317 | * Store this function in the HCD's struct pci_driver as resume(). | 328 | * Store this function in the HCD's struct pci_driver as resume(). |
318 | */ | 329 | */ |
319 | int usb_hcd_pci_resume (struct pci_dev *dev) | 330 | int usb_hcd_pci_resume(struct pci_dev *dev) |
320 | { | 331 | { |
321 | struct usb_hcd *hcd; | 332 | struct usb_hcd *hcd; |
322 | int retval; | 333 | int retval; |
323 | 334 | ||
324 | hcd = pci_get_drvdata(dev); | 335 | hcd = pci_get_drvdata(dev); |
325 | if (hcd->state != HC_STATE_SUSPENDED) { | 336 | if (hcd->state != HC_STATE_SUSPENDED) { |
326 | dev_dbg (hcd->self.controller, | 337 | dev_dbg(hcd->self.controller, |
327 | "can't resume, not suspended!\n"); | 338 | "can't resume, not suspended!\n"); |
328 | return 0; | 339 | return 0; |
329 | } | 340 | } |
@@ -333,9 +344,9 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
333 | if (machine_is(powermac)) { | 344 | if (machine_is(powermac)) { |
334 | struct device_node *of_node; | 345 | struct device_node *of_node; |
335 | 346 | ||
336 | of_node = pci_device_to_OF_node (dev); | 347 | of_node = pci_device_to_OF_node(dev); |
337 | if (of_node) | 348 | if (of_node) |
338 | pmac_call_feature (PMAC_FTR_USB_ENABLE, | 349 | pmac_call_feature(PMAC_FTR_USB_ENABLE, |
339 | of_node, 0, 1); | 350 | of_node, 0, 1); |
340 | } | 351 | } |
341 | #endif | 352 | #endif |
@@ -374,8 +385,8 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
374 | } | 385 | } |
375 | #endif | 386 | #endif |
376 | /* yes, ignore these results too... */ | 387 | /* yes, ignore these results too... */ |
377 | (void) pci_enable_wake (dev, dev->current_state, 0); | 388 | (void) pci_enable_wake(dev, dev->current_state, 0); |
378 | (void) pci_enable_wake (dev, PCI_D3cold, 0); | 389 | (void) pci_enable_wake(dev, PCI_D3cold, 0); |
379 | } else { | 390 | } else { |
380 | /* Same basic cases: clean (powered/not), dirty */ | 391 | /* Same basic cases: clean (powered/not), dirty */ |
381 | dev_dbg(hcd->self.controller, "PCI legacy resume\n"); | 392 | dev_dbg(hcd->self.controller, "PCI legacy resume\n"); |
@@ -386,14 +397,14 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
386 | * but that won't re-enable bus mastering. Yet pci_disable_device() | 397 | * but that won't re-enable bus mastering. Yet pci_disable_device() |
387 | * explicitly disables bus mastering... | 398 | * explicitly disables bus mastering... |
388 | */ | 399 | */ |
389 | retval = pci_enable_device (dev); | 400 | retval = pci_enable_device(dev); |
390 | if (retval < 0) { | 401 | if (retval < 0) { |
391 | dev_err (hcd->self.controller, | 402 | dev_err(hcd->self.controller, |
392 | "can't re-enable after resume, %d!\n", retval); | 403 | "can't re-enable after resume, %d!\n", retval); |
393 | return retval; | 404 | return retval; |
394 | } | 405 | } |
395 | pci_set_master (dev); | 406 | pci_set_master(dev); |
396 | pci_restore_state (dev); | 407 | pci_restore_state(dev); |
397 | 408 | ||
398 | dev->dev.power.power_state = PMSG_ON; | 409 | dev->dev.power.power_state = PMSG_ON; |
399 | 410 | ||
@@ -402,15 +413,15 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
402 | if (hcd->driver->resume) { | 413 | if (hcd->driver->resume) { |
403 | retval = hcd->driver->resume(hcd); | 414 | retval = hcd->driver->resume(hcd); |
404 | if (retval) { | 415 | if (retval) { |
405 | dev_err (hcd->self.controller, | 416 | dev_err(hcd->self.controller, |
406 | "PCI post-resume error %d!\n", retval); | 417 | "PCI post-resume error %d!\n", retval); |
407 | usb_hc_died (hcd); | 418 | usb_hc_died(hcd); |
408 | } | 419 | } |
409 | } | 420 | } |
410 | 421 | ||
411 | return retval; | 422 | return retval; |
412 | } | 423 | } |
413 | EXPORT_SYMBOL (usb_hcd_pci_resume); | 424 | EXPORT_SYMBOL_GPL(usb_hcd_pci_resume); |
414 | 425 | ||
415 | #endif /* CONFIG_PM */ | 426 | #endif /* CONFIG_PM */ |
416 | 427 | ||
@@ -418,7 +429,7 @@ EXPORT_SYMBOL (usb_hcd_pci_resume); | |||
418 | * usb_hcd_pci_shutdown - shutdown host controller | 429 | * usb_hcd_pci_shutdown - shutdown host controller |
419 | * @dev: USB Host Controller being shutdown | 430 | * @dev: USB Host Controller being shutdown |
420 | */ | 431 | */ |
421 | void usb_hcd_pci_shutdown (struct pci_dev *dev) | 432 | void usb_hcd_pci_shutdown(struct pci_dev *dev) |
422 | { | 433 | { |
423 | struct usb_hcd *hcd; | 434 | struct usb_hcd *hcd; |
424 | 435 | ||
@@ -429,5 +440,5 @@ void usb_hcd_pci_shutdown (struct pci_dev *dev) | |||
429 | if (hcd->driver->shutdown) | 440 | if (hcd->driver->shutdown) |
430 | hcd->driver->shutdown(hcd); | 441 | hcd->driver->shutdown(hcd); |
431 | } | 442 | } |
432 | EXPORT_SYMBOL (usb_hcd_pci_shutdown); | 443 | EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown); |
433 | 444 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index d5ed3fa9e304..e52ed1663b3c 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
37 | #include <asm/byteorder.h> | 37 | #include <asm/byteorder.h> |
38 | #include <asm/unaligned.h> | ||
38 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
39 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
40 | 41 | ||
@@ -131,8 +132,8 @@ static const u8 usb2_rh_dev_descriptor [18] = { | |||
131 | 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ | 132 | 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ |
132 | 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ | 133 | 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ |
133 | 134 | ||
134 | 0x00, 0x00, /* __le16 idVendor; */ | 135 | 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ |
135 | 0x00, 0x00, /* __le16 idProduct; */ | 136 | 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ |
136 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ | 137 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ |
137 | 138 | ||
138 | 0x03, /* __u8 iManufacturer; */ | 139 | 0x03, /* __u8 iManufacturer; */ |
@@ -154,8 +155,8 @@ static const u8 usb11_rh_dev_descriptor [18] = { | |||
154 | 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ | 155 | 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ |
155 | 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ | 156 | 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ |
156 | 157 | ||
157 | 0x00, 0x00, /* __le16 idVendor; */ | 158 | 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ |
158 | 0x00, 0x00, /* __le16 idProduct; */ | 159 | 0x01, 0x00, /* __le16 idProduct; device 0x0001 */ |
159 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ | 160 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ |
160 | 161 | ||
161 | 0x03, /* __u8 iManufacturer; */ | 162 | 0x03, /* __u8 iManufacturer; */ |
@@ -807,13 +808,13 @@ static int usb_register_bus(struct usb_bus *bus) | |||
807 | } | 808 | } |
808 | set_bit (busnum, busmap.busmap); | 809 | set_bit (busnum, busmap.busmap); |
809 | bus->busnum = busnum; | 810 | bus->busnum = busnum; |
810 | bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0), | 811 | |
811 | bus->controller, "usb_host%d", | 812 | bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0), |
812 | busnum); | 813 | "usb_host%d", busnum); |
813 | result = PTR_ERR(bus->class_dev); | 814 | result = PTR_ERR(bus->dev); |
814 | if (IS_ERR(bus->class_dev)) | 815 | if (IS_ERR(bus->dev)) |
815 | goto error_create_class_dev; | 816 | goto error_create_class_dev; |
816 | class_set_devdata(bus->class_dev, bus); | 817 | dev_set_drvdata(bus->dev, bus); |
817 | 818 | ||
818 | /* Add it to the local list of buses */ | 819 | /* Add it to the local list of buses */ |
819 | list_add (&bus->bus_list, &usb_bus_list); | 820 | list_add (&bus->bus_list, &usb_bus_list); |
@@ -857,7 +858,7 @@ static void usb_deregister_bus (struct usb_bus *bus) | |||
857 | 858 | ||
858 | clear_bit (bus->busnum, busmap.busmap); | 859 | clear_bit (bus->busnum, busmap.busmap); |
859 | 860 | ||
860 | class_device_unregister(bus->class_dev); | 861 | device_unregister(bus->dev); |
861 | } | 862 | } |
862 | 863 | ||
863 | /** | 864 | /** |
@@ -970,7 +971,7 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) | |||
970 | return -1; | 971 | return -1; |
971 | } | 972 | } |
972 | } | 973 | } |
973 | EXPORT_SYMBOL (usb_calc_bus_time); | 974 | EXPORT_SYMBOL_GPL(usb_calc_bus_time); |
974 | 975 | ||
975 | 976 | ||
976 | /*-------------------------------------------------------------------------*/ | 977 | /*-------------------------------------------------------------------------*/ |
@@ -1112,48 +1113,177 @@ void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb) | |||
1112 | } | 1113 | } |
1113 | EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep); | 1114 | EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep); |
1114 | 1115 | ||
1115 | static void map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) | 1116 | /* |
1117 | * Some usb host controllers can only perform dma using a small SRAM area. | ||
1118 | * The usb core itself is however optimized for host controllers that can dma | ||
1119 | * using regular system memory - like pci devices doing bus mastering. | ||
1120 | * | ||
1121 | * To support host controllers with limited dma capabilites we provide dma | ||
1122 | * bounce buffers. This feature can be enabled using the HCD_LOCAL_MEM flag. | ||
1123 | * For this to work properly the host controller code must first use the | ||
1124 | * function dma_declare_coherent_memory() to point out which memory area | ||
1125 | * that should be used for dma allocations. | ||
1126 | * | ||
1127 | * The HCD_LOCAL_MEM flag then tells the usb code to allocate all data for | ||
1128 | * dma using dma_alloc_coherent() which in turn allocates from the memory | ||
1129 | * area pointed out with dma_declare_coherent_memory(). | ||
1130 | * | ||
1131 | * So, to summarize... | ||
1132 | * | ||
1133 | * - We need "local" memory, canonical example being | ||
1134 | * a small SRAM on a discrete controller being the | ||
1135 | * only memory that the controller can read ... | ||
1136 | * (a) "normal" kernel memory is no good, and | ||
1137 | * (b) there's not enough to share | ||
1138 | * | ||
1139 | * - The only *portable* hook for such stuff in the | ||
1140 | * DMA framework is dma_declare_coherent_memory() | ||
1141 | * | ||
1142 | * - So we use that, even though the primary requirement | ||
1143 | * is that the memory be "local" (hence addressible | ||
1144 | * by that device), not "coherent". | ||
1145 | * | ||
1146 | */ | ||
1147 | |||
1148 | static int hcd_alloc_coherent(struct usb_bus *bus, | ||
1149 | gfp_t mem_flags, dma_addr_t *dma_handle, | ||
1150 | void **vaddr_handle, size_t size, | ||
1151 | enum dma_data_direction dir) | ||
1152 | { | ||
1153 | unsigned char *vaddr; | ||
1154 | |||
1155 | vaddr = hcd_buffer_alloc(bus, size + sizeof(vaddr), | ||
1156 | mem_flags, dma_handle); | ||
1157 | if (!vaddr) | ||
1158 | return -ENOMEM; | ||
1159 | |||
1160 | /* | ||
1161 | * Store the virtual address of the buffer at the end | ||
1162 | * of the allocated dma buffer. The size of the buffer | ||
1163 | * may be uneven so use unaligned functions instead | ||
1164 | * of just rounding up. It makes sense to optimize for | ||
1165 | * memory footprint over access speed since the amount | ||
1166 | * of memory available for dma may be limited. | ||
1167 | */ | ||
1168 | put_unaligned((unsigned long)*vaddr_handle, | ||
1169 | (unsigned long *)(vaddr + size)); | ||
1170 | |||
1171 | if (dir == DMA_TO_DEVICE) | ||
1172 | memcpy(vaddr, *vaddr_handle, size); | ||
1173 | |||
1174 | *vaddr_handle = vaddr; | ||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle, | ||
1179 | void **vaddr_handle, size_t size, | ||
1180 | enum dma_data_direction dir) | ||
1181 | { | ||
1182 | unsigned char *vaddr = *vaddr_handle; | ||
1183 | |||
1184 | vaddr = (void *)get_unaligned((unsigned long *)(vaddr + size)); | ||
1185 | |||
1186 | if (dir == DMA_FROM_DEVICE) | ||
1187 | memcpy(vaddr, *vaddr_handle, size); | ||
1188 | |||
1189 | hcd_buffer_free(bus, size + sizeof(vaddr), *vaddr_handle, *dma_handle); | ||
1190 | |||
1191 | *vaddr_handle = vaddr; | ||
1192 | *dma_handle = 0; | ||
1193 | } | ||
1194 | |||
1195 | static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | ||
1196 | gfp_t mem_flags) | ||
1116 | { | 1197 | { |
1198 | enum dma_data_direction dir; | ||
1199 | int ret = 0; | ||
1200 | |||
1117 | /* Map the URB's buffers for DMA access. | 1201 | /* Map the URB's buffers for DMA access. |
1118 | * Lower level HCD code should use *_dma exclusively, | 1202 | * Lower level HCD code should use *_dma exclusively, |
1119 | * unless it uses pio or talks to another transport. | 1203 | * unless it uses pio or talks to another transport. |
1120 | */ | 1204 | */ |
1121 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { | 1205 | if (is_root_hub(urb->dev)) |
1122 | if (usb_endpoint_xfer_control(&urb->ep->desc) | 1206 | return 0; |
1123 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 1207 | |
1124 | urb->setup_dma = dma_map_single ( | 1208 | if (usb_endpoint_xfer_control(&urb->ep->desc) |
1209 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
1210 | if (hcd->self.uses_dma) | ||
1211 | urb->setup_dma = dma_map_single( | ||
1125 | hcd->self.controller, | 1212 | hcd->self.controller, |
1126 | urb->setup_packet, | 1213 | urb->setup_packet, |
1127 | sizeof (struct usb_ctrlrequest), | 1214 | sizeof(struct usb_ctrlrequest), |
1215 | DMA_TO_DEVICE); | ||
1216 | else if (hcd->driver->flags & HCD_LOCAL_MEM) | ||
1217 | ret = hcd_alloc_coherent( | ||
1218 | urb->dev->bus, mem_flags, | ||
1219 | &urb->setup_dma, | ||
1220 | (void **)&urb->setup_packet, | ||
1221 | sizeof(struct usb_ctrlrequest), | ||
1128 | DMA_TO_DEVICE); | 1222 | DMA_TO_DEVICE); |
1129 | if (urb->transfer_buffer_length != 0 | 1223 | } |
1130 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) | 1224 | |
1225 | dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
1226 | if (ret == 0 && urb->transfer_buffer_length != 0 | ||
1227 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { | ||
1228 | if (hcd->self.uses_dma) | ||
1131 | urb->transfer_dma = dma_map_single ( | 1229 | urb->transfer_dma = dma_map_single ( |
1132 | hcd->self.controller, | 1230 | hcd->self.controller, |
1133 | urb->transfer_buffer, | 1231 | urb->transfer_buffer, |
1134 | urb->transfer_buffer_length, | 1232 | urb->transfer_buffer_length, |
1135 | usb_urb_dir_in(urb) | 1233 | dir); |
1136 | ? DMA_FROM_DEVICE | 1234 | else if (hcd->driver->flags & HCD_LOCAL_MEM) { |
1137 | : DMA_TO_DEVICE); | 1235 | ret = hcd_alloc_coherent( |
1236 | urb->dev->bus, mem_flags, | ||
1237 | &urb->transfer_dma, | ||
1238 | &urb->transfer_buffer, | ||
1239 | urb->transfer_buffer_length, | ||
1240 | dir); | ||
1241 | |||
1242 | if (ret && usb_endpoint_xfer_control(&urb->ep->desc) | ||
1243 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | ||
1244 | hcd_free_coherent(urb->dev->bus, | ||
1245 | &urb->setup_dma, | ||
1246 | (void **)&urb->setup_packet, | ||
1247 | sizeof(struct usb_ctrlrequest), | ||
1248 | DMA_TO_DEVICE); | ||
1249 | } | ||
1138 | } | 1250 | } |
1251 | return ret; | ||
1139 | } | 1252 | } |
1140 | 1253 | ||
1141 | static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) | 1254 | static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) |
1142 | { | 1255 | { |
1143 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { | 1256 | enum dma_data_direction dir; |
1144 | if (usb_endpoint_xfer_control(&urb->ep->desc) | 1257 | |
1145 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 1258 | if (is_root_hub(urb->dev)) |
1259 | return; | ||
1260 | |||
1261 | if (usb_endpoint_xfer_control(&urb->ep->desc) | ||
1262 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
1263 | if (hcd->self.uses_dma) | ||
1146 | dma_unmap_single(hcd->self.controller, urb->setup_dma, | 1264 | dma_unmap_single(hcd->self.controller, urb->setup_dma, |
1147 | sizeof(struct usb_ctrlrequest), | 1265 | sizeof(struct usb_ctrlrequest), |
1148 | DMA_TO_DEVICE); | 1266 | DMA_TO_DEVICE); |
1149 | if (urb->transfer_buffer_length != 0 | 1267 | else if (hcd->driver->flags & HCD_LOCAL_MEM) |
1150 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) | 1268 | hcd_free_coherent(urb->dev->bus, &urb->setup_dma, |
1269 | (void **)&urb->setup_packet, | ||
1270 | sizeof(struct usb_ctrlrequest), | ||
1271 | DMA_TO_DEVICE); | ||
1272 | } | ||
1273 | |||
1274 | dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
1275 | if (urb->transfer_buffer_length != 0 | ||
1276 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { | ||
1277 | if (hcd->self.uses_dma) | ||
1151 | dma_unmap_single(hcd->self.controller, | 1278 | dma_unmap_single(hcd->self.controller, |
1152 | urb->transfer_dma, | 1279 | urb->transfer_dma, |
1153 | urb->transfer_buffer_length, | 1280 | urb->transfer_buffer_length, |
1154 | usb_urb_dir_in(urb) | 1281 | dir); |
1155 | ? DMA_FROM_DEVICE | 1282 | else if (hcd->driver->flags & HCD_LOCAL_MEM) |
1156 | : DMA_TO_DEVICE); | 1283 | hcd_free_coherent(urb->dev->bus, &urb->transfer_dma, |
1284 | &urb->transfer_buffer, | ||
1285 | urb->transfer_buffer_length, | ||
1286 | dir); | ||
1157 | } | 1287 | } |
1158 | } | 1288 | } |
1159 | 1289 | ||
@@ -1185,7 +1315,12 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
1185 | * URBs must be submitted in process context with interrupts | 1315 | * URBs must be submitted in process context with interrupts |
1186 | * enabled. | 1316 | * enabled. |
1187 | */ | 1317 | */ |
1188 | map_urb_for_dma(hcd, urb); | 1318 | status = map_urb_for_dma(hcd, urb, mem_flags); |
1319 | if (unlikely(status)) { | ||
1320 | usbmon_urb_submit_error(&hcd->self, urb, status); | ||
1321 | goto error; | ||
1322 | } | ||
1323 | |||
1189 | if (is_root_hub(urb->dev)) | 1324 | if (is_root_hub(urb->dev)) |
1190 | status = rh_urb_enqueue(hcd, urb); | 1325 | status = rh_urb_enqueue(hcd, urb); |
1191 | else | 1326 | else |
@@ -1194,6 +1329,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
1194 | if (unlikely(status)) { | 1329 | if (unlikely(status)) { |
1195 | usbmon_urb_submit_error(&hcd->self, urb, status); | 1330 | usbmon_urb_submit_error(&hcd->self, urb, status); |
1196 | unmap_urb_for_dma(hcd, urb); | 1331 | unmap_urb_for_dma(hcd, urb); |
1332 | error: | ||
1197 | urb->hcpriv = NULL; | 1333 | urb->hcpriv = NULL; |
1198 | INIT_LIST_HEAD(&urb->urb_list); | 1334 | INIT_LIST_HEAD(&urb->urb_list); |
1199 | atomic_dec(&urb->use_count); | 1335 | atomic_dec(&urb->use_count); |
@@ -1291,7 +1427,7 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1291 | wake_up (&usb_kill_urb_queue); | 1427 | wake_up (&usb_kill_urb_queue); |
1292 | usb_put_urb (urb); | 1428 | usb_put_urb (urb); |
1293 | } | 1429 | } |
1294 | EXPORT_SYMBOL (usb_hcd_giveback_urb); | 1430 | EXPORT_SYMBOL_GPL(usb_hcd_giveback_urb); |
1295 | 1431 | ||
1296 | /*-------------------------------------------------------------------------*/ | 1432 | /*-------------------------------------------------------------------------*/ |
1297 | 1433 | ||
@@ -1531,7 +1667,7 @@ int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num) | |||
1531 | mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(10)); | 1667 | mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(10)); |
1532 | return status; | 1668 | return status; |
1533 | } | 1669 | } |
1534 | EXPORT_SYMBOL (usb_bus_start_enum); | 1670 | EXPORT_SYMBOL_GPL(usb_bus_start_enum); |
1535 | 1671 | ||
1536 | #endif | 1672 | #endif |
1537 | 1673 | ||
@@ -1638,7 +1774,7 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, | |||
1638 | "USB Host Controller"; | 1774 | "USB Host Controller"; |
1639 | return hcd; | 1775 | return hcd; |
1640 | } | 1776 | } |
1641 | EXPORT_SYMBOL (usb_create_hcd); | 1777 | EXPORT_SYMBOL_GPL(usb_create_hcd); |
1642 | 1778 | ||
1643 | static void hcd_release (struct kref *kref) | 1779 | static void hcd_release (struct kref *kref) |
1644 | { | 1780 | { |
@@ -1653,14 +1789,14 @@ struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd) | |||
1653 | kref_get (&hcd->kref); | 1789 | kref_get (&hcd->kref); |
1654 | return hcd; | 1790 | return hcd; |
1655 | } | 1791 | } |
1656 | EXPORT_SYMBOL (usb_get_hcd); | 1792 | EXPORT_SYMBOL_GPL(usb_get_hcd); |
1657 | 1793 | ||
1658 | void usb_put_hcd (struct usb_hcd *hcd) | 1794 | void usb_put_hcd (struct usb_hcd *hcd) |
1659 | { | 1795 | { |
1660 | if (hcd) | 1796 | if (hcd) |
1661 | kref_put (&hcd->kref, hcd_release); | 1797 | kref_put (&hcd->kref, hcd_release); |
1662 | } | 1798 | } |
1663 | EXPORT_SYMBOL (usb_put_hcd); | 1799 | EXPORT_SYMBOL_GPL(usb_put_hcd); |
1664 | 1800 | ||
1665 | /** | 1801 | /** |
1666 | * usb_add_hcd - finish generic HCD structure initialization and register | 1802 | * usb_add_hcd - finish generic HCD structure initialization and register |
@@ -1786,7 +1922,7 @@ err_register_bus: | |||
1786 | hcd_buffer_destroy(hcd); | 1922 | hcd_buffer_destroy(hcd); |
1787 | return retval; | 1923 | return retval; |
1788 | } | 1924 | } |
1789 | EXPORT_SYMBOL (usb_add_hcd); | 1925 | EXPORT_SYMBOL_GPL(usb_add_hcd); |
1790 | 1926 | ||
1791 | /** | 1927 | /** |
1792 | * usb_remove_hcd - shutdown processing for generic HCDs | 1928 | * usb_remove_hcd - shutdown processing for generic HCDs |
@@ -1828,7 +1964,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
1828 | usb_deregister_bus(&hcd->self); | 1964 | usb_deregister_bus(&hcd->self); |
1829 | hcd_buffer_destroy(hcd); | 1965 | hcd_buffer_destroy(hcd); |
1830 | } | 1966 | } |
1831 | EXPORT_SYMBOL (usb_remove_hcd); | 1967 | EXPORT_SYMBOL_GPL(usb_remove_hcd); |
1832 | 1968 | ||
1833 | void | 1969 | void |
1834 | usb_hcd_platform_shutdown(struct platform_device* dev) | 1970 | usb_hcd_platform_shutdown(struct platform_device* dev) |
@@ -1838,7 +1974,7 @@ usb_hcd_platform_shutdown(struct platform_device* dev) | |||
1838 | if (hcd->driver->shutdown) | 1974 | if (hcd->driver->shutdown) |
1839 | hcd->driver->shutdown(hcd); | 1975 | hcd->driver->shutdown(hcd); |
1840 | } | 1976 | } |
1841 | EXPORT_SYMBOL (usb_hcd_platform_shutdown); | 1977 | EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown); |
1842 | 1978 | ||
1843 | /*-------------------------------------------------------------------------*/ | 1979 | /*-------------------------------------------------------------------------*/ |
1844 | 1980 | ||
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 98e24194a4ab..2d1c3d5e47b8 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -125,7 +125,7 @@ struct usb_hcd { | |||
125 | 125 | ||
126 | /* more shared queuing code would be good; it should support | 126 | /* more shared queuing code would be good; it should support |
127 | * smarter scheduling, handle transaction translators, etc; | 127 | * smarter scheduling, handle transaction translators, etc; |
128 | * input size of periodic table to an interrupt scheduler. | 128 | * input size of periodic table to an interrupt scheduler. |
129 | * (ohci 32, uhci 1024, ehci 256/512/1024). | 129 | * (ohci 32, uhci 1024, ehci 256/512/1024). |
130 | */ | 130 | */ |
131 | 131 | ||
@@ -133,16 +133,16 @@ struct usb_hcd { | |||
133 | * this structure. | 133 | * this structure. |
134 | */ | 134 | */ |
135 | unsigned long hcd_priv[0] | 135 | unsigned long hcd_priv[0] |
136 | __attribute__ ((aligned (sizeof(unsigned long)))); | 136 | __attribute__ ((aligned(sizeof(unsigned long)))); |
137 | }; | 137 | }; |
138 | 138 | ||
139 | /* 2.4 does this a bit differently ... */ | 139 | /* 2.4 does this a bit differently ... */ |
140 | static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd) | 140 | static inline struct usb_bus *hcd_to_bus(struct usb_hcd *hcd) |
141 | { | 141 | { |
142 | return &hcd->self; | 142 | return &hcd->self; |
143 | } | 143 | } |
144 | 144 | ||
145 | static inline struct usb_hcd *bus_to_hcd (struct usb_bus *bus) | 145 | static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus) |
146 | { | 146 | { |
147 | return container_of(bus, struct usb_hcd, self); | 147 | return container_of(bus, struct usb_hcd, self); |
148 | } | 148 | } |
@@ -165,6 +165,7 @@ struct hc_driver { | |||
165 | 165 | ||
166 | int flags; | 166 | int flags; |
167 | #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ | 167 | #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ |
168 | #define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */ | ||
168 | #define HCD_USB11 0x0010 /* USB 1.1 */ | 169 | #define HCD_USB11 0x0010 /* USB 1.1 */ |
169 | #define HCD_USB2 0x0020 /* USB 2.0 */ | 170 | #define HCD_USB2 0x0020 /* USB 2.0 */ |
170 | 171 | ||
@@ -201,15 +202,18 @@ struct hc_driver { | |||
201 | struct usb_host_endpoint *ep); | 202 | struct usb_host_endpoint *ep); |
202 | 203 | ||
203 | /* root hub support */ | 204 | /* root hub support */ |
204 | int (*hub_status_data) (struct usb_hcd *hcd, char *buf); | 205 | int (*hub_status_data) (struct usb_hcd *hcd, char *buf); |
205 | int (*hub_control) (struct usb_hcd *hcd, | 206 | int (*hub_control) (struct usb_hcd *hcd, |
206 | u16 typeReq, u16 wValue, u16 wIndex, | 207 | u16 typeReq, u16 wValue, u16 wIndex, |
207 | char *buf, u16 wLength); | 208 | char *buf, u16 wLength); |
208 | int (*bus_suspend)(struct usb_hcd *); | 209 | int (*bus_suspend)(struct usb_hcd *); |
209 | int (*bus_resume)(struct usb_hcd *); | 210 | int (*bus_resume)(struct usb_hcd *); |
210 | int (*start_port_reset)(struct usb_hcd *, unsigned port_num); | 211 | int (*start_port_reset)(struct usb_hcd *, unsigned port_num); |
211 | void (*hub_irq_enable)(struct usb_hcd *); | 212 | void (*hub_irq_enable)(struct usb_hcd *); |
212 | /* Needed only if port-change IRQs are level-triggered */ | 213 | /* Needed only if port-change IRQs are level-triggered */ |
214 | |||
215 | /* force handover of high-speed port to full-speed companion */ | ||
216 | void (*relinquish_port)(struct usb_hcd *, int); | ||
213 | }; | 217 | }; |
214 | 218 | ||
215 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | 219 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
@@ -217,56 +221,56 @@ extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | |||
217 | int status); | 221 | int status); |
218 | extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb); | 222 | extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb); |
219 | 223 | ||
220 | extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); | 224 | extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags); |
221 | extern int usb_hcd_unlink_urb (struct urb *urb, int status); | 225 | extern int usb_hcd_unlink_urb(struct urb *urb, int status); |
222 | extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, | 226 | extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, |
223 | int status); | 227 | int status); |
224 | extern void usb_hcd_flush_endpoint(struct usb_device *udev, | 228 | extern void usb_hcd_flush_endpoint(struct usb_device *udev, |
225 | struct usb_host_endpoint *ep); | 229 | struct usb_host_endpoint *ep); |
226 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, | 230 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, |
227 | struct usb_host_endpoint *ep); | 231 | struct usb_host_endpoint *ep); |
228 | extern int usb_hcd_get_frame_number (struct usb_device *udev); | 232 | extern int usb_hcd_get_frame_number(struct usb_device *udev); |
229 | 233 | ||
230 | extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, | 234 | extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, |
231 | struct device *dev, char *bus_name); | 235 | struct device *dev, char *bus_name); |
232 | extern struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd); | 236 | extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd); |
233 | extern void usb_put_hcd (struct usb_hcd *hcd); | 237 | extern void usb_put_hcd(struct usb_hcd *hcd); |
234 | extern int usb_add_hcd(struct usb_hcd *hcd, | 238 | extern int usb_add_hcd(struct usb_hcd *hcd, |
235 | unsigned int irqnum, unsigned long irqflags); | 239 | unsigned int irqnum, unsigned long irqflags); |
236 | extern void usb_remove_hcd(struct usb_hcd *hcd); | 240 | extern void usb_remove_hcd(struct usb_hcd *hcd); |
237 | 241 | ||
238 | struct platform_device; | 242 | struct platform_device; |
239 | extern void usb_hcd_platform_shutdown(struct platform_device* dev); | 243 | extern void usb_hcd_platform_shutdown(struct platform_device *dev); |
240 | 244 | ||
241 | #ifdef CONFIG_PCI | 245 | #ifdef CONFIG_PCI |
242 | struct pci_dev; | 246 | struct pci_dev; |
243 | struct pci_device_id; | 247 | struct pci_device_id; |
244 | extern int usb_hcd_pci_probe (struct pci_dev *dev, | 248 | extern int usb_hcd_pci_probe(struct pci_dev *dev, |
245 | const struct pci_device_id *id); | 249 | const struct pci_device_id *id); |
246 | extern void usb_hcd_pci_remove (struct pci_dev *dev); | 250 | extern void usb_hcd_pci_remove(struct pci_dev *dev); |
247 | 251 | ||
248 | #ifdef CONFIG_PM | 252 | #ifdef CONFIG_PM |
249 | extern int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t state); | 253 | extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t state); |
250 | extern int usb_hcd_pci_resume (struct pci_dev *dev); | 254 | extern int usb_hcd_pci_resume(struct pci_dev *dev); |
251 | #endif /* CONFIG_PM */ | 255 | #endif /* CONFIG_PM */ |
252 | 256 | ||
253 | extern void usb_hcd_pci_shutdown (struct pci_dev *dev); | 257 | extern void usb_hcd_pci_shutdown(struct pci_dev *dev); |
254 | 258 | ||
255 | #endif /* CONFIG_PCI */ | 259 | #endif /* CONFIG_PCI */ |
256 | 260 | ||
257 | /* pci-ish (pdev null is ok) buffer alloc/mapping support */ | 261 | /* pci-ish (pdev null is ok) buffer alloc/mapping support */ |
258 | int hcd_buffer_create (struct usb_hcd *hcd); | 262 | int hcd_buffer_create(struct usb_hcd *hcd); |
259 | void hcd_buffer_destroy (struct usb_hcd *hcd); | 263 | void hcd_buffer_destroy(struct usb_hcd *hcd); |
260 | 264 | ||
261 | void *hcd_buffer_alloc (struct usb_bus *bus, size_t size, | 265 | void *hcd_buffer_alloc(struct usb_bus *bus, size_t size, |
262 | gfp_t mem_flags, dma_addr_t *dma); | 266 | gfp_t mem_flags, dma_addr_t *dma); |
263 | void hcd_buffer_free (struct usb_bus *bus, size_t size, | 267 | void hcd_buffer_free(struct usb_bus *bus, size_t size, |
264 | void *addr, dma_addr_t dma); | 268 | void *addr, dma_addr_t dma); |
265 | 269 | ||
266 | /* generic bus glue, needed for host controllers that don't use PCI */ | 270 | /* generic bus glue, needed for host controllers that don't use PCI */ |
267 | extern irqreturn_t usb_hcd_irq (int irq, void *__hcd); | 271 | extern irqreturn_t usb_hcd_irq(int irq, void *__hcd); |
268 | 272 | ||
269 | extern void usb_hc_died (struct usb_hcd *hcd); | 273 | extern void usb_hc_died(struct usb_hcd *hcd); |
270 | extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); | 274 | extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); |
271 | 275 | ||
272 | /* -------------------------------------------------------------------------- */ | 276 | /* -------------------------------------------------------------------------- */ |
@@ -319,9 +323,9 @@ extern void usb_destroy_configuration(struct usb_device *dev); | |||
319 | * Generic bandwidth allocation constants/support | 323 | * Generic bandwidth allocation constants/support |
320 | */ | 324 | */ |
321 | #define FRAME_TIME_USECS 1000L | 325 | #define FRAME_TIME_USECS 1000L |
322 | #define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */ | 326 | #define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */ |
323 | /* Trying not to use worst-case bit-stuffing | 327 | /* Trying not to use worst-case bit-stuffing |
324 | of (7/6 * 8 * bytecount) = 9.33 * bytecount */ | 328 | * of (7/6 * 8 * bytecount) = 9.33 * bytecount */ |
325 | /* bytecount = data payload byte count */ | 329 | /* bytecount = data payload byte count */ |
326 | 330 | ||
327 | #define NS_TO_US(ns) ((ns + 500L) / 1000L) | 331 | #define NS_TO_US(ns) ((ns + 500L) / 1000L) |
@@ -333,9 +337,9 @@ extern void usb_destroy_configuration(struct usb_device *dev); | |||
333 | */ | 337 | */ |
334 | #define BW_HOST_DELAY 1000L /* nanoseconds */ | 338 | #define BW_HOST_DELAY 1000L /* nanoseconds */ |
335 | #define BW_HUB_LS_SETUP 333L /* nanoseconds */ | 339 | #define BW_HUB_LS_SETUP 333L /* nanoseconds */ |
336 | /* 4 full-speed bit times (est.) */ | 340 | /* 4 full-speed bit times (est.) */ |
337 | 341 | ||
338 | #define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */ | 342 | #define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */ |
339 | #define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) | 343 | #define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) |
340 | #define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) | 344 | #define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) |
341 | 345 | ||
@@ -345,16 +349,16 @@ extern void usb_destroy_configuration(struct usb_device *dev); | |||
345 | * to preallocate bandwidth) | 349 | * to preallocate bandwidth) |
346 | */ | 350 | */ |
347 | #define USB2_HOST_DELAY 5 /* nsec, guess */ | 351 | #define USB2_HOST_DELAY 5 /* nsec, guess */ |
348 | #define HS_NSECS(bytes) ( ((55 * 8 * 2083) \ | 352 | #define HS_NSECS(bytes) (((55 * 8 * 2083) \ |
349 | + (2083UL * (3 + BitTime(bytes))))/1000 \ | 353 | + (2083UL * (3 + BitTime(bytes))))/1000 \ |
350 | + USB2_HOST_DELAY) | 354 | + USB2_HOST_DELAY) |
351 | #define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083) \ | 355 | #define HS_NSECS_ISO(bytes) (((38 * 8 * 2083) \ |
352 | + (2083UL * (3 + BitTime(bytes))))/1000 \ | 356 | + (2083UL * (3 + BitTime(bytes))))/1000 \ |
353 | + USB2_HOST_DELAY) | 357 | + USB2_HOST_DELAY) |
354 | #define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes)) | 358 | #define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes)) |
355 | #define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes)) | 359 | #define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes)) |
356 | 360 | ||
357 | extern long usb_calc_bus_time (int speed, int is_input, | 361 | extern long usb_calc_bus_time(int speed, int is_input, |
358 | int isoc, int bytecount); | 362 | int isoc, int bytecount); |
359 | 363 | ||
360 | /*-------------------------------------------------------------------------*/ | 364 | /*-------------------------------------------------------------------------*/ |
@@ -370,16 +374,16 @@ extern struct list_head usb_bus_list; | |||
370 | extern struct mutex usb_bus_list_lock; | 374 | extern struct mutex usb_bus_list_lock; |
371 | extern wait_queue_head_t usb_kill_urb_queue; | 375 | extern wait_queue_head_t usb_kill_urb_queue; |
372 | 376 | ||
373 | extern void usb_enable_root_hub_irq (struct usb_bus *bus); | 377 | extern void usb_enable_root_hub_irq(struct usb_bus *bus); |
374 | 378 | ||
375 | extern int usb_find_interface_driver (struct usb_device *dev, | 379 | extern int usb_find_interface_driver(struct usb_device *dev, |
376 | struct usb_interface *interface); | 380 | struct usb_interface *interface); |
377 | 381 | ||
378 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) | 382 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) |
379 | 383 | ||
380 | #ifdef CONFIG_PM | 384 | #ifdef CONFIG_PM |
381 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); | 385 | extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd); |
382 | extern void usb_root_hub_lost_power (struct usb_device *rhdev); | 386 | extern void usb_root_hub_lost_power(struct usb_device *rhdev); |
383 | extern int hcd_bus_suspend(struct usb_device *rhdev); | 387 | extern int hcd_bus_suspend(struct usb_device *rhdev); |
384 | extern int hcd_bus_resume(struct usb_device *rhdev); | 388 | extern int hcd_bus_resume(struct usb_device *rhdev); |
385 | #else | 389 | #else |
@@ -399,13 +403,13 @@ static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) | |||
399 | * these are expected to be called from the USB core/hub thread | 403 | * these are expected to be called from the USB core/hub thread |
400 | * with the kernel lock held | 404 | * with the kernel lock held |
401 | */ | 405 | */ |
402 | extern void usbfs_update_special (void); | 406 | extern void usbfs_update_special(void); |
403 | extern int usbfs_init(void); | 407 | extern int usbfs_init(void); |
404 | extern void usbfs_cleanup(void); | 408 | extern void usbfs_cleanup(void); |
405 | 409 | ||
406 | #else /* CONFIG_USB_DEVICEFS */ | 410 | #else /* CONFIG_USB_DEVICEFS */ |
407 | 411 | ||
408 | static inline void usbfs_update_special (void) {} | 412 | static inline void usbfs_update_special(void) {} |
409 | static inline int usbfs_init(void) { return 0; } | 413 | static inline int usbfs_init(void) { return 0; } |
410 | static inline void usbfs_cleanup(void) { } | 414 | static inline void usbfs_cleanup(void) { } |
411 | 415 | ||
@@ -460,7 +464,7 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, | |||
460 | /*-------------------------------------------------------------------------*/ | 464 | /*-------------------------------------------------------------------------*/ |
461 | 465 | ||
462 | /* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */ | 466 | /* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */ |
463 | // bleech -- resurfaced in 2.4.11 or 2.4.12 | 467 | /* bleech -- resurfaced in 2.4.11 or 2.4.12 */ |
464 | #define bitmap DeviceRemovable | 468 | #define bitmap DeviceRemovable |
465 | 469 | ||
466 | 470 | ||
@@ -468,8 +472,8 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, | |||
468 | 472 | ||
469 | /* random stuff */ | 473 | /* random stuff */ |
470 | 474 | ||
471 | #define RUN_CONTEXT (in_irq () ? "in_irq" \ | 475 | #define RUN_CONTEXT (in_irq() ? "in_irq" \ |
472 | : (in_interrupt () ? "in_interrupt" : "can sleep")) | 476 | : (in_interrupt() ? "in_interrupt" : "can sleep")) |
473 | 477 | ||
474 | 478 | ||
475 | /* This rwsem is for use only by the hub driver and ehci-hcd. | 479 | /* This rwsem is for use only by the hub driver and ehci-hcd. |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b04d232d4c65..68fc5219ca15 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -37,6 +37,13 @@ | |||
37 | #define USB_PERSIST 0 | 37 | #define USB_PERSIST 0 |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | /* if we are in debug mode, always announce new devices */ | ||
41 | #ifdef DEBUG | ||
42 | #ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES | ||
43 | #define CONFIG_USB_ANNOUNCE_NEW_DEVICES | ||
44 | #endif | ||
45 | #endif | ||
46 | |||
40 | struct usb_hub { | 47 | struct usb_hub { |
41 | struct device *intfdev; /* the "interface" device */ | 48 | struct device *intfdev; /* the "interface" device */ |
42 | struct usb_device *hdev; | 49 | struct usb_device *hdev; |
@@ -487,6 +494,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
487 | schedule_work (&tt->kevent); | 494 | schedule_work (&tt->kevent); |
488 | spin_unlock_irqrestore (&tt->lock, flags); | 495 | spin_unlock_irqrestore (&tt->lock, flags); |
489 | } | 496 | } |
497 | EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer); | ||
490 | 498 | ||
491 | static void hub_power_on(struct usb_hub *hub) | 499 | static void hub_power_on(struct usb_hub *hub) |
492 | { | 500 | { |
@@ -1027,8 +1035,10 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev) | |||
1027 | if (udev->children[i]) | 1035 | if (udev->children[i]) |
1028 | recursively_mark_NOTATTACHED(udev->children[i]); | 1036 | recursively_mark_NOTATTACHED(udev->children[i]); |
1029 | } | 1037 | } |
1030 | if (udev->state == USB_STATE_SUSPENDED) | 1038 | if (udev->state == USB_STATE_SUSPENDED) { |
1031 | udev->discon_suspended = 1; | 1039 | udev->discon_suspended = 1; |
1040 | udev->active_duration -= jiffies; | ||
1041 | } | ||
1032 | udev->state = USB_STATE_NOTATTACHED; | 1042 | udev->state = USB_STATE_NOTATTACHED; |
1033 | } | 1043 | } |
1034 | 1044 | ||
@@ -1077,6 +1087,12 @@ void usb_set_device_state(struct usb_device *udev, | |||
1077 | else | 1087 | else |
1078 | device_init_wakeup(&udev->dev, 0); | 1088 | device_init_wakeup(&udev->dev, 0); |
1079 | } | 1089 | } |
1090 | if (udev->state == USB_STATE_SUSPENDED && | ||
1091 | new_state != USB_STATE_SUSPENDED) | ||
1092 | udev->active_duration -= jiffies; | ||
1093 | else if (new_state == USB_STATE_SUSPENDED && | ||
1094 | udev->state != USB_STATE_SUSPENDED) | ||
1095 | udev->active_duration += jiffies; | ||
1080 | udev->state = new_state; | 1096 | udev->state = new_state; |
1081 | } else | 1097 | } else |
1082 | recursively_mark_NOTATTACHED(udev); | 1098 | recursively_mark_NOTATTACHED(udev); |
@@ -1207,7 +1223,7 @@ void usb_disconnect(struct usb_device **pdev) | |||
1207 | put_device(&udev->dev); | 1223 | put_device(&udev->dev); |
1208 | } | 1224 | } |
1209 | 1225 | ||
1210 | #ifdef DEBUG | 1226 | #ifdef CONFIG_USB_ANNOUNCE_NEW_DEVICES |
1211 | static void show_string(struct usb_device *udev, char *id, char *string) | 1227 | static void show_string(struct usb_device *udev, char *id, char *string) |
1212 | { | 1228 | { |
1213 | if (!string) | 1229 | if (!string) |
@@ -1215,12 +1231,24 @@ static void show_string(struct usb_device *udev, char *id, char *string) | |||
1215 | dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, string); | 1231 | dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, string); |
1216 | } | 1232 | } |
1217 | 1233 | ||
1234 | static void announce_device(struct usb_device *udev) | ||
1235 | { | ||
1236 | dev_info(&udev->dev, "New USB device found, idVendor=%04x, idProduct=%04x\n", | ||
1237 | le16_to_cpu(udev->descriptor.idVendor), | ||
1238 | le16_to_cpu(udev->descriptor.idProduct)); | ||
1239 | dev_info(&udev->dev, "New USB device strings: Mfr=%d, Product=%d, " | ||
1240 | "SerialNumber=%d\n", | ||
1241 | udev->descriptor.iManufacturer, | ||
1242 | udev->descriptor.iProduct, | ||
1243 | udev->descriptor.iSerialNumber); | ||
1244 | show_string(udev, "Product", udev->product); | ||
1245 | show_string(udev, "Manufacturer", udev->manufacturer); | ||
1246 | show_string(udev, "SerialNumber", udev->serial); | ||
1247 | } | ||
1218 | #else | 1248 | #else |
1219 | static inline void show_string(struct usb_device *udev, char *id, char *string) | 1249 | static inline void announce_device(struct usb_device *udev) { } |
1220 | {} | ||
1221 | #endif | 1250 | #endif |
1222 | 1251 | ||
1223 | |||
1224 | #ifdef CONFIG_USB_OTG | 1252 | #ifdef CONFIG_USB_OTG |
1225 | #include "otg_whitelist.h" | 1253 | #include "otg_whitelist.h" |
1226 | #endif | 1254 | #endif |
@@ -1390,14 +1418,7 @@ int usb_new_device(struct usb_device *udev) | |||
1390 | } | 1418 | } |
1391 | 1419 | ||
1392 | /* Tell the world! */ | 1420 | /* Tell the world! */ |
1393 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " | 1421 | announce_device(udev); |
1394 | "SerialNumber=%d\n", | ||
1395 | udev->descriptor.iManufacturer, | ||
1396 | udev->descriptor.iProduct, | ||
1397 | udev->descriptor.iSerialNumber); | ||
1398 | show_string(udev, "Product", udev->product); | ||
1399 | show_string(udev, "Manufacturer", udev->manufacturer); | ||
1400 | show_string(udev, "SerialNumber", udev->serial); | ||
1401 | return err; | 1422 | return err; |
1402 | 1423 | ||
1403 | fail: | 1424 | fail: |
@@ -2482,6 +2503,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2482 | { | 2503 | { |
2483 | struct usb_device *hdev = hub->hdev; | 2504 | struct usb_device *hdev = hub->hdev; |
2484 | struct device *hub_dev = hub->intfdev; | 2505 | struct device *hub_dev = hub->intfdev; |
2506 | struct usb_hcd *hcd = bus_to_hcd(hdev->bus); | ||
2485 | u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | 2507 | u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); |
2486 | int status, i; | 2508 | int status, i; |
2487 | 2509 | ||
@@ -2645,6 +2667,8 @@ loop: | |||
2645 | 2667 | ||
2646 | done: | 2668 | done: |
2647 | hub_port_disable(hub, port1, 1); | 2669 | hub_port_disable(hub, port1, 1); |
2670 | if (hcd->driver->relinquish_port && !hub->hdev->parent) | ||
2671 | hcd->driver->relinquish_port(hcd, port1); | ||
2648 | } | 2672 | } |
2649 | 2673 | ||
2650 | static void hub_events(void) | 2674 | static void hub_events(void) |
@@ -2946,7 +2970,7 @@ static int config_descriptors_changed(struct usb_device *udev) | |||
2946 | if (len < le16_to_cpu(udev->config[index].desc.wTotalLength)) | 2970 | if (len < le16_to_cpu(udev->config[index].desc.wTotalLength)) |
2947 | len = le16_to_cpu(udev->config[index].desc.wTotalLength); | 2971 | len = le16_to_cpu(udev->config[index].desc.wTotalLength); |
2948 | } | 2972 | } |
2949 | buf = kmalloc (len, GFP_KERNEL); | 2973 | buf = kmalloc(len, GFP_NOIO); |
2950 | if (buf == NULL) { | 2974 | if (buf == NULL) { |
2951 | dev_err(&udev->dev, "no mem to re-read configs after reset\n"); | 2975 | dev_err(&udev->dev, "no mem to re-read configs after reset\n"); |
2952 | /* assume the worst */ | 2976 | /* assume the worst */ |
@@ -3093,7 +3117,7 @@ re_enumerate: | |||
3093 | hub_port_logical_disconnect(parent_hub, port1); | 3117 | hub_port_logical_disconnect(parent_hub, port1); |
3094 | return -ENODEV; | 3118 | return -ENODEV; |
3095 | } | 3119 | } |
3096 | EXPORT_SYMBOL(usb_reset_device); | 3120 | EXPORT_SYMBOL_GPL(usb_reset_device); |
3097 | 3121 | ||
3098 | /** | 3122 | /** |
3099 | * usb_reset_composite_device - warn interface drivers and perform a USB port reset | 3123 | * usb_reset_composite_device - warn interface drivers and perform a USB port reset |
@@ -3110,16 +3134,12 @@ EXPORT_SYMBOL(usb_reset_device); | |||
3110 | * this from a driver probe() routine after downloading new firmware. | 3134 | * this from a driver probe() routine after downloading new firmware. |
3111 | * For calls that might not occur during probe(), drivers should lock | 3135 | * For calls that might not occur during probe(), drivers should lock |
3112 | * the device using usb_lock_device_for_reset(). | 3136 | * the device using usb_lock_device_for_reset(). |
3113 | * | ||
3114 | * The interface locks are acquired during the pre_reset stage and released | ||
3115 | * during the post_reset stage. However if iface is not NULL and is | ||
3116 | * currently being probed, we assume that the caller already owns its | ||
3117 | * lock. | ||
3118 | */ | 3137 | */ |
3119 | int usb_reset_composite_device(struct usb_device *udev, | 3138 | int usb_reset_composite_device(struct usb_device *udev, |
3120 | struct usb_interface *iface) | 3139 | struct usb_interface *iface) |
3121 | { | 3140 | { |
3122 | int ret; | 3141 | int ret; |
3142 | int i; | ||
3123 | struct usb_host_config *config = udev->actconfig; | 3143 | struct usb_host_config *config = udev->actconfig; |
3124 | 3144 | ||
3125 | if (udev->state == USB_STATE_NOTATTACHED || | 3145 | if (udev->state == USB_STATE_NOTATTACHED || |
@@ -3136,16 +3156,11 @@ int usb_reset_composite_device(struct usb_device *udev, | |||
3136 | iface = NULL; | 3156 | iface = NULL; |
3137 | 3157 | ||
3138 | if (config) { | 3158 | if (config) { |
3139 | int i; | ||
3140 | struct usb_interface *cintf; | ||
3141 | struct usb_driver *drv; | ||
3142 | |||
3143 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { | 3159 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { |
3144 | cintf = config->interface[i]; | 3160 | struct usb_interface *cintf = config->interface[i]; |
3145 | if (cintf != iface) | 3161 | struct usb_driver *drv; |
3146 | down(&cintf->dev.sem); | 3162 | |
3147 | if (device_is_registered(&cintf->dev) && | 3163 | if (cintf->dev.driver) { |
3148 | cintf->dev.driver) { | ||
3149 | drv = to_usb_driver(cintf->dev.driver); | 3164 | drv = to_usb_driver(cintf->dev.driver); |
3150 | if (drv->pre_reset) | 3165 | if (drv->pre_reset) |
3151 | (drv->pre_reset)(cintf); | 3166 | (drv->pre_reset)(cintf); |
@@ -3157,25 +3172,20 @@ int usb_reset_composite_device(struct usb_device *udev, | |||
3157 | ret = usb_reset_device(udev); | 3172 | ret = usb_reset_device(udev); |
3158 | 3173 | ||
3159 | if (config) { | 3174 | if (config) { |
3160 | int i; | ||
3161 | struct usb_interface *cintf; | ||
3162 | struct usb_driver *drv; | ||
3163 | |||
3164 | for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) { | 3175 | for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) { |
3165 | cintf = config->interface[i]; | 3176 | struct usb_interface *cintf = config->interface[i]; |
3166 | if (device_is_registered(&cintf->dev) && | 3177 | struct usb_driver *drv; |
3167 | cintf->dev.driver) { | 3178 | |
3179 | if (cintf->dev.driver) { | ||
3168 | drv = to_usb_driver(cintf->dev.driver); | 3180 | drv = to_usb_driver(cintf->dev.driver); |
3169 | if (drv->post_reset) | 3181 | if (drv->post_reset) |
3170 | (drv->post_reset)(cintf); | 3182 | (drv->post_reset)(cintf); |
3171 | /* FIXME: Unbind if post_reset returns an error or isn't defined */ | 3183 | /* FIXME: Unbind if post_reset returns an error or isn't defined */ |
3172 | } | 3184 | } |
3173 | if (cintf != iface) | ||
3174 | up(&cintf->dev.sem); | ||
3175 | } | 3185 | } |
3176 | } | 3186 | } |
3177 | 3187 | ||
3178 | usb_autosuspend_device(udev); | 3188 | usb_autosuspend_device(udev); |
3179 | return ret; | 3189 | return ret; |
3180 | } | 3190 | } |
3181 | EXPORT_SYMBOL(usb_reset_composite_device); | 3191 | EXPORT_SYMBOL_GPL(usb_reset_composite_device); |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index cf9559c6c9b6..1551aed65e05 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -55,16 +55,16 @@ | |||
55 | #define USB_PORT_FEAT_TEST 21 | 55 | #define USB_PORT_FEAT_TEST 21 |
56 | #define USB_PORT_FEAT_INDICATOR 22 | 56 | #define USB_PORT_FEAT_INDICATOR 22 |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * Hub Status and Hub Change results | 59 | * Hub Status and Hub Change results |
60 | * See USB 2.0 spec Table 11-19 and Table 11-20 | 60 | * See USB 2.0 spec Table 11-19 and Table 11-20 |
61 | */ | 61 | */ |
62 | struct usb_port_status { | 62 | struct usb_port_status { |
63 | __le16 wPortStatus; | 63 | __le16 wPortStatus; |
64 | __le16 wPortChange; | 64 | __le16 wPortChange; |
65 | } __attribute__ ((packed)); | 65 | } __attribute__ ((packed)); |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * wPortStatus bit field | 68 | * wPortStatus bit field |
69 | * See USB 2.0 spec Table 11-21 | 69 | * See USB 2.0 spec Table 11-21 |
70 | */ | 70 | */ |
@@ -81,7 +81,7 @@ struct usb_port_status { | |||
81 | #define USB_PORT_STAT_INDICATOR 0x1000 | 81 | #define USB_PORT_STAT_INDICATOR 0x1000 |
82 | /* bits 13 to 15 are reserved */ | 82 | /* bits 13 to 15 are reserved */ |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * wPortChange bit field | 85 | * wPortChange bit field |
86 | * See USB 2.0 spec Table 11-22 | 86 | * See USB 2.0 spec Table 11-22 |
87 | * Bits 0 to 4 shown, bits 5 to 15 are reserved | 87 | * Bits 0 to 4 shown, bits 5 to 15 are reserved |
@@ -93,7 +93,7 @@ struct usb_port_status { | |||
93 | #define USB_PORT_STAT_C_RESET 0x0010 | 93 | #define USB_PORT_STAT_C_RESET 0x0010 |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * wHubCharacteristics (masks) | 96 | * wHubCharacteristics (masks) |
97 | * See USB 2.0 spec Table 11-13, offset 3 | 97 | * See USB 2.0 spec Table 11-13, offset 3 |
98 | */ | 98 | */ |
99 | #define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */ | 99 | #define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */ |
@@ -119,8 +119,8 @@ struct usb_hub_status { | |||
119 | #define HUB_CHANGE_OVERCURRENT 0x0002 | 119 | #define HUB_CHANGE_OVERCURRENT 0x0002 |
120 | 120 | ||
121 | 121 | ||
122 | /* | 122 | /* |
123 | * Hub descriptor | 123 | * Hub descriptor |
124 | * See USB 2.0 spec Table 11-13 | 124 | * See USB 2.0 spec Table 11-13 |
125 | */ | 125 | */ |
126 | 126 | ||
@@ -134,7 +134,7 @@ struct usb_hub_descriptor { | |||
134 | __le16 wHubCharacteristics; | 134 | __le16 wHubCharacteristics; |
135 | __u8 bPwrOn2PwrGood; | 135 | __u8 bPwrOn2PwrGood; |
136 | __u8 bHubContrCurrent; | 136 | __u8 bHubContrCurrent; |
137 | /* add 1 bit for hub status change; round to bytes */ | 137 | /* add 1 bit for hub status change; round to bytes */ |
138 | __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8]; | 138 | __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8]; |
139 | __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8]; | 139 | __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8]; |
140 | } __attribute__ ((packed)); | 140 | } __attribute__ ((packed)); |
@@ -190,6 +190,6 @@ struct usb_tt_clear { | |||
190 | u16 devinfo; | 190 | u16 devinfo; |
191 | }; | 191 | }; |
192 | 192 | ||
193 | extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe); | 193 | extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe); |
194 | 194 | ||
195 | #endif /* __LINUX_HUB_H */ | 195 | #endif /* __LINUX_HUB_H */ |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index cd4f11157280..83a373e9cc36 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -38,10 +38,15 @@ | |||
38 | #include <linux/usbdevice_fs.h> | 38 | #include <linux/usbdevice_fs.h> |
39 | #include <linux/parser.h> | 39 | #include <linux/parser.h> |
40 | #include <linux/notifier.h> | 40 | #include <linux/notifier.h> |
41 | #include <linux/seq_file.h> | ||
41 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
42 | #include "usb.h" | 43 | #include "usb.h" |
43 | #include "hcd.h" | 44 | #include "hcd.h" |
44 | 45 | ||
46 | #define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO) | ||
47 | #define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO) | ||
48 | #define USBFS_DEFAULT_LISTMODE S_IRUGO | ||
49 | |||
45 | static struct super_operations usbfs_ops; | 50 | static struct super_operations usbfs_ops; |
46 | static const struct file_operations default_file_operations; | 51 | static const struct file_operations default_file_operations; |
47 | static struct vfsmount *usbfs_mount; | 52 | static struct vfsmount *usbfs_mount; |
@@ -57,9 +62,33 @@ static uid_t listuid; /* = 0 */ | |||
57 | static gid_t devgid; /* = 0 */ | 62 | static gid_t devgid; /* = 0 */ |
58 | static gid_t busgid; /* = 0 */ | 63 | static gid_t busgid; /* = 0 */ |
59 | static gid_t listgid; /* = 0 */ | 64 | static gid_t listgid; /* = 0 */ |
60 | static umode_t devmode = S_IWUSR | S_IRUGO; | 65 | static umode_t devmode = USBFS_DEFAULT_DEVMODE; |
61 | static umode_t busmode = S_IXUGO | S_IRUGO; | 66 | static umode_t busmode = USBFS_DEFAULT_BUSMODE; |
62 | static umode_t listmode = S_IRUGO; | 67 | static umode_t listmode = USBFS_DEFAULT_LISTMODE; |
68 | |||
69 | static int usbfs_show_options(struct seq_file *seq, struct vfsmount *mnt) | ||
70 | { | ||
71 | if (devuid != 0) | ||
72 | seq_printf(seq, ",devuid=%u", devuid); | ||
73 | if (devgid != 0) | ||
74 | seq_printf(seq, ",devgid=%u", devgid); | ||
75 | if (devmode != USBFS_DEFAULT_DEVMODE) | ||
76 | seq_printf(seq, ",devmode=%o", devmode); | ||
77 | if (busuid != 0) | ||
78 | seq_printf(seq, ",busuid=%u", busuid); | ||
79 | if (busgid != 0) | ||
80 | seq_printf(seq, ",busgid=%u", busgid); | ||
81 | if (busmode != USBFS_DEFAULT_BUSMODE) | ||
82 | seq_printf(seq, ",busmode=%o", busmode); | ||
83 | if (listuid != 0) | ||
84 | seq_printf(seq, ",listuid=%u", listuid); | ||
85 | if (listgid != 0) | ||
86 | seq_printf(seq, ",listgid=%u", listgid); | ||
87 | if (listmode != USBFS_DEFAULT_LISTMODE) | ||
88 | seq_printf(seq, ",listmode=%o", listmode); | ||
89 | |||
90 | return 0; | ||
91 | } | ||
63 | 92 | ||
64 | enum { | 93 | enum { |
65 | Opt_devuid, Opt_devgid, Opt_devmode, | 94 | Opt_devuid, Opt_devgid, Opt_devmode, |
@@ -93,9 +122,9 @@ static int parse_options(struct super_block *s, char *data) | |||
93 | devgid = 0; | 122 | devgid = 0; |
94 | busgid = 0; | 123 | busgid = 0; |
95 | listgid = 0; | 124 | listgid = 0; |
96 | devmode = S_IWUSR | S_IRUGO; | 125 | devmode = USBFS_DEFAULT_DEVMODE; |
97 | busmode = S_IXUGO | S_IRUGO; | 126 | busmode = USBFS_DEFAULT_BUSMODE; |
98 | listmode = S_IRUGO; | 127 | listmode = USBFS_DEFAULT_LISTMODE; |
99 | 128 | ||
100 | while ((p = strsep(&data, ",")) != NULL) { | 129 | while ((p = strsep(&data, ",")) != NULL) { |
101 | substring_t args[MAX_OPT_ARGS]; | 130 | substring_t args[MAX_OPT_ARGS]; |
@@ -418,6 +447,7 @@ static struct super_operations usbfs_ops = { | |||
418 | .statfs = simple_statfs, | 447 | .statfs = simple_statfs, |
419 | .drop_inode = generic_delete_inode, | 448 | .drop_inode = generic_delete_inode, |
420 | .remount_fs = remount, | 449 | .remount_fs = remount, |
450 | .show_options = usbfs_show_options, | ||
421 | }; | 451 | }; |
422 | 452 | ||
423 | static int usbfs_fill_super(struct super_block *sb, void *data, int silent) | 453 | static int usbfs_fill_super(struct super_block *sb, void *data, int silent) |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fcd40ecbeecc..fefb92296e8f 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -39,7 +39,7 @@ static void usb_api_blocking_completion(struct urb *urb) | |||
39 | * own interruptible routines. | 39 | * own interruptible routines. |
40 | */ | 40 | */ |
41 | static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | 41 | static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) |
42 | { | 42 | { |
43 | struct api_context ctx; | 43 | struct api_context ctx; |
44 | unsigned long expire; | 44 | unsigned long expire; |
45 | int retval; | 45 | int retval; |
@@ -74,9 +74,9 @@ out: | |||
74 | } | 74 | } |
75 | 75 | ||
76 | /*-------------------------------------------------------------------*/ | 76 | /*-------------------------------------------------------------------*/ |
77 | // returns status (negative) or length (positive) | 77 | /* returns status (negative) or length (positive) */ |
78 | static int usb_internal_control_msg(struct usb_device *usb_dev, | 78 | static int usb_internal_control_msg(struct usb_device *usb_dev, |
79 | unsigned int pipe, | 79 | unsigned int pipe, |
80 | struct usb_ctrlrequest *cmd, | 80 | struct usb_ctrlrequest *cmd, |
81 | void *data, int len, int timeout) | 81 | void *data, int len, int timeout) |
82 | { | 82 | { |
@@ -87,7 +87,7 @@ static int usb_internal_control_msg(struct usb_device *usb_dev, | |||
87 | urb = usb_alloc_urb(0, GFP_NOIO); | 87 | urb = usb_alloc_urb(0, GFP_NOIO); |
88 | if (!urb) | 88 | if (!urb) |
89 | return -ENOMEM; | 89 | return -ENOMEM; |
90 | 90 | ||
91 | usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, | 91 | usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, |
92 | len, usb_api_blocking_completion, NULL); | 92 | len, usb_api_blocking_completion, NULL); |
93 | 93 | ||
@@ -99,47 +99,51 @@ static int usb_internal_control_msg(struct usb_device *usb_dev, | |||
99 | } | 99 | } |
100 | 100 | ||
101 | /** | 101 | /** |
102 | * usb_control_msg - Builds a control urb, sends it off and waits for completion | 102 | * usb_control_msg - Builds a control urb, sends it off and waits for completion |
103 | * @dev: pointer to the usb device to send the message to | 103 | * @dev: pointer to the usb device to send the message to |
104 | * @pipe: endpoint "pipe" to send the message to | 104 | * @pipe: endpoint "pipe" to send the message to |
105 | * @request: USB message request value | 105 | * @request: USB message request value |
106 | * @requesttype: USB message request type value | 106 | * @requesttype: USB message request type value |
107 | * @value: USB message value | 107 | * @value: USB message value |
108 | * @index: USB message index value | 108 | * @index: USB message index value |
109 | * @data: pointer to the data to send | 109 | * @data: pointer to the data to send |
110 | * @size: length in bytes of the data to send | 110 | * @size: length in bytes of the data to send |
111 | * @timeout: time in msecs to wait for the message to complete before | 111 | * @timeout: time in msecs to wait for the message to complete before timing |
112 | * timing out (if 0 the wait is forever) | 112 | * out (if 0 the wait is forever) |
113 | * Context: !in_interrupt () | 113 | * |
114 | * | 114 | * Context: !in_interrupt () |
115 | * This function sends a simple control message to a specified endpoint | 115 | * |
116 | * and waits for the message to complete, or timeout. | 116 | * This function sends a simple control message to a specified endpoint and |
117 | * | 117 | * waits for the message to complete, or timeout. |
118 | * If successful, it returns the number of bytes transferred, otherwise a negative error number. | 118 | * |
119 | * | 119 | * If successful, it returns the number of bytes transferred, otherwise a |
120 | * Don't use this function from within an interrupt context, like a | 120 | * negative error number. |
121 | * bottom half handler. If you need an asynchronous message, or need to send | 121 | * |
122 | * a message from within interrupt context, use usb_submit_urb() | 122 | * Don't use this function from within an interrupt context, like a bottom half |
123 | * If a thread in your driver uses this call, make sure your disconnect() | 123 | * handler. If you need an asynchronous message, or need to send a message |
124 | * method can wait for it to complete. Since you don't have a handle on | 124 | * from within interrupt context, use usb_submit_urb(). |
125 | * the URB used, you can't cancel the request. | 125 | * If a thread in your driver uses this call, make sure your disconnect() |
126 | * method can wait for it to complete. Since you don't have a handle on the | ||
127 | * URB used, you can't cancel the request. | ||
126 | */ | 128 | */ |
127 | int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, | 129 | int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, |
128 | __u16 value, __u16 index, void *data, __u16 size, int timeout) | 130 | __u8 requesttype, __u16 value, __u16 index, void *data, |
131 | __u16 size, int timeout) | ||
129 | { | 132 | { |
130 | struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); | 133 | struct usb_ctrlrequest *dr; |
131 | int ret; | 134 | int ret; |
132 | 135 | ||
136 | dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); | ||
133 | if (!dr) | 137 | if (!dr) |
134 | return -ENOMEM; | 138 | return -ENOMEM; |
135 | 139 | ||
136 | dr->bRequestType= requesttype; | 140 | dr->bRequestType = requesttype; |
137 | dr->bRequest = request; | 141 | dr->bRequest = request; |
138 | dr->wValue = cpu_to_le16p(&value); | 142 | dr->wValue = cpu_to_le16p(&value); |
139 | dr->wIndex = cpu_to_le16p(&index); | 143 | dr->wIndex = cpu_to_le16p(&index); |
140 | dr->wLength = cpu_to_le16p(&size); | 144 | dr->wLength = cpu_to_le16p(&size); |
141 | 145 | ||
142 | //dbg("usb_control_msg"); | 146 | /* dbg("usb_control_msg"); */ |
143 | 147 | ||
144 | ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); | 148 | ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); |
145 | 149 | ||
@@ -147,7 +151,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u | |||
147 | 151 | ||
148 | return ret; | 152 | return ret; |
149 | } | 153 | } |
150 | 154 | EXPORT_SYMBOL_GPL(usb_control_msg); | |
151 | 155 | ||
152 | /** | 156 | /** |
153 | * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion | 157 | * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion |
@@ -155,9 +159,11 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u | |||
155 | * @pipe: endpoint "pipe" to send the message to | 159 | * @pipe: endpoint "pipe" to send the message to |
156 | * @data: pointer to the data to send | 160 | * @data: pointer to the data to send |
157 | * @len: length in bytes of the data to send | 161 | * @len: length in bytes of the data to send |
158 | * @actual_length: pointer to a location to put the actual length transferred in bytes | 162 | * @actual_length: pointer to a location to put the actual length transferred |
163 | * in bytes | ||
159 | * @timeout: time in msecs to wait for the message to complete before | 164 | * @timeout: time in msecs to wait for the message to complete before |
160 | * timing out (if 0 the wait is forever) | 165 | * timing out (if 0 the wait is forever) |
166 | * | ||
161 | * Context: !in_interrupt () | 167 | * Context: !in_interrupt () |
162 | * | 168 | * |
163 | * This function sends a simple interrupt message to a specified endpoint and | 169 | * This function sends a simple interrupt message to a specified endpoint and |
@@ -181,38 +187,38 @@ int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe, | |||
181 | EXPORT_SYMBOL_GPL(usb_interrupt_msg); | 187 | EXPORT_SYMBOL_GPL(usb_interrupt_msg); |
182 | 188 | ||
183 | /** | 189 | /** |
184 | * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion | 190 | * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion |
185 | * @usb_dev: pointer to the usb device to send the message to | 191 | * @usb_dev: pointer to the usb device to send the message to |
186 | * @pipe: endpoint "pipe" to send the message to | 192 | * @pipe: endpoint "pipe" to send the message to |
187 | * @data: pointer to the data to send | 193 | * @data: pointer to the data to send |
188 | * @len: length in bytes of the data to send | 194 | * @len: length in bytes of the data to send |
189 | * @actual_length: pointer to a location to put the actual length transferred in bytes | 195 | * @actual_length: pointer to a location to put the actual length transferred |
190 | * @timeout: time in msecs to wait for the message to complete before | 196 | * in bytes |
191 | * timing out (if 0 the wait is forever) | 197 | * @timeout: time in msecs to wait for the message to complete before |
192 | * Context: !in_interrupt () | 198 | * timing out (if 0 the wait is forever) |
193 | * | 199 | * |
194 | * This function sends a simple bulk message to a specified endpoint | 200 | * Context: !in_interrupt () |
195 | * and waits for the message to complete, or timeout. | 201 | * |
196 | * | 202 | * This function sends a simple bulk message to a specified endpoint |
197 | * If successful, it returns 0, otherwise a negative error number. | 203 | * and waits for the message to complete, or timeout. |
198 | * The number of actual bytes transferred will be stored in the | 204 | * |
199 | * actual_length paramater. | 205 | * If successful, it returns 0, otherwise a negative error number. The number |
200 | * | 206 | * of actual bytes transferred will be stored in the actual_length paramater. |
201 | * Don't use this function from within an interrupt context, like a | 207 | * |
202 | * bottom half handler. If you need an asynchronous message, or need to | 208 | * Don't use this function from within an interrupt context, like a bottom half |
203 | * send a message from within interrupt context, use usb_submit_urb() | 209 | * handler. If you need an asynchronous message, or need to send a message |
204 | * If a thread in your driver uses this call, make sure your disconnect() | 210 | * from within interrupt context, use usb_submit_urb() If a thread in your |
205 | * method can wait for it to complete. Since you don't have a handle on | 211 | * driver uses this call, make sure your disconnect() method can wait for it to |
206 | * the URB used, you can't cancel the request. | 212 | * complete. Since you don't have a handle on the URB used, you can't cancel |
207 | * | 213 | * the request. |
208 | * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT | 214 | * |
209 | * ioctl, users are forced to abuse this routine by using it to submit | 215 | * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT ioctl, |
210 | * URBs for interrupt endpoints. We will take the liberty of creating | 216 | * users are forced to abuse this routine by using it to submit URBs for |
211 | * an interrupt URB (with the default interval) if the target is an | 217 | * interrupt endpoints. We will take the liberty of creating an interrupt URB |
212 | * interrupt endpoint. | 218 | * (with the default interval) if the target is an interrupt endpoint. |
213 | */ | 219 | */ |
214 | int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, | 220 | int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, |
215 | void *data, int len, int *actual_length, int timeout) | 221 | void *data, int len, int *actual_length, int timeout) |
216 | { | 222 | { |
217 | struct urb *urb; | 223 | struct urb *urb; |
218 | struct usb_host_endpoint *ep; | 224 | struct usb_host_endpoint *ep; |
@@ -238,29 +244,30 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, | |||
238 | 244 | ||
239 | return usb_start_wait_urb(urb, timeout, actual_length); | 245 | return usb_start_wait_urb(urb, timeout, actual_length); |
240 | } | 246 | } |
247 | EXPORT_SYMBOL_GPL(usb_bulk_msg); | ||
241 | 248 | ||
242 | /*-------------------------------------------------------------------*/ | 249 | /*-------------------------------------------------------------------*/ |
243 | 250 | ||
244 | static void sg_clean (struct usb_sg_request *io) | 251 | static void sg_clean(struct usb_sg_request *io) |
245 | { | 252 | { |
246 | if (io->urbs) { | 253 | if (io->urbs) { |
247 | while (io->entries--) | 254 | while (io->entries--) |
248 | usb_free_urb (io->urbs [io->entries]); | 255 | usb_free_urb(io->urbs [io->entries]); |
249 | kfree (io->urbs); | 256 | kfree(io->urbs); |
250 | io->urbs = NULL; | 257 | io->urbs = NULL; |
251 | } | 258 | } |
252 | if (io->dev->dev.dma_mask != NULL) | 259 | if (io->dev->dev.dma_mask != NULL) |
253 | usb_buffer_unmap_sg (io->dev, usb_pipein(io->pipe), | 260 | usb_buffer_unmap_sg(io->dev, usb_pipein(io->pipe), |
254 | io->sg, io->nents); | 261 | io->sg, io->nents); |
255 | io->dev = NULL; | 262 | io->dev = NULL; |
256 | } | 263 | } |
257 | 264 | ||
258 | static void sg_complete (struct urb *urb) | 265 | static void sg_complete(struct urb *urb) |
259 | { | 266 | { |
260 | struct usb_sg_request *io = urb->context; | 267 | struct usb_sg_request *io = urb->context; |
261 | int status = urb->status; | 268 | int status = urb->status; |
262 | 269 | ||
263 | spin_lock (&io->lock); | 270 | spin_lock(&io->lock); |
264 | 271 | ||
265 | /* In 2.5 we require hcds' endpoint queues not to progress after fault | 272 | /* In 2.5 we require hcds' endpoint queues not to progress after fault |
266 | * reports, until the completion callback (this!) returns. That lets | 273 | * reports, until the completion callback (this!) returns. That lets |
@@ -276,13 +283,13 @@ static void sg_complete (struct urb *urb) | |||
276 | && (io->status != -ECONNRESET | 283 | && (io->status != -ECONNRESET |
277 | || status != -ECONNRESET) | 284 | || status != -ECONNRESET) |
278 | && urb->actual_length) { | 285 | && urb->actual_length) { |
279 | dev_err (io->dev->bus->controller, | 286 | dev_err(io->dev->bus->controller, |
280 | "dev %s ep%d%s scatterlist error %d/%d\n", | 287 | "dev %s ep%d%s scatterlist error %d/%d\n", |
281 | io->dev->devpath, | 288 | io->dev->devpath, |
282 | usb_endpoint_num(&urb->ep->desc), | 289 | usb_endpoint_num(&urb->ep->desc), |
283 | usb_urb_dir_in(urb) ? "in" : "out", | 290 | usb_urb_dir_in(urb) ? "in" : "out", |
284 | status, io->status); | 291 | status, io->status); |
285 | // BUG (); | 292 | /* BUG (); */ |
286 | } | 293 | } |
287 | 294 | ||
288 | if (io->status == 0 && status && status != -ECONNRESET) { | 295 | if (io->status == 0 && status && status != -ECONNRESET) { |
@@ -294,22 +301,22 @@ static void sg_complete (struct urb *urb) | |||
294 | * unlink pending urbs so they won't rx/tx bad data. | 301 | * unlink pending urbs so they won't rx/tx bad data. |
295 | * careful: unlink can sometimes be synchronous... | 302 | * careful: unlink can sometimes be synchronous... |
296 | */ | 303 | */ |
297 | spin_unlock (&io->lock); | 304 | spin_unlock(&io->lock); |
298 | for (i = 0, found = 0; i < io->entries; i++) { | 305 | for (i = 0, found = 0; i < io->entries; i++) { |
299 | if (!io->urbs [i] || !io->urbs [i]->dev) | 306 | if (!io->urbs [i] || !io->urbs [i]->dev) |
300 | continue; | 307 | continue; |
301 | if (found) { | 308 | if (found) { |
302 | retval = usb_unlink_urb (io->urbs [i]); | 309 | retval = usb_unlink_urb(io->urbs [i]); |
303 | if (retval != -EINPROGRESS && | 310 | if (retval != -EINPROGRESS && |
304 | retval != -ENODEV && | 311 | retval != -ENODEV && |
305 | retval != -EBUSY) | 312 | retval != -EBUSY) |
306 | dev_err (&io->dev->dev, | 313 | dev_err(&io->dev->dev, |
307 | "%s, unlink --> %d\n", | 314 | "%s, unlink --> %d\n", |
308 | __FUNCTION__, retval); | 315 | __FUNCTION__, retval); |
309 | } else if (urb == io->urbs [i]) | 316 | } else if (urb == io->urbs [i]) |
310 | found = 1; | 317 | found = 1; |
311 | } | 318 | } |
312 | spin_lock (&io->lock); | 319 | spin_lock(&io->lock); |
313 | } | 320 | } |
314 | urb->dev = NULL; | 321 | urb->dev = NULL; |
315 | 322 | ||
@@ -317,9 +324,9 @@ static void sg_complete (struct urb *urb) | |||
317 | io->bytes += urb->actual_length; | 324 | io->bytes += urb->actual_length; |
318 | io->count--; | 325 | io->count--; |
319 | if (!io->count) | 326 | if (!io->count) |
320 | complete (&io->complete); | 327 | complete(&io->complete); |
321 | 328 | ||
322 | spin_unlock (&io->lock); | 329 | spin_unlock(&io->lock); |
323 | } | 330 | } |
324 | 331 | ||
325 | 332 | ||
@@ -348,28 +355,21 @@ static void sg_complete (struct urb *urb) | |||
348 | * The request may be canceled with usb_sg_cancel(), either before or after | 355 | * The request may be canceled with usb_sg_cancel(), either before or after |
349 | * usb_sg_wait() is called. | 356 | * usb_sg_wait() is called. |
350 | */ | 357 | */ |
351 | int usb_sg_init ( | 358 | int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, |
352 | struct usb_sg_request *io, | 359 | unsigned pipe, unsigned period, struct scatterlist *sg, |
353 | struct usb_device *dev, | 360 | int nents, size_t length, gfp_t mem_flags) |
354 | unsigned pipe, | ||
355 | unsigned period, | ||
356 | struct scatterlist *sg, | ||
357 | int nents, | ||
358 | size_t length, | ||
359 | gfp_t mem_flags | ||
360 | ) | ||
361 | { | 361 | { |
362 | int i; | 362 | int i; |
363 | int urb_flags; | 363 | int urb_flags; |
364 | int dma; | 364 | int dma; |
365 | 365 | ||
366 | if (!io || !dev || !sg | 366 | if (!io || !dev || !sg |
367 | || usb_pipecontrol (pipe) | 367 | || usb_pipecontrol(pipe) |
368 | || usb_pipeisoc (pipe) | 368 | || usb_pipeisoc(pipe) |
369 | || nents <= 0) | 369 | || nents <= 0) |
370 | return -EINVAL; | 370 | return -EINVAL; |
371 | 371 | ||
372 | spin_lock_init (&io->lock); | 372 | spin_lock_init(&io->lock); |
373 | io->dev = dev; | 373 | io->dev = dev; |
374 | io->pipe = pipe; | 374 | io->pipe = pipe; |
375 | io->sg = sg; | 375 | io->sg = sg; |
@@ -381,7 +381,7 @@ int usb_sg_init ( | |||
381 | dma = (dev->dev.dma_mask != NULL); | 381 | dma = (dev->dev.dma_mask != NULL); |
382 | if (dma) | 382 | if (dma) |
383 | io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe), | 383 | io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe), |
384 | sg, nents); | 384 | sg, nents); |
385 | else | 385 | else |
386 | io->entries = nents; | 386 | io->entries = nents; |
387 | 387 | ||
@@ -390,30 +390,30 @@ int usb_sg_init ( | |||
390 | return io->entries; | 390 | return io->entries; |
391 | 391 | ||
392 | io->count = io->entries; | 392 | io->count = io->entries; |
393 | io->urbs = kmalloc (io->entries * sizeof *io->urbs, mem_flags); | 393 | io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); |
394 | if (!io->urbs) | 394 | if (!io->urbs) |
395 | goto nomem; | 395 | goto nomem; |
396 | 396 | ||
397 | urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; | 397 | urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; |
398 | if (usb_pipein (pipe)) | 398 | if (usb_pipein(pipe)) |
399 | urb_flags |= URB_SHORT_NOT_OK; | 399 | urb_flags |= URB_SHORT_NOT_OK; |
400 | 400 | ||
401 | for (i = 0; i < io->entries; i++) { | 401 | for (i = 0; i < io->entries; i++) { |
402 | unsigned len; | 402 | unsigned len; |
403 | 403 | ||
404 | io->urbs [i] = usb_alloc_urb (0, mem_flags); | 404 | io->urbs[i] = usb_alloc_urb(0, mem_flags); |
405 | if (!io->urbs [i]) { | 405 | if (!io->urbs[i]) { |
406 | io->entries = i; | 406 | io->entries = i; |
407 | goto nomem; | 407 | goto nomem; |
408 | } | 408 | } |
409 | 409 | ||
410 | io->urbs [i]->dev = NULL; | 410 | io->urbs[i]->dev = NULL; |
411 | io->urbs [i]->pipe = pipe; | 411 | io->urbs[i]->pipe = pipe; |
412 | io->urbs [i]->interval = period; | 412 | io->urbs[i]->interval = period; |
413 | io->urbs [i]->transfer_flags = urb_flags; | 413 | io->urbs[i]->transfer_flags = urb_flags; |
414 | 414 | ||
415 | io->urbs [i]->complete = sg_complete; | 415 | io->urbs[i]->complete = sg_complete; |
416 | io->urbs [i]->context = io; | 416 | io->urbs[i]->context = io; |
417 | 417 | ||
418 | /* | 418 | /* |
419 | * Some systems need to revert to PIO when DMA is temporarily | 419 | * Some systems need to revert to PIO when DMA is temporarily |
@@ -432,8 +432,8 @@ int usb_sg_init ( | |||
432 | * to prevent stale pointers and to help spot bugs. | 432 | * to prevent stale pointers and to help spot bugs. |
433 | */ | 433 | */ |
434 | if (dma) { | 434 | if (dma) { |
435 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); | 435 | io->urbs[i]->transfer_dma = sg_dma_address(sg + i); |
436 | len = sg_dma_len (sg + i); | 436 | len = sg_dma_len(sg + i); |
437 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU) | 437 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU) |
438 | io->urbs[i]->transfer_buffer = NULL; | 438 | io->urbs[i]->transfer_buffer = NULL; |
439 | #else | 439 | #else |
@@ -441,31 +441,31 @@ int usb_sg_init ( | |||
441 | #endif | 441 | #endif |
442 | } else { | 442 | } else { |
443 | /* hc may use _only_ transfer_buffer */ | 443 | /* hc may use _only_ transfer_buffer */ |
444 | io->urbs [i]->transfer_buffer = sg_virt(&sg[i]); | 444 | io->urbs[i]->transfer_buffer = sg_virt(&sg[i]); |
445 | len = sg [i].length; | 445 | len = sg[i].length; |
446 | } | 446 | } |
447 | 447 | ||
448 | if (length) { | 448 | if (length) { |
449 | len = min_t (unsigned, len, length); | 449 | len = min_t(unsigned, len, length); |
450 | length -= len; | 450 | length -= len; |
451 | if (length == 0) | 451 | if (length == 0) |
452 | io->entries = i + 1; | 452 | io->entries = i + 1; |
453 | } | 453 | } |
454 | io->urbs [i]->transfer_buffer_length = len; | 454 | io->urbs[i]->transfer_buffer_length = len; |
455 | } | 455 | } |
456 | io->urbs [--i]->transfer_flags &= ~URB_NO_INTERRUPT; | 456 | io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; |
457 | 457 | ||
458 | /* transaction state */ | 458 | /* transaction state */ |
459 | io->status = 0; | 459 | io->status = 0; |
460 | io->bytes = 0; | 460 | io->bytes = 0; |
461 | init_completion (&io->complete); | 461 | init_completion(&io->complete); |
462 | return 0; | 462 | return 0; |
463 | 463 | ||
464 | nomem: | 464 | nomem: |
465 | sg_clean (io); | 465 | sg_clean(io); |
466 | return -ENOMEM; | 466 | return -ENOMEM; |
467 | } | 467 | } |
468 | 468 | EXPORT_SYMBOL_GPL(usb_sg_init); | |
469 | 469 | ||
470 | /** | 470 | /** |
471 | * usb_sg_wait - synchronously execute scatter/gather request | 471 | * usb_sg_wait - synchronously execute scatter/gather request |
@@ -506,31 +506,32 @@ nomem: | |||
506 | * speed interrupt endpoints, which allow at most one packet per millisecond, | 506 | * speed interrupt endpoints, which allow at most one packet per millisecond, |
507 | * of at most 8 or 64 bytes (respectively). | 507 | * of at most 8 or 64 bytes (respectively). |
508 | */ | 508 | */ |
509 | void usb_sg_wait (struct usb_sg_request *io) | 509 | void usb_sg_wait(struct usb_sg_request *io) |
510 | { | 510 | { |
511 | int i, entries = io->entries; | 511 | int i; |
512 | int entries = io->entries; | ||
512 | 513 | ||
513 | /* queue the urbs. */ | 514 | /* queue the urbs. */ |
514 | spin_lock_irq (&io->lock); | 515 | spin_lock_irq(&io->lock); |
515 | i = 0; | 516 | i = 0; |
516 | while (i < entries && !io->status) { | 517 | while (i < entries && !io->status) { |
517 | int retval; | 518 | int retval; |
518 | 519 | ||
519 | io->urbs [i]->dev = io->dev; | 520 | io->urbs[i]->dev = io->dev; |
520 | retval = usb_submit_urb (io->urbs [i], GFP_ATOMIC); | 521 | retval = usb_submit_urb(io->urbs [i], GFP_ATOMIC); |
521 | 522 | ||
522 | /* after we submit, let completions or cancelations fire; | 523 | /* after we submit, let completions or cancelations fire; |
523 | * we handshake using io->status. | 524 | * we handshake using io->status. |
524 | */ | 525 | */ |
525 | spin_unlock_irq (&io->lock); | 526 | spin_unlock_irq(&io->lock); |
526 | switch (retval) { | 527 | switch (retval) { |
527 | /* maybe we retrying will recover */ | 528 | /* maybe we retrying will recover */ |
528 | case -ENXIO: // hc didn't queue this one | 529 | case -ENXIO: /* hc didn't queue this one */ |
529 | case -EAGAIN: | 530 | case -EAGAIN: |
530 | case -ENOMEM: | 531 | case -ENOMEM: |
531 | io->urbs[i]->dev = NULL; | 532 | io->urbs[i]->dev = NULL; |
532 | retval = 0; | 533 | retval = 0; |
533 | yield (); | 534 | yield(); |
534 | break; | 535 | break; |
535 | 536 | ||
536 | /* no error? continue immediately. | 537 | /* no error? continue immediately. |
@@ -541,34 +542,35 @@ void usb_sg_wait (struct usb_sg_request *io) | |||
541 | */ | 542 | */ |
542 | case 0: | 543 | case 0: |
543 | ++i; | 544 | ++i; |
544 | cpu_relax (); | 545 | cpu_relax(); |
545 | break; | 546 | break; |
546 | 547 | ||
547 | /* fail any uncompleted urbs */ | 548 | /* fail any uncompleted urbs */ |
548 | default: | 549 | default: |
549 | io->urbs [i]->dev = NULL; | 550 | io->urbs[i]->dev = NULL; |
550 | io->urbs [i]->status = retval; | 551 | io->urbs[i]->status = retval; |
551 | dev_dbg (&io->dev->dev, "%s, submit --> %d\n", | 552 | dev_dbg(&io->dev->dev, "%s, submit --> %d\n", |
552 | __FUNCTION__, retval); | 553 | __FUNCTION__, retval); |
553 | usb_sg_cancel (io); | 554 | usb_sg_cancel(io); |
554 | } | 555 | } |
555 | spin_lock_irq (&io->lock); | 556 | spin_lock_irq(&io->lock); |
556 | if (retval && (io->status == 0 || io->status == -ECONNRESET)) | 557 | if (retval && (io->status == 0 || io->status == -ECONNRESET)) |
557 | io->status = retval; | 558 | io->status = retval; |
558 | } | 559 | } |
559 | io->count -= entries - i; | 560 | io->count -= entries - i; |
560 | if (io->count == 0) | 561 | if (io->count == 0) |
561 | complete (&io->complete); | 562 | complete(&io->complete); |
562 | spin_unlock_irq (&io->lock); | 563 | spin_unlock_irq(&io->lock); |
563 | 564 | ||
564 | /* OK, yes, this could be packaged as non-blocking. | 565 | /* OK, yes, this could be packaged as non-blocking. |
565 | * So could the submit loop above ... but it's easier to | 566 | * So could the submit loop above ... but it's easier to |
566 | * solve neither problem than to solve both! | 567 | * solve neither problem than to solve both! |
567 | */ | 568 | */ |
568 | wait_for_completion (&io->complete); | 569 | wait_for_completion(&io->complete); |
569 | 570 | ||
570 | sg_clean (io); | 571 | sg_clean(io); |
571 | } | 572 | } |
573 | EXPORT_SYMBOL_GPL(usb_sg_wait); | ||
572 | 574 | ||
573 | /** | 575 | /** |
574 | * usb_sg_cancel - stop scatter/gather i/o issued by usb_sg_wait() | 576 | * usb_sg_cancel - stop scatter/gather i/o issued by usb_sg_wait() |
@@ -578,32 +580,33 @@ void usb_sg_wait (struct usb_sg_request *io) | |||
578 | * It can also prevents one initialized by usb_sg_init() from starting, | 580 | * It can also prevents one initialized by usb_sg_init() from starting, |
579 | * so that call just frees resources allocated to the request. | 581 | * so that call just frees resources allocated to the request. |
580 | */ | 582 | */ |
581 | void usb_sg_cancel (struct usb_sg_request *io) | 583 | void usb_sg_cancel(struct usb_sg_request *io) |
582 | { | 584 | { |
583 | unsigned long flags; | 585 | unsigned long flags; |
584 | 586 | ||
585 | spin_lock_irqsave (&io->lock, flags); | 587 | spin_lock_irqsave(&io->lock, flags); |
586 | 588 | ||
587 | /* shut everything down, if it didn't already */ | 589 | /* shut everything down, if it didn't already */ |
588 | if (!io->status) { | 590 | if (!io->status) { |
589 | int i; | 591 | int i; |
590 | 592 | ||
591 | io->status = -ECONNRESET; | 593 | io->status = -ECONNRESET; |
592 | spin_unlock (&io->lock); | 594 | spin_unlock(&io->lock); |
593 | for (i = 0; i < io->entries; i++) { | 595 | for (i = 0; i < io->entries; i++) { |
594 | int retval; | 596 | int retval; |
595 | 597 | ||
596 | if (!io->urbs [i]->dev) | 598 | if (!io->urbs [i]->dev) |
597 | continue; | 599 | continue; |
598 | retval = usb_unlink_urb (io->urbs [i]); | 600 | retval = usb_unlink_urb(io->urbs [i]); |
599 | if (retval != -EINPROGRESS && retval != -EBUSY) | 601 | if (retval != -EINPROGRESS && retval != -EBUSY) |
600 | dev_warn (&io->dev->dev, "%s, unlink --> %d\n", | 602 | dev_warn(&io->dev->dev, "%s, unlink --> %d\n", |
601 | __FUNCTION__, retval); | 603 | __FUNCTION__, retval); |
602 | } | 604 | } |
603 | spin_lock (&io->lock); | 605 | spin_lock(&io->lock); |
604 | } | 606 | } |
605 | spin_unlock_irqrestore (&io->lock, flags); | 607 | spin_unlock_irqrestore(&io->lock, flags); |
606 | } | 608 | } |
609 | EXPORT_SYMBOL_GPL(usb_sg_cancel); | ||
607 | 610 | ||
608 | /*-------------------------------------------------------------------*/ | 611 | /*-------------------------------------------------------------------*/ |
609 | 612 | ||
@@ -629,12 +632,13 @@ void usb_sg_cancel (struct usb_sg_request *io) | |||
629 | * Returns the number of bytes received on success, or else the status code | 632 | * Returns the number of bytes received on success, or else the status code |
630 | * returned by the underlying usb_control_msg() call. | 633 | * returned by the underlying usb_control_msg() call. |
631 | */ | 634 | */ |
632 | int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) | 635 | int usb_get_descriptor(struct usb_device *dev, unsigned char type, |
636 | unsigned char index, void *buf, int size) | ||
633 | { | 637 | { |
634 | int i; | 638 | int i; |
635 | int result; | 639 | int result; |
636 | 640 | ||
637 | memset(buf,0,size); // Make sure we parse really received data | 641 | memset(buf, 0, size); /* Make sure we parse really received data */ |
638 | 642 | ||
639 | for (i = 0; i < 3; ++i) { | 643 | for (i = 0; i < 3; ++i) { |
640 | /* retry on length 0 or error; some devices are flakey */ | 644 | /* retry on length 0 or error; some devices are flakey */ |
@@ -652,6 +656,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char | |||
652 | } | 656 | } |
653 | return result; | 657 | return result; |
654 | } | 658 | } |
659 | EXPORT_SYMBOL_GPL(usb_get_descriptor); | ||
655 | 660 | ||
656 | /** | 661 | /** |
657 | * usb_get_string - gets a string descriptor | 662 | * usb_get_string - gets a string descriptor |
@@ -708,7 +713,7 @@ static void usb_try_string_workarounds(unsigned char *buf, int *length) | |||
708 | } | 713 | } |
709 | 714 | ||
710 | static int usb_string_sub(struct usb_device *dev, unsigned int langid, | 715 | static int usb_string_sub(struct usb_device *dev, unsigned int langid, |
711 | unsigned int index, unsigned char *buf) | 716 | unsigned int index, unsigned char *buf) |
712 | { | 717 | { |
713 | int rc; | 718 | int rc; |
714 | 719 | ||
@@ -751,7 +756,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, | |||
751 | * @buf: where to put the string | 756 | * @buf: where to put the string |
752 | * @size: how big is "buf"? | 757 | * @size: how big is "buf"? |
753 | * Context: !in_interrupt () | 758 | * Context: !in_interrupt () |
754 | * | 759 | * |
755 | * This converts the UTF-16LE encoded strings returned by devices, from | 760 | * This converts the UTF-16LE encoded strings returned by devices, from |
756 | * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones | 761 | * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones |
757 | * that are more usable in most kernel contexts. Note that all characters | 762 | * that are more usable in most kernel contexts. Note that all characters |
@@ -787,23 +792,23 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
787 | if (!dev->have_langid) { | 792 | if (!dev->have_langid) { |
788 | err = usb_string_sub(dev, 0, 0, tbuf); | 793 | err = usb_string_sub(dev, 0, 0, tbuf); |
789 | if (err < 0) { | 794 | if (err < 0) { |
790 | dev_err (&dev->dev, | 795 | dev_err(&dev->dev, |
791 | "string descriptor 0 read error: %d\n", | 796 | "string descriptor 0 read error: %d\n", |
792 | err); | 797 | err); |
793 | goto errout; | 798 | goto errout; |
794 | } else if (err < 4) { | 799 | } else if (err < 4) { |
795 | dev_err (&dev->dev, "string descriptor 0 too short\n"); | 800 | dev_err(&dev->dev, "string descriptor 0 too short\n"); |
796 | err = -EINVAL; | 801 | err = -EINVAL; |
797 | goto errout; | 802 | goto errout; |
798 | } else { | 803 | } else { |
799 | dev->have_langid = 1; | 804 | dev->have_langid = 1; |
800 | dev->string_langid = tbuf[2] | (tbuf[3]<< 8); | 805 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); |
801 | /* always use the first langid listed */ | 806 | /* always use the first langid listed */ |
802 | dev_dbg (&dev->dev, "default language 0x%04x\n", | 807 | dev_dbg(&dev->dev, "default language 0x%04x\n", |
803 | dev->string_langid); | 808 | dev->string_langid); |
804 | } | 809 | } |
805 | } | 810 | } |
806 | 811 | ||
807 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 812 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
808 | if (err < 0) | 813 | if (err < 0) |
809 | goto errout; | 814 | goto errout; |
@@ -821,12 +826,15 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
821 | err = idx; | 826 | err = idx; |
822 | 827 | ||
823 | if (tbuf[1] != USB_DT_STRING) | 828 | if (tbuf[1] != USB_DT_STRING) |
824 | dev_dbg(&dev->dev, "wrong descriptor type %02x for string %d (\"%s\")\n", tbuf[1], index, buf); | 829 | dev_dbg(&dev->dev, |
830 | "wrong descriptor type %02x for string %d (\"%s\")\n", | ||
831 | tbuf[1], index, buf); | ||
825 | 832 | ||
826 | errout: | 833 | errout: |
827 | kfree(tbuf); | 834 | kfree(tbuf); |
828 | return err; | 835 | return err; |
829 | } | 836 | } |
837 | EXPORT_SYMBOL_GPL(usb_string); | ||
830 | 838 | ||
831 | /** | 839 | /** |
832 | * usb_cache_string - read a string descriptor and cache it for later use | 840 | * usb_cache_string - read a string descriptor and cache it for later use |
@@ -842,9 +850,15 @@ char *usb_cache_string(struct usb_device *udev, int index) | |||
842 | char *smallbuf = NULL; | 850 | char *smallbuf = NULL; |
843 | int len; | 851 | int len; |
844 | 852 | ||
845 | if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) { | 853 | if (index <= 0) |
846 | if ((len = usb_string(udev, index, buf, 256)) > 0) { | 854 | return NULL; |
847 | if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL) | 855 | |
856 | buf = kmalloc(256, GFP_KERNEL); | ||
857 | if (buf) { | ||
858 | len = usb_string(udev, index, buf, 256); | ||
859 | if (len > 0) { | ||
860 | smallbuf = kmalloc(++len, GFP_KERNEL); | ||
861 | if (!smallbuf) | ||
848 | return buf; | 862 | return buf; |
849 | memcpy(smallbuf, buf, len); | 863 | memcpy(smallbuf, buf, len); |
850 | } | 864 | } |
@@ -883,7 +897,7 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size) | |||
883 | return -ENOMEM; | 897 | return -ENOMEM; |
884 | 898 | ||
885 | ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size); | 899 | ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size); |
886 | if (ret >= 0) | 900 | if (ret >= 0) |
887 | memcpy(&dev->descriptor, desc, size); | 901 | memcpy(&dev->descriptor, desc, size); |
888 | kfree(desc); | 902 | kfree(desc); |
889 | return ret; | 903 | return ret; |
@@ -927,6 +941,7 @@ int usb_get_status(struct usb_device *dev, int type, int target, void *data) | |||
927 | kfree(status); | 941 | kfree(status); |
928 | return ret; | 942 | return ret; |
929 | } | 943 | } |
944 | EXPORT_SYMBOL_GPL(usb_get_status); | ||
930 | 945 | ||
931 | /** | 946 | /** |
932 | * usb_clear_halt - tells device to clear endpoint halt/stall condition | 947 | * usb_clear_halt - tells device to clear endpoint halt/stall condition |
@@ -955,8 +970,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe) | |||
955 | { | 970 | { |
956 | int result; | 971 | int result; |
957 | int endp = usb_pipeendpoint(pipe); | 972 | int endp = usb_pipeendpoint(pipe); |
958 | 973 | ||
959 | if (usb_pipein (pipe)) | 974 | if (usb_pipein(pipe)) |
960 | endp |= USB_DIR_IN; | 975 | endp |= USB_DIR_IN; |
961 | 976 | ||
962 | /* we don't care if it wasn't halted first. in fact some devices | 977 | /* we don't care if it wasn't halted first. in fact some devices |
@@ -985,6 +1000,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe) | |||
985 | 1000 | ||
986 | return 0; | 1001 | return 0; |
987 | } | 1002 | } |
1003 | EXPORT_SYMBOL_GPL(usb_clear_halt); | ||
988 | 1004 | ||
989 | /** | 1005 | /** |
990 | * usb_disable_endpoint -- Disable an endpoint by address | 1006 | * usb_disable_endpoint -- Disable an endpoint by address |
@@ -1038,7 +1054,7 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf) | |||
1038 | } | 1054 | } |
1039 | } | 1055 | } |
1040 | 1056 | ||
1041 | /* | 1057 | /** |
1042 | * usb_disable_device - Disable all the endpoints for a USB device | 1058 | * usb_disable_device - Disable all the endpoints for a USB device |
1043 | * @dev: the device whose endpoints are being disabled | 1059 | * @dev: the device whose endpoints are being disabled |
1044 | * @skip_ep0: 0 to disable endpoint 0, 1 to skip it. | 1060 | * @skip_ep0: 0 to disable endpoint 0, 1 to skip it. |
@@ -1053,7 +1069,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1053 | int i; | 1069 | int i; |
1054 | 1070 | ||
1055 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __FUNCTION__, | 1071 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __FUNCTION__, |
1056 | skip_ep0 ? "non-ep0" : "all"); | 1072 | skip_ep0 ? "non-ep0" : "all"); |
1057 | for (i = skip_ep0; i < 16; ++i) { | 1073 | for (i = skip_ep0; i < 16; ++i) { |
1058 | usb_disable_endpoint(dev, i); | 1074 | usb_disable_endpoint(dev, i); |
1059 | usb_disable_endpoint(dev, i + USB_DIR_IN); | 1075 | usb_disable_endpoint(dev, i + USB_DIR_IN); |
@@ -1071,17 +1087,17 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1071 | interface = dev->actconfig->interface[i]; | 1087 | interface = dev->actconfig->interface[i]; |
1072 | if (!device_is_registered(&interface->dev)) | 1088 | if (!device_is_registered(&interface->dev)) |
1073 | continue; | 1089 | continue; |
1074 | dev_dbg (&dev->dev, "unregistering interface %s\n", | 1090 | dev_dbg(&dev->dev, "unregistering interface %s\n", |
1075 | interface->dev.bus_id); | 1091 | interface->dev.bus_id); |
1076 | usb_remove_sysfs_intf_files(interface); | 1092 | usb_remove_sysfs_intf_files(interface); |
1077 | device_del (&interface->dev); | 1093 | device_del(&interface->dev); |
1078 | } | 1094 | } |
1079 | 1095 | ||
1080 | /* Now that the interfaces are unbound, nobody should | 1096 | /* Now that the interfaces are unbound, nobody should |
1081 | * try to access them. | 1097 | * try to access them. |
1082 | */ | 1098 | */ |
1083 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { | 1099 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { |
1084 | put_device (&dev->actconfig->interface[i]->dev); | 1100 | put_device(&dev->actconfig->interface[i]->dev); |
1085 | dev->actconfig->interface[i] = NULL; | 1101 | dev->actconfig->interface[i] = NULL; |
1086 | } | 1102 | } |
1087 | dev->actconfig = NULL; | 1103 | dev->actconfig = NULL; |
@@ -1090,8 +1106,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1090 | } | 1106 | } |
1091 | } | 1107 | } |
1092 | 1108 | ||
1093 | 1109 | /** | |
1094 | /* | ||
1095 | * usb_enable_endpoint - Enable an endpoint for USB communications | 1110 | * usb_enable_endpoint - Enable an endpoint for USB communications |
1096 | * @dev: the device whose interface is being enabled | 1111 | * @dev: the device whose interface is being enabled |
1097 | * @ep: the endpoint | 1112 | * @ep: the endpoint |
@@ -1116,7 +1131,7 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) | |||
1116 | ep->enabled = 1; | 1131 | ep->enabled = 1; |
1117 | } | 1132 | } |
1118 | 1133 | ||
1119 | /* | 1134 | /** |
1120 | * usb_enable_interface - Enable all the endpoints for an interface | 1135 | * usb_enable_interface - Enable all the endpoints for an interface |
1121 | * @dev: the device whose interface is being enabled | 1136 | * @dev: the device whose interface is being enabled |
1122 | * @intf: pointer to the interface descriptor | 1137 | * @intf: pointer to the interface descriptor |
@@ -1172,6 +1187,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1172 | struct usb_host_interface *alt; | 1187 | struct usb_host_interface *alt; |
1173 | int ret; | 1188 | int ret; |
1174 | int manual = 0; | 1189 | int manual = 0; |
1190 | unsigned int epaddr; | ||
1191 | unsigned int pipe; | ||
1175 | 1192 | ||
1176 | if (dev->state == USB_STATE_SUSPENDED) | 1193 | if (dev->state == USB_STATE_SUSPENDED) |
1177 | return -EHOSTUNREACH; | 1194 | return -EHOSTUNREACH; |
@@ -1226,11 +1243,11 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1226 | int i; | 1243 | int i; |
1227 | 1244 | ||
1228 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { | 1245 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { |
1229 | unsigned int epaddr = | 1246 | epaddr = alt->endpoint[i].desc.bEndpointAddress; |
1230 | alt->endpoint[i].desc.bEndpointAddress; | 1247 | pipe = __create_pipe(dev, |
1231 | unsigned int pipe = | 1248 | USB_ENDPOINT_NUMBER_MASK & epaddr) | |
1232 | __create_pipe(dev, USB_ENDPOINT_NUMBER_MASK & epaddr) | 1249 | (usb_endpoint_out(epaddr) ? |
1233 | | (usb_endpoint_out(epaddr) ? USB_DIR_OUT : USB_DIR_IN); | 1250 | USB_DIR_OUT : USB_DIR_IN); |
1234 | 1251 | ||
1235 | usb_clear_halt(dev, pipe); | 1252 | usb_clear_halt(dev, pipe); |
1236 | } | 1253 | } |
@@ -1253,6 +1270,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1253 | 1270 | ||
1254 | return 0; | 1271 | return 0; |
1255 | } | 1272 | } |
1273 | EXPORT_SYMBOL_GPL(usb_set_interface); | ||
1256 | 1274 | ||
1257 | /** | 1275 | /** |
1258 | * usb_reset_configuration - lightweight device reset | 1276 | * usb_reset_configuration - lightweight device reset |
@@ -1328,6 +1346,7 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1328 | } | 1346 | } |
1329 | return 0; | 1347 | return 0; |
1330 | } | 1348 | } |
1349 | EXPORT_SYMBOL_GPL(usb_reset_configuration); | ||
1331 | 1350 | ||
1332 | static void usb_release_interface(struct device *dev) | 1351 | static void usb_release_interface(struct device *dev) |
1333 | { | 1352 | { |
@@ -1357,7 +1376,8 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
1357 | return -ENOMEM; | 1376 | return -ENOMEM; |
1358 | 1377 | ||
1359 | if (add_uevent_var(env, | 1378 | if (add_uevent_var(env, |
1360 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | 1379 | "MODALIAS=usb:" |
1380 | "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | ||
1361 | le16_to_cpu(usb_dev->descriptor.idVendor), | 1381 | le16_to_cpu(usb_dev->descriptor.idVendor), |
1362 | le16_to_cpu(usb_dev->descriptor.idProduct), | 1382 | le16_to_cpu(usb_dev->descriptor.idProduct), |
1363 | le16_to_cpu(usb_dev->descriptor.bcdDevice), | 1383 | le16_to_cpu(usb_dev->descriptor.bcdDevice), |
@@ -1387,8 +1407,8 @@ struct device_type usb_if_device_type = { | |||
1387 | }; | 1407 | }; |
1388 | 1408 | ||
1389 | static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, | 1409 | static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, |
1390 | struct usb_host_config *config, | 1410 | struct usb_host_config *config, |
1391 | u8 inum) | 1411 | u8 inum) |
1392 | { | 1412 | { |
1393 | struct usb_interface_assoc_descriptor *retval = NULL; | 1413 | struct usb_interface_assoc_descriptor *retval = NULL; |
1394 | struct usb_interface_assoc_descriptor *intf_assoc; | 1414 | struct usb_interface_assoc_descriptor *intf_assoc; |
@@ -1415,7 +1435,6 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, | |||
1415 | return retval; | 1435 | return retval; |
1416 | } | 1436 | } |
1417 | 1437 | ||
1418 | |||
1419 | /* | 1438 | /* |
1420 | * usb_set_configuration - Makes a particular device setting be current | 1439 | * usb_set_configuration - Makes a particular device setting be current |
1421 | * @dev: the device whose configuration is being updated | 1440 | * @dev: the device whose configuration is being updated |
@@ -1533,12 +1552,12 @@ free_interfaces: | |||
1533 | * getting rid of old interfaces means unbinding their drivers. | 1552 | * getting rid of old interfaces means unbinding their drivers. |
1534 | */ | 1553 | */ |
1535 | if (dev->state != USB_STATE_ADDRESS) | 1554 | if (dev->state != USB_STATE_ADDRESS) |
1536 | usb_disable_device (dev, 1); // Skip ep0 | 1555 | usb_disable_device(dev, 1); /* Skip ep0 */ |
1537 | |||
1538 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
1539 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | ||
1540 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) { | ||
1541 | 1556 | ||
1557 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
1558 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | ||
1559 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
1560 | if (ret < 0) { | ||
1542 | /* All the old state is gone, so what else can we do? | 1561 | /* All the old state is gone, so what else can we do? |
1543 | * The device is probably useless now anyway. | 1562 | * The device is probably useless now anyway. |
1544 | */ | 1563 | */ |
@@ -1585,11 +1604,11 @@ free_interfaces: | |||
1585 | intf->dev.bus = &usb_bus_type; | 1604 | intf->dev.bus = &usb_bus_type; |
1586 | intf->dev.type = &usb_if_device_type; | 1605 | intf->dev.type = &usb_if_device_type; |
1587 | intf->dev.dma_mask = dev->dev.dma_mask; | 1606 | intf->dev.dma_mask = dev->dev.dma_mask; |
1588 | device_initialize (&intf->dev); | 1607 | device_initialize(&intf->dev); |
1589 | mark_quiesced(intf); | 1608 | mark_quiesced(intf); |
1590 | sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", | 1609 | sprintf(&intf->dev.bus_id[0], "%d-%s:%d.%d", |
1591 | dev->bus->busnum, dev->devpath, | 1610 | dev->bus->busnum, dev->devpath, |
1592 | configuration, alt->desc.bInterfaceNumber); | 1611 | configuration, alt->desc.bInterfaceNumber); |
1593 | } | 1612 | } |
1594 | kfree(new_interfaces); | 1613 | kfree(new_interfaces); |
1595 | 1614 | ||
@@ -1605,11 +1624,11 @@ free_interfaces: | |||
1605 | for (i = 0; i < nintf; ++i) { | 1624 | for (i = 0; i < nintf; ++i) { |
1606 | struct usb_interface *intf = cp->interface[i]; | 1625 | struct usb_interface *intf = cp->interface[i]; |
1607 | 1626 | ||
1608 | dev_dbg (&dev->dev, | 1627 | dev_dbg(&dev->dev, |
1609 | "adding %s (config #%d, interface %d)\n", | 1628 | "adding %s (config #%d, interface %d)\n", |
1610 | intf->dev.bus_id, configuration, | 1629 | intf->dev.bus_id, configuration, |
1611 | intf->cur_altsetting->desc.bInterfaceNumber); | 1630 | intf->cur_altsetting->desc.bInterfaceNumber); |
1612 | ret = device_add (&intf->dev); | 1631 | ret = device_add(&intf->dev); |
1613 | if (ret != 0) { | 1632 | if (ret != 0) { |
1614 | dev_err(&dev->dev, "device_add(%s) --> %d\n", | 1633 | dev_err(&dev->dev, "device_add(%s) --> %d\n", |
1615 | intf->dev.bus_id, ret); | 1634 | intf->dev.bus_id, ret); |
@@ -1677,22 +1696,3 @@ int usb_driver_set_configuration(struct usb_device *udev, int config) | |||
1677 | return 0; | 1696 | return 0; |
1678 | } | 1697 | } |
1679 | EXPORT_SYMBOL_GPL(usb_driver_set_configuration); | 1698 | EXPORT_SYMBOL_GPL(usb_driver_set_configuration); |
1680 | |||
1681 | // synchronous request completion model | ||
1682 | EXPORT_SYMBOL(usb_control_msg); | ||
1683 | EXPORT_SYMBOL(usb_bulk_msg); | ||
1684 | |||
1685 | EXPORT_SYMBOL(usb_sg_init); | ||
1686 | EXPORT_SYMBOL(usb_sg_cancel); | ||
1687 | EXPORT_SYMBOL(usb_sg_wait); | ||
1688 | |||
1689 | // synchronous control message convenience routines | ||
1690 | EXPORT_SYMBOL(usb_get_descriptor); | ||
1691 | EXPORT_SYMBOL(usb_get_status); | ||
1692 | EXPORT_SYMBOL(usb_string); | ||
1693 | |||
1694 | // synchronous calls that also maintain usbcore state | ||
1695 | EXPORT_SYMBOL(usb_clear_halt); | ||
1696 | EXPORT_SYMBOL(usb_reset_configuration); | ||
1697 | EXPORT_SYMBOL(usb_set_interface); | ||
1698 | |||
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c index 6b36897ca151..7542dce3f5a1 100644 --- a/drivers/usb/core/notify.c +++ b/drivers/usb/core/notify.c | |||
@@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(usb_register_notify); | |||
33 | * usb_unregister_notify - unregister a notifier callback | 33 | * usb_unregister_notify - unregister a notifier callback |
34 | * @nb: pointer to the notifier block for the callback events. | 34 | * @nb: pointer to the notifier block for the callback events. |
35 | * | 35 | * |
36 | * usb_register_notifier() must have been previously called for this function | 36 | * usb_register_notify() must have been previously called for this function |
37 | * to work properly. | 37 | * to work properly. |
38 | */ | 38 | */ |
39 | void usb_unregister_notify(struct notifier_block *nb) | 39 | void usb_unregister_notify(struct notifier_block *nb) |
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h index 7f31a495a25d..e8cdce571bb1 100644 --- a/drivers/usb/core/otg_whitelist.h +++ b/drivers/usb/core/otg_whitelist.h | |||
@@ -14,7 +14,7 @@ | |||
14 | * mostly use of USB_DEVICE() or USB_DEVICE_VER() entries.. | 14 | * mostly use of USB_DEVICE() or USB_DEVICE_VER() entries.. |
15 | * | 15 | * |
16 | * YOU _SHOULD_ CHANGE THIS LIST TO MATCH YOUR PRODUCT AND ITS TESTING! | 16 | * YOU _SHOULD_ CHANGE THIS LIST TO MATCH YOUR PRODUCT AND ITS TESTING! |
17 | */ | 17 | */ |
18 | 18 | ||
19 | static struct usb_device_id whitelist_table [] = { | 19 | static struct usb_device_id whitelist_table [] = { |
20 | 20 | ||
@@ -55,7 +55,7 @@ static int is_targeted(struct usb_device *dev) | |||
55 | return 1; | 55 | return 1; |
56 | 56 | ||
57 | /* HNP test device is _never_ targeted (see OTG spec 6.6.6) */ | 57 | /* HNP test device is _never_ targeted (see OTG spec 6.6.6) */ |
58 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && | 58 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && |
59 | le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) | 59 | le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) |
60 | return 0; | 60 | return 0; |
61 | 61 | ||
@@ -86,7 +86,7 @@ static int is_targeted(struct usb_device *dev) | |||
86 | continue; | 86 | continue; |
87 | 87 | ||
88 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | 88 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && |
89 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | 89 | (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass)) |
90 | continue; | 90 | continue; |
91 | 91 | ||
92 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | 92 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 32bd130b1eed..a37ccbd1e007 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -72,7 +72,7 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr, | |||
72 | return (value < 0) ? value : count; | 72 | return (value < 0) ? value : count; |
73 | } | 73 | } |
74 | 74 | ||
75 | static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, | 75 | static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, |
76 | show_bConfigurationValue, set_bConfigurationValue); | 76 | show_bConfigurationValue, set_bConfigurationValue); |
77 | 77 | ||
78 | /* String fields */ | 78 | /* String fields */ |
@@ -249,6 +249,41 @@ static void remove_persist_attributes(struct device *dev) | |||
249 | #ifdef CONFIG_USB_SUSPEND | 249 | #ifdef CONFIG_USB_SUSPEND |
250 | 250 | ||
251 | static ssize_t | 251 | static ssize_t |
252 | show_connected_duration(struct device *dev, struct device_attribute *attr, | ||
253 | char *buf) | ||
254 | { | ||
255 | struct usb_device *udev = to_usb_device(dev); | ||
256 | |||
257 | return sprintf(buf, "%u\n", | ||
258 | jiffies_to_msecs(jiffies - udev->connect_time)); | ||
259 | } | ||
260 | |||
261 | static DEVICE_ATTR(connected_duration, S_IRUGO, show_connected_duration, NULL); | ||
262 | |||
263 | /* | ||
264 | * If the device is resumed, the last time the device was suspended has | ||
265 | * been pre-subtracted from active_duration. We add the current time to | ||
266 | * get the duration that the device was actually active. | ||
267 | * | ||
268 | * If the device is suspended, the active_duration is up-to-date. | ||
269 | */ | ||
270 | static ssize_t | ||
271 | show_active_duration(struct device *dev, struct device_attribute *attr, | ||
272 | char *buf) | ||
273 | { | ||
274 | struct usb_device *udev = to_usb_device(dev); | ||
275 | int duration; | ||
276 | |||
277 | if (udev->state != USB_STATE_SUSPENDED) | ||
278 | duration = jiffies_to_msecs(jiffies + udev->active_duration); | ||
279 | else | ||
280 | duration = jiffies_to_msecs(udev->active_duration); | ||
281 | return sprintf(buf, "%u\n", duration); | ||
282 | } | ||
283 | |||
284 | static DEVICE_ATTR(active_duration, S_IRUGO, show_active_duration, NULL); | ||
285 | |||
286 | static ssize_t | ||
252 | show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) | 287 | show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) |
253 | { | 288 | { |
254 | struct usb_device *udev = to_usb_device(dev); | 289 | struct usb_device *udev = to_usb_device(dev); |
@@ -365,6 +400,14 @@ static int add_power_attributes(struct device *dev) | |||
365 | rc = sysfs_add_file_to_group(&dev->kobj, | 400 | rc = sysfs_add_file_to_group(&dev->kobj, |
366 | &dev_attr_level.attr, | 401 | &dev_attr_level.attr, |
367 | power_group); | 402 | power_group); |
403 | if (rc == 0) | ||
404 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
405 | &dev_attr_connected_duration.attr, | ||
406 | power_group); | ||
407 | if (rc == 0) | ||
408 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
409 | &dev_attr_active_duration.attr, | ||
410 | power_group); | ||
368 | } | 411 | } |
369 | return rc; | 412 | return rc; |
370 | } | 413 | } |
@@ -372,6 +415,12 @@ static int add_power_attributes(struct device *dev) | |||
372 | static void remove_power_attributes(struct device *dev) | 415 | static void remove_power_attributes(struct device *dev) |
373 | { | 416 | { |
374 | sysfs_remove_file_from_group(&dev->kobj, | 417 | sysfs_remove_file_from_group(&dev->kobj, |
418 | &dev_attr_active_duration.attr, | ||
419 | power_group); | ||
420 | sysfs_remove_file_from_group(&dev->kobj, | ||
421 | &dev_attr_connected_duration.attr, | ||
422 | power_group); | ||
423 | sysfs_remove_file_from_group(&dev->kobj, | ||
375 | &dev_attr_level.attr, | 424 | &dev_attr_level.attr, |
376 | power_group); | 425 | power_group); |
377 | sysfs_remove_file_from_group(&dev->kobj, | 426 | sysfs_remove_file_from_group(&dev->kobj, |
@@ -601,21 +650,21 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) | |||
601 | /* Interface Accociation Descriptor fields */ | 650 | /* Interface Accociation Descriptor fields */ |
602 | #define usb_intf_assoc_attr(field, format_string) \ | 651 | #define usb_intf_assoc_attr(field, format_string) \ |
603 | static ssize_t \ | 652 | static ssize_t \ |
604 | show_iad_##field (struct device *dev, struct device_attribute *attr, \ | 653 | show_iad_##field(struct device *dev, struct device_attribute *attr, \ |
605 | char *buf) \ | 654 | char *buf) \ |
606 | { \ | 655 | { \ |
607 | struct usb_interface *intf = to_usb_interface (dev); \ | 656 | struct usb_interface *intf = to_usb_interface(dev); \ |
608 | \ | 657 | \ |
609 | return sprintf (buf, format_string, \ | 658 | return sprintf(buf, format_string, \ |
610 | intf->intf_assoc->field); \ | 659 | intf->intf_assoc->field); \ |
611 | } \ | 660 | } \ |
612 | static DEVICE_ATTR(iad_##field, S_IRUGO, show_iad_##field, NULL); | 661 | static DEVICE_ATTR(iad_##field, S_IRUGO, show_iad_##field, NULL); |
613 | 662 | ||
614 | usb_intf_assoc_attr (bFirstInterface, "%02x\n") | 663 | usb_intf_assoc_attr(bFirstInterface, "%02x\n") |
615 | usb_intf_assoc_attr (bInterfaceCount, "%02d\n") | 664 | usb_intf_assoc_attr(bInterfaceCount, "%02d\n") |
616 | usb_intf_assoc_attr (bFunctionClass, "%02x\n") | 665 | usb_intf_assoc_attr(bFunctionClass, "%02x\n") |
617 | usb_intf_assoc_attr (bFunctionSubClass, "%02x\n") | 666 | usb_intf_assoc_attr(bFunctionSubClass, "%02x\n") |
618 | usb_intf_assoc_attr (bFunctionProtocol, "%02x\n") | 667 | usb_intf_assoc_attr(bFunctionProtocol, "%02x\n") |
619 | 668 | ||
620 | /* Interface fields */ | 669 | /* Interface fields */ |
621 | #define usb_intf_attr(field, format_string) \ | 670 | #define usb_intf_attr(field, format_string) \ |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index d05ead20081c..9d7e63292c01 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -42,6 +42,7 @@ void usb_init_urb(struct urb *urb) | |||
42 | INIT_LIST_HEAD(&urb->anchor_list); | 42 | INIT_LIST_HEAD(&urb->anchor_list); |
43 | } | 43 | } |
44 | } | 44 | } |
45 | EXPORT_SYMBOL_GPL(usb_init_urb); | ||
45 | 46 | ||
46 | /** | 47 | /** |
47 | * usb_alloc_urb - creates a new urb for a USB driver to use | 48 | * usb_alloc_urb - creates a new urb for a USB driver to use |
@@ -73,6 +74,7 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) | |||
73 | usb_init_urb(urb); | 74 | usb_init_urb(urb); |
74 | return urb; | 75 | return urb; |
75 | } | 76 | } |
77 | EXPORT_SYMBOL_GPL(usb_alloc_urb); | ||
76 | 78 | ||
77 | /** | 79 | /** |
78 | * usb_free_urb - frees the memory used by a urb when all users of it are finished | 80 | * usb_free_urb - frees the memory used by a urb when all users of it are finished |
@@ -89,6 +91,7 @@ void usb_free_urb(struct urb *urb) | |||
89 | if (urb) | 91 | if (urb) |
90 | kref_put(&urb->kref, urb_destroy); | 92 | kref_put(&urb->kref, urb_destroy); |
91 | } | 93 | } |
94 | EXPORT_SYMBOL_GPL(usb_free_urb); | ||
92 | 95 | ||
93 | /** | 96 | /** |
94 | * usb_get_urb - increments the reference count of the urb | 97 | * usb_get_urb - increments the reference count of the urb |
@@ -100,12 +103,13 @@ void usb_free_urb(struct urb *urb) | |||
100 | * | 103 | * |
101 | * A pointer to the urb with the incremented reference counter is returned. | 104 | * A pointer to the urb with the incremented reference counter is returned. |
102 | */ | 105 | */ |
103 | struct urb * usb_get_urb(struct urb *urb) | 106 | struct urb *usb_get_urb(struct urb *urb) |
104 | { | 107 | { |
105 | if (urb) | 108 | if (urb) |
106 | kref_get(&urb->kref); | 109 | kref_get(&urb->kref); |
107 | return urb; | 110 | return urb; |
108 | } | 111 | } |
112 | EXPORT_SYMBOL_GPL(usb_get_urb); | ||
109 | 113 | ||
110 | /** | 114 | /** |
111 | * usb_anchor_urb - anchors an URB while it is processed | 115 | * usb_anchor_urb - anchors an URB while it is processed |
@@ -172,7 +176,7 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); | |||
172 | * describing that request to the USB subsystem. Request completion will | 176 | * describing that request to the USB subsystem. Request completion will |
173 | * be indicated later, asynchronously, by calling the completion handler. | 177 | * be indicated later, asynchronously, by calling the completion handler. |
174 | * The three types of completion are success, error, and unlink | 178 | * The three types of completion are success, error, and unlink |
175 | * (a software-induced fault, also called "request cancellation"). | 179 | * (a software-induced fault, also called "request cancellation"). |
176 | * | 180 | * |
177 | * URBs may be submitted in interrupt context. | 181 | * URBs may be submitted in interrupt context. |
178 | * | 182 | * |
@@ -255,7 +259,7 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); | |||
255 | * semaphores), or | 259 | * semaphores), or |
256 | * (c) current->state != TASK_RUNNING, this is the case only after | 260 | * (c) current->state != TASK_RUNNING, this is the case only after |
257 | * you've changed it. | 261 | * you've changed it. |
258 | * | 262 | * |
259 | * GFP_NOIO is used in the block io path and error handling of storage | 263 | * GFP_NOIO is used in the block io path and error handling of storage |
260 | * devices. | 264 | * devices. |
261 | * | 265 | * |
@@ -284,7 +288,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
284 | 288 | ||
285 | if (!urb || urb->hcpriv || !urb->complete) | 289 | if (!urb || urb->hcpriv || !urb->complete) |
286 | return -EINVAL; | 290 | return -EINVAL; |
287 | if (!(dev = urb->dev) || dev->state < USB_STATE_DEFAULT) | 291 | dev = urb->dev; |
292 | if ((!dev) || (dev->state < USB_STATE_DEFAULT)) | ||
288 | return -ENODEV; | 293 | return -ENODEV; |
289 | 294 | ||
290 | /* For now, get the endpoint from the pipe. Eventually drivers | 295 | /* For now, get the endpoint from the pipe. Eventually drivers |
@@ -347,11 +352,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
347 | max *= mult; | 352 | max *= mult; |
348 | } | 353 | } |
349 | 354 | ||
350 | if (urb->number_of_packets <= 0) | 355 | if (urb->number_of_packets <= 0) |
351 | return -EINVAL; | 356 | return -EINVAL; |
352 | for (n = 0; n < urb->number_of_packets; n++) { | 357 | for (n = 0; n < urb->number_of_packets; n++) { |
353 | len = urb->iso_frame_desc[n].length; | 358 | len = urb->iso_frame_desc[n].length; |
354 | if (len < 0 || len > max) | 359 | if (len < 0 || len > max) |
355 | return -EMSGSIZE; | 360 | return -EMSGSIZE; |
356 | urb->iso_frame_desc[n].status = -EXDEV; | 361 | urb->iso_frame_desc[n].status = -EXDEV; |
357 | urb->iso_frame_desc[n].actual_length = 0; | 362 | urb->iso_frame_desc[n].actual_length = 0; |
@@ -416,7 +421,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
416 | /* too big? */ | 421 | /* too big? */ |
417 | switch (dev->speed) { | 422 | switch (dev->speed) { |
418 | case USB_SPEED_HIGH: /* units are microframes */ | 423 | case USB_SPEED_HIGH: /* units are microframes */ |
419 | // NOTE usb handles 2^15 | 424 | /* NOTE usb handles 2^15 */ |
420 | if (urb->interval > (1024 * 8)) | 425 | if (urb->interval > (1024 * 8)) |
421 | urb->interval = 1024 * 8; | 426 | urb->interval = 1024 * 8; |
422 | max = 1024 * 8; | 427 | max = 1024 * 8; |
@@ -426,12 +431,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
426 | if (xfertype == USB_ENDPOINT_XFER_INT) { | 431 | if (xfertype == USB_ENDPOINT_XFER_INT) { |
427 | if (urb->interval > 255) | 432 | if (urb->interval > 255) |
428 | return -EINVAL; | 433 | return -EINVAL; |
429 | // NOTE ohci only handles up to 32 | 434 | /* NOTE ohci only handles up to 32 */ |
430 | max = 128; | 435 | max = 128; |
431 | } else { | 436 | } else { |
432 | if (urb->interval > 1024) | 437 | if (urb->interval > 1024) |
433 | urb->interval = 1024; | 438 | urb->interval = 1024; |
434 | // NOTE usb and ohci handle up to 2^15 | 439 | /* NOTE usb and ohci handle up to 2^15 */ |
435 | max = 1024; | 440 | max = 1024; |
436 | } | 441 | } |
437 | break; | 442 | break; |
@@ -444,6 +449,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
444 | 449 | ||
445 | return usb_hcd_submit_urb(urb, mem_flags); | 450 | return usb_hcd_submit_urb(urb, mem_flags); |
446 | } | 451 | } |
452 | EXPORT_SYMBOL_GPL(usb_submit_urb); | ||
447 | 453 | ||
448 | /*-------------------------------------------------------------------*/ | 454 | /*-------------------------------------------------------------------*/ |
449 | 455 | ||
@@ -514,6 +520,7 @@ int usb_unlink_urb(struct urb *urb) | |||
514 | return -EIDRM; | 520 | return -EIDRM; |
515 | return usb_hcd_unlink_urb(urb, -ECONNRESET); | 521 | return usb_hcd_unlink_urb(urb, -ECONNRESET); |
516 | } | 522 | } |
523 | EXPORT_SYMBOL_GPL(usb_unlink_urb); | ||
517 | 524 | ||
518 | /** | 525 | /** |
519 | * usb_kill_urb - cancel a transfer request and wait for it to finish | 526 | * usb_kill_urb - cancel a transfer request and wait for it to finish |
@@ -553,6 +560,7 @@ void usb_kill_urb(struct urb *urb) | |||
553 | --urb->reject; | 560 | --urb->reject; |
554 | mutex_unlock(&reject_mutex); | 561 | mutex_unlock(&reject_mutex); |
555 | } | 562 | } |
563 | EXPORT_SYMBOL_GPL(usb_kill_urb); | ||
556 | 564 | ||
557 | /** | 565 | /** |
558 | * usb_kill_anchored_urbs - cancel transfer requests en masse | 566 | * usb_kill_anchored_urbs - cancel transfer requests en masse |
@@ -567,7 +575,8 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor) | |||
567 | 575 | ||
568 | spin_lock_irq(&anchor->lock); | 576 | spin_lock_irq(&anchor->lock); |
569 | while (!list_empty(&anchor->urb_list)) { | 577 | while (!list_empty(&anchor->urb_list)) { |
570 | victim = list_entry(anchor->urb_list.prev, struct urb, anchor_list); | 578 | victim = list_entry(anchor->urb_list.prev, struct urb, |
579 | anchor_list); | ||
571 | /* we must make sure the URB isn't freed before we kill it*/ | 580 | /* we must make sure the URB isn't freed before we kill it*/ |
572 | usb_get_urb(victim); | 581 | usb_get_urb(victim); |
573 | spin_unlock_irq(&anchor->lock); | 582 | spin_unlock_irq(&anchor->lock); |
@@ -595,11 +604,3 @@ int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, | |||
595 | msecs_to_jiffies(timeout)); | 604 | msecs_to_jiffies(timeout)); |
596 | } | 605 | } |
597 | EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout); | 606 | EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout); |
598 | |||
599 | EXPORT_SYMBOL(usb_init_urb); | ||
600 | EXPORT_SYMBOL(usb_alloc_urb); | ||
601 | EXPORT_SYMBOL(usb_free_urb); | ||
602 | EXPORT_SYMBOL(usb_get_urb); | ||
603 | EXPORT_SYMBOL(usb_submit_urb); | ||
604 | EXPORT_SYMBOL(usb_unlink_urb); | ||
605 | EXPORT_SYMBOL(usb_kill_urb); | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8f142370103d..4e984060c984 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -96,6 +96,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev, | |||
96 | 96 | ||
97 | return NULL; | 97 | return NULL; |
98 | } | 98 | } |
99 | EXPORT_SYMBOL_GPL(usb_ifnum_to_if); | ||
99 | 100 | ||
100 | /** | 101 | /** |
101 | * usb_altnum_to_altsetting - get the altsetting structure with a given | 102 | * usb_altnum_to_altsetting - get the altsetting structure with a given |
@@ -115,8 +116,9 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev, | |||
115 | * Don't call this function unless you are bound to the intf interface | 116 | * Don't call this function unless you are bound to the intf interface |
116 | * or you have locked the device! | 117 | * or you have locked the device! |
117 | */ | 118 | */ |
118 | struct usb_host_interface *usb_altnum_to_altsetting(const struct usb_interface *intf, | 119 | struct usb_host_interface *usb_altnum_to_altsetting( |
119 | unsigned int altnum) | 120 | const struct usb_interface *intf, |
121 | unsigned int altnum) | ||
120 | { | 122 | { |
121 | int i; | 123 | int i; |
122 | 124 | ||
@@ -126,13 +128,14 @@ struct usb_host_interface *usb_altnum_to_altsetting(const struct usb_interface * | |||
126 | } | 128 | } |
127 | return NULL; | 129 | return NULL; |
128 | } | 130 | } |
131 | EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting); | ||
129 | 132 | ||
130 | struct find_interface_arg { | 133 | struct find_interface_arg { |
131 | int minor; | 134 | int minor; |
132 | struct usb_interface *interface; | 135 | struct usb_interface *interface; |
133 | }; | 136 | }; |
134 | 137 | ||
135 | static int __find_interface(struct device * dev, void * data) | 138 | static int __find_interface(struct device *dev, void *data) |
136 | { | 139 | { |
137 | struct find_interface_arg *arg = data; | 140 | struct find_interface_arg *arg = data; |
138 | struct usb_interface *intf; | 141 | struct usb_interface *intf; |
@@ -154,7 +157,7 @@ static int __find_interface(struct device * dev, void * data) | |||
154 | * @drv: the driver whose current configuration is considered | 157 | * @drv: the driver whose current configuration is considered |
155 | * @minor: the minor number of the desired device | 158 | * @minor: the minor number of the desired device |
156 | * | 159 | * |
157 | * This walks the driver device list and returns a pointer to the interface | 160 | * This walks the driver device list and returns a pointer to the interface |
158 | * with the matching minor. Note, this only works for devices that share the | 161 | * with the matching minor. Note, this only works for devices that share the |
159 | * USB major number. | 162 | * USB major number. |
160 | */ | 163 | */ |
@@ -170,6 +173,7 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | |||
170 | __find_interface); | 173 | __find_interface); |
171 | return argb.interface; | 174 | return argb.interface; |
172 | } | 175 | } |
176 | EXPORT_SYMBOL_GPL(usb_find_interface); | ||
173 | 177 | ||
174 | /** | 178 | /** |
175 | * usb_release_dev - free a usb device structure when all users of it are finished. | 179 | * usb_release_dev - free a usb device structure when all users of it are finished. |
@@ -230,7 +234,7 @@ static int ksuspend_usb_init(void) | |||
230 | * singlethreaded. Its job doesn't justify running on more | 234 | * singlethreaded. Its job doesn't justify running on more |
231 | * than one CPU. | 235 | * than one CPU. |
232 | */ | 236 | */ |
233 | ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd"); | 237 | ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd"); |
234 | if (!ksuspend_usb_wq) | 238 | if (!ksuspend_usb_wq) |
235 | return -ENOMEM; | 239 | return -ENOMEM; |
236 | return 0; | 240 | return 0; |
@@ -269,8 +273,8 @@ static unsigned usb_bus_is_wusb(struct usb_bus *bus) | |||
269 | * | 273 | * |
270 | * This call may not be used in a non-sleeping context. | 274 | * This call may not be used in a non-sleeping context. |
271 | */ | 275 | */ |
272 | struct usb_device * | 276 | struct usb_device *usb_alloc_dev(struct usb_device *parent, |
273 | usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | 277 | struct usb_bus *bus, unsigned port1) |
274 | { | 278 | { |
275 | struct usb_device *dev; | 279 | struct usb_device *dev; |
276 | struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); | 280 | struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); |
@@ -339,6 +343,8 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
339 | mutex_init(&dev->pm_mutex); | 343 | mutex_init(&dev->pm_mutex); |
340 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); | 344 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); |
341 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; | 345 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; |
346 | dev->connect_time = jiffies; | ||
347 | dev->active_duration = -jiffies; | ||
342 | #endif | 348 | #endif |
343 | if (root_hub) /* Root hub always ok [and always wired] */ | 349 | if (root_hub) /* Root hub always ok [and always wired] */ |
344 | dev->authorized = 1; | 350 | dev->authorized = 1; |
@@ -367,6 +373,7 @@ struct usb_device *usb_get_dev(struct usb_device *dev) | |||
367 | get_device(&dev->dev); | 373 | get_device(&dev->dev); |
368 | return dev; | 374 | return dev; |
369 | } | 375 | } |
376 | EXPORT_SYMBOL_GPL(usb_get_dev); | ||
370 | 377 | ||
371 | /** | 378 | /** |
372 | * usb_put_dev - release a use of the usb device structure | 379 | * usb_put_dev - release a use of the usb device structure |
@@ -380,6 +387,7 @@ void usb_put_dev(struct usb_device *dev) | |||
380 | if (dev) | 387 | if (dev) |
381 | put_device(&dev->dev); | 388 | put_device(&dev->dev); |
382 | } | 389 | } |
390 | EXPORT_SYMBOL_GPL(usb_put_dev); | ||
383 | 391 | ||
384 | /** | 392 | /** |
385 | * usb_get_intf - increments the reference count of the usb interface structure | 393 | * usb_get_intf - increments the reference count of the usb interface structure |
@@ -400,6 +408,7 @@ struct usb_interface *usb_get_intf(struct usb_interface *intf) | |||
400 | get_device(&intf->dev); | 408 | get_device(&intf->dev); |
401 | return intf; | 409 | return intf; |
402 | } | 410 | } |
411 | EXPORT_SYMBOL_GPL(usb_get_intf); | ||
403 | 412 | ||
404 | /** | 413 | /** |
405 | * usb_put_intf - release a use of the usb interface structure | 414 | * usb_put_intf - release a use of the usb interface structure |
@@ -414,7 +423,7 @@ void usb_put_intf(struct usb_interface *intf) | |||
414 | if (intf) | 423 | if (intf) |
415 | put_device(&intf->dev); | 424 | put_device(&intf->dev); |
416 | } | 425 | } |
417 | 426 | EXPORT_SYMBOL_GPL(usb_put_intf); | |
418 | 427 | ||
419 | /* USB device locking | 428 | /* USB device locking |
420 | * | 429 | * |
@@ -461,11 +470,11 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
461 | return -EHOSTUNREACH; | 470 | return -EHOSTUNREACH; |
462 | if (iface) { | 471 | if (iface) { |
463 | switch (iface->condition) { | 472 | switch (iface->condition) { |
464 | case USB_INTERFACE_BINDING: | 473 | case USB_INTERFACE_BINDING: |
465 | return 0; | 474 | return 0; |
466 | case USB_INTERFACE_BOUND: | 475 | case USB_INTERFACE_BOUND: |
467 | break; | 476 | break; |
468 | default: | 477 | default: |
469 | return -EINTR; | 478 | return -EINTR; |
470 | } | 479 | } |
471 | } | 480 | } |
@@ -487,7 +496,7 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
487 | } | 496 | } |
488 | return 1; | 497 | return 1; |
489 | } | 498 | } |
490 | 499 | EXPORT_SYMBOL_GPL(usb_lock_device_for_reset); | |
491 | 500 | ||
492 | static struct usb_device *match_device(struct usb_device *dev, | 501 | static struct usb_device *match_device(struct usb_device *dev, |
493 | u16 vendor_id, u16 product_id) | 502 | u16 vendor_id, u16 product_id) |
@@ -540,10 +549,10 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id) | |||
540 | struct list_head *buslist; | 549 | struct list_head *buslist; |
541 | struct usb_bus *bus; | 550 | struct usb_bus *bus; |
542 | struct usb_device *dev = NULL; | 551 | struct usb_device *dev = NULL; |
543 | 552 | ||
544 | mutex_lock(&usb_bus_list_lock); | 553 | mutex_lock(&usb_bus_list_lock); |
545 | for (buslist = usb_bus_list.next; | 554 | for (buslist = usb_bus_list.next; |
546 | buslist != &usb_bus_list; | 555 | buslist != &usb_bus_list; |
547 | buslist = buslist->next) { | 556 | buslist = buslist->next) { |
548 | bus = container_of(buslist, struct usb_bus, bus_list); | 557 | bus = container_of(buslist, struct usb_bus, bus_list); |
549 | if (!bus->root_hub) | 558 | if (!bus->root_hub) |
@@ -576,6 +585,7 @@ int usb_get_current_frame_number(struct usb_device *dev) | |||
576 | { | 585 | { |
577 | return usb_hcd_get_frame_number(dev); | 586 | return usb_hcd_get_frame_number(dev); |
578 | } | 587 | } |
588 | EXPORT_SYMBOL_GPL(usb_get_current_frame_number); | ||
579 | 589 | ||
580 | /*-------------------------------------------------------------------*/ | 590 | /*-------------------------------------------------------------------*/ |
581 | /* | 591 | /* |
@@ -584,7 +594,7 @@ int usb_get_current_frame_number(struct usb_device *dev) | |||
584 | */ | 594 | */ |
585 | 595 | ||
586 | int __usb_get_extra_descriptor(char *buffer, unsigned size, | 596 | int __usb_get_extra_descriptor(char *buffer, unsigned size, |
587 | unsigned char type, void **ptr) | 597 | unsigned char type, void **ptr) |
588 | { | 598 | { |
589 | struct usb_descriptor_header *header; | 599 | struct usb_descriptor_header *header; |
590 | 600 | ||
@@ -595,7 +605,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, | |||
595 | printk(KERN_ERR | 605 | printk(KERN_ERR |
596 | "%s: bogus descriptor, type %d length %d\n", | 606 | "%s: bogus descriptor, type %d length %d\n", |
597 | usbcore_name, | 607 | usbcore_name, |
598 | header->bDescriptorType, | 608 | header->bDescriptorType, |
599 | header->bLength); | 609 | header->bLength); |
600 | return -1; | 610 | return -1; |
601 | } | 611 | } |
@@ -610,6 +620,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, | |||
610 | } | 620 | } |
611 | return -1; | 621 | return -1; |
612 | } | 622 | } |
623 | EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor); | ||
613 | 624 | ||
614 | /** | 625 | /** |
615 | * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP | 626 | * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP |
@@ -633,17 +644,14 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, | |||
633 | * | 644 | * |
634 | * When the buffer is no longer used, free it with usb_buffer_free(). | 645 | * When the buffer is no longer used, free it with usb_buffer_free(). |
635 | */ | 646 | */ |
636 | void *usb_buffer_alloc( | 647 | void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags, |
637 | struct usb_device *dev, | 648 | dma_addr_t *dma) |
638 | size_t size, | ||
639 | gfp_t mem_flags, | ||
640 | dma_addr_t *dma | ||
641 | ) | ||
642 | { | 649 | { |
643 | if (!dev || !dev->bus) | 650 | if (!dev || !dev->bus) |
644 | return NULL; | 651 | return NULL; |
645 | return hcd_buffer_alloc(dev->bus, size, mem_flags, dma); | 652 | return hcd_buffer_alloc(dev->bus, size, mem_flags, dma); |
646 | } | 653 | } |
654 | EXPORT_SYMBOL_GPL(usb_buffer_alloc); | ||
647 | 655 | ||
648 | /** | 656 | /** |
649 | * usb_buffer_free - free memory allocated with usb_buffer_alloc() | 657 | * usb_buffer_free - free memory allocated with usb_buffer_alloc() |
@@ -656,12 +664,8 @@ void *usb_buffer_alloc( | |||
656 | * been allocated using usb_buffer_alloc(), and the parameters must match | 664 | * been allocated using usb_buffer_alloc(), and the parameters must match |
657 | * those provided in that allocation request. | 665 | * those provided in that allocation request. |
658 | */ | 666 | */ |
659 | void usb_buffer_free( | 667 | void usb_buffer_free(struct usb_device *dev, size_t size, void *addr, |
660 | struct usb_device *dev, | 668 | dma_addr_t dma) |
661 | size_t size, | ||
662 | void *addr, | ||
663 | dma_addr_t dma | ||
664 | ) | ||
665 | { | 669 | { |
666 | if (!dev || !dev->bus) | 670 | if (!dev || !dev->bus) |
667 | return; | 671 | return; |
@@ -669,6 +673,7 @@ void usb_buffer_free( | |||
669 | return; | 673 | return; |
670 | hcd_buffer_free(dev->bus, size, addr, dma); | 674 | hcd_buffer_free(dev->bus, size, addr, dma); |
671 | } | 675 | } |
676 | EXPORT_SYMBOL_GPL(usb_buffer_free); | ||
672 | 677 | ||
673 | /** | 678 | /** |
674 | * usb_buffer_map - create DMA mapping(s) for an urb | 679 | * usb_buffer_map - create DMA mapping(s) for an urb |
@@ -708,14 +713,15 @@ struct urb *usb_buffer_map(struct urb *urb) | |||
708 | urb->setup_packet, | 713 | urb->setup_packet, |
709 | sizeof(struct usb_ctrlrequest), | 714 | sizeof(struct usb_ctrlrequest), |
710 | DMA_TO_DEVICE); | 715 | DMA_TO_DEVICE); |
711 | // FIXME generic api broken like pci, can't report errors | 716 | /* FIXME generic api broken like pci, can't report errors */ |
712 | // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; | 717 | /* if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; */ |
713 | } else | 718 | } else |
714 | urb->transfer_dma = ~0; | 719 | urb->transfer_dma = ~0; |
715 | urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | 720 | urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP |
716 | | URB_NO_SETUP_DMA_MAP); | 721 | | URB_NO_SETUP_DMA_MAP); |
717 | return urb; | 722 | return urb; |
718 | } | 723 | } |
724 | EXPORT_SYMBOL_GPL(usb_buffer_map); | ||
719 | #endif /* 0 */ | 725 | #endif /* 0 */ |
720 | 726 | ||
721 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 727 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
@@ -753,6 +759,7 @@ void usb_buffer_dmasync(struct urb *urb) | |||
753 | DMA_TO_DEVICE); | 759 | DMA_TO_DEVICE); |
754 | } | 760 | } |
755 | } | 761 | } |
762 | EXPORT_SYMBOL_GPL(usb_buffer_dmasync); | ||
756 | #endif | 763 | #endif |
757 | 764 | ||
758 | /** | 765 | /** |
@@ -788,6 +795,7 @@ void usb_buffer_unmap(struct urb *urb) | |||
788 | urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP | 795 | urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP |
789 | | URB_NO_SETUP_DMA_MAP); | 796 | | URB_NO_SETUP_DMA_MAP); |
790 | } | 797 | } |
798 | EXPORT_SYMBOL_GPL(usb_buffer_unmap); | ||
791 | #endif /* 0 */ | 799 | #endif /* 0 */ |
792 | 800 | ||
793 | /** | 801 | /** |
@@ -828,10 +836,11 @@ int usb_buffer_map_sg(const struct usb_device *dev, int is_in, | |||
828 | || !controller->dma_mask) | 836 | || !controller->dma_mask) |
829 | return -1; | 837 | return -1; |
830 | 838 | ||
831 | // FIXME generic api broken like pci, can't report errors | 839 | /* FIXME generic api broken like pci, can't report errors */ |
832 | return dma_map_sg(controller, sg, nents, | 840 | return dma_map_sg(controller, sg, nents, |
833 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 841 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
834 | } | 842 | } |
843 | EXPORT_SYMBOL_GPL(usb_buffer_map_sg); | ||
835 | 844 | ||
836 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 845 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
837 | * XXX please determine whether the sync is to transfer ownership of | 846 | * XXX please determine whether the sync is to transfer ownership of |
@@ -865,6 +874,7 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, | |||
865 | dma_sync_sg(controller, sg, n_hw_ents, | 874 | dma_sync_sg(controller, sg, n_hw_ents, |
866 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 875 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
867 | } | 876 | } |
877 | EXPORT_SYMBOL_GPL(usb_buffer_dmasync_sg); | ||
868 | #endif | 878 | #endif |
869 | 879 | ||
870 | /** | 880 | /** |
@@ -891,6 +901,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, | |||
891 | dma_unmap_sg(controller, sg, n_hw_ents, | 901 | dma_unmap_sg(controller, sg, n_hw_ents, |
892 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 902 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
893 | } | 903 | } |
904 | EXPORT_SYMBOL_GPL(usb_buffer_unmap_sg); | ||
894 | 905 | ||
895 | /* format to disable USB on kernel command line is: nousb */ | 906 | /* format to disable USB on kernel command line is: nousb */ |
896 | __module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444); | 907 | __module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444); |
@@ -902,6 +913,7 @@ int usb_disabled(void) | |||
902 | { | 913 | { |
903 | return nousb; | 914 | return nousb; |
904 | } | 915 | } |
916 | EXPORT_SYMBOL_GPL(usb_disabled); | ||
905 | 917 | ||
906 | /* | 918 | /* |
907 | * Init | 919 | * Init |
@@ -918,7 +930,7 @@ static int __init usb_init(void) | |||
918 | if (retval) | 930 | if (retval) |
919 | goto out; | 931 | goto out; |
920 | retval = bus_register(&usb_bus_type); | 932 | retval = bus_register(&usb_bus_type); |
921 | if (retval) | 933 | if (retval) |
922 | goto bus_register_failed; | 934 | goto bus_register_failed; |
923 | retval = usb_host_init(); | 935 | retval = usb_host_init(); |
924 | if (retval) | 936 | if (retval) |
@@ -983,45 +995,4 @@ static void __exit usb_exit(void) | |||
983 | 995 | ||
984 | subsys_initcall(usb_init); | 996 | subsys_initcall(usb_init); |
985 | module_exit(usb_exit); | 997 | module_exit(usb_exit); |
986 | |||
987 | /* | ||
988 | * USB may be built into the kernel or be built as modules. | ||
989 | * These symbols are exported for device (or host controller) | ||
990 | * driver modules to use. | ||
991 | */ | ||
992 | |||
993 | EXPORT_SYMBOL(usb_disabled); | ||
994 | |||
995 | EXPORT_SYMBOL_GPL(usb_get_intf); | ||
996 | EXPORT_SYMBOL_GPL(usb_put_intf); | ||
997 | |||
998 | EXPORT_SYMBOL(usb_put_dev); | ||
999 | EXPORT_SYMBOL(usb_get_dev); | ||
1000 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); | ||
1001 | |||
1002 | EXPORT_SYMBOL(usb_lock_device_for_reset); | ||
1003 | |||
1004 | EXPORT_SYMBOL(usb_find_interface); | ||
1005 | EXPORT_SYMBOL(usb_ifnum_to_if); | ||
1006 | EXPORT_SYMBOL(usb_altnum_to_altsetting); | ||
1007 | |||
1008 | EXPORT_SYMBOL(__usb_get_extra_descriptor); | ||
1009 | |||
1010 | EXPORT_SYMBOL(usb_get_current_frame_number); | ||
1011 | |||
1012 | EXPORT_SYMBOL(usb_buffer_alloc); | ||
1013 | EXPORT_SYMBOL(usb_buffer_free); | ||
1014 | |||
1015 | #if 0 | ||
1016 | EXPORT_SYMBOL(usb_buffer_map); | ||
1017 | EXPORT_SYMBOL(usb_buffer_dmasync); | ||
1018 | EXPORT_SYMBOL(usb_buffer_unmap); | ||
1019 | #endif | ||
1020 | |||
1021 | EXPORT_SYMBOL(usb_buffer_map_sg); | ||
1022 | #if 0 | ||
1023 | EXPORT_SYMBOL(usb_buffer_dmasync_sg); | ||
1024 | #endif | ||
1025 | EXPORT_SYMBOL(usb_buffer_unmap_sg); | ||
1026 | |||
1027 | MODULE_LICENSE("GPL"); | 998 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index c52626c51f70..2375194a9d43 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -1,22 +1,23 @@ | |||
1 | /* Functions local to drivers/usb/core/ */ | 1 | /* Functions local to drivers/usb/core/ */ |
2 | 2 | ||
3 | extern int usb_create_sysfs_dev_files (struct usb_device *dev); | 3 | extern int usb_create_sysfs_dev_files(struct usb_device *dev); |
4 | extern void usb_remove_sysfs_dev_files (struct usb_device *dev); | 4 | extern void usb_remove_sysfs_dev_files(struct usb_device *dev); |
5 | extern int usb_create_sysfs_intf_files (struct usb_interface *intf); | 5 | extern int usb_create_sysfs_intf_files(struct usb_interface *intf); |
6 | extern void usb_remove_sysfs_intf_files (struct usb_interface *intf); | 6 | extern void usb_remove_sysfs_intf_files(struct usb_interface *intf); |
7 | extern int usb_create_ep_files(struct device *parent, struct usb_host_endpoint *endpoint, | 7 | extern int usb_create_ep_files(struct device *parent, |
8 | struct usb_host_endpoint *endpoint, | ||
8 | struct usb_device *udev); | 9 | struct usb_device *udev); |
9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); | 10 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); |
10 | 11 | ||
11 | extern void usb_enable_endpoint(struct usb_device *dev, | 12 | extern void usb_enable_endpoint(struct usb_device *dev, |
12 | struct usb_host_endpoint *ep); | 13 | struct usb_host_endpoint *ep); |
13 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); | 14 | extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr); |
14 | extern void usb_disable_interface (struct usb_device *dev, | 15 | extern void usb_disable_interface(struct usb_device *dev, |
15 | struct usb_interface *intf); | 16 | struct usb_interface *intf); |
16 | extern void usb_release_interface_cache(struct kref *ref); | 17 | extern void usb_release_interface_cache(struct kref *ref); |
17 | extern void usb_disable_device (struct usb_device *dev, int skip_ep0); | 18 | extern void usb_disable_device(struct usb_device *dev, int skip_ep0); |
18 | extern int usb_deauthorize_device (struct usb_device *); | 19 | extern int usb_deauthorize_device(struct usb_device *); |
19 | extern int usb_authorize_device (struct usb_device *); | 20 | extern int usb_authorize_device(struct usb_device *); |
20 | extern void usb_detect_quirks(struct usb_device *udev); | 21 | extern void usb_detect_quirks(struct usb_device *udev); |
21 | 22 | ||
22 | extern int usb_get_device_descriptor(struct usb_device *dev, | 23 | extern int usb_get_device_descriptor(struct usb_device *dev, |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 77a3759d6fc7..c13955164686 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -12,10 +12,9 @@ | |||
12 | # With help from a special transceiver and a "Mini-AB" jack, systems with | 12 | # With help from a special transceiver and a "Mini-AB" jack, systems with |
13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). | 13 | # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). |
14 | # | 14 | # |
15 | menu "USB Gadget Support" | ||
16 | 15 | ||
17 | config USB_GADGET | 16 | menuconfig USB_GADGET |
18 | tristate "Support for USB Gadgets" | 17 | tristate "USB Gadget Support" |
19 | help | 18 | help |
20 | USB is a master/slave protocol, organized with one master | 19 | USB is a master/slave protocol, organized with one master |
21 | host (such as a PC) controlling up to 127 peripheral devices. | 20 | host (such as a PC) controlling up to 127 peripheral devices. |
@@ -42,6 +41,8 @@ config USB_GADGET | |||
42 | For more information, see <http://www.linux-usb.org/gadget> and | 41 | For more information, see <http://www.linux-usb.org/gadget> and |
43 | the kernel DocBook documentation for this API. | 42 | the kernel DocBook documentation for this API. |
44 | 43 | ||
44 | if USB_GADGET | ||
45 | |||
45 | config USB_GADGET_DEBUG | 46 | config USB_GADGET_DEBUG |
46 | boolean "Debugging messages" | 47 | boolean "Debugging messages" |
47 | depends on USB_GADGET && DEBUG_KERNEL && EXPERIMENTAL | 48 | depends on USB_GADGET && DEBUG_KERNEL && EXPERIMENTAL |
@@ -220,6 +221,16 @@ config USB_M66592 | |||
220 | default USB_GADGET | 221 | default USB_GADGET |
221 | select USB_GADGET_SELECTED | 222 | select USB_GADGET_SELECTED |
222 | 223 | ||
224 | config SUPERH_BUILT_IN_M66592 | ||
225 | boolean "Enable SuperH built-in USB like the M66592" | ||
226 | depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722 | ||
227 | help | ||
228 | SH7722 has USB like the M66592. | ||
229 | |||
230 | The transfer rate is very slow when use "Ethernet Gadget". | ||
231 | However, this problem is improved if change a value of | ||
232 | NET_IP_ALIGN to 4. | ||
233 | |||
223 | config USB_GADGET_GOKU | 234 | config USB_GADGET_GOKU |
224 | boolean "Toshiba TC86C001 'Goku-S'" | 235 | boolean "Toshiba TC86C001 'Goku-S'" |
225 | depends on PCI | 236 | depends on PCI |
@@ -538,6 +549,20 @@ config USB_MIDI_GADGET | |||
538 | Say "y" to link the driver statically, or "m" to build a | 549 | Say "y" to link the driver statically, or "m" to build a |
539 | dynamically linked module called "g_midi". | 550 | dynamically linked module called "g_midi". |
540 | 551 | ||
552 | config USB_G_PRINTER | ||
553 | tristate "Printer Gadget" | ||
554 | help | ||
555 | The Printer Gadget channels data between the USB host and a | ||
556 | userspace program driving the print engine. The user space | ||
557 | program reads and writes the device file /dev/g_printer to | ||
558 | receive or send printer data. It can use ioctl calls to | ||
559 | the device file to get or set printer status. | ||
560 | |||
561 | Say "y" to link the driver statically, or "m" to build a | ||
562 | dynamically linked module called "g_printer". | ||
563 | |||
564 | For more information, see Documentation/usb/gadget_printer.txt | ||
565 | which includes sample code for accessing the device file. | ||
541 | 566 | ||
542 | # put drivers that need isochronous transfer support (for audio | 567 | # put drivers that need isochronous transfer support (for audio |
543 | # or video class gadget drivers), or specific hardware, here. | 568 | # or video class gadget drivers), or specific hardware, here. |
@@ -546,4 +571,4 @@ config USB_MIDI_GADGET | |||
546 | 571 | ||
547 | endchoice | 572 | endchoice |
548 | 573 | ||
549 | endmenu | 574 | endif # USB_GADGET |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 904e57bf6112..c3aab80b6c76 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -28,6 +28,8 @@ g_midi-objs := gmidi.o usbstring.o config.o epautoconf.o | |||
28 | gadgetfs-objs := inode.o | 28 | gadgetfs-objs := inode.o |
29 | g_file_storage-objs := file_storage.o usbstring.o config.o \ | 29 | g_file_storage-objs := file_storage.o usbstring.o config.o \ |
30 | epautoconf.o | 30 | epautoconf.o |
31 | g_printer-objs := printer.o usbstring.o config.o \ | ||
32 | epautoconf.o | ||
31 | 33 | ||
32 | ifeq ($(CONFIG_USB_ETH_RNDIS),y) | 34 | ifeq ($(CONFIG_USB_ETH_RNDIS),y) |
33 | g_ether-objs += rndis.o | 35 | g_ether-objs += rndis.o |
@@ -38,5 +40,6 @@ obj-$(CONFIG_USB_ETH) += g_ether.o | |||
38 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o | 40 | obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o |
39 | obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o | 41 | obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o |
40 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o | 42 | obj-$(CONFIG_USB_G_SERIAL) += g_serial.o |
43 | obj-$(CONFIG_USB_G_PRINTER) += g_printer.o | ||
41 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o | 44 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o |
42 | 45 | ||
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index c72e9620bf8d..b663f23f2642 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -1244,7 +1244,7 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) | |||
1244 | /* stop OUT naking */ | 1244 | /* stop OUT naking */ |
1245 | if (!ep->in) { | 1245 | if (!ep->in) { |
1246 | if (!use_dma && udc_rxfifo_pending) { | 1246 | if (!use_dma && udc_rxfifo_pending) { |
1247 | DBG(dev, "udc_queue(): pending bytes in" | 1247 | DBG(dev, "udc_queue(): pending bytes in " |
1248 | "rxfifo after nyet\n"); | 1248 | "rxfifo after nyet\n"); |
1249 | /* | 1249 | /* |
1250 | * read pending bytes afer nyet: | 1250 | * read pending bytes afer nyet: |
@@ -2038,6 +2038,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
2038 | spin_unlock_irqrestore(&dev->lock, flags); | 2038 | spin_unlock_irqrestore(&dev->lock, flags); |
2039 | 2039 | ||
2040 | driver->unbind(&dev->gadget); | 2040 | driver->unbind(&dev->gadget); |
2041 | dev->gadget.dev.driver = NULL; | ||
2041 | dev->driver = NULL; | 2042 | dev->driver = NULL; |
2042 | 2043 | ||
2043 | /* set SD */ | 2044 | /* set SD */ |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index cd62b029d176..a83e8b798ec9 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -21,8 +21,7 @@ | |||
21 | * Boston, MA 02111-1307, USA. | 21 | * Boston, MA 02111-1307, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #undef DEBUG | 24 | #undef VERBOSE_DEBUG |
25 | #undef VERBOSE | ||
26 | #undef PACKET_TRACE | 25 | #undef PACKET_TRACE |
27 | 26 | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -46,8 +45,8 @@ | |||
46 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
47 | #include <asm/system.h> | 46 | #include <asm/system.h> |
48 | #include <asm/mach-types.h> | 47 | #include <asm/mach-types.h> |
48 | #include <asm/gpio.h> | ||
49 | 49 | ||
50 | #include <asm/arch/gpio.h> | ||
51 | #include <asm/arch/board.h> | 50 | #include <asm/arch/board.h> |
52 | #include <asm/arch/cpu.h> | 51 | #include <asm/arch/cpu.h> |
53 | #include <asm/arch/at91sam9261_matrix.h> | 52 | #include <asm/arch/at91sam9261_matrix.h> |
@@ -580,7 +579,7 @@ static int at91_ep_disable (struct usb_ep * _ep) | |||
580 | */ | 579 | */ |
581 | 580 | ||
582 | static struct usb_request * | 581 | static struct usb_request * |
583 | at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags) | 582 | at91_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) |
584 | { | 583 | { |
585 | struct at91_request *req; | 584 | struct at91_request *req; |
586 | 585 | ||
@@ -881,6 +880,8 @@ static void clk_off(struct at91_udc *udc) | |||
881 | */ | 880 | */ |
882 | static void pullup(struct at91_udc *udc, int is_on) | 881 | static void pullup(struct at91_udc *udc, int is_on) |
883 | { | 882 | { |
883 | int active = !udc->board.pullup_active_low; | ||
884 | |||
884 | if (!udc->enabled || !udc->vbus) | 885 | if (!udc->enabled || !udc->vbus) |
885 | is_on = 0; | 886 | is_on = 0; |
886 | DBG("%sactive\n", is_on ? "" : "in"); | 887 | DBG("%sactive\n", is_on ? "" : "in"); |
@@ -890,7 +891,7 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
890 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); | 891 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); |
891 | at91_udp_write(udc, AT91_UDP_TXVC, 0); | 892 | at91_udp_write(udc, AT91_UDP_TXVC, 0); |
892 | if (cpu_is_at91rm9200()) | 893 | if (cpu_is_at91rm9200()) |
893 | at91_set_gpio_value(udc->board.pullup_pin, 1); | 894 | gpio_set_value(udc->board.pullup_pin, active); |
894 | else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { | 895 | else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { |
895 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | 896 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); |
896 | 897 | ||
@@ -908,7 +909,7 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
908 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); | 909 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); |
909 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 910 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
910 | if (cpu_is_at91rm9200()) | 911 | if (cpu_is_at91rm9200()) |
911 | at91_set_gpio_value(udc->board.pullup_pin, 0); | 912 | gpio_set_value(udc->board.pullup_pin, !active); |
912 | else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { | 913 | else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { |
913 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | 914 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); |
914 | 915 | ||
@@ -1153,7 +1154,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1153 | | USB_REQ_GET_STATUS: | 1154 | | USB_REQ_GET_STATUS: |
1154 | tmp = w_index & USB_ENDPOINT_NUMBER_MASK; | 1155 | tmp = w_index & USB_ENDPOINT_NUMBER_MASK; |
1155 | ep = &udc->ep[tmp]; | 1156 | ep = &udc->ep[tmp]; |
1156 | if (tmp > NUM_ENDPOINTS || (tmp && !ep->desc)) | 1157 | if (tmp >= NUM_ENDPOINTS || (tmp && !ep->desc)) |
1157 | goto stall; | 1158 | goto stall; |
1158 | 1159 | ||
1159 | if (tmp) { | 1160 | if (tmp) { |
@@ -1176,7 +1177,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1176 | | USB_REQ_SET_FEATURE: | 1177 | | USB_REQ_SET_FEATURE: |
1177 | tmp = w_index & USB_ENDPOINT_NUMBER_MASK; | 1178 | tmp = w_index & USB_ENDPOINT_NUMBER_MASK; |
1178 | ep = &udc->ep[tmp]; | 1179 | ep = &udc->ep[tmp]; |
1179 | if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS) | 1180 | if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS) |
1180 | goto stall; | 1181 | goto stall; |
1181 | if (!ep->desc || ep->is_iso) | 1182 | if (!ep->desc || ep->is_iso) |
1182 | goto stall; | 1183 | goto stall; |
@@ -1195,7 +1196,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1195 | | USB_REQ_CLEAR_FEATURE: | 1196 | | USB_REQ_CLEAR_FEATURE: |
1196 | tmp = w_index & USB_ENDPOINT_NUMBER_MASK; | 1197 | tmp = w_index & USB_ENDPOINT_NUMBER_MASK; |
1197 | ep = &udc->ep[tmp]; | 1198 | ep = &udc->ep[tmp]; |
1198 | if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS) | 1199 | if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS) |
1199 | goto stall; | 1200 | goto stall; |
1200 | if (tmp == 0) | 1201 | if (tmp == 0) |
1201 | goto succeed; | 1202 | goto succeed; |
@@ -1551,7 +1552,7 @@ static irqreturn_t at91_vbus_irq(int irq, void *_udc) | |||
1551 | 1552 | ||
1552 | /* vbus needs at least brief debouncing */ | 1553 | /* vbus needs at least brief debouncing */ |
1553 | udelay(10); | 1554 | udelay(10); |
1554 | value = at91_get_gpio_value(udc->board.vbus_pin); | 1555 | value = gpio_get_value(udc->board.vbus_pin); |
1555 | if (value != udc->vbus) | 1556 | if (value != udc->vbus) |
1556 | at91_vbus_session(&udc->gadget, value); | 1557 | at91_vbus_session(&udc->gadget, value); |
1557 | 1558 | ||
@@ -1616,6 +1617,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
1616 | local_irq_enable(); | 1617 | local_irq_enable(); |
1617 | 1618 | ||
1618 | driver->unbind(&udc->gadget); | 1619 | driver->unbind(&udc->gadget); |
1620 | udc->gadget.dev.driver = NULL; | ||
1621 | udc->gadget.dev.driver_data = NULL; | ||
1619 | udc->driver = NULL; | 1622 | udc->driver = NULL; |
1620 | 1623 | ||
1621 | DBG("unbound from %s\n", driver->driver.name); | 1624 | DBG("unbound from %s\n", driver->driver.name); |
@@ -1645,12 +1648,12 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1645 | } | 1648 | } |
1646 | 1649 | ||
1647 | if (pdev->num_resources != 2) { | 1650 | if (pdev->num_resources != 2) { |
1648 | DBG("invalid num_resources"); | 1651 | DBG("invalid num_resources\n"); |
1649 | return -ENODEV; | 1652 | return -ENODEV; |
1650 | } | 1653 | } |
1651 | if ((pdev->resource[0].flags != IORESOURCE_MEM) | 1654 | if ((pdev->resource[0].flags != IORESOURCE_MEM) |
1652 | || (pdev->resource[1].flags != IORESOURCE_IRQ)) { | 1655 | || (pdev->resource[1].flags != IORESOURCE_IRQ)) { |
1653 | DBG("invalid resource type"); | 1656 | DBG("invalid resource type\n"); |
1654 | return -ENODEV; | 1657 | return -ENODEV; |
1655 | } | 1658 | } |
1656 | 1659 | ||
@@ -1672,10 +1675,26 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1672 | udc->pdev = pdev; | 1675 | udc->pdev = pdev; |
1673 | udc->enabled = 0; | 1676 | udc->enabled = 0; |
1674 | 1677 | ||
1678 | /* rm9200 needs manual D+ pullup; off by default */ | ||
1679 | if (cpu_is_at91rm9200()) { | ||
1680 | if (udc->board.pullup_pin <= 0) { | ||
1681 | DBG("no D+ pullup?\n"); | ||
1682 | retval = -ENODEV; | ||
1683 | goto fail0; | ||
1684 | } | ||
1685 | retval = gpio_request(udc->board.pullup_pin, "udc_pullup"); | ||
1686 | if (retval) { | ||
1687 | DBG("D+ pullup is busy\n"); | ||
1688 | goto fail0; | ||
1689 | } | ||
1690 | gpio_direction_output(udc->board.pullup_pin, | ||
1691 | udc->board.pullup_active_low); | ||
1692 | } | ||
1693 | |||
1675 | udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); | 1694 | udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); |
1676 | if (!udc->udp_baseaddr) { | 1695 | if (!udc->udp_baseaddr) { |
1677 | release_mem_region(res->start, res->end - res->start + 1); | 1696 | retval = -ENOMEM; |
1678 | return -ENOMEM; | 1697 | goto fail0a; |
1679 | } | 1698 | } |
1680 | 1699 | ||
1681 | udc_reinit(udc); | 1700 | udc_reinit(udc); |
@@ -1686,12 +1705,13 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1686 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { | 1705 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { |
1687 | DBG("clocks missing\n"); | 1706 | DBG("clocks missing\n"); |
1688 | retval = -ENODEV; | 1707 | retval = -ENODEV; |
1689 | goto fail0; | 1708 | /* NOTE: we "know" here that refcounts on these are NOPs */ |
1709 | goto fail0b; | ||
1690 | } | 1710 | } |
1691 | 1711 | ||
1692 | retval = device_register(&udc->gadget.dev); | 1712 | retval = device_register(&udc->gadget.dev); |
1693 | if (retval < 0) | 1713 | if (retval < 0) |
1694 | goto fail0; | 1714 | goto fail0b; |
1695 | 1715 | ||
1696 | /* don't do anything until we have both gadget driver and VBUS */ | 1716 | /* don't do anything until we have both gadget driver and VBUS */ |
1697 | clk_enable(udc->iclk); | 1717 | clk_enable(udc->iclk); |
@@ -1703,25 +1723,32 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1703 | 1723 | ||
1704 | /* request UDC and maybe VBUS irqs */ | 1724 | /* request UDC and maybe VBUS irqs */ |
1705 | udc->udp_irq = platform_get_irq(pdev, 0); | 1725 | udc->udp_irq = platform_get_irq(pdev, 0); |
1706 | if (request_irq(udc->udp_irq, at91_udc_irq, | 1726 | retval = request_irq(udc->udp_irq, at91_udc_irq, |
1707 | IRQF_DISABLED, driver_name, udc)) { | 1727 | IRQF_DISABLED, driver_name, udc); |
1728 | if (retval < 0) { | ||
1708 | DBG("request irq %d failed\n", udc->udp_irq); | 1729 | DBG("request irq %d failed\n", udc->udp_irq); |
1709 | retval = -EBUSY; | ||
1710 | goto fail1; | 1730 | goto fail1; |
1711 | } | 1731 | } |
1712 | if (udc->board.vbus_pin > 0) { | 1732 | if (udc->board.vbus_pin > 0) { |
1733 | retval = gpio_request(udc->board.vbus_pin, "udc_vbus"); | ||
1734 | if (retval < 0) { | ||
1735 | DBG("request vbus pin failed\n"); | ||
1736 | goto fail2; | ||
1737 | } | ||
1738 | gpio_direction_input(udc->board.vbus_pin); | ||
1739 | |||
1713 | /* | 1740 | /* |
1714 | * Get the initial state of VBUS - we cannot expect | 1741 | * Get the initial state of VBUS - we cannot expect |
1715 | * a pending interrupt. | 1742 | * a pending interrupt. |
1716 | */ | 1743 | */ |
1717 | udc->vbus = at91_get_gpio_value(udc->board.vbus_pin); | 1744 | udc->vbus = gpio_get_value(udc->board.vbus_pin); |
1718 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, | 1745 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, |
1719 | IRQF_DISABLED, driver_name, udc)) { | 1746 | IRQF_DISABLED, driver_name, udc)) { |
1720 | DBG("request vbus irq %d failed\n", | 1747 | DBG("request vbus irq %d failed\n", |
1721 | udc->board.vbus_pin); | 1748 | udc->board.vbus_pin); |
1722 | free_irq(udc->udp_irq, udc); | 1749 | free_irq(udc->udp_irq, udc); |
1723 | retval = -EBUSY; | 1750 | retval = -EBUSY; |
1724 | goto fail1; | 1751 | goto fail3; |
1725 | } | 1752 | } |
1726 | } else { | 1753 | } else { |
1727 | DBG("no VBUS detection, assuming always-on\n"); | 1754 | DBG("no VBUS detection, assuming always-on\n"); |
@@ -1734,8 +1761,18 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1734 | INFO("%s version %s\n", driver_name, DRIVER_VERSION); | 1761 | INFO("%s version %s\n", driver_name, DRIVER_VERSION); |
1735 | return 0; | 1762 | return 0; |
1736 | 1763 | ||
1764 | fail3: | ||
1765 | if (udc->board.vbus_pin > 0) | ||
1766 | gpio_free(udc->board.vbus_pin); | ||
1767 | fail2: | ||
1768 | free_irq(udc->udp_irq, udc); | ||
1737 | fail1: | 1769 | fail1: |
1738 | device_unregister(&udc->gadget.dev); | 1770 | device_unregister(&udc->gadget.dev); |
1771 | fail0b: | ||
1772 | iounmap(udc->udp_baseaddr); | ||
1773 | fail0a: | ||
1774 | if (cpu_is_at91rm9200()) | ||
1775 | gpio_free(udc->board.pullup_pin); | ||
1739 | fail0: | 1776 | fail0: |
1740 | release_mem_region(res->start, res->end - res->start + 1); | 1777 | release_mem_region(res->start, res->end - res->start + 1); |
1741 | DBG("%s probe failed, %d\n", driver_name, retval); | 1778 | DBG("%s probe failed, %d\n", driver_name, retval); |
@@ -1756,12 +1793,18 @@ static int __exit at91udc_remove(struct platform_device *pdev) | |||
1756 | 1793 | ||
1757 | device_init_wakeup(&pdev->dev, 0); | 1794 | device_init_wakeup(&pdev->dev, 0); |
1758 | remove_debug_file(udc); | 1795 | remove_debug_file(udc); |
1759 | if (udc->board.vbus_pin > 0) | 1796 | if (udc->board.vbus_pin > 0) { |
1760 | free_irq(udc->board.vbus_pin, udc); | 1797 | free_irq(udc->board.vbus_pin, udc); |
1798 | gpio_free(udc->board.vbus_pin); | ||
1799 | } | ||
1761 | free_irq(udc->udp_irq, udc); | 1800 | free_irq(udc->udp_irq, udc); |
1762 | device_unregister(&udc->gadget.dev); | 1801 | device_unregister(&udc->gadget.dev); |
1763 | 1802 | ||
1764 | iounmap(udc->udp_baseaddr); | 1803 | iounmap(udc->udp_baseaddr); |
1804 | |||
1805 | if (cpu_is_at91rm9200()) | ||
1806 | gpio_free(udc->board.pullup_pin); | ||
1807 | |||
1765 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1808 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1766 | release_mem_region(res->start, res->end - res->start + 1); | 1809 | release_mem_region(res->start, res->end - res->start + 1); |
1767 | 1810 | ||
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index 7e34e2f864f9..a973f2a50fb9 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ | 53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ |
54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ | 54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ |
55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ | 55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ |
56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ | 56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrupt Status */ |
57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ | 57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ |
58 | 58 | ||
59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ | 59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ |
@@ -158,13 +158,7 @@ struct at91_request { | |||
158 | 158 | ||
159 | /*-------------------------------------------------------------------------*/ | 159 | /*-------------------------------------------------------------------------*/ |
160 | 160 | ||
161 | #ifdef DEBUG | 161 | #ifdef VERBOSE_DEBUG |
162 | #define DBG(stuff...) printk(KERN_DEBUG "udc: " stuff) | ||
163 | #else | ||
164 | #define DBG(stuff...) do{}while(0) | ||
165 | #endif | ||
166 | |||
167 | #ifdef VERBOSE | ||
168 | # define VDBG DBG | 162 | # define VDBG DBG |
169 | #else | 163 | #else |
170 | # define VDBG(stuff...) do{}while(0) | 164 | # define VDBG(stuff...) do{}while(0) |
@@ -176,9 +170,10 @@ struct at91_request { | |||
176 | # define PACKET(stuff...) do{}while(0) | 170 | # define PACKET(stuff...) do{}while(0) |
177 | #endif | 171 | #endif |
178 | 172 | ||
179 | #define ERR(stuff...) printk(KERN_ERR "udc: " stuff) | 173 | #define ERR(stuff...) pr_err("udc: " stuff) |
180 | #define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) | 174 | #define WARN(stuff...) pr_warning("udc: " stuff) |
181 | #define INFO(stuff...) printk(KERN_INFO "udc: " stuff) | 175 | #define INFO(stuff...) pr_info("udc: " stuff) |
176 | #define DBG(stuff...) pr_debug("udc: " stuff) | ||
182 | 177 | ||
183 | #endif | 178 | #endif |
184 | 179 | ||
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 4fb5ff469574..af8b2a3a2d4a 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1384,8 +1384,7 @@ delegate: | |||
1384 | return retval; | 1384 | return retval; |
1385 | 1385 | ||
1386 | stall: | 1386 | stall: |
1387 | printk(KERN_ERR | 1387 | pr_err("udc: %s: Invalid setup request: %02x.%02x v%04x i%04x l%d, " |
1388 | "udc: %s: Invalid setup request: %02x.%02x v%04x i%04x l%d, " | ||
1389 | "halting endpoint...\n", | 1388 | "halting endpoint...\n", |
1390 | ep->ep.name, crq->bRequestType, crq->bRequest, | 1389 | ep->ep.name, crq->bRequestType, crq->bRequest, |
1391 | le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex), | 1390 | le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex), |
@@ -1456,8 +1455,7 @@ restart: | |||
1456 | set_protocol_stall(udc, ep); | 1455 | set_protocol_stall(udc, ep); |
1457 | break; | 1456 | break; |
1458 | default: | 1457 | default: |
1459 | printk(KERN_ERR | 1458 | pr_err("udc: %s: TXCOMP: Invalid endpoint state %d, " |
1460 | "udc: %s: TXCOMP: Invalid endpoint state %d, " | ||
1461 | "halting endpoint...\n", | 1459 | "halting endpoint...\n", |
1462 | ep->ep.name, ep->state); | 1460 | ep->ep.name, ep->state); |
1463 | set_protocol_stall(udc, ep); | 1461 | set_protocol_stall(udc, ep); |
@@ -1486,8 +1484,7 @@ restart: | |||
1486 | default: | 1484 | default: |
1487 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | 1485 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); |
1488 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | 1486 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); |
1489 | printk(KERN_ERR | 1487 | pr_err("udc: %s: RXRDY: Invalid endpoint state %d, " |
1490 | "udc: %s: RXRDY: Invalid endpoint state %d, " | ||
1491 | "halting endpoint...\n", | 1488 | "halting endpoint...\n", |
1492 | ep->ep.name, ep->state); | 1489 | ep->ep.name, ep->state); |
1493 | set_protocol_stall(udc, ep); | 1490 | set_protocol_stall(udc, ep); |
@@ -1532,7 +1529,7 @@ restart: | |||
1532 | pkt_len = USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA)); | 1529 | pkt_len = USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA)); |
1533 | DBG(DBG_HW, "Packet length: %u\n", pkt_len); | 1530 | DBG(DBG_HW, "Packet length: %u\n", pkt_len); |
1534 | if (pkt_len != sizeof(crq)) { | 1531 | if (pkt_len != sizeof(crq)) { |
1535 | printk(KERN_WARNING "udc: Invalid packet length %u " | 1532 | pr_warning("udc: Invalid packet length %u " |
1536 | "(expected %lu)\n", pkt_len, sizeof(crq)); | 1533 | "(expected %lu)\n", pkt_len, sizeof(crq)); |
1537 | set_protocol_stall(udc, ep); | 1534 | set_protocol_stall(udc, ep); |
1538 | return; | 1535 | return; |
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h index a68304e31a68..08bf6f9aaf7e 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/atmel_usba_udc.h | |||
@@ -216,7 +216,6 @@ | |||
216 | #define FIFO_IOMEM_ID 0 | 216 | #define FIFO_IOMEM_ID 0 |
217 | #define CTRL_IOMEM_ID 1 | 217 | #define CTRL_IOMEM_ID 1 |
218 | 218 | ||
219 | #ifdef DEBUG | ||
220 | #define DBG_ERR 0x0001 /* report all error returns */ | 219 | #define DBG_ERR 0x0001 /* report all error returns */ |
221 | #define DBG_HW 0x0002 /* debug hardware initialization */ | 220 | #define DBG_HW 0x0002 /* debug hardware initialization */ |
222 | #define DBG_GADGET 0x0004 /* calls to/from gadget driver */ | 221 | #define DBG_GADGET 0x0004 /* calls to/from gadget driver */ |
@@ -230,14 +229,12 @@ | |||
230 | #define DBG_NONE 0x0000 | 229 | #define DBG_NONE 0x0000 |
231 | 230 | ||
232 | #define DEBUG_LEVEL (DBG_ERR) | 231 | #define DEBUG_LEVEL (DBG_ERR) |
232 | |||
233 | #define DBG(level, fmt, ...) \ | 233 | #define DBG(level, fmt, ...) \ |
234 | do { \ | 234 | do { \ |
235 | if ((level) & DEBUG_LEVEL) \ | 235 | if ((level) & DEBUG_LEVEL) \ |
236 | printk(KERN_DEBUG "udc: " fmt, ## __VA_ARGS__); \ | 236 | pr_debug("udc: " fmt, ## __VA_ARGS__); \ |
237 | } while (0) | 237 | } while (0) |
238 | #else | ||
239 | #define DBG(level, fmt...) | ||
240 | #endif | ||
241 | 238 | ||
242 | enum usba_ctrl_state { | 239 | enum usba_ctrl_state { |
243 | WAIT_FOR_SETUP, | 240 | WAIT_FOR_SETUP, |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 9db2482bdfa2..cbe44535c0f0 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -61,6 +61,8 @@ | |||
61 | #define DRIVER_DESC "USB Host+Gadget Emulator" | 61 | #define DRIVER_DESC "USB Host+Gadget Emulator" |
62 | #define DRIVER_VERSION "02 May 2005" | 62 | #define DRIVER_VERSION "02 May 2005" |
63 | 63 | ||
64 | #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ | ||
65 | |||
64 | static const char driver_name [] = "dummy_hcd"; | 66 | static const char driver_name [] = "dummy_hcd"; |
65 | static const char driver_desc [] = "USB Host+Gadget Emulator"; | 67 | static const char driver_desc [] = "USB Host+Gadget Emulator"; |
66 | 68 | ||
@@ -772,18 +774,17 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
772 | list_del_init (&dum->ep [0].ep.ep_list); | 774 | list_del_init (&dum->ep [0].ep.ep_list); |
773 | INIT_LIST_HEAD(&dum->fifo_req.queue); | 775 | INIT_LIST_HEAD(&dum->fifo_req.queue); |
774 | 776 | ||
777 | driver->driver.bus = NULL; | ||
775 | dum->driver = driver; | 778 | dum->driver = driver; |
776 | dum->gadget.dev.driver = &driver->driver; | 779 | dum->gadget.dev.driver = &driver->driver; |
777 | dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", | 780 | dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", |
778 | driver->driver.name); | 781 | driver->driver.name); |
779 | if ((retval = driver->bind (&dum->gadget)) != 0) | 782 | retval = driver->bind(&dum->gadget); |
780 | goto err_bind_gadget; | 783 | if (retval) { |
781 | 784 | dum->driver = NULL; | |
782 | driver->driver.bus = dum->gadget.dev.parent->bus; | 785 | dum->gadget.dev.driver = NULL; |
783 | if ((retval = driver_register (&driver->driver)) != 0) | 786 | return retval; |
784 | goto err_register; | 787 | } |
785 | if ((retval = device_bind_driver (&dum->gadget.dev)) != 0) | ||
786 | goto err_bind_driver; | ||
787 | 788 | ||
788 | /* khubd will enumerate this in a while */ | 789 | /* khubd will enumerate this in a while */ |
789 | spin_lock_irq (&dum->lock); | 790 | spin_lock_irq (&dum->lock); |
@@ -793,20 +794,6 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
793 | 794 | ||
794 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 795 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
795 | return 0; | 796 | return 0; |
796 | |||
797 | err_bind_driver: | ||
798 | driver_unregister (&driver->driver); | ||
799 | err_register: | ||
800 | if (driver->unbind) | ||
801 | driver->unbind (&dum->gadget); | ||
802 | spin_lock_irq (&dum->lock); | ||
803 | dum->pullup = 0; | ||
804 | set_link_state (dum); | ||
805 | spin_unlock_irq (&dum->lock); | ||
806 | err_bind_gadget: | ||
807 | dum->driver = NULL; | ||
808 | dum->gadget.dev.driver = NULL; | ||
809 | return retval; | ||
810 | } | 797 | } |
811 | EXPORT_SYMBOL (usb_gadget_register_driver); | 798 | EXPORT_SYMBOL (usb_gadget_register_driver); |
812 | 799 | ||
@@ -830,11 +817,9 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
830 | spin_unlock_irqrestore (&dum->lock, flags); | 817 | spin_unlock_irqrestore (&dum->lock, flags); |
831 | 818 | ||
832 | driver->unbind (&dum->gadget); | 819 | driver->unbind (&dum->gadget); |
820 | dum->gadget.dev.driver = NULL; | ||
833 | dum->driver = NULL; | 821 | dum->driver = NULL; |
834 | 822 | ||
835 | device_release_driver (&dum->gadget.dev); | ||
836 | driver_unregister (&driver->driver); | ||
837 | |||
838 | spin_lock_irqsave (&dum->lock, flags); | 823 | spin_lock_irqsave (&dum->lock, flags); |
839 | dum->pullup = 0; | 824 | dum->pullup = 0; |
840 | set_link_state (dum); | 825 | set_link_state (dum); |
@@ -1827,8 +1812,7 @@ static int dummy_start (struct usb_hcd *hcd) | |||
1827 | 1812 | ||
1828 | INIT_LIST_HEAD (&dum->urbp_list); | 1813 | INIT_LIST_HEAD (&dum->urbp_list); |
1829 | 1814 | ||
1830 | /* only show a low-power port: just 8mA */ | 1815 | hcd->power_budget = POWER_BUDGET; |
1831 | hcd->power_budget = 8; | ||
1832 | hcd->state = HC_STATE_RUNNING; | 1816 | hcd->state = HC_STATE_RUNNING; |
1833 | hcd->uses_new_polling = 1; | 1817 | hcd->uses_new_polling = 1; |
1834 | 1818 | ||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 9e732bff9df0..a70e255402b8 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -1067,19 +1067,19 @@ done: | |||
1067 | 1067 | ||
1068 | /* on error, disable any endpoints */ | 1068 | /* on error, disable any endpoints */ |
1069 | if (result < 0) { | 1069 | if (result < 0) { |
1070 | if (!subset_active(dev)) | 1070 | if (!subset_active(dev) && dev->status_ep) |
1071 | (void) usb_ep_disable (dev->status_ep); | 1071 | (void) usb_ep_disable (dev->status_ep); |
1072 | dev->status = NULL; | 1072 | dev->status = NULL; |
1073 | (void) usb_ep_disable (dev->in_ep); | 1073 | (void) usb_ep_disable (dev->in_ep); |
1074 | (void) usb_ep_disable (dev->out_ep); | 1074 | (void) usb_ep_disable (dev->out_ep); |
1075 | dev->in = NULL; | 1075 | dev->in = NULL; |
1076 | dev->out = NULL; | 1076 | dev->out = NULL; |
1077 | } else | 1077 | } |
1078 | 1078 | ||
1079 | /* activate non-CDC configs right away | 1079 | /* activate non-CDC configs right away |
1080 | * this isn't strictly according to the RNDIS spec | 1080 | * this isn't strictly according to the RNDIS spec |
1081 | */ | 1081 | */ |
1082 | if (!cdc_active (dev)) { | 1082 | else if (!cdc_active (dev)) { |
1083 | netif_carrier_on (dev->net); | 1083 | netif_carrier_on (dev->net); |
1084 | if (netif_running (dev->net)) { | 1084 | if (netif_running (dev->net)) { |
1085 | spin_unlock (&dev->lock); | 1085 | spin_unlock (&dev->lock); |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 1d174dcb3ac9..3301167d4f2a 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -275,19 +275,15 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
275 | 275 | ||
276 | /*-------------------------------------------------------------------------*/ | 276 | /*-------------------------------------------------------------------------*/ |
277 | 277 | ||
278 | #ifdef DEBUG | ||
279 | #define LDBG(lun,fmt,args...) \ | 278 | #define LDBG(lun,fmt,args...) \ |
280 | dev_dbg(&(lun)->dev , fmt , ## args) | 279 | dev_dbg(&(lun)->dev , fmt , ## args) |
281 | #define MDBG(fmt,args...) \ | 280 | #define MDBG(fmt,args...) \ |
282 | printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args) | 281 | pr_debug(DRIVER_NAME ": " fmt , ## args) |
283 | #else | 282 | |
284 | #define LDBG(lun,fmt,args...) \ | 283 | #ifndef DEBUG |
285 | do { } while (0) | ||
286 | #define MDBG(fmt,args...) \ | ||
287 | do { } while (0) | ||
288 | #undef VERBOSE_DEBUG | 284 | #undef VERBOSE_DEBUG |
289 | #undef DUMP_MSGS | 285 | #undef DUMP_MSGS |
290 | #endif /* DEBUG */ | 286 | #endif /* !DEBUG */ |
291 | 287 | ||
292 | #ifdef VERBOSE_DEBUG | 288 | #ifdef VERBOSE_DEBUG |
293 | #define VLDBG LDBG | 289 | #define VLDBG LDBG |
@@ -304,7 +300,7 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
304 | dev_info(&(lun)->dev , fmt , ## args) | 300 | dev_info(&(lun)->dev , fmt , ## args) |
305 | 301 | ||
306 | #define MINFO(fmt,args...) \ | 302 | #define MINFO(fmt,args...) \ |
307 | printk(KERN_INFO DRIVER_NAME ": " fmt , ## args) | 303 | pr_info(DRIVER_NAME ": " fmt , ## args) |
308 | 304 | ||
309 | #define DBG(d, fmt, args...) \ | 305 | #define DBG(d, fmt, args...) \ |
310 | dev_dbg(&(d)->gadget->dev , fmt , ## args) | 306 | dev_dbg(&(d)->gadget->dev , fmt , ## args) |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 038e7d7b4da1..63e8fa3a69e1 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -776,7 +776,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
776 | VDBG("%s, bad params\n", __FUNCTION__); | 776 | VDBG("%s, bad params\n", __FUNCTION__); |
777 | return -EINVAL; | 777 | return -EINVAL; |
778 | } | 778 | } |
779 | if (!_ep || (!ep->desc && ep_index(ep))) { | 779 | if (unlikely(!_ep || !ep->desc)) { |
780 | VDBG("%s, bad ep\n", __FUNCTION__); | 780 | VDBG("%s, bad ep\n", __FUNCTION__); |
781 | return -EINVAL; | 781 | return -EINVAL; |
782 | } | 782 | } |
@@ -1896,7 +1896,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, | |||
1896 | 1896 | ||
1897 | spin_lock_irqsave(&udc->lock, flags); | 1897 | spin_lock_irqsave(&udc->lock, flags); |
1898 | 1898 | ||
1899 | /* ------basic driver infomation ---- */ | 1899 | /* ------basic driver information ---- */ |
1900 | t = scnprintf(next, size, | 1900 | t = scnprintf(next, size, |
1901 | DRIVER_DESC "\n" | 1901 | DRIVER_DESC "\n" |
1902 | "%s version: %s\n" | 1902 | "%s version: %s\n" |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 832ab82b4882..9fb0b1ec8526 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h | |||
@@ -551,9 +551,9 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) | |||
551 | #define VDBG(stuff...) do{}while(0) | 551 | #define VDBG(stuff...) do{}while(0) |
552 | #endif | 552 | #endif |
553 | 553 | ||
554 | #define ERR(stuff...) printk(KERN_ERR "udc: " stuff) | 554 | #define ERR(stuff...) pr_err("udc: " stuff) |
555 | #define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) | 555 | #define WARN(stuff...) pr_warning("udc: " stuff) |
556 | #define INFO(stuff...) printk(KERN_INFO "udc: " stuff) | 556 | #define INFO(stuff...) pr_info("udc: " stuff) |
557 | 557 | ||
558 | /*-------------------------------------------------------------------------*/ | 558 | /*-------------------------------------------------------------------------*/ |
559 | 559 | ||
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 7da7fcb05640..5b42ccd0035f 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -1158,7 +1158,7 @@ static int __devinit gmidi_bind(struct usb_gadget *gadget) | |||
1158 | /* support optional vendor/distro customization */ | 1158 | /* support optional vendor/distro customization */ |
1159 | if (idVendor) { | 1159 | if (idVendor) { |
1160 | if (!idProduct) { | 1160 | if (!idProduct) { |
1161 | printk(KERN_ERR "idVendor needs idProduct!\n"); | 1161 | pr_err("idVendor needs idProduct!\n"); |
1162 | return -ENODEV; | 1162 | return -ENODEV; |
1163 | } | 1163 | } |
1164 | device_desc.idVendor = cpu_to_le16(idVendor); | 1164 | device_desc.idVendor = cpu_to_le16(idVendor); |
@@ -1190,7 +1190,7 @@ static int __devinit gmidi_bind(struct usb_gadget *gadget) | |||
1190 | in_ep = usb_ep_autoconfig(gadget, &bulk_in_desc); | 1190 | in_ep = usb_ep_autoconfig(gadget, &bulk_in_desc); |
1191 | if (!in_ep) { | 1191 | if (!in_ep) { |
1192 | autoconf_fail: | 1192 | autoconf_fail: |
1193 | printk(KERN_ERR "%s: can't autoconfigure on %s\n", | 1193 | pr_err("%s: can't autoconfigure on %s\n", |
1194 | shortname, gadget->name); | 1194 | shortname, gadget->name); |
1195 | return -ENODEV; | 1195 | return -ENODEV; |
1196 | } | 1196 | } |
@@ -1212,7 +1212,7 @@ autoconf_fail: | |||
1212 | * it SHOULD NOT have problems with bulk-capable hardware. | 1212 | * it SHOULD NOT have problems with bulk-capable hardware. |
1213 | * so warn about unrecognized controllers, don't panic. | 1213 | * so warn about unrecognized controllers, don't panic. |
1214 | */ | 1214 | */ |
1215 | printk(KERN_WARNING "%s: controller '%s' not recognized\n", | 1215 | pr_warning("%s: controller '%s' not recognized\n", |
1216 | shortname, gadget->name); | 1216 | shortname, gadget->name); |
1217 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 1217 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); |
1218 | } | 1218 | } |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 2ec9d196a8cf..d3e702576de6 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1422,6 +1422,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1422 | spin_unlock_irqrestore(&dev->lock, flags); | 1422 | spin_unlock_irqrestore(&dev->lock, flags); |
1423 | 1423 | ||
1424 | driver->unbind(&dev->gadget); | 1424 | driver->unbind(&dev->gadget); |
1425 | dev->gadget.dev.driver = NULL; | ||
1425 | 1426 | ||
1426 | DBG(dev, "unregistered driver '%s'\n", driver->driver.name); | 1427 | DBG(dev, "unregistered driver '%s'\n", driver->driver.name); |
1427 | return 0; | 1428 | return 0; |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 47ef8bd58a00..805602a687cb 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1699,7 +1699,7 @@ gadgetfs_bind (struct usb_gadget *gadget) | |||
1699 | if (!dev) | 1699 | if (!dev) |
1700 | return -ESRCH; | 1700 | return -ESRCH; |
1701 | if (0 != strcmp (CHIP, gadget->name)) { | 1701 | if (0 != strcmp (CHIP, gadget->name)) { |
1702 | printk (KERN_ERR "%s expected %s controller not %s\n", | 1702 | pr_err("%s expected %s controller not %s\n", |
1703 | shortname, CHIP, gadget->name); | 1703 | shortname, CHIP, gadget->name); |
1704 | return -ENODEV; | 1704 | return -ENODEV; |
1705 | } | 1705 | } |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 367b75c0b25b..37243ef7104e 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -474,6 +474,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
474 | spin_unlock_irqrestore(&dev->lock, flags); | 474 | spin_unlock_irqrestore(&dev->lock, flags); |
475 | 475 | ||
476 | driver->unbind(&dev->gadget); | 476 | driver->unbind(&dev->gadget); |
477 | dev->gadget.dev.driver = NULL; | ||
477 | device_del(&dev->gadget.dev); | 478 | device_del(&dev->gadget.dev); |
478 | 479 | ||
479 | udc_disable(dev); | 480 | udc_disable(dev); |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index ebc5536aa271..835948f0715a 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -36,9 +36,14 @@ MODULE_DESCRIPTION("M66592 USB gadget driver"); | |||
36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
37 | MODULE_AUTHOR("Yoshihiro Shimoda"); | 37 | MODULE_AUTHOR("Yoshihiro Shimoda"); |
38 | 38 | ||
39 | #define DRIVER_VERSION "29 May 2007" | 39 | #define DRIVER_VERSION "18 Oct 2007" |
40 | 40 | ||
41 | /* module parameters */ | 41 | /* module parameters */ |
42 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
43 | static unsigned short endian = M66592_LITTLE; | ||
44 | module_param(endian, ushort, 0644); | ||
45 | MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)"); | ||
46 | #else | ||
42 | static unsigned short clock = M66592_XTAL24; | 47 | static unsigned short clock = M66592_XTAL24; |
43 | module_param(clock, ushort, 0644); | 48 | module_param(clock, ushort, 0644); |
44 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " | 49 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
@@ -56,6 +61,7 @@ static unsigned short irq_sense = M66592_INTL; | |||
56 | module_param(irq_sense, ushort, 0644); | 61 | module_param(irq_sense, ushort, 0644); |
57 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " | 62 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " |
58 | "(default=2)"); | 63 | "(default=2)"); |
64 | #endif | ||
59 | 65 | ||
60 | static const char udc_name[] = "m66592_udc"; | 66 | static const char udc_name[] = "m66592_udc"; |
61 | static const char *m66592_ep_name[] = { | 67 | static const char *m66592_ep_name[] = { |
@@ -141,7 +147,7 @@ static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) | |||
141 | offset = get_pipectr_addr(pipenum); | 147 | offset = get_pipectr_addr(pipenum); |
142 | pid = m66592_read(m66592, offset) & M66592_PID; | 148 | pid = m66592_read(m66592, offset) & M66592_PID; |
143 | } else | 149 | } else |
144 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | 150 | pr_err("unexpect pipe num (%d)\n", pipenum); |
145 | 151 | ||
146 | return pid; | 152 | return pid; |
147 | } | 153 | } |
@@ -157,7 +163,7 @@ static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, | |||
157 | offset = get_pipectr_addr(pipenum); | 163 | offset = get_pipectr_addr(pipenum); |
158 | m66592_mdfy(m66592, pid, M66592_PID, offset); | 164 | m66592_mdfy(m66592, pid, M66592_PID, offset); |
159 | } else | 165 | } else |
160 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | 166 | pr_err("unexpect pipe num (%d)\n", pipenum); |
161 | } | 167 | } |
162 | 168 | ||
163 | static inline void pipe_start(struct m66592 *m66592, u16 pipenum) | 169 | static inline void pipe_start(struct m66592 *m66592, u16 pipenum) |
@@ -186,7 +192,7 @@ static inline u16 control_reg_get(struct m66592 *m66592, u16 pipenum) | |||
186 | offset = get_pipectr_addr(pipenum); | 192 | offset = get_pipectr_addr(pipenum); |
187 | ret = m66592_read(m66592, offset); | 193 | ret = m66592_read(m66592, offset); |
188 | } else | 194 | } else |
189 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | 195 | pr_err("unexpect pipe num (%d)\n", pipenum); |
190 | 196 | ||
191 | return ret; | 197 | return ret; |
192 | } | 198 | } |
@@ -203,7 +209,7 @@ static inline void control_reg_sqclr(struct m66592 *m66592, u16 pipenum) | |||
203 | offset = get_pipectr_addr(pipenum); | 209 | offset = get_pipectr_addr(pipenum); |
204 | m66592_bset(m66592, M66592_SQCLR, offset); | 210 | m66592_bset(m66592, M66592_SQCLR, offset); |
205 | } else | 211 | } else |
206 | printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum); | 212 | pr_err("unexpect pipe num(%d)\n", pipenum); |
207 | } | 213 | } |
208 | 214 | ||
209 | static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum) | 215 | static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum) |
@@ -285,7 +291,7 @@ static int pipe_buffer_setting(struct m66592 *m66592, | |||
285 | break; | 291 | break; |
286 | } | 292 | } |
287 | if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { | 293 | if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { |
288 | printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", | 294 | pr_err("m66592 pipe memory is insufficient(%d)\n", |
289 | m66592->bi_bufnum); | 295 | m66592->bi_bufnum); |
290 | return -ENOMEM; | 296 | return -ENOMEM; |
291 | } | 297 | } |
@@ -326,7 +332,7 @@ static void pipe_buffer_release(struct m66592 *m66592, | |||
326 | if (info->type == M66592_BULK) | 332 | if (info->type == M66592_BULK) |
327 | m66592->bulk--; | 333 | m66592->bulk--; |
328 | } else | 334 | } else |
329 | printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", | 335 | pr_err("ep_release: unexpect pipenum (%d)\n", |
330 | info->pipe); | 336 | info->pipe); |
331 | } | 337 | } |
332 | 338 | ||
@@ -360,6 +366,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | |||
360 | ep->fifosel = M66592_D0FIFOSEL; | 366 | ep->fifosel = M66592_D0FIFOSEL; |
361 | ep->fifoctr = M66592_D0FIFOCTR; | 367 | ep->fifoctr = M66592_D0FIFOCTR; |
362 | ep->fifotrn = M66592_D0FIFOTRN; | 368 | ep->fifotrn = M66592_D0FIFOTRN; |
369 | #if !defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
363 | } else if (m66592->num_dma == 1) { | 370 | } else if (m66592->num_dma == 1) { |
364 | m66592->num_dma++; | 371 | m66592->num_dma++; |
365 | ep->use_dma = 1; | 372 | ep->use_dma = 1; |
@@ -367,6 +374,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | |||
367 | ep->fifosel = M66592_D1FIFOSEL; | 374 | ep->fifosel = M66592_D1FIFOSEL; |
368 | ep->fifoctr = M66592_D1FIFOCTR; | 375 | ep->fifoctr = M66592_D1FIFOCTR; |
369 | ep->fifotrn = M66592_D1FIFOTRN; | 376 | ep->fifotrn = M66592_D1FIFOTRN; |
377 | #endif | ||
370 | } else { | 378 | } else { |
371 | ep->use_dma = 0; | 379 | ep->use_dma = 0; |
372 | ep->fifoaddr = M66592_CFIFO; | 380 | ep->fifoaddr = M66592_CFIFO; |
@@ -422,7 +430,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
422 | case USB_ENDPOINT_XFER_BULK: | 430 | case USB_ENDPOINT_XFER_BULK: |
423 | if (m66592->bulk >= M66592_MAX_NUM_BULK) { | 431 | if (m66592->bulk >= M66592_MAX_NUM_BULK) { |
424 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { | 432 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { |
425 | printk(KERN_ERR "bulk pipe is insufficient\n"); | 433 | pr_err("bulk pipe is insufficient\n"); |
426 | return -ENODEV; | 434 | return -ENODEV; |
427 | } else { | 435 | } else { |
428 | info.pipe = M66592_BASE_PIPENUM_ISOC | 436 | info.pipe = M66592_BASE_PIPENUM_ISOC |
@@ -438,7 +446,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
438 | break; | 446 | break; |
439 | case USB_ENDPOINT_XFER_INT: | 447 | case USB_ENDPOINT_XFER_INT: |
440 | if (m66592->interrupt >= M66592_MAX_NUM_INT) { | 448 | if (m66592->interrupt >= M66592_MAX_NUM_INT) { |
441 | printk(KERN_ERR "interrupt pipe is insufficient\n"); | 449 | pr_err("interrupt pipe is insufficient\n"); |
442 | return -ENODEV; | 450 | return -ENODEV; |
443 | } | 451 | } |
444 | info.pipe = M66592_BASE_PIPENUM_INT + m66592->interrupt; | 452 | info.pipe = M66592_BASE_PIPENUM_INT + m66592->interrupt; |
@@ -447,7 +455,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
447 | break; | 455 | break; |
448 | case USB_ENDPOINT_XFER_ISOC: | 456 | case USB_ENDPOINT_XFER_ISOC: |
449 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { | 457 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { |
450 | printk(KERN_ERR "isochronous pipe is insufficient\n"); | 458 | pr_err("isochronous pipe is insufficient\n"); |
451 | return -ENODEV; | 459 | return -ENODEV; |
452 | } | 460 | } |
453 | info.pipe = M66592_BASE_PIPENUM_ISOC + m66592->isochronous; | 461 | info.pipe = M66592_BASE_PIPENUM_ISOC + m66592->isochronous; |
@@ -455,7 +463,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
455 | counter = &m66592->isochronous; | 463 | counter = &m66592->isochronous; |
456 | break; | 464 | break; |
457 | default: | 465 | default: |
458 | printk(KERN_ERR "unexpect xfer type\n"); | 466 | pr_err("unexpect xfer type\n"); |
459 | return -EINVAL; | 467 | return -EINVAL; |
460 | } | 468 | } |
461 | ep->type = info.type; | 469 | ep->type = info.type; |
@@ -470,7 +478,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
470 | 478 | ||
471 | ret = pipe_buffer_setting(m66592, &info); | 479 | ret = pipe_buffer_setting(m66592, &info); |
472 | if (ret < 0) { | 480 | if (ret < 0) { |
473 | printk(KERN_ERR "pipe_buffer_setting fail\n"); | 481 | pr_err("pipe_buffer_setting fail\n"); |
474 | return ret; | 482 | return ret; |
475 | } | 483 | } |
476 | 484 | ||
@@ -606,11 +614,33 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) | |||
606 | control_end(ep->m66592, 0); | 614 | control_end(ep->m66592, 0); |
607 | break; | 615 | break; |
608 | default: | 616 | default: |
609 | printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq); | 617 | pr_err("start_ep0: unexpect ctsq(%x)\n", ctsq); |
610 | break; | 618 | break; |
611 | } | 619 | } |
612 | } | 620 | } |
613 | 621 | ||
622 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
623 | static void init_controller(struct m66592 *m66592) | ||
624 | { | ||
625 | usbf_start_clock(); | ||
626 | m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ | ||
627 | m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); | ||
628 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | ||
629 | m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); | ||
630 | |||
631 | /* This is a workaound for SH7722 2nd cut */ | ||
632 | m66592_bset(m66592, 0x8000, M66592_DVSTCTR); | ||
633 | m66592_bset(m66592, 0x1000, M66592_TESTMODE); | ||
634 | m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); | ||
635 | |||
636 | m66592_bset(m66592, M66592_INTL, M66592_INTENB1); | ||
637 | |||
638 | m66592_write(m66592, 0, M66592_CFBCFG); | ||
639 | m66592_write(m66592, 0, M66592_D0FBCFG); | ||
640 | m66592_bset(m66592, endian, M66592_CFBCFG); | ||
641 | m66592_bset(m66592, endian, M66592_D0FBCFG); | ||
642 | } | ||
643 | #else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
614 | static void init_controller(struct m66592 *m66592) | 644 | static void init_controller(struct m66592 *m66592) |
615 | { | 645 | { |
616 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), | 646 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), |
@@ -636,9 +666,13 @@ static void init_controller(struct m66592 *m66592) | |||
636 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, | 666 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, |
637 | M66592_DMA0CFG); | 667 | M66592_DMA0CFG); |
638 | } | 668 | } |
669 | #endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
639 | 670 | ||
640 | static void disable_controller(struct m66592 *m66592) | 671 | static void disable_controller(struct m66592 *m66592) |
641 | { | 672 | { |
673 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
674 | usbf_stop_clock(); | ||
675 | #else | ||
642 | m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); | 676 | m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); |
643 | udelay(1); | 677 | udelay(1); |
644 | m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); | 678 | m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); |
@@ -646,15 +680,20 @@ static void disable_controller(struct m66592 *m66592) | |||
646 | m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); | 680 | m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); |
647 | udelay(1); | 681 | udelay(1); |
648 | m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); | 682 | m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); |
683 | #endif | ||
649 | } | 684 | } |
650 | 685 | ||
651 | static void m66592_start_xclock(struct m66592 *m66592) | 686 | static void m66592_start_xclock(struct m66592 *m66592) |
652 | { | 687 | { |
688 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
689 | usbf_start_clock(); | ||
690 | #else | ||
653 | u16 tmp; | 691 | u16 tmp; |
654 | 692 | ||
655 | tmp = m66592_read(m66592, M66592_SYSCFG); | 693 | tmp = m66592_read(m66592, M66592_SYSCFG); |
656 | if (!(tmp & M66592_XCKE)) | 694 | if (!(tmp & M66592_XCKE)) |
657 | m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); | 695 | m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); |
696 | #endif | ||
658 | } | 697 | } |
659 | 698 | ||
660 | /*-------------------------------------------------------------------------*/ | 699 | /*-------------------------------------------------------------------------*/ |
@@ -709,7 +748,7 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | |||
709 | do { | 748 | do { |
710 | tmp = m66592_read(m66592, ep->fifoctr); | 749 | tmp = m66592_read(m66592, ep->fifoctr); |
711 | if (i++ > 100000) { | 750 | if (i++ > 100000) { |
712 | printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus" | 751 | pr_err("pipe0 is busy. maybe cpu i/o bus " |
713 | "conflict. please power off this controller."); | 752 | "conflict. please power off this controller."); |
714 | return; | 753 | return; |
715 | } | 754 | } |
@@ -759,7 +798,7 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) | |||
759 | if (unlikely((tmp & M66592_FRDY) == 0)) { | 798 | if (unlikely((tmp & M66592_FRDY) == 0)) { |
760 | pipe_stop(m66592, pipenum); | 799 | pipe_stop(m66592, pipenum); |
761 | pipe_irq_disable(m66592, pipenum); | 800 | pipe_irq_disable(m66592, pipenum); |
762 | printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum); | 801 | pr_err("write fifo not ready. pipnum=%d\n", pipenum); |
763 | return; | 802 | return; |
764 | } | 803 | } |
765 | 804 | ||
@@ -808,7 +847,7 @@ static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) | |||
808 | req->req.status = -EPIPE; | 847 | req->req.status = -EPIPE; |
809 | pipe_stop(m66592, pipenum); | 848 | pipe_stop(m66592, pipenum); |
810 | pipe_irq_disable(m66592, pipenum); | 849 | pipe_irq_disable(m66592, pipenum); |
811 | printk(KERN_ERR "read fifo not ready"); | 850 | pr_err("read fifo not ready"); |
812 | return; | 851 | return; |
813 | } | 852 | } |
814 | 853 | ||
@@ -1063,7 +1102,7 @@ static void m66592_update_usb_speed(struct m66592 *m66592) | |||
1063 | break; | 1102 | break; |
1064 | default: | 1103 | default: |
1065 | m66592->gadget.speed = USB_SPEED_UNKNOWN; | 1104 | m66592->gadget.speed = USB_SPEED_UNKNOWN; |
1066 | printk(KERN_ERR "USB speed unknown\n"); | 1105 | pr_err("USB speed unknown\n"); |
1067 | } | 1106 | } |
1068 | } | 1107 | } |
1069 | 1108 | ||
@@ -1122,7 +1161,7 @@ __acquires(m66592->lock) | |||
1122 | control_end(m66592, 0); | 1161 | control_end(m66592, 0); |
1123 | break; | 1162 | break; |
1124 | default: | 1163 | default: |
1125 | printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq); | 1164 | pr_err("ctrl_stage: unexpect ctsq(%x)\n", ctsq); |
1126 | break; | 1165 | break; |
1127 | } | 1166 | } |
1128 | } | 1167 | } |
@@ -1142,6 +1181,19 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1142 | intsts0 = m66592_read(m66592, M66592_INTSTS0); | 1181 | intsts0 = m66592_read(m66592, M66592_INTSTS0); |
1143 | intenb0 = m66592_read(m66592, M66592_INTENB0); | 1182 | intenb0 = m66592_read(m66592, M66592_INTENB0); |
1144 | 1183 | ||
1184 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
1185 | if (!intsts0 && !intenb0) { | ||
1186 | /* | ||
1187 | * When USB clock stops, it cannot read register. Even if a | ||
1188 | * clock stops, the interrupt occurs. So this driver turn on | ||
1189 | * a clock by this timing and do re-reading of register. | ||
1190 | */ | ||
1191 | m66592_start_xclock(m66592); | ||
1192 | intsts0 = m66592_read(m66592, M66592_INTSTS0); | ||
1193 | intenb0 = m66592_read(m66592, M66592_INTENB0); | ||
1194 | } | ||
1195 | #endif | ||
1196 | |||
1145 | savepipe = m66592_read(m66592, M66592_CFIFOSEL); | 1197 | savepipe = m66592_read(m66592, M66592_CFIFOSEL); |
1146 | 1198 | ||
1147 | mask0 = intsts0 & intenb0; | 1199 | mask0 = intsts0 & intenb0; |
@@ -1409,13 +1461,13 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1409 | 1461 | ||
1410 | retval = device_add(&m66592->gadget.dev); | 1462 | retval = device_add(&m66592->gadget.dev); |
1411 | if (retval) { | 1463 | if (retval) { |
1412 | printk(KERN_ERR "device_add error (%d)\n", retval); | 1464 | pr_err("device_add error (%d)\n", retval); |
1413 | goto error; | 1465 | goto error; |
1414 | } | 1466 | } |
1415 | 1467 | ||
1416 | retval = driver->bind (&m66592->gadget); | 1468 | retval = driver->bind (&m66592->gadget); |
1417 | if (retval) { | 1469 | if (retval) { |
1418 | printk(KERN_ERR "bind to driver error (%d)\n", retval); | 1470 | pr_err("bind to driver error (%d)\n", retval); |
1419 | device_del(&m66592->gadget.dev); | 1471 | device_del(&m66592->gadget.dev); |
1420 | goto error; | 1472 | goto error; |
1421 | } | 1473 | } |
@@ -1456,6 +1508,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1456 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); | 1508 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); |
1457 | 1509 | ||
1458 | driver->unbind(&m66592->gadget); | 1510 | driver->unbind(&m66592->gadget); |
1511 | m66592->gadget.dev.driver = NULL; | ||
1459 | 1512 | ||
1460 | init_controller(m66592); | 1513 | init_controller(m66592); |
1461 | disable_controller(m66592); | 1514 | disable_controller(m66592); |
@@ -1485,6 +1538,7 @@ static int __exit m66592_remove(struct platform_device *pdev) | |||
1485 | iounmap(m66592->reg); | 1538 | iounmap(m66592->reg); |
1486 | free_irq(platform_get_irq(pdev, 0), m66592); | 1539 | free_irq(platform_get_irq(pdev, 0), m66592); |
1487 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); | 1540 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); |
1541 | usbf_stop_clock(); | ||
1488 | kfree(m66592); | 1542 | kfree(m66592); |
1489 | return 0; | 1543 | return 0; |
1490 | } | 1544 | } |
@@ -1508,28 +1562,28 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1508 | (char *)udc_name); | 1562 | (char *)udc_name); |
1509 | if (!res) { | 1563 | if (!res) { |
1510 | ret = -ENODEV; | 1564 | ret = -ENODEV; |
1511 | printk(KERN_ERR "platform_get_resource_byname error.\n"); | 1565 | pr_err("platform_get_resource_byname error.\n"); |
1512 | goto clean_up; | 1566 | goto clean_up; |
1513 | } | 1567 | } |
1514 | 1568 | ||
1515 | irq = platform_get_irq(pdev, 0); | 1569 | irq = platform_get_irq(pdev, 0); |
1516 | if (irq < 0) { | 1570 | if (irq < 0) { |
1517 | ret = -ENODEV; | 1571 | ret = -ENODEV; |
1518 | printk(KERN_ERR "platform_get_irq error.\n"); | 1572 | pr_err("platform_get_irq error.\n"); |
1519 | goto clean_up; | 1573 | goto clean_up; |
1520 | } | 1574 | } |
1521 | 1575 | ||
1522 | reg = ioremap(res->start, resource_len(res)); | 1576 | reg = ioremap(res->start, resource_len(res)); |
1523 | if (reg == NULL) { | 1577 | if (reg == NULL) { |
1524 | ret = -ENOMEM; | 1578 | ret = -ENOMEM; |
1525 | printk(KERN_ERR "ioremap error.\n"); | 1579 | pr_err("ioremap error.\n"); |
1526 | goto clean_up; | 1580 | goto clean_up; |
1527 | } | 1581 | } |
1528 | 1582 | ||
1529 | /* initialize ucd */ | 1583 | /* initialize ucd */ |
1530 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); | 1584 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); |
1531 | if (m66592 == NULL) { | 1585 | if (m66592 == NULL) { |
1532 | printk(KERN_ERR "kzalloc error\n"); | 1586 | pr_err("kzalloc error\n"); |
1533 | goto clean_up; | 1587 | goto clean_up; |
1534 | } | 1588 | } |
1535 | 1589 | ||
@@ -1555,7 +1609,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1555 | ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, | 1609 | ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, |
1556 | udc_name, m66592); | 1610 | udc_name, m66592); |
1557 | if (ret < 0) { | 1611 | if (ret < 0) { |
1558 | printk(KERN_ERR "request_irq error (%d)\n", ret); | 1612 | pr_err("request_irq error (%d)\n", ret); |
1559 | goto clean_up; | 1613 | goto clean_up; |
1560 | } | 1614 | } |
1561 | 1615 | ||
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index bfa0c645f229..17b792b7f6bf 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h | |||
@@ -72,6 +72,11 @@ | |||
72 | #define M66592_P_TST_J 0x0001 /* PERI TEST J */ | 72 | #define M66592_P_TST_J 0x0001 /* PERI TEST J */ |
73 | #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ | 73 | #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ |
74 | 74 | ||
75 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
76 | #define M66592_CFBCFG 0x0A | ||
77 | #define M66592_D0FBCFG 0x0C | ||
78 | #define M66592_LITTLE 0x0100 /* b8: Little endian mode */ | ||
79 | #else | ||
75 | #define M66592_PINCFG 0x0A | 80 | #define M66592_PINCFG 0x0A |
76 | #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ | 81 | #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ |
77 | #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ | 82 | #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ |
@@ -91,6 +96,7 @@ | |||
91 | #define M66592_PKTM 0x0020 /* b5: Packet mode */ | 96 | #define M66592_PKTM 0x0020 /* b5: Packet mode */ |
92 | #define M66592_DENDE 0x0010 /* b4: Dend enable */ | 97 | #define M66592_DENDE 0x0010 /* b4: Dend enable */ |
93 | #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ | 98 | #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ |
99 | #endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
94 | 100 | ||
95 | #define M66592_CFIFO 0x10 | 101 | #define M66592_CFIFO 0x10 |
96 | #define M66592_D0FIFO 0x14 | 102 | #define M66592_D0FIFO 0x14 |
@@ -103,9 +109,13 @@ | |||
103 | #define M66592_REW 0x4000 /* b14: Buffer rewind */ | 109 | #define M66592_REW 0x4000 /* b14: Buffer rewind */ |
104 | #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ | 110 | #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ |
105 | #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ | 111 | #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ |
112 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
113 | #define M66592_MBW 0x0800 /* b11: Maximum bit width for FIFO */ | ||
114 | #else | ||
106 | #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ | 115 | #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ |
107 | #define M66592_MBW_8 0x0000 /* 8bit */ | 116 | #define M66592_MBW_8 0x0000 /* 8bit */ |
108 | #define M66592_MBW_16 0x0400 /* 16bit */ | 117 | #define M66592_MBW_16 0x0400 /* 16bit */ |
118 | #endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
109 | #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ | 119 | #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ |
110 | #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ | 120 | #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ |
111 | #define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ | 121 | #define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ |
@@ -530,8 +540,13 @@ static inline void m66592_read_fifo(struct m66592 *m66592, | |||
530 | { | 540 | { |
531 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | 541 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; |
532 | 542 | ||
543 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
544 | len = (len + 3) / 4; | ||
545 | insl(fifoaddr, buf, len); | ||
546 | #else | ||
533 | len = (len + 1) / 2; | 547 | len = (len + 1) / 2; |
534 | insw(fifoaddr, buf, len); | 548 | insw(fifoaddr, buf, len); |
549 | #endif | ||
535 | } | 550 | } |
536 | 551 | ||
537 | static inline void m66592_write(struct m66592 *m66592, u16 val, | 552 | static inline void m66592_write(struct m66592 *m66592, u16 val, |
@@ -545,6 +560,24 @@ static inline void m66592_write_fifo(struct m66592 *m66592, | |||
545 | void *buf, unsigned long len) | 560 | void *buf, unsigned long len) |
546 | { | 561 | { |
547 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | 562 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; |
563 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
564 | unsigned long count; | ||
565 | unsigned char *pb; | ||
566 | int i; | ||
567 | |||
568 | count = len / 4; | ||
569 | outsl(fifoaddr, buf, count); | ||
570 | |||
571 | if (len & 0x00000003) { | ||
572 | pb = buf + count * 4; | ||
573 | for (i = 0; i < (len & 0x00000003); i++) { | ||
574 | if (m66592_read(m66592, M66592_CFBCFG)) /* little */ | ||
575 | outb(pb[i], fifoaddr + (3 - i)); | ||
576 | else | ||
577 | outb(pb[i], fifoaddr + i); | ||
578 | } | ||
579 | } | ||
580 | #else | ||
548 | unsigned long odd = len & 0x0001; | 581 | unsigned long odd = len & 0x0001; |
549 | 582 | ||
550 | len = len / 2; | 583 | len = len / 2; |
@@ -553,6 +586,7 @@ static inline void m66592_write_fifo(struct m66592 *m66592, | |||
553 | unsigned char *p = buf + len*2; | 586 | unsigned char *p = buf + len*2; |
554 | outb(*p, fifoaddr); | 587 | outb(*p, fifoaddr); |
555 | } | 588 | } |
589 | #endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
556 | } | 590 | } |
557 | 591 | ||
558 | static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, | 592 | static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, |
@@ -570,6 +604,26 @@ static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, | |||
570 | #define m66592_bset(m66592, val, offset) \ | 604 | #define m66592_bset(m66592, val, offset) \ |
571 | m66592_mdfy(m66592, val, 0, offset) | 605 | m66592_mdfy(m66592, val, 0, offset) |
572 | 606 | ||
607 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
608 | #include <asm/io.h> | ||
609 | #define MSTPCR2 0xA4150038 /* for SH7722 */ | ||
610 | #define MSTPCR2_USB 0x00000800 | ||
611 | |||
612 | static inline void usbf_start_clock(void) | ||
613 | { | ||
614 | ctrl_outl(ctrl_inl(MSTPCR2) & ~MSTPCR2_USB, MSTPCR2); | ||
615 | } | ||
616 | |||
617 | static inline void usbf_stop_clock(void) | ||
618 | { | ||
619 | ctrl_outl(ctrl_inl(MSTPCR2) | MSTPCR2_USB, MSTPCR2); | ||
620 | } | ||
621 | |||
622 | #else | ||
623 | #define usbf_start_clock(x) | ||
624 | #define usbf_stop_clock(x) | ||
625 | #endif /* if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
626 | |||
573 | #endif /* ifndef __M66592_UDC_H__ */ | 627 | #endif /* ifndef __M66592_UDC_H__ */ |
574 | 628 | ||
575 | 629 | ||
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index d5d473f8144b..33469cf5aec3 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -2435,7 +2435,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2435 | break; | 2435 | break; |
2436 | default: | 2436 | default: |
2437 | delegate: | 2437 | delegate: |
2438 | VDEBUG (dev, "setup %02x.%02x v%04x i%04x l%04x" | 2438 | VDEBUG (dev, "setup %02x.%02x v%04x i%04x l%04x " |
2439 | "ep_cfg %08x\n", | 2439 | "ep_cfg %08x\n", |
2440 | u.r.bRequestType, u.r.bRequest, | 2440 | u.r.bRequestType, u.r.bRequest, |
2441 | w_value, w_index, w_length, | 2441 | w_value, w_index, w_length, |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index d377154658b5..e6d68bda428a 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 2004 Texas Instruments, Inc. | 4 | * Copyright (C) 2004 Texas Instruments, Inc. |
5 | * Copyright (C) 2004-2005 David Brownell | 5 | * Copyright (C) 2004-2005 David Brownell |
6 | * | 6 | * |
7 | * OMAP2 & DMA support by Kyungmin Park <kyungmin.park@samsung.com> | ||
8 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License, or |
@@ -60,11 +62,6 @@ | |||
60 | /* bulk DMA seems to be behaving for both IN and OUT */ | 62 | /* bulk DMA seems to be behaving for both IN and OUT */ |
61 | #define USE_DMA | 63 | #define USE_DMA |
62 | 64 | ||
63 | /* FIXME: OMAP2 currently has some problem in DMA mode */ | ||
64 | #ifdef CONFIG_ARCH_OMAP2 | ||
65 | #undef USE_DMA | ||
66 | #endif | ||
67 | |||
68 | /* ISO too */ | 65 | /* ISO too */ |
69 | #define USE_ISO | 66 | #define USE_ISO |
70 | 67 | ||
@@ -73,6 +70,8 @@ | |||
73 | 70 | ||
74 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | 71 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) |
75 | 72 | ||
73 | #define OMAP2_DMA_CH(ch) (((ch) - 1) << 1) | ||
74 | #define OMAP24XX_DMA(name, ch) (OMAP24XX_DMA_##name + OMAP2_DMA_CH(ch)) | ||
76 | 75 | ||
77 | /* | 76 | /* |
78 | * The OMAP UDC needs _very_ early endpoint setup: before enabling the | 77 | * The OMAP UDC needs _very_ early endpoint setup: before enabling the |
@@ -571,20 +570,25 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) | |||
571 | const int sync_mode = cpu_is_omap15xx() | 570 | const int sync_mode = cpu_is_omap15xx() |
572 | ? OMAP_DMA_SYNC_FRAME | 571 | ? OMAP_DMA_SYNC_FRAME |
573 | : OMAP_DMA_SYNC_ELEMENT; | 572 | : OMAP_DMA_SYNC_ELEMENT; |
573 | int dma_trigger = 0; | ||
574 | |||
575 | if (cpu_is_omap24xx()) | ||
576 | dma_trigger = OMAP24XX_DMA(USB_W2FC_TX0, ep->dma_channel); | ||
574 | 577 | ||
575 | /* measure length in either bytes or packets */ | 578 | /* measure length in either bytes or packets */ |
576 | if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) | 579 | if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) |
580 | || (cpu_is_omap24xx() && length < ep->maxpacket) | ||
577 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { | 581 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { |
578 | txdma_ctrl = UDC_TXN_EOT | length; | 582 | txdma_ctrl = UDC_TXN_EOT | length; |
579 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, | 583 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, |
580 | length, 1, sync_mode, 0, 0); | 584 | length, 1, sync_mode, dma_trigger, 0); |
581 | } else { | 585 | } else { |
582 | length = min(length / ep->maxpacket, | 586 | length = min(length / ep->maxpacket, |
583 | (unsigned) UDC_TXN_TSC + 1); | 587 | (unsigned) UDC_TXN_TSC + 1); |
584 | txdma_ctrl = length; | 588 | txdma_ctrl = length; |
585 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, | 589 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, |
586 | ep->ep.maxpacket >> 1, length, sync_mode, | 590 | ep->ep.maxpacket >> 1, length, sync_mode, |
587 | 0, 0); | 591 | dma_trigger, 0); |
588 | length *= ep->maxpacket; | 592 | length *= ep->maxpacket; |
589 | } | 593 | } |
590 | omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, | 594 | omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, |
@@ -622,20 +626,31 @@ static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status) | |||
622 | 626 | ||
623 | static void next_out_dma(struct omap_ep *ep, struct omap_req *req) | 627 | static void next_out_dma(struct omap_ep *ep, struct omap_req *req) |
624 | { | 628 | { |
625 | unsigned packets; | 629 | unsigned packets = req->req.length - req->req.actual; |
630 | int dma_trigger = 0; | ||
631 | |||
632 | if (cpu_is_omap24xx()) | ||
633 | dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel); | ||
626 | 634 | ||
627 | /* NOTE: we filtered out "short reads" before, so we know | 635 | /* NOTE: we filtered out "short reads" before, so we know |
628 | * the buffer has only whole numbers of packets. | 636 | * the buffer has only whole numbers of packets. |
637 | * except MODE SELECT(6) sent the 24 bytes data in OMAP24XX DMA mode | ||
629 | */ | 638 | */ |
630 | 639 | if (cpu_is_omap24xx() && packets < ep->maxpacket) { | |
631 | /* set up this DMA transfer, enable the fifo, start */ | 640 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, |
632 | packets = (req->req.length - req->req.actual) / ep->ep.maxpacket; | 641 | packets, 1, OMAP_DMA_SYNC_ELEMENT, |
633 | packets = min(packets, (unsigned)UDC_RXN_TC + 1); | 642 | dma_trigger, 0); |
634 | req->dma_bytes = packets * ep->ep.maxpacket; | 643 | req->dma_bytes = packets; |
635 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, | 644 | } else { |
636 | ep->ep.maxpacket >> 1, packets, | 645 | /* set up this DMA transfer, enable the fifo, start */ |
637 | OMAP_DMA_SYNC_ELEMENT, | 646 | packets /= ep->ep.maxpacket; |
638 | 0, 0); | 647 | packets = min(packets, (unsigned)UDC_RXN_TC + 1); |
648 | req->dma_bytes = packets * ep->ep.maxpacket; | ||
649 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, | ||
650 | ep->ep.maxpacket >> 1, packets, | ||
651 | OMAP_DMA_SYNC_ELEMENT, | ||
652 | dma_trigger, 0); | ||
653 | } | ||
639 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, | 654 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, |
640 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, | 655 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, |
641 | 0, 0); | 656 | 0, 0); |
@@ -743,6 +758,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
743 | { | 758 | { |
744 | u16 reg; | 759 | u16 reg; |
745 | int status, restart, is_in; | 760 | int status, restart, is_in; |
761 | int dma_channel; | ||
746 | 762 | ||
747 | is_in = ep->bEndpointAddress & USB_DIR_IN; | 763 | is_in = ep->bEndpointAddress & USB_DIR_IN; |
748 | if (is_in) | 764 | if (is_in) |
@@ -769,11 +785,15 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
769 | ep->dma_channel = channel; | 785 | ep->dma_channel = channel; |
770 | 786 | ||
771 | if (is_in) { | 787 | if (is_in) { |
772 | status = omap_request_dma(OMAP_DMA_USB_W2FC_TX0 - 1 + channel, | 788 | if (cpu_is_omap24xx()) |
789 | dma_channel = OMAP24XX_DMA(USB_W2FC_TX0, channel); | ||
790 | else | ||
791 | dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; | ||
792 | status = omap_request_dma(dma_channel, | ||
773 | ep->ep.name, dma_error, ep, &ep->lch); | 793 | ep->ep.name, dma_error, ep, &ep->lch); |
774 | if (status == 0) { | 794 | if (status == 0) { |
775 | UDC_TXDMA_CFG_REG = reg; | 795 | UDC_TXDMA_CFG_REG = reg; |
776 | /* EMIFF */ | 796 | /* EMIFF or SDRC */ |
777 | omap_set_dma_src_burst_mode(ep->lch, | 797 | omap_set_dma_src_burst_mode(ep->lch, |
778 | OMAP_DMA_DATA_BURST_4); | 798 | OMAP_DMA_DATA_BURST_4); |
779 | omap_set_dma_src_data_pack(ep->lch, 1); | 799 | omap_set_dma_src_data_pack(ep->lch, 1); |
@@ -785,7 +805,12 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
785 | 0, 0); | 805 | 0, 0); |
786 | } | 806 | } |
787 | } else { | 807 | } else { |
788 | status = omap_request_dma(OMAP_DMA_USB_W2FC_RX0 - 1 + channel, | 808 | if (cpu_is_omap24xx()) |
809 | dma_channel = OMAP24XX_DMA(USB_W2FC_RX0, channel); | ||
810 | else | ||
811 | dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; | ||
812 | |||
813 | status = omap_request_dma(dma_channel, | ||
789 | ep->ep.name, dma_error, ep, &ep->lch); | 814 | ep->ep.name, dma_error, ep, &ep->lch); |
790 | if (status == 0) { | 815 | if (status == 0) { |
791 | UDC_RXDMA_CFG_REG = reg; | 816 | UDC_RXDMA_CFG_REG = reg; |
@@ -795,7 +820,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
795 | OMAP_DMA_AMODE_CONSTANT, | 820 | OMAP_DMA_AMODE_CONSTANT, |
796 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), | 821 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), |
797 | 0, 0); | 822 | 0, 0); |
798 | /* EMIFF */ | 823 | /* EMIFF or SDRC */ |
799 | omap_set_dma_dest_burst_mode(ep->lch, | 824 | omap_set_dma_dest_burst_mode(ep->lch, |
800 | OMAP_DMA_DATA_BURST_4); | 825 | OMAP_DMA_DATA_BURST_4); |
801 | omap_set_dma_dest_data_pack(ep->lch, 1); | 826 | omap_set_dma_dest_data_pack(ep->lch, 1); |
@@ -808,7 +833,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
808 | omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); | 833 | omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); |
809 | 834 | ||
810 | /* channel type P: hw synch (fifo) */ | 835 | /* channel type P: hw synch (fifo) */ |
811 | if (!cpu_is_omap15xx()) | 836 | if (cpu_class_is_omap1() && !cpu_is_omap15xx()) |
812 | OMAP1_DMA_LCH_CTRL_REG(ep->lch) = 2; | 837 | OMAP1_DMA_LCH_CTRL_REG(ep->lch) = 2; |
813 | } | 838 | } |
814 | 839 | ||
@@ -926,11 +951,13 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
926 | 951 | ||
927 | /* this isn't bogus, but OMAP DMA isn't the only hardware to | 952 | /* this isn't bogus, but OMAP DMA isn't the only hardware to |
928 | * have a hard time with partial packet reads... reject it. | 953 | * have a hard time with partial packet reads... reject it. |
954 | * Except OMAP2 can handle the small packets. | ||
929 | */ | 955 | */ |
930 | if (use_dma | 956 | if (use_dma |
931 | && ep->has_dma | 957 | && ep->has_dma |
932 | && ep->bEndpointAddress != 0 | 958 | && ep->bEndpointAddress != 0 |
933 | && (ep->bEndpointAddress & USB_DIR_IN) == 0 | 959 | && (ep->bEndpointAddress & USB_DIR_IN) == 0 |
960 | && !cpu_class_is_omap2() | ||
934 | && (req->req.length % ep->ep.maxpacket) != 0) { | 961 | && (req->req.length % ep->ep.maxpacket) != 0) { |
935 | DBG("%s, no partial packet OUT reads\n", __FUNCTION__); | 962 | DBG("%s, no partial packet OUT reads\n", __FUNCTION__); |
936 | return -EMSGSIZE; | 963 | return -EMSGSIZE; |
@@ -1001,7 +1028,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
1001 | 1028 | ||
1002 | /* STATUS for zero length DATA stages is | 1029 | /* STATUS for zero length DATA stages is |
1003 | * always an IN ... even for IN transfers, | 1030 | * always an IN ... even for IN transfers, |
1004 | * a wierd case which seem to stall OMAP. | 1031 | * a weird case which seem to stall OMAP. |
1005 | */ | 1032 | */ |
1006 | UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR); | 1033 | UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR); |
1007 | UDC_CTRL_REG = UDC_CLR_EP; | 1034 | UDC_CTRL_REG = UDC_CLR_EP; |
diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h index 1dc398bb9ab2..c6b9cbc7230a 100644 --- a/drivers/usb/gadget/omap_udc.h +++ b/drivers/usb/gadget/omap_udc.h | |||
@@ -182,21 +182,16 @@ struct omap_udc { | |||
182 | 182 | ||
183 | /*-------------------------------------------------------------------------*/ | 183 | /*-------------------------------------------------------------------------*/ |
184 | 184 | ||
185 | #ifdef DEBUG | ||
186 | #define DBG(stuff...) printk(KERN_DEBUG "udc: " stuff) | ||
187 | #else | ||
188 | #define DBG(stuff...) do{}while(0) | ||
189 | #endif | ||
190 | |||
191 | #ifdef VERBOSE | 185 | #ifdef VERBOSE |
192 | # define VDBG DBG | 186 | # define VDBG DBG |
193 | #else | 187 | #else |
194 | # define VDBG(stuff...) do{}while(0) | 188 | # define VDBG(stuff...) do{}while(0) |
195 | #endif | 189 | #endif |
196 | 190 | ||
197 | #define ERR(stuff...) printk(KERN_ERR "udc: " stuff) | 191 | #define ERR(stuff...) pr_err("udc: " stuff) |
198 | #define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) | 192 | #define WARN(stuff...) pr_warning("udc: " stuff) |
199 | #define INFO(stuff...) printk(KERN_INFO "udc: " stuff) | 193 | #define INFO(stuff...) pr_info("udc: " stuff) |
194 | #define DBG(stuff...) pr_debug("udc: " stuff) | ||
200 | 195 | ||
201 | /*-------------------------------------------------------------------------*/ | 196 | /*-------------------------------------------------------------------------*/ |
202 | 197 | ||
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c new file mode 100644 index 000000000000..9fdabc8fcac4 --- /dev/null +++ b/drivers/usb/gadget/printer.c | |||
@@ -0,0 +1,1592 @@ | |||
1 | /* | ||
2 | * printer.c -- Printer gadget driver | ||
3 | * | ||
4 | * Copyright (C) 2003-2005 David Brownell | ||
5 | * Copyright (C) 2006 Craig W. Nadler | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/timer.h> | ||
32 | #include <linux/list.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/utsname.h> | ||
35 | #include <linux/device.h> | ||
36 | #include <linux/moduleparam.h> | ||
37 | #include <linux/fs.h> | ||
38 | #include <linux/poll.h> | ||
39 | #include <linux/types.h> | ||
40 | #include <linux/ctype.h> | ||
41 | #include <linux/cdev.h> | ||
42 | |||
43 | #include <asm/byteorder.h> | ||
44 | #include <linux/io.h> | ||
45 | #include <linux/irq.h> | ||
46 | #include <asm/system.h> | ||
47 | #include <linux/uaccess.h> | ||
48 | #include <asm/unaligned.h> | ||
49 | |||
50 | #include <linux/usb/ch9.h> | ||
51 | #include <linux/usb/gadget.h> | ||
52 | #include <linux/usb/g_printer.h> | ||
53 | |||
54 | #include "gadget_chips.h" | ||
55 | |||
56 | #define DRIVER_DESC "Printer Gadget" | ||
57 | #define DRIVER_VERSION "2007 OCT 06" | ||
58 | |||
59 | static const char shortname [] = "printer"; | ||
60 | static const char driver_desc [] = DRIVER_DESC; | ||
61 | |||
62 | static dev_t g_printer_devno; | ||
63 | |||
64 | static struct class *usb_gadget_class; | ||
65 | |||
66 | /*-------------------------------------------------------------------------*/ | ||
67 | |||
68 | struct printer_dev { | ||
69 | spinlock_t lock; /* lock this structure */ | ||
70 | /* lock buffer lists during read/write calls */ | ||
71 | spinlock_t lock_printer_io; | ||
72 | struct usb_gadget *gadget; | ||
73 | struct usb_request *req; /* for control responses */ | ||
74 | u8 config; | ||
75 | s8 interface; | ||
76 | struct usb_ep *in_ep, *out_ep; | ||
77 | const struct usb_endpoint_descriptor | ||
78 | *in, *out; | ||
79 | struct list_head rx_reqs; /* List of free RX structs */ | ||
80 | struct list_head rx_reqs_active; /* List of Active RX xfers */ | ||
81 | struct list_head rx_buffers; /* List of completed xfers */ | ||
82 | /* wait until there is data to be read. */ | ||
83 | wait_queue_head_t rx_wait; | ||
84 | struct list_head tx_reqs; /* List of free TX structs */ | ||
85 | struct list_head tx_reqs_active; /* List of Active TX xfers */ | ||
86 | /* Wait until there are write buffers available to use. */ | ||
87 | wait_queue_head_t tx_wait; | ||
88 | /* Wait until all write buffers have been sent. */ | ||
89 | wait_queue_head_t tx_flush_wait; | ||
90 | struct usb_request *current_rx_req; | ||
91 | size_t current_rx_bytes; | ||
92 | u8 *current_rx_buf; | ||
93 | u8 printer_status; | ||
94 | u8 reset_printer; | ||
95 | struct class_device *printer_class_dev; | ||
96 | struct cdev printer_cdev; | ||
97 | struct device *pdev; | ||
98 | u8 printer_cdev_open; | ||
99 | wait_queue_head_t wait; | ||
100 | }; | ||
101 | |||
102 | static struct printer_dev usb_printer_gadget; | ||
103 | |||
104 | /*-------------------------------------------------------------------------*/ | ||
105 | |||
106 | /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! | ||
107 | * Instead: allocate your own, using normal USB-IF procedures. | ||
108 | */ | ||
109 | |||
110 | /* Thanks to NetChip Technologies for donating this product ID. | ||
111 | */ | ||
112 | #define PRINTER_VENDOR_NUM 0x0525 /* NetChip */ | ||
113 | #define PRINTER_PRODUCT_NUM 0xa4a8 /* Linux-USB Printer Gadget */ | ||
114 | |||
115 | /* Some systems will want different product identifers published in the | ||
116 | * device descriptor, either numbers or strings or both. These string | ||
117 | * parameters are in UTF-8 (superset of ASCII's 7 bit characters). | ||
118 | */ | ||
119 | |||
120 | static ushort __initdata idVendor; | ||
121 | module_param(idVendor, ushort, S_IRUGO); | ||
122 | MODULE_PARM_DESC(idVendor, "USB Vendor ID"); | ||
123 | |||
124 | static ushort __initdata idProduct; | ||
125 | module_param(idProduct, ushort, S_IRUGO); | ||
126 | MODULE_PARM_DESC(idProduct, "USB Product ID"); | ||
127 | |||
128 | static ushort __initdata bcdDevice; | ||
129 | module_param(bcdDevice, ushort, S_IRUGO); | ||
130 | MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); | ||
131 | |||
132 | static char *__initdata iManufacturer; | ||
133 | module_param(iManufacturer, charp, S_IRUGO); | ||
134 | MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); | ||
135 | |||
136 | static char *__initdata iProduct; | ||
137 | module_param(iProduct, charp, S_IRUGO); | ||
138 | MODULE_PARM_DESC(iProduct, "USB Product string"); | ||
139 | |||
140 | static char *__initdata iSerialNum; | ||
141 | module_param(iSerialNum, charp, S_IRUGO); | ||
142 | MODULE_PARM_DESC(iSerialNum, "1"); | ||
143 | |||
144 | static char *__initdata iPNPstring; | ||
145 | module_param(iPNPstring, charp, S_IRUGO); | ||
146 | MODULE_PARM_DESC(iPNPstring, "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"); | ||
147 | |||
148 | /* Number of requests to allocate per endpoint, not used for ep0. */ | ||
149 | static unsigned qlen = 10; | ||
150 | module_param(qlen, uint, S_IRUGO|S_IWUSR); | ||
151 | |||
152 | #define QLEN qlen | ||
153 | |||
154 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
155 | #define DEVSPEED USB_SPEED_HIGH | ||
156 | #else /* full speed (low speed doesn't do bulk) */ | ||
157 | #define DEVSPEED USB_SPEED_FULL | ||
158 | #endif | ||
159 | |||
160 | /*-------------------------------------------------------------------------*/ | ||
161 | |||
162 | #define xprintk(d, level, fmt, args...) \ | ||
163 | printk(level "%s: " fmt, DRIVER_DESC, ## args) | ||
164 | |||
165 | #ifdef DEBUG | ||
166 | #define DBG(dev, fmt, args...) \ | ||
167 | xprintk(dev, KERN_DEBUG, fmt, ## args) | ||
168 | #else | ||
169 | #define DBG(dev, fmt, args...) \ | ||
170 | do { } while (0) | ||
171 | #endif /* DEBUG */ | ||
172 | |||
173 | #ifdef VERBOSE | ||
174 | #define VDBG(dev, fmt, args...) \ | ||
175 | xprintk(dev, KERN_DEBUG, fmt, ## args) | ||
176 | #else | ||
177 | #define VDBG(dev, fmt, args...) \ | ||
178 | do { } while (0) | ||
179 | #endif /* VERBOSE */ | ||
180 | |||
181 | #define ERROR(dev, fmt, args...) \ | ||
182 | xprintk(dev, KERN_ERR, fmt, ## args) | ||
183 | #define WARN(dev, fmt, args...) \ | ||
184 | xprintk(dev, KERN_WARNING, fmt, ## args) | ||
185 | #define INFO(dev, fmt, args...) \ | ||
186 | xprintk(dev, KERN_INFO, fmt, ## args) | ||
187 | |||
188 | /*-------------------------------------------------------------------------*/ | ||
189 | |||
190 | /* USB DRIVER HOOKUP (to the hardware driver, below us), mostly | ||
191 | * ep0 implementation: descriptors, config management, setup(). | ||
192 | * also optional class-specific notification interrupt transfer. | ||
193 | */ | ||
194 | |||
195 | /* | ||
196 | * DESCRIPTORS ... most are static, but strings and (full) configuration | ||
197 | * descriptors are built on demand. | ||
198 | */ | ||
199 | |||
200 | #define STRING_MANUFACTURER 1 | ||
201 | #define STRING_PRODUCT 2 | ||
202 | #define STRING_SERIALNUM 3 | ||
203 | |||
204 | /* holds our biggest descriptor */ | ||
205 | #define USB_DESC_BUFSIZE 256 | ||
206 | #define USB_BUFSIZE 8192 | ||
207 | |||
208 | /* This device advertises one configuration. */ | ||
209 | #define DEV_CONFIG_VALUE 1 | ||
210 | #define PRINTER_INTERFACE 0 | ||
211 | |||
212 | static struct usb_device_descriptor device_desc = { | ||
213 | .bLength = sizeof device_desc, | ||
214 | .bDescriptorType = USB_DT_DEVICE, | ||
215 | .bcdUSB = __constant_cpu_to_le16(0x0200), | ||
216 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
217 | .bDeviceSubClass = 0, | ||
218 | .bDeviceProtocol = 0, | ||
219 | .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM), | ||
220 | .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM), | ||
221 | .iManufacturer = STRING_MANUFACTURER, | ||
222 | .iProduct = STRING_PRODUCT, | ||
223 | .iSerialNumber = STRING_SERIALNUM, | ||
224 | .bNumConfigurations = 1 | ||
225 | }; | ||
226 | |||
227 | static struct usb_otg_descriptor otg_desc = { | ||
228 | .bLength = sizeof otg_desc, | ||
229 | .bDescriptorType = USB_DT_OTG, | ||
230 | .bmAttributes = USB_OTG_SRP | ||
231 | }; | ||
232 | |||
233 | static struct usb_config_descriptor config_desc = { | ||
234 | .bLength = sizeof config_desc, | ||
235 | .bDescriptorType = USB_DT_CONFIG, | ||
236 | |||
237 | /* compute wTotalLength on the fly */ | ||
238 | .bNumInterfaces = 1, | ||
239 | .bConfigurationValue = DEV_CONFIG_VALUE, | ||
240 | .iConfiguration = 0, | ||
241 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
242 | .bMaxPower = 1 /* Self-Powered */ | ||
243 | }; | ||
244 | |||
245 | static struct usb_interface_descriptor intf_desc = { | ||
246 | .bLength = sizeof intf_desc, | ||
247 | .bDescriptorType = USB_DT_INTERFACE, | ||
248 | .bInterfaceNumber = PRINTER_INTERFACE, | ||
249 | .bNumEndpoints = 2, | ||
250 | .bInterfaceClass = USB_CLASS_PRINTER, | ||
251 | .bInterfaceSubClass = 1, /* Printer Sub-Class */ | ||
252 | .bInterfaceProtocol = 2, /* Bi-Directional */ | ||
253 | .iInterface = 0 | ||
254 | }; | ||
255 | |||
256 | static struct usb_endpoint_descriptor fs_ep_in_desc = { | ||
257 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
258 | .bDescriptorType = USB_DT_ENDPOINT, | ||
259 | .bEndpointAddress = USB_DIR_IN, | ||
260 | .bmAttributes = USB_ENDPOINT_XFER_BULK | ||
261 | }; | ||
262 | |||
263 | static struct usb_endpoint_descriptor fs_ep_out_desc = { | ||
264 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
265 | .bDescriptorType = USB_DT_ENDPOINT, | ||
266 | .bEndpointAddress = USB_DIR_OUT, | ||
267 | .bmAttributes = USB_ENDPOINT_XFER_BULK | ||
268 | }; | ||
269 | |||
270 | static const struct usb_descriptor_header *fs_printer_function [11] = { | ||
271 | (struct usb_descriptor_header *) &otg_desc, | ||
272 | (struct usb_descriptor_header *) &intf_desc, | ||
273 | (struct usb_descriptor_header *) &fs_ep_in_desc, | ||
274 | (struct usb_descriptor_header *) &fs_ep_out_desc, | ||
275 | NULL | ||
276 | }; | ||
277 | |||
278 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
279 | |||
280 | /* | ||
281 | * usb 2.0 devices need to expose both high speed and full speed | ||
282 | * descriptors, unless they only run at full speed. | ||
283 | */ | ||
284 | |||
285 | static struct usb_endpoint_descriptor hs_ep_in_desc = { | ||
286 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
287 | .bDescriptorType = USB_DT_ENDPOINT, | ||
288 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
289 | .wMaxPacketSize = __constant_cpu_to_le16(512) | ||
290 | }; | ||
291 | |||
292 | static struct usb_endpoint_descriptor hs_ep_out_desc = { | ||
293 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
294 | .bDescriptorType = USB_DT_ENDPOINT, | ||
295 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
296 | .wMaxPacketSize = __constant_cpu_to_le16(512) | ||
297 | }; | ||
298 | |||
299 | static struct usb_qualifier_descriptor dev_qualifier = { | ||
300 | .bLength = sizeof dev_qualifier, | ||
301 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | ||
302 | .bcdUSB = __constant_cpu_to_le16(0x0200), | ||
303 | .bDeviceClass = USB_CLASS_PRINTER, | ||
304 | .bNumConfigurations = 1 | ||
305 | }; | ||
306 | |||
307 | static const struct usb_descriptor_header *hs_printer_function [11] = { | ||
308 | (struct usb_descriptor_header *) &otg_desc, | ||
309 | (struct usb_descriptor_header *) &intf_desc, | ||
310 | (struct usb_descriptor_header *) &hs_ep_in_desc, | ||
311 | (struct usb_descriptor_header *) &hs_ep_out_desc, | ||
312 | NULL | ||
313 | }; | ||
314 | |||
315 | /* maxpacket and other transfer characteristics vary by speed. */ | ||
316 | #define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs)) | ||
317 | |||
318 | #else | ||
319 | |||
320 | /* if there's no high speed support, maxpacket doesn't change. */ | ||
321 | #define ep_desc(g, hs, fs) (((void)(g)), (fs)) | ||
322 | |||
323 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | ||
324 | |||
325 | /*-------------------------------------------------------------------------*/ | ||
326 | |||
327 | /* descriptors that are built on-demand */ | ||
328 | |||
329 | static char manufacturer [50]; | ||
330 | static char product_desc [40] = DRIVER_DESC; | ||
331 | static char serial_num [40] = "1"; | ||
332 | static char pnp_string [1024] = | ||
333 | "XXMFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"; | ||
334 | |||
335 | /* static strings, in UTF-8 */ | ||
336 | static struct usb_string strings [] = { | ||
337 | { STRING_MANUFACTURER, manufacturer, }, | ||
338 | { STRING_PRODUCT, product_desc, }, | ||
339 | { STRING_SERIALNUM, serial_num, }, | ||
340 | { } /* end of list */ | ||
341 | }; | ||
342 | |||
343 | static struct usb_gadget_strings stringtab = { | ||
344 | .language = 0x0409, /* en-us */ | ||
345 | .strings = strings, | ||
346 | }; | ||
347 | |||
348 | /*-------------------------------------------------------------------------*/ | ||
349 | |||
350 | static struct usb_request * | ||
351 | printer_req_alloc(struct usb_ep *ep, unsigned len, gfp_t gfp_flags) | ||
352 | { | ||
353 | struct usb_request *req; | ||
354 | |||
355 | req = usb_ep_alloc_request(ep, gfp_flags); | ||
356 | |||
357 | if (req != NULL) { | ||
358 | req->length = len; | ||
359 | req->buf = kmalloc(len, gfp_flags); | ||
360 | if (req->buf == NULL) { | ||
361 | usb_ep_free_request(ep, req); | ||
362 | return NULL; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | return req; | ||
367 | } | ||
368 | |||
369 | static void | ||
370 | printer_req_free(struct usb_ep *ep, struct usb_request *req) | ||
371 | { | ||
372 | if (ep != NULL && req != NULL) { | ||
373 | kfree(req->buf); | ||
374 | usb_ep_free_request(ep, req); | ||
375 | } | ||
376 | } | ||
377 | |||
378 | /*-------------------------------------------------------------------------*/ | ||
379 | |||
380 | static void rx_complete(struct usb_ep *ep, struct usb_request *req) | ||
381 | { | ||
382 | struct printer_dev *dev = ep->driver_data; | ||
383 | int status = req->status; | ||
384 | unsigned long flags; | ||
385 | |||
386 | spin_lock_irqsave(&dev->lock, flags); | ||
387 | |||
388 | list_del_init(&req->list); /* Remode from Active List */ | ||
389 | |||
390 | switch (status) { | ||
391 | |||
392 | /* normal completion */ | ||
393 | case 0: | ||
394 | list_add_tail(&req->list, &dev->rx_buffers); | ||
395 | wake_up_interruptible(&dev->rx_wait); | ||
396 | DBG(dev, "G_Printer : rx length %d\n", req->actual); | ||
397 | break; | ||
398 | |||
399 | /* software-driven interface shutdown */ | ||
400 | case -ECONNRESET: /* unlink */ | ||
401 | case -ESHUTDOWN: /* disconnect etc */ | ||
402 | VDBG(dev, "rx shutdown, code %d\n", status); | ||
403 | list_add(&req->list, &dev->rx_reqs); | ||
404 | break; | ||
405 | |||
406 | /* for hardware automagic (such as pxa) */ | ||
407 | case -ECONNABORTED: /* endpoint reset */ | ||
408 | DBG(dev, "rx %s reset\n", ep->name); | ||
409 | list_add(&req->list, &dev->rx_reqs); | ||
410 | break; | ||
411 | |||
412 | /* data overrun */ | ||
413 | case -EOVERFLOW: | ||
414 | /* FALLTHROUGH */ | ||
415 | |||
416 | default: | ||
417 | DBG(dev, "rx status %d\n", status); | ||
418 | list_add(&req->list, &dev->rx_reqs); | ||
419 | break; | ||
420 | } | ||
421 | spin_unlock_irqrestore(&dev->lock, flags); | ||
422 | } | ||
423 | |||
424 | static void tx_complete(struct usb_ep *ep, struct usb_request *req) | ||
425 | { | ||
426 | struct printer_dev *dev = ep->driver_data; | ||
427 | |||
428 | switch (req->status) { | ||
429 | default: | ||
430 | VDBG(dev, "tx err %d\n", req->status); | ||
431 | /* FALLTHROUGH */ | ||
432 | case -ECONNRESET: /* unlink */ | ||
433 | case -ESHUTDOWN: /* disconnect etc */ | ||
434 | break; | ||
435 | case 0: | ||
436 | break; | ||
437 | } | ||
438 | |||
439 | spin_lock(&dev->lock); | ||
440 | /* Take the request struct off the active list and put it on the | ||
441 | * free list. | ||
442 | */ | ||
443 | list_del_init(&req->list); | ||
444 | list_add(&req->list, &dev->tx_reqs); | ||
445 | wake_up_interruptible(&dev->tx_wait); | ||
446 | if (likely(list_empty(&dev->tx_reqs_active))) | ||
447 | wake_up_interruptible(&dev->tx_flush_wait); | ||
448 | |||
449 | spin_unlock(&dev->lock); | ||
450 | } | ||
451 | |||
452 | /*-------------------------------------------------------------------------*/ | ||
453 | |||
454 | static int | ||
455 | printer_open(struct inode *inode, struct file *fd) | ||
456 | { | ||
457 | struct printer_dev *dev; | ||
458 | unsigned long flags; | ||
459 | int ret = -EBUSY; | ||
460 | |||
461 | dev = container_of(inode->i_cdev, struct printer_dev, printer_cdev); | ||
462 | |||
463 | spin_lock_irqsave(&dev->lock, flags); | ||
464 | |||
465 | if (!dev->printer_cdev_open) { | ||
466 | dev->printer_cdev_open = 1; | ||
467 | fd->private_data = dev; | ||
468 | ret = 0; | ||
469 | /* Change the printer status to show that it's on-line. */ | ||
470 | dev->printer_status |= PRINTER_SELECTED; | ||
471 | } | ||
472 | |||
473 | spin_unlock_irqrestore(&dev->lock, flags); | ||
474 | |||
475 | DBG(dev, "printer_open returned %x\n", ret); | ||
476 | |||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | static int | ||
481 | printer_close(struct inode *inode, struct file *fd) | ||
482 | { | ||
483 | struct printer_dev *dev = fd->private_data; | ||
484 | unsigned long flags; | ||
485 | |||
486 | spin_lock_irqsave(&dev->lock, flags); | ||
487 | dev->printer_cdev_open = 0; | ||
488 | fd->private_data = NULL; | ||
489 | /* Change printer status to show that the printer is off-line. */ | ||
490 | dev->printer_status &= ~PRINTER_SELECTED; | ||
491 | spin_unlock_irqrestore(&dev->lock, flags); | ||
492 | |||
493 | DBG(dev, "printer_close\n"); | ||
494 | |||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static ssize_t | ||
499 | printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) | ||
500 | { | ||
501 | struct printer_dev *dev = fd->private_data; | ||
502 | unsigned long flags; | ||
503 | size_t size; | ||
504 | size_t bytes_copied; | ||
505 | struct usb_request *req; | ||
506 | /* This is a pointer to the current USB rx request. */ | ||
507 | struct usb_request *current_rx_req; | ||
508 | /* This is the number of bytes in the current rx buffer. */ | ||
509 | size_t current_rx_bytes; | ||
510 | /* This is a pointer to the current rx buffer. */ | ||
511 | u8 *current_rx_buf; | ||
512 | |||
513 | if (len == 0) | ||
514 | return -EINVAL; | ||
515 | |||
516 | DBG(dev, "printer_read trying to read %d bytes\n", (int)len); | ||
517 | |||
518 | spin_lock(&dev->lock_printer_io); | ||
519 | spin_lock_irqsave(&dev->lock, flags); | ||
520 | |||
521 | /* We will use this flag later to check if a printer reset happened | ||
522 | * after we turn interrupts back on. | ||
523 | */ | ||
524 | dev->reset_printer = 0; | ||
525 | |||
526 | while (likely(!list_empty(&dev->rx_reqs))) { | ||
527 | int error; | ||
528 | |||
529 | req = container_of(dev->rx_reqs.next, | ||
530 | struct usb_request, list); | ||
531 | list_del_init(&req->list); | ||
532 | |||
533 | /* The USB Host sends us whatever amount of data it wants to | ||
534 | * so we always set the length field to the full USB_BUFSIZE. | ||
535 | * If the amount of data is more than the read() caller asked | ||
536 | * for it will be stored in the request buffer until it is | ||
537 | * asked for by read(). | ||
538 | */ | ||
539 | req->length = USB_BUFSIZE; | ||
540 | req->complete = rx_complete; | ||
541 | |||
542 | error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); | ||
543 | if (error) { | ||
544 | DBG(dev, "rx submit --> %d\n", error); | ||
545 | list_add(&req->list, &dev->rx_reqs); | ||
546 | break; | ||
547 | } else { | ||
548 | list_add(&req->list, &dev->rx_reqs_active); | ||
549 | } | ||
550 | } | ||
551 | |||
552 | bytes_copied = 0; | ||
553 | current_rx_req = dev->current_rx_req; | ||
554 | current_rx_bytes = dev->current_rx_bytes; | ||
555 | current_rx_buf = dev->current_rx_buf; | ||
556 | dev->current_rx_req = NULL; | ||
557 | dev->current_rx_bytes = 0; | ||
558 | dev->current_rx_buf = NULL; | ||
559 | |||
560 | /* Check if there is any data in the read buffers. Please note that | ||
561 | * current_rx_bytes is the number of bytes in the current rx buffer. | ||
562 | * If it is zero then check if there are any other rx_buffers that | ||
563 | * are on the completed list. We are only out of data if all rx | ||
564 | * buffers are empty. | ||
565 | */ | ||
566 | if ((current_rx_bytes == 0) && | ||
567 | (likely(list_empty(&dev->rx_buffers)))) { | ||
568 | /* Turn interrupts back on before sleeping. */ | ||
569 | spin_unlock_irqrestore(&dev->lock, flags); | ||
570 | |||
571 | /* | ||
572 | * If no data is available check if this is a NON-Blocking | ||
573 | * call or not. | ||
574 | */ | ||
575 | if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { | ||
576 | spin_unlock(&dev->lock_printer_io); | ||
577 | return -EAGAIN; | ||
578 | } | ||
579 | |||
580 | /* Sleep until data is available */ | ||
581 | wait_event_interruptible(dev->rx_wait, | ||
582 | (likely(!list_empty(&dev->rx_buffers)))); | ||
583 | spin_lock_irqsave(&dev->lock, flags); | ||
584 | } | ||
585 | |||
586 | /* We have data to return then copy it to the caller's buffer.*/ | ||
587 | while ((current_rx_bytes || likely(!list_empty(&dev->rx_buffers))) | ||
588 | && len) { | ||
589 | if (current_rx_bytes == 0) { | ||
590 | req = container_of(dev->rx_buffers.next, | ||
591 | struct usb_request, list); | ||
592 | list_del_init(&req->list); | ||
593 | |||
594 | if (req->actual && req->buf) { | ||
595 | current_rx_req = req; | ||
596 | current_rx_bytes = req->actual; | ||
597 | current_rx_buf = req->buf; | ||
598 | } else { | ||
599 | list_add(&req->list, &dev->rx_reqs); | ||
600 | continue; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | /* Don't leave irqs off while doing memory copies */ | ||
605 | spin_unlock_irqrestore(&dev->lock, flags); | ||
606 | |||
607 | if (len > current_rx_bytes) | ||
608 | size = current_rx_bytes; | ||
609 | else | ||
610 | size = len; | ||
611 | |||
612 | size -= copy_to_user(buf, current_rx_buf, size); | ||
613 | bytes_copied += size; | ||
614 | len -= size; | ||
615 | buf += size; | ||
616 | |||
617 | spin_lock_irqsave(&dev->lock, flags); | ||
618 | |||
619 | /* We've disconnected or reset free the req and buffer */ | ||
620 | if (dev->reset_printer) { | ||
621 | printer_req_free(dev->out_ep, current_rx_req); | ||
622 | spin_unlock_irqrestore(&dev->lock, flags); | ||
623 | spin_unlock(&dev->lock_printer_io); | ||
624 | return -EAGAIN; | ||
625 | } | ||
626 | |||
627 | /* If we not returning all the data left in this RX request | ||
628 | * buffer then adjust the amount of data left in the buffer. | ||
629 | * Othewise if we are done with this RX request buffer then | ||
630 | * requeue it to get any incoming data from the USB host. | ||
631 | */ | ||
632 | if (size < current_rx_bytes) { | ||
633 | current_rx_bytes -= size; | ||
634 | current_rx_buf += size; | ||
635 | } else { | ||
636 | list_add(¤t_rx_req->list, &dev->rx_reqs); | ||
637 | current_rx_bytes = 0; | ||
638 | current_rx_buf = NULL; | ||
639 | current_rx_req = NULL; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | dev->current_rx_req = current_rx_req; | ||
644 | dev->current_rx_bytes = current_rx_bytes; | ||
645 | dev->current_rx_buf = current_rx_buf; | ||
646 | |||
647 | spin_unlock_irqrestore(&dev->lock, flags); | ||
648 | spin_unlock(&dev->lock_printer_io); | ||
649 | |||
650 | DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied); | ||
651 | |||
652 | if (bytes_copied) | ||
653 | return bytes_copied; | ||
654 | else | ||
655 | return -EAGAIN; | ||
656 | } | ||
657 | |||
658 | static ssize_t | ||
659 | printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | ||
660 | { | ||
661 | struct printer_dev *dev = fd->private_data; | ||
662 | unsigned long flags; | ||
663 | size_t size; /* Amount of data in a TX request. */ | ||
664 | size_t bytes_copied = 0; | ||
665 | struct usb_request *req; | ||
666 | |||
667 | DBG(dev, "printer_write trying to send %d bytes\n", (int)len); | ||
668 | |||
669 | if (len == 0) | ||
670 | return -EINVAL; | ||
671 | |||
672 | spin_lock(&dev->lock_printer_io); | ||
673 | spin_lock_irqsave(&dev->lock, flags); | ||
674 | |||
675 | /* Check if a printer reset happens while we have interrupts on */ | ||
676 | dev->reset_printer = 0; | ||
677 | |||
678 | /* Check if there is any available write buffers */ | ||
679 | if (likely(list_empty(&dev->tx_reqs))) { | ||
680 | /* Turn interrupts back on before sleeping. */ | ||
681 | spin_unlock_irqrestore(&dev->lock, flags); | ||
682 | |||
683 | /* | ||
684 | * If write buffers are available check if this is | ||
685 | * a NON-Blocking call or not. | ||
686 | */ | ||
687 | if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { | ||
688 | spin_unlock(&dev->lock_printer_io); | ||
689 | return -EAGAIN; | ||
690 | } | ||
691 | |||
692 | /* Sleep until a write buffer is available */ | ||
693 | wait_event_interruptible(dev->tx_wait, | ||
694 | (likely(!list_empty(&dev->tx_reqs)))); | ||
695 | spin_lock_irqsave(&dev->lock, flags); | ||
696 | } | ||
697 | |||
698 | while (likely(!list_empty(&dev->tx_reqs)) && len) { | ||
699 | |||
700 | if (len > USB_BUFSIZE) | ||
701 | size = USB_BUFSIZE; | ||
702 | else | ||
703 | size = len; | ||
704 | |||
705 | req = container_of(dev->tx_reqs.next, struct usb_request, | ||
706 | list); | ||
707 | list_del_init(&req->list); | ||
708 | |||
709 | req->complete = tx_complete; | ||
710 | req->length = size; | ||
711 | |||
712 | /* Check if we need to send a zero length packet. */ | ||
713 | if (len > size) | ||
714 | /* They will be more TX requests so no yet. */ | ||
715 | req->zero = 0; | ||
716 | else | ||
717 | /* If the data amount is not a multple of the | ||
718 | * maxpacket size then send a zero length packet. | ||
719 | */ | ||
720 | req->zero = ((len % dev->in_ep->maxpacket) == 0); | ||
721 | |||
722 | /* Don't leave irqs off while doing memory copies */ | ||
723 | spin_unlock_irqrestore(&dev->lock, flags); | ||
724 | |||
725 | if (copy_from_user(req->buf, buf, size)) { | ||
726 | list_add(&req->list, &dev->tx_reqs); | ||
727 | spin_unlock(&dev->lock_printer_io); | ||
728 | return bytes_copied; | ||
729 | } | ||
730 | |||
731 | bytes_copied += size; | ||
732 | len -= size; | ||
733 | buf += size; | ||
734 | |||
735 | spin_lock_irqsave(&dev->lock, flags); | ||
736 | |||
737 | /* We've disconnected or reset so free the req and buffer */ | ||
738 | if (dev->reset_printer) { | ||
739 | printer_req_free(dev->in_ep, req); | ||
740 | spin_unlock_irqrestore(&dev->lock, flags); | ||
741 | spin_unlock(&dev->lock_printer_io); | ||
742 | return -EAGAIN; | ||
743 | } | ||
744 | |||
745 | if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { | ||
746 | list_add(&req->list, &dev->tx_reqs); | ||
747 | spin_unlock_irqrestore(&dev->lock, flags); | ||
748 | spin_unlock(&dev->lock_printer_io); | ||
749 | return -EAGAIN; | ||
750 | } | ||
751 | |||
752 | list_add(&req->list, &dev->tx_reqs_active); | ||
753 | |||
754 | } | ||
755 | |||
756 | spin_unlock_irqrestore(&dev->lock, flags); | ||
757 | spin_unlock(&dev->lock_printer_io); | ||
758 | |||
759 | DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied); | ||
760 | |||
761 | if (bytes_copied) { | ||
762 | return bytes_copied; | ||
763 | } else { | ||
764 | return -EAGAIN; | ||
765 | } | ||
766 | } | ||
767 | |||
768 | static int | ||
769 | printer_fsync(struct file *fd, struct dentry *dentry, int datasync) | ||
770 | { | ||
771 | struct printer_dev *dev = fd->private_data; | ||
772 | unsigned long flags; | ||
773 | int tx_list_empty; | ||
774 | |||
775 | spin_lock_irqsave(&dev->lock, flags); | ||
776 | tx_list_empty = (likely(list_empty(&dev->tx_reqs))); | ||
777 | spin_unlock_irqrestore(&dev->lock, flags); | ||
778 | |||
779 | if (!tx_list_empty) { | ||
780 | /* Sleep until all data has been sent */ | ||
781 | wait_event_interruptible(dev->tx_flush_wait, | ||
782 | (likely(list_empty(&dev->tx_reqs_active)))); | ||
783 | } | ||
784 | |||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | static unsigned int | ||
789 | printer_poll(struct file *fd, poll_table *wait) | ||
790 | { | ||
791 | struct printer_dev *dev = fd->private_data; | ||
792 | unsigned long flags; | ||
793 | int status = 0; | ||
794 | |||
795 | poll_wait(fd, &dev->rx_wait, wait); | ||
796 | poll_wait(fd, &dev->tx_wait, wait); | ||
797 | |||
798 | spin_lock_irqsave(&dev->lock, flags); | ||
799 | if (likely(!list_empty(&dev->tx_reqs))) | ||
800 | status |= POLLOUT | POLLWRNORM; | ||
801 | |||
802 | if (likely(!list_empty(&dev->rx_buffers))) | ||
803 | status |= POLLIN | POLLRDNORM; | ||
804 | |||
805 | spin_unlock_irqrestore(&dev->lock, flags); | ||
806 | |||
807 | return status; | ||
808 | } | ||
809 | |||
810 | static int | ||
811 | printer_ioctl(struct inode *inode, struct file *fd, unsigned int code, | ||
812 | unsigned long arg) | ||
813 | { | ||
814 | struct printer_dev *dev = fd->private_data; | ||
815 | unsigned long flags; | ||
816 | int status = 0; | ||
817 | |||
818 | DBG(dev, "printer_ioctl: cmd=0x%4.4x, arg=%lu\n", code, arg); | ||
819 | |||
820 | /* handle ioctls */ | ||
821 | |||
822 | spin_lock_irqsave(&dev->lock, flags); | ||
823 | |||
824 | switch (code) { | ||
825 | case GADGET_GET_PRINTER_STATUS: | ||
826 | status = (int)dev->printer_status; | ||
827 | break; | ||
828 | case GADGET_SET_PRINTER_STATUS: | ||
829 | dev->printer_status = (u8)arg; | ||
830 | break; | ||
831 | default: | ||
832 | /* could not handle ioctl */ | ||
833 | DBG(dev, "printer_ioctl: ERROR cmd=0x%4.4xis not supported\n", | ||
834 | code); | ||
835 | status = -ENOTTY; | ||
836 | } | ||
837 | |||
838 | spin_unlock_irqrestore(&dev->lock, flags); | ||
839 | |||
840 | return status; | ||
841 | } | ||
842 | |||
843 | /* used after endpoint configuration */ | ||
844 | static struct file_operations printer_io_operations = { | ||
845 | .owner = THIS_MODULE, | ||
846 | .open = printer_open, | ||
847 | .read = printer_read, | ||
848 | .write = printer_write, | ||
849 | .fsync = printer_fsync, | ||
850 | .poll = printer_poll, | ||
851 | .ioctl = printer_ioctl, | ||
852 | .release = printer_close | ||
853 | }; | ||
854 | |||
855 | /*-------------------------------------------------------------------------*/ | ||
856 | |||
857 | static int | ||
858 | set_printer_interface(struct printer_dev *dev) | ||
859 | { | ||
860 | int result = 0; | ||
861 | |||
862 | dev->in = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc); | ||
863 | dev->in_ep->driver_data = dev; | ||
864 | |||
865 | dev->out = ep_desc(dev->gadget, &hs_ep_out_desc, &fs_ep_out_desc); | ||
866 | dev->out_ep->driver_data = dev; | ||
867 | |||
868 | result = usb_ep_enable(dev->in_ep, dev->in); | ||
869 | if (result != 0) { | ||
870 | DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); | ||
871 | goto done; | ||
872 | } | ||
873 | |||
874 | result = usb_ep_enable(dev->out_ep, dev->out); | ||
875 | if (result != 0) { | ||
876 | DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); | ||
877 | goto done; | ||
878 | } | ||
879 | |||
880 | done: | ||
881 | /* on error, disable any endpoints */ | ||
882 | if (result != 0) { | ||
883 | (void) usb_ep_disable(dev->in_ep); | ||
884 | (void) usb_ep_disable(dev->out_ep); | ||
885 | dev->in = NULL; | ||
886 | dev->out = NULL; | ||
887 | } | ||
888 | |||
889 | /* caller is responsible for cleanup on error */ | ||
890 | return result; | ||
891 | } | ||
892 | |||
893 | static void printer_reset_interface(struct printer_dev *dev) | ||
894 | { | ||
895 | if (dev->interface < 0) | ||
896 | return; | ||
897 | |||
898 | DBG(dev, "%s\n", __FUNCTION__); | ||
899 | |||
900 | if (dev->in) | ||
901 | usb_ep_disable(dev->in_ep); | ||
902 | |||
903 | if (dev->out) | ||
904 | usb_ep_disable(dev->out_ep); | ||
905 | |||
906 | dev->interface = -1; | ||
907 | } | ||
908 | |||
909 | /* change our operational config. must agree with the code | ||
910 | * that returns config descriptors, and altsetting code. | ||
911 | */ | ||
912 | static int | ||
913 | printer_set_config(struct printer_dev *dev, unsigned number) | ||
914 | { | ||
915 | int result = 0; | ||
916 | struct usb_gadget *gadget = dev->gadget; | ||
917 | |||
918 | if (gadget_is_sa1100(gadget) && dev->config) { | ||
919 | /* tx fifo is full, but we can't clear it...*/ | ||
920 | INFO(dev, "can't change configurations\n"); | ||
921 | return -ESPIPE; | ||
922 | } | ||
923 | |||
924 | switch (number) { | ||
925 | case DEV_CONFIG_VALUE: | ||
926 | result = 0; | ||
927 | break; | ||
928 | default: | ||
929 | result = -EINVAL; | ||
930 | /* FALL THROUGH */ | ||
931 | case 0: | ||
932 | break; | ||
933 | } | ||
934 | |||
935 | if (result) { | ||
936 | usb_gadget_vbus_draw(dev->gadget, | ||
937 | dev->gadget->is_otg ? 8 : 100); | ||
938 | } else { | ||
939 | char *speed; | ||
940 | unsigned power; | ||
941 | |||
942 | power = 2 * config_desc.bMaxPower; | ||
943 | usb_gadget_vbus_draw(dev->gadget, power); | ||
944 | |||
945 | switch (gadget->speed) { | ||
946 | case USB_SPEED_FULL: speed = "full"; break; | ||
947 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
948 | case USB_SPEED_HIGH: speed = "high"; break; | ||
949 | #endif | ||
950 | default: speed = "?"; break; | ||
951 | } | ||
952 | |||
953 | dev->config = number; | ||
954 | INFO(dev, "%s speed config #%d: %d mA, %s\n", | ||
955 | speed, number, power, driver_desc); | ||
956 | } | ||
957 | return result; | ||
958 | } | ||
959 | |||
960 | static int | ||
961 | config_buf(enum usb_device_speed speed, u8 *buf, u8 type, unsigned index, | ||
962 | int is_otg) | ||
963 | { | ||
964 | int len; | ||
965 | const struct usb_descriptor_header **function; | ||
966 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
967 | int hs = (speed == USB_SPEED_HIGH); | ||
968 | |||
969 | if (type == USB_DT_OTHER_SPEED_CONFIG) | ||
970 | hs = !hs; | ||
971 | |||
972 | if (hs) { | ||
973 | function = hs_printer_function; | ||
974 | } else { | ||
975 | function = fs_printer_function; | ||
976 | } | ||
977 | #else | ||
978 | function = fs_printer_function; | ||
979 | #endif | ||
980 | |||
981 | if (index >= device_desc.bNumConfigurations) | ||
982 | return -EINVAL; | ||
983 | |||
984 | /* for now, don't advertise srp-only devices */ | ||
985 | if (!is_otg) | ||
986 | function++; | ||
987 | |||
988 | len = usb_gadget_config_buf(&config_desc, buf, USB_DESC_BUFSIZE, | ||
989 | function); | ||
990 | if (len < 0) | ||
991 | return len; | ||
992 | ((struct usb_config_descriptor *) buf)->bDescriptorType = type; | ||
993 | return len; | ||
994 | } | ||
995 | |||
996 | /* Change our operational Interface. */ | ||
997 | static int | ||
998 | set_interface(struct printer_dev *dev, unsigned number) | ||
999 | { | ||
1000 | int result = 0; | ||
1001 | |||
1002 | if (gadget_is_sa1100(dev->gadget) && dev->interface < 0) { | ||
1003 | /* tx fifo is full, but we can't clear it...*/ | ||
1004 | INFO(dev, "can't change interfaces\n"); | ||
1005 | return -ESPIPE; | ||
1006 | } | ||
1007 | |||
1008 | /* Free the current interface */ | ||
1009 | switch (dev->interface) { | ||
1010 | case PRINTER_INTERFACE: | ||
1011 | printer_reset_interface(dev); | ||
1012 | break; | ||
1013 | } | ||
1014 | |||
1015 | switch (number) { | ||
1016 | case PRINTER_INTERFACE: | ||
1017 | result = set_printer_interface(dev); | ||
1018 | if (result) { | ||
1019 | printer_reset_interface(dev); | ||
1020 | } else { | ||
1021 | dev->interface = PRINTER_INTERFACE; | ||
1022 | } | ||
1023 | break; | ||
1024 | default: | ||
1025 | result = -EINVAL; | ||
1026 | /* FALL THROUGH */ | ||
1027 | } | ||
1028 | |||
1029 | if (!result) | ||
1030 | INFO(dev, "Using interface %x\n", number); | ||
1031 | |||
1032 | return result; | ||
1033 | } | ||
1034 | |||
1035 | static void printer_setup_complete(struct usb_ep *ep, struct usb_request *req) | ||
1036 | { | ||
1037 | if (req->status || req->actual != req->length) | ||
1038 | DBG((struct printer_dev *) ep->driver_data, | ||
1039 | "setup complete --> %d, %d/%d\n", | ||
1040 | req->status, req->actual, req->length); | ||
1041 | } | ||
1042 | |||
1043 | static void printer_soft_reset(struct printer_dev *dev) | ||
1044 | { | ||
1045 | struct usb_request *req; | ||
1046 | |||
1047 | INFO(dev, "Received Printer Reset Request\n"); | ||
1048 | |||
1049 | if (usb_ep_disable(dev->in_ep)) | ||
1050 | DBG(dev, "Failed to disable USB in_ep\n"); | ||
1051 | if (usb_ep_disable(dev->out_ep)) | ||
1052 | DBG(dev, "Failed to disable USB out_ep\n"); | ||
1053 | |||
1054 | if (dev->current_rx_req != NULL) { | ||
1055 | list_add(&dev->current_rx_req->list, &dev->rx_reqs); | ||
1056 | dev->current_rx_req = NULL; | ||
1057 | } | ||
1058 | dev->current_rx_bytes = 0; | ||
1059 | dev->current_rx_buf = NULL; | ||
1060 | dev->reset_printer = 1; | ||
1061 | |||
1062 | while (likely(!(list_empty(&dev->rx_buffers)))) { | ||
1063 | req = container_of(dev->rx_buffers.next, struct usb_request, | ||
1064 | list); | ||
1065 | list_del_init(&req->list); | ||
1066 | list_add(&req->list, &dev->rx_reqs); | ||
1067 | } | ||
1068 | |||
1069 | while (likely(!(list_empty(&dev->rx_reqs_active)))) { | ||
1070 | req = container_of(dev->rx_buffers.next, struct usb_request, | ||
1071 | list); | ||
1072 | list_del_init(&req->list); | ||
1073 | list_add(&req->list, &dev->rx_reqs); | ||
1074 | } | ||
1075 | |||
1076 | while (likely(!(list_empty(&dev->tx_reqs_active)))) { | ||
1077 | req = container_of(dev->tx_reqs_active.next, | ||
1078 | struct usb_request, list); | ||
1079 | list_del_init(&req->list); | ||
1080 | list_add(&req->list, &dev->tx_reqs); | ||
1081 | } | ||
1082 | |||
1083 | if (usb_ep_enable(dev->in_ep, dev->in)) | ||
1084 | DBG(dev, "Failed to enable USB in_ep\n"); | ||
1085 | if (usb_ep_enable(dev->out_ep, dev->out)) | ||
1086 | DBG(dev, "Failed to enable USB out_ep\n"); | ||
1087 | |||
1088 | wake_up_interruptible(&dev->tx_wait); | ||
1089 | wake_up_interruptible(&dev->tx_flush_wait); | ||
1090 | } | ||
1091 | |||
1092 | /*-------------------------------------------------------------------------*/ | ||
1093 | |||
1094 | /* | ||
1095 | * The setup() callback implements all the ep0 functionality that's not | ||
1096 | * handled lower down. | ||
1097 | */ | ||
1098 | static int | ||
1099 | printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | ||
1100 | { | ||
1101 | struct printer_dev *dev = get_gadget_data(gadget); | ||
1102 | struct usb_request *req = dev->req; | ||
1103 | int value = -EOPNOTSUPP; | ||
1104 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | ||
1105 | u16 wValue = le16_to_cpu(ctrl->wValue); | ||
1106 | u16 wLength = le16_to_cpu(ctrl->wLength); | ||
1107 | |||
1108 | DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n", | ||
1109 | ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); | ||
1110 | |||
1111 | req->complete = printer_setup_complete; | ||
1112 | |||
1113 | switch (ctrl->bRequestType&USB_TYPE_MASK) { | ||
1114 | |||
1115 | case USB_TYPE_STANDARD: | ||
1116 | switch (ctrl->bRequest) { | ||
1117 | |||
1118 | case USB_REQ_GET_DESCRIPTOR: | ||
1119 | if (ctrl->bRequestType != USB_DIR_IN) | ||
1120 | break; | ||
1121 | switch (wValue >> 8) { | ||
1122 | |||
1123 | case USB_DT_DEVICE: | ||
1124 | value = min(wLength, (u16) sizeof device_desc); | ||
1125 | memcpy(req->buf, &device_desc, value); | ||
1126 | break; | ||
1127 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1128 | case USB_DT_DEVICE_QUALIFIER: | ||
1129 | if (!gadget->is_dualspeed) | ||
1130 | break; | ||
1131 | value = min(wLength, | ||
1132 | (u16) sizeof dev_qualifier); | ||
1133 | memcpy(req->buf, &dev_qualifier, value); | ||
1134 | break; | ||
1135 | |||
1136 | case USB_DT_OTHER_SPEED_CONFIG: | ||
1137 | if (!gadget->is_dualspeed) | ||
1138 | break; | ||
1139 | /* FALLTHROUGH */ | ||
1140 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1141 | case USB_DT_CONFIG: | ||
1142 | value = config_buf(gadget->speed, req->buf, | ||
1143 | wValue >> 8, | ||
1144 | wValue & 0xff, | ||
1145 | gadget->is_otg); | ||
1146 | if (value >= 0) | ||
1147 | value = min(wLength, (u16) value); | ||
1148 | break; | ||
1149 | |||
1150 | case USB_DT_STRING: | ||
1151 | value = usb_gadget_get_string(&stringtab, | ||
1152 | wValue & 0xff, req->buf); | ||
1153 | if (value >= 0) | ||
1154 | value = min(wLength, (u16) value); | ||
1155 | break; | ||
1156 | } | ||
1157 | break; | ||
1158 | |||
1159 | case USB_REQ_SET_CONFIGURATION: | ||
1160 | if (ctrl->bRequestType != 0) | ||
1161 | break; | ||
1162 | if (gadget->a_hnp_support) | ||
1163 | DBG(dev, "HNP available\n"); | ||
1164 | else if (gadget->a_alt_hnp_support) | ||
1165 | DBG(dev, "HNP needs a different root port\n"); | ||
1166 | value = printer_set_config(dev, wValue); | ||
1167 | break; | ||
1168 | case USB_REQ_GET_CONFIGURATION: | ||
1169 | if (ctrl->bRequestType != USB_DIR_IN) | ||
1170 | break; | ||
1171 | *(u8 *)req->buf = dev->config; | ||
1172 | value = min(wLength, (u16) 1); | ||
1173 | break; | ||
1174 | |||
1175 | case USB_REQ_SET_INTERFACE: | ||
1176 | if (ctrl->bRequestType != USB_RECIP_INTERFACE || | ||
1177 | !dev->config) | ||
1178 | break; | ||
1179 | |||
1180 | value = set_interface(dev, PRINTER_INTERFACE); | ||
1181 | break; | ||
1182 | case USB_REQ_GET_INTERFACE: | ||
1183 | if (ctrl->bRequestType != | ||
1184 | (USB_DIR_IN|USB_RECIP_INTERFACE) | ||
1185 | || !dev->config) | ||
1186 | break; | ||
1187 | |||
1188 | *(u8 *)req->buf = dev->interface; | ||
1189 | value = min(wLength, (u16) 1); | ||
1190 | break; | ||
1191 | |||
1192 | default: | ||
1193 | goto unknown; | ||
1194 | } | ||
1195 | break; | ||
1196 | |||
1197 | case USB_TYPE_CLASS: | ||
1198 | switch (ctrl->bRequest) { | ||
1199 | case 0: /* Get the IEEE-1284 PNP String */ | ||
1200 | /* Only one printer interface is supported. */ | ||
1201 | if ((wIndex>>8) != PRINTER_INTERFACE) | ||
1202 | break; | ||
1203 | |||
1204 | value = (pnp_string[0]<<8)|pnp_string[1]; | ||
1205 | memcpy(req->buf, pnp_string, value); | ||
1206 | DBG(dev, "1284 PNP String: %x %s\n", value, | ||
1207 | &pnp_string[2]); | ||
1208 | break; | ||
1209 | |||
1210 | case 1: /* Get Port Status */ | ||
1211 | /* Only one printer interface is supported. */ | ||
1212 | if (wIndex != PRINTER_INTERFACE) | ||
1213 | break; | ||
1214 | |||
1215 | *(u8 *)req->buf = dev->printer_status; | ||
1216 | value = min(wLength, (u16) 1); | ||
1217 | break; | ||
1218 | |||
1219 | case 2: /* Soft Reset */ | ||
1220 | /* Only one printer interface is supported. */ | ||
1221 | if (wIndex != PRINTER_INTERFACE) | ||
1222 | break; | ||
1223 | |||
1224 | printer_soft_reset(dev); | ||
1225 | |||
1226 | value = 0; | ||
1227 | break; | ||
1228 | |||
1229 | default: | ||
1230 | goto unknown; | ||
1231 | } | ||
1232 | break; | ||
1233 | |||
1234 | default: | ||
1235 | unknown: | ||
1236 | VDBG(dev, | ||
1237 | "unknown ctrl req%02x.%02x v%04x i%04x l%d\n", | ||
1238 | ctrl->bRequestType, ctrl->bRequest, | ||
1239 | wValue, wIndex, wLength); | ||
1240 | break; | ||
1241 | } | ||
1242 | |||
1243 | /* respond with data transfer before status phase? */ | ||
1244 | if (value >= 0) { | ||
1245 | req->length = value; | ||
1246 | req->zero = value < wLength | ||
1247 | && (value % gadget->ep0->maxpacket) == 0; | ||
1248 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | ||
1249 | if (value < 0) { | ||
1250 | DBG(dev, "ep_queue --> %d\n", value); | ||
1251 | req->status = 0; | ||
1252 | printer_setup_complete(gadget->ep0, req); | ||
1253 | } | ||
1254 | } | ||
1255 | |||
1256 | /* host either stalls (value < 0) or reports success */ | ||
1257 | return value; | ||
1258 | } | ||
1259 | |||
1260 | static void | ||
1261 | printer_disconnect(struct usb_gadget *gadget) | ||
1262 | { | ||
1263 | struct printer_dev *dev = get_gadget_data(gadget); | ||
1264 | unsigned long flags; | ||
1265 | |||
1266 | DBG(dev, "%s\n", __FUNCTION__); | ||
1267 | |||
1268 | spin_lock_irqsave(&dev->lock, flags); | ||
1269 | |||
1270 | printer_reset_interface(dev); | ||
1271 | |||
1272 | spin_unlock_irqrestore(&dev->lock, flags); | ||
1273 | } | ||
1274 | |||
1275 | static void | ||
1276 | printer_unbind(struct usb_gadget *gadget) | ||
1277 | { | ||
1278 | struct printer_dev *dev = get_gadget_data(gadget); | ||
1279 | struct usb_request *req; | ||
1280 | |||
1281 | |||
1282 | DBG(dev, "%s\n", __FUNCTION__); | ||
1283 | |||
1284 | /* Remove sysfs files */ | ||
1285 | device_destroy(usb_gadget_class, g_printer_devno); | ||
1286 | |||
1287 | /* Remove Character Device */ | ||
1288 | cdev_del(&dev->printer_cdev); | ||
1289 | |||
1290 | /* we must already have been disconnected ... no i/o may be active */ | ||
1291 | WARN_ON(!list_empty(&dev->tx_reqs_active)); | ||
1292 | WARN_ON(!list_empty(&dev->rx_reqs_active)); | ||
1293 | |||
1294 | /* Free all memory for this driver. */ | ||
1295 | while (!list_empty(&dev->tx_reqs)) { | ||
1296 | req = container_of(dev->tx_reqs.next, struct usb_request, | ||
1297 | list); | ||
1298 | list_del(&req->list); | ||
1299 | printer_req_free(dev->in_ep, req); | ||
1300 | } | ||
1301 | |||
1302 | if (dev->current_rx_req != NULL); | ||
1303 | printer_req_free(dev->out_ep, dev->current_rx_req); | ||
1304 | |||
1305 | while (!list_empty(&dev->rx_reqs)) { | ||
1306 | req = container_of(dev->rx_reqs.next, | ||
1307 | struct usb_request, list); | ||
1308 | list_del(&req->list); | ||
1309 | printer_req_free(dev->out_ep, req); | ||
1310 | } | ||
1311 | |||
1312 | while (!list_empty(&dev->rx_buffers)) { | ||
1313 | req = container_of(dev->rx_buffers.next, | ||
1314 | struct usb_request, list); | ||
1315 | list_del(&req->list); | ||
1316 | printer_req_free(dev->out_ep, req); | ||
1317 | } | ||
1318 | |||
1319 | if (dev->req) { | ||
1320 | printer_req_free(gadget->ep0, dev->req); | ||
1321 | dev->req = NULL; | ||
1322 | } | ||
1323 | |||
1324 | set_gadget_data(gadget, NULL); | ||
1325 | } | ||
1326 | |||
1327 | static int __init | ||
1328 | printer_bind(struct usb_gadget *gadget) | ||
1329 | { | ||
1330 | struct printer_dev *dev; | ||
1331 | struct usb_ep *in_ep, *out_ep; | ||
1332 | int status = -ENOMEM; | ||
1333 | int gcnum; | ||
1334 | size_t len; | ||
1335 | u32 i; | ||
1336 | struct usb_request *req; | ||
1337 | |||
1338 | dev = &usb_printer_gadget; | ||
1339 | |||
1340 | |||
1341 | /* Setup the sysfs files for the printer gadget. */ | ||
1342 | dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno, | ||
1343 | "g_printer"); | ||
1344 | if (IS_ERR(dev->pdev)) { | ||
1345 | ERROR(dev, "Failed to create device: g_printer\n"); | ||
1346 | goto fail; | ||
1347 | } | ||
1348 | |||
1349 | /* | ||
1350 | * Register a character device as an interface to a user mode | ||
1351 | * program that handles the printer specific functionality. | ||
1352 | */ | ||
1353 | cdev_init(&dev->printer_cdev, &printer_io_operations); | ||
1354 | dev->printer_cdev.owner = THIS_MODULE; | ||
1355 | status = cdev_add(&dev->printer_cdev, g_printer_devno, 1); | ||
1356 | if (status) { | ||
1357 | ERROR(dev, "Failed to open char device\n"); | ||
1358 | goto fail; | ||
1359 | } | ||
1360 | |||
1361 | if (gadget_is_sa1100(gadget)) { | ||
1362 | /* hardware can't write zero length packets. */ | ||
1363 | ERROR(dev, "SA1100 controller is unsupport by this driver\n"); | ||
1364 | goto fail; | ||
1365 | } | ||
1366 | |||
1367 | gcnum = usb_gadget_controller_number(gadget); | ||
1368 | if (gcnum >= 0) { | ||
1369 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); | ||
1370 | } else { | ||
1371 | dev_warn(&gadget->dev, "controller '%s' not recognized\n", | ||
1372 | gadget->name); | ||
1373 | /* unrecognized, but safe unless bulk is REALLY quirky */ | ||
1374 | device_desc.bcdDevice = | ||
1375 | __constant_cpu_to_le16(0xFFFF); | ||
1376 | } | ||
1377 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | ||
1378 | init_utsname()->sysname, init_utsname()->release, | ||
1379 | gadget->name); | ||
1380 | |||
1381 | device_desc.idVendor = | ||
1382 | __constant_cpu_to_le16(PRINTER_VENDOR_NUM); | ||
1383 | device_desc.idProduct = | ||
1384 | __constant_cpu_to_le16(PRINTER_PRODUCT_NUM); | ||
1385 | |||
1386 | /* support optional vendor/distro customization */ | ||
1387 | if (idVendor) { | ||
1388 | if (!idProduct) { | ||
1389 | dev_err(&gadget->dev, "idVendor needs idProduct!\n"); | ||
1390 | return -ENODEV; | ||
1391 | } | ||
1392 | device_desc.idVendor = cpu_to_le16(idVendor); | ||
1393 | device_desc.idProduct = cpu_to_le16(idProduct); | ||
1394 | if (bcdDevice) | ||
1395 | device_desc.bcdDevice = cpu_to_le16(bcdDevice); | ||
1396 | } | ||
1397 | |||
1398 | if (iManufacturer) | ||
1399 | strlcpy(manufacturer, iManufacturer, sizeof manufacturer); | ||
1400 | |||
1401 | if (iProduct) | ||
1402 | strlcpy(product_desc, iProduct, sizeof product_desc); | ||
1403 | |||
1404 | if (iSerialNum) | ||
1405 | strlcpy(serial_num, iSerialNum, sizeof serial_num); | ||
1406 | |||
1407 | if (iPNPstring) | ||
1408 | strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); | ||
1409 | |||
1410 | len = strlen(pnp_string); | ||
1411 | pnp_string[0] = (len >> 8) & 0xFF; | ||
1412 | pnp_string[1] = len & 0xFF; | ||
1413 | |||
1414 | /* all we really need is bulk IN/OUT */ | ||
1415 | usb_ep_autoconfig_reset(gadget); | ||
1416 | in_ep = usb_ep_autoconfig(gadget, &fs_ep_in_desc); | ||
1417 | if (!in_ep) { | ||
1418 | autoconf_fail: | ||
1419 | dev_err(&gadget->dev, "can't autoconfigure on %s\n", | ||
1420 | gadget->name); | ||
1421 | return -ENODEV; | ||
1422 | } | ||
1423 | in_ep->driver_data = in_ep; /* claim */ | ||
1424 | |||
1425 | out_ep = usb_ep_autoconfig(gadget, &fs_ep_out_desc); | ||
1426 | if (!out_ep) | ||
1427 | goto autoconf_fail; | ||
1428 | out_ep->driver_data = out_ep; /* claim */ | ||
1429 | |||
1430 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1431 | /* assumes ep0 uses the same value for both speeds ... */ | ||
1432 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; | ||
1433 | |||
1434 | /* and that all endpoints are dual-speed */ | ||
1435 | hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; | ||
1436 | hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; | ||
1437 | #endif /* DUALSPEED */ | ||
1438 | |||
1439 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
1440 | usb_gadget_set_selfpowered(gadget); | ||
1441 | |||
1442 | if (gadget->is_otg) { | ||
1443 | otg_desc.bmAttributes |= USB_OTG_HNP, | ||
1444 | config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
1445 | config_desc.bMaxPower = 4; | ||
1446 | } | ||
1447 | |||
1448 | spin_lock_init(&dev->lock); | ||
1449 | spin_lock_init(&dev->lock_printer_io); | ||
1450 | INIT_LIST_HEAD(&dev->tx_reqs); | ||
1451 | INIT_LIST_HEAD(&dev->tx_reqs_active); | ||
1452 | INIT_LIST_HEAD(&dev->rx_reqs); | ||
1453 | INIT_LIST_HEAD(&dev->rx_reqs_active); | ||
1454 | INIT_LIST_HEAD(&dev->rx_buffers); | ||
1455 | init_waitqueue_head(&dev->rx_wait); | ||
1456 | init_waitqueue_head(&dev->tx_wait); | ||
1457 | init_waitqueue_head(&dev->tx_flush_wait); | ||
1458 | |||
1459 | dev->config = 0; | ||
1460 | dev->interface = -1; | ||
1461 | dev->printer_cdev_open = 0; | ||
1462 | dev->printer_status = PRINTER_NOT_ERROR; | ||
1463 | dev->current_rx_req = NULL; | ||
1464 | dev->current_rx_bytes = 0; | ||
1465 | dev->current_rx_buf = NULL; | ||
1466 | |||
1467 | dev->in_ep = in_ep; | ||
1468 | dev->out_ep = out_ep; | ||
1469 | |||
1470 | /* preallocate control message data and buffer */ | ||
1471 | dev->req = printer_req_alloc(gadget->ep0, USB_DESC_BUFSIZE, | ||
1472 | GFP_KERNEL); | ||
1473 | if (!dev->req) { | ||
1474 | status = -ENOMEM; | ||
1475 | goto fail; | ||
1476 | } | ||
1477 | |||
1478 | for (i = 0; i < QLEN; i++) { | ||
1479 | req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); | ||
1480 | if (!req) { | ||
1481 | while (!list_empty(&dev->tx_reqs)) { | ||
1482 | req = container_of(dev->tx_reqs.next, | ||
1483 | struct usb_request, list); | ||
1484 | list_del(&req->list); | ||
1485 | printer_req_free(dev->in_ep, req); | ||
1486 | } | ||
1487 | return -ENOMEM; | ||
1488 | } | ||
1489 | list_add(&req->list, &dev->tx_reqs); | ||
1490 | } | ||
1491 | |||
1492 | for (i = 0; i < QLEN; i++) { | ||
1493 | req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); | ||
1494 | if (!req) { | ||
1495 | while (!list_empty(&dev->rx_reqs)) { | ||
1496 | req = container_of(dev->rx_reqs.next, | ||
1497 | struct usb_request, list); | ||
1498 | list_del(&req->list); | ||
1499 | printer_req_free(dev->out_ep, req); | ||
1500 | } | ||
1501 | return -ENOMEM; | ||
1502 | } | ||
1503 | list_add(&req->list, &dev->rx_reqs); | ||
1504 | } | ||
1505 | |||
1506 | dev->req->complete = printer_setup_complete; | ||
1507 | |||
1508 | /* finish hookup to lower layer ... */ | ||
1509 | dev->gadget = gadget; | ||
1510 | set_gadget_data(gadget, dev); | ||
1511 | gadget->ep0->driver_data = dev; | ||
1512 | |||
1513 | INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); | ||
1514 | INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name, | ||
1515 | in_ep->name); | ||
1516 | |||
1517 | return 0; | ||
1518 | |||
1519 | fail: | ||
1520 | printer_unbind(gadget); | ||
1521 | return status; | ||
1522 | } | ||
1523 | |||
1524 | /*-------------------------------------------------------------------------*/ | ||
1525 | |||
1526 | static struct usb_gadget_driver printer_driver = { | ||
1527 | .speed = DEVSPEED, | ||
1528 | |||
1529 | .function = (char *) driver_desc, | ||
1530 | .bind = printer_bind, | ||
1531 | .unbind = printer_unbind, | ||
1532 | |||
1533 | .setup = printer_setup, | ||
1534 | .disconnect = printer_disconnect, | ||
1535 | |||
1536 | .driver = { | ||
1537 | .name = (char *) shortname, | ||
1538 | .owner = THIS_MODULE, | ||
1539 | }, | ||
1540 | }; | ||
1541 | |||
1542 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1543 | MODULE_AUTHOR("Craig Nadler"); | ||
1544 | MODULE_LICENSE("GPL"); | ||
1545 | |||
1546 | static int __init | ||
1547 | init(void) | ||
1548 | { | ||
1549 | int status; | ||
1550 | |||
1551 | usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); | ||
1552 | if (IS_ERR(usb_gadget_class)) { | ||
1553 | status = PTR_ERR(usb_gadget_class); | ||
1554 | ERROR(dev, "unable to create usb_gadget class %d\n", status); | ||
1555 | return status; | ||
1556 | } | ||
1557 | |||
1558 | status = alloc_chrdev_region(&g_printer_devno, 0, 1, | ||
1559 | "USB printer gadget"); | ||
1560 | if (status) { | ||
1561 | ERROR(dev, "alloc_chrdev_region %d\n", status); | ||
1562 | class_destroy(usb_gadget_class); | ||
1563 | return status; | ||
1564 | } | ||
1565 | |||
1566 | status = usb_gadget_register_driver(&printer_driver); | ||
1567 | if (status) { | ||
1568 | class_destroy(usb_gadget_class); | ||
1569 | unregister_chrdev_region(g_printer_devno, 1); | ||
1570 | DBG(dev, "usb_gadget_register_driver %x\n", status); | ||
1571 | } | ||
1572 | |||
1573 | return status; | ||
1574 | } | ||
1575 | module_init(init); | ||
1576 | |||
1577 | static void __exit | ||
1578 | cleanup(void) | ||
1579 | { | ||
1580 | int status; | ||
1581 | |||
1582 | spin_lock(&usb_printer_gadget.lock_printer_io); | ||
1583 | class_destroy(usb_gadget_class); | ||
1584 | unregister_chrdev_region(g_printer_devno, 2); | ||
1585 | |||
1586 | status = usb_gadget_unregister_driver(&printer_driver); | ||
1587 | if (status) | ||
1588 | ERROR(dev, "usb_gadget_unregister_driver %x\n", status); | ||
1589 | |||
1590 | spin_unlock(&usb_printer_gadget.lock_printer_io); | ||
1591 | } | ||
1592 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 3173b39f0bfd..4402d6f042d9 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | // #define VERBOSE DBG_VERBOSE | 27 | /* #define VERBOSE_DEBUG */ |
28 | 28 | ||
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
@@ -38,13 +38,14 @@ | |||
38 | #include <linux/timer.h> | 38 | #include <linux/timer.h> |
39 | #include <linux/list.h> | 39 | #include <linux/list.h> |
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <linux/proc_fs.h> | ||
42 | #include <linux/mm.h> | 41 | #include <linux/mm.h> |
43 | #include <linux/platform_device.h> | 42 | #include <linux/platform_device.h> |
44 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
45 | #include <linux/irq.h> | 44 | #include <linux/irq.h> |
46 | #include <linux/clk.h> | 45 | #include <linux/clk.h> |
47 | #include <linux/err.h> | 46 | #include <linux/err.h> |
47 | #include <linux/seq_file.h> | ||
48 | #include <linux/debugfs.h> | ||
48 | 49 | ||
49 | #include <asm/byteorder.h> | 50 | #include <asm/byteorder.h> |
50 | #include <asm/dma.h> | 51 | #include <asm/dma.h> |
@@ -127,8 +128,10 @@ static int is_vbus_present(void) | |||
127 | { | 128 | { |
128 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 129 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
129 | 130 | ||
130 | if (mach->gpio_vbus) | 131 | if (mach->gpio_vbus) { |
131 | return gpio_get_value(mach->gpio_vbus); | 132 | int value = gpio_get_value(mach->gpio_vbus); |
133 | return mach->gpio_vbus_inverted ? !value : value; | ||
134 | } | ||
132 | if (mach->udc_is_connected) | 135 | if (mach->udc_is_connected) |
133 | return mach->udc_is_connected(); | 136 | return mach->udc_is_connected(); |
134 | return 1; | 137 | return 1; |
@@ -677,7 +680,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
677 | 680 | ||
678 | /* kickstart this i/o queue? */ | 681 | /* kickstart this i/o queue? */ |
679 | if (list_empty(&ep->queue) && !ep->stopped) { | 682 | if (list_empty(&ep->queue) && !ep->stopped) { |
680 | if (ep->desc == 0 /* ep0 */) { | 683 | if (ep->desc == NULL/* ep0 */) { |
681 | unsigned length = _req->length; | 684 | unsigned length = _req->length; |
682 | 685 | ||
683 | switch (dev->ep0state) { | 686 | switch (dev->ep0state) { |
@@ -731,7 +734,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
731 | } | 734 | } |
732 | 735 | ||
733 | /* pio or dma irq handler advances the queue. */ | 736 | /* pio or dma irq handler advances the queue. */ |
734 | if (likely (req != 0)) | 737 | if (likely(req != NULL)) |
735 | list_add_tail(&req->queue, &ep->queue); | 738 | list_add_tail(&req->queue, &ep->queue); |
736 | local_irq_restore(flags); | 739 | local_irq_restore(flags); |
737 | 740 | ||
@@ -991,45 +994,32 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { | |||
991 | 994 | ||
992 | /*-------------------------------------------------------------------------*/ | 995 | /*-------------------------------------------------------------------------*/ |
993 | 996 | ||
994 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 997 | #ifdef CONFIG_USB_GADGET_DEBUG_FS |
995 | |||
996 | static const char proc_node_name [] = "driver/udc"; | ||
997 | 998 | ||
998 | static int | 999 | static int |
999 | udc_proc_read(char *page, char **start, off_t off, int count, | 1000 | udc_seq_show(struct seq_file *m, void *d) |
1000 | int *eof, void *_dev) | ||
1001 | { | 1001 | { |
1002 | char *buf = page; | 1002 | struct pxa2xx_udc *dev = m->private; |
1003 | struct pxa2xx_udc *dev = _dev; | ||
1004 | char *next = buf; | ||
1005 | unsigned size = count; | ||
1006 | unsigned long flags; | 1003 | unsigned long flags; |
1007 | int i, t; | 1004 | int i; |
1008 | u32 tmp; | 1005 | u32 tmp; |
1009 | 1006 | ||
1010 | if (off != 0) | ||
1011 | return 0; | ||
1012 | |||
1013 | local_irq_save(flags); | 1007 | local_irq_save(flags); |
1014 | 1008 | ||
1015 | /* basic device status */ | 1009 | /* basic device status */ |
1016 | t = scnprintf(next, size, DRIVER_DESC "\n" | 1010 | seq_printf(m, DRIVER_DESC "\n" |
1017 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", | 1011 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", |
1018 | driver_name, DRIVER_VERSION SIZE_STR "(pio)", | 1012 | driver_name, DRIVER_VERSION SIZE_STR "(pio)", |
1019 | dev->driver ? dev->driver->driver.name : "(none)", | 1013 | dev->driver ? dev->driver->driver.name : "(none)", |
1020 | is_vbus_present() ? "full speed" : "disconnected"); | 1014 | is_vbus_present() ? "full speed" : "disconnected"); |
1021 | size -= t; | ||
1022 | next += t; | ||
1023 | 1015 | ||
1024 | /* registers for device and ep0 */ | 1016 | /* registers for device and ep0 */ |
1025 | t = scnprintf(next, size, | 1017 | seq_printf(m, |
1026 | "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", | 1018 | "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", |
1027 | UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); | 1019 | UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); |
1028 | size -= t; | ||
1029 | next += t; | ||
1030 | 1020 | ||
1031 | tmp = UDCCR; | 1021 | tmp = UDCCR; |
1032 | t = scnprintf(next, size, | 1022 | seq_printf(m, |
1033 | "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp, | 1023 | "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp, |
1034 | (tmp & UDCCR_REM) ? " rem" : "", | 1024 | (tmp & UDCCR_REM) ? " rem" : "", |
1035 | (tmp & UDCCR_RSTIR) ? " rstir" : "", | 1025 | (tmp & UDCCR_RSTIR) ? " rstir" : "", |
@@ -1039,11 +1029,9 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1039 | (tmp & UDCCR_RSM) ? " rsm" : "", | 1029 | (tmp & UDCCR_RSM) ? " rsm" : "", |
1040 | (tmp & UDCCR_UDA) ? " uda" : "", | 1030 | (tmp & UDCCR_UDA) ? " uda" : "", |
1041 | (tmp & UDCCR_UDE) ? " ude" : ""); | 1031 | (tmp & UDCCR_UDE) ? " ude" : ""); |
1042 | size -= t; | ||
1043 | next += t; | ||
1044 | 1032 | ||
1045 | tmp = UDCCS0; | 1033 | tmp = UDCCS0; |
1046 | t = scnprintf(next, size, | 1034 | seq_printf(m, |
1047 | "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp, | 1035 | "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp, |
1048 | (tmp & UDCCS0_SA) ? " sa" : "", | 1036 | (tmp & UDCCS0_SA) ? " sa" : "", |
1049 | (tmp & UDCCS0_RNE) ? " rne" : "", | 1037 | (tmp & UDCCS0_RNE) ? " rne" : "", |
@@ -1053,28 +1041,22 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1053 | (tmp & UDCCS0_FTF) ? " ftf" : "", | 1041 | (tmp & UDCCS0_FTF) ? " ftf" : "", |
1054 | (tmp & UDCCS0_IPR) ? " ipr" : "", | 1042 | (tmp & UDCCS0_IPR) ? " ipr" : "", |
1055 | (tmp & UDCCS0_OPR) ? " opr" : ""); | 1043 | (tmp & UDCCS0_OPR) ? " opr" : ""); |
1056 | size -= t; | ||
1057 | next += t; | ||
1058 | 1044 | ||
1059 | if (dev->has_cfr) { | 1045 | if (dev->has_cfr) { |
1060 | tmp = UDCCFR; | 1046 | tmp = UDCCFR; |
1061 | t = scnprintf(next, size, | 1047 | seq_printf(m, |
1062 | "udccfr %02X =%s%s\n", tmp, | 1048 | "udccfr %02X =%s%s\n", tmp, |
1063 | (tmp & UDCCFR_AREN) ? " aren" : "", | 1049 | (tmp & UDCCFR_AREN) ? " aren" : "", |
1064 | (tmp & UDCCFR_ACM) ? " acm" : ""); | 1050 | (tmp & UDCCFR_ACM) ? " acm" : ""); |
1065 | size -= t; | ||
1066 | next += t; | ||
1067 | } | 1051 | } |
1068 | 1052 | ||
1069 | if (!is_vbus_present() || !dev->driver) | 1053 | if (!is_vbus_present() || !dev->driver) |
1070 | goto done; | 1054 | goto done; |
1071 | 1055 | ||
1072 | t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", | 1056 | seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", |
1073 | dev->stats.write.bytes, dev->stats.write.ops, | 1057 | dev->stats.write.bytes, dev->stats.write.ops, |
1074 | dev->stats.read.bytes, dev->stats.read.ops, | 1058 | dev->stats.read.bytes, dev->stats.read.ops, |
1075 | dev->stats.irqs); | 1059 | dev->stats.irqs); |
1076 | size -= t; | ||
1077 | next += t; | ||
1078 | 1060 | ||
1079 | /* dump endpoint queues */ | 1061 | /* dump endpoint queues */ |
1080 | for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { | 1062 | for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { |
@@ -1082,61 +1064,68 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1082 | struct pxa2xx_request *req; | 1064 | struct pxa2xx_request *req; |
1083 | 1065 | ||
1084 | if (i != 0) { | 1066 | if (i != 0) { |
1085 | const struct usb_endpoint_descriptor *d; | 1067 | const struct usb_endpoint_descriptor *desc; |
1086 | 1068 | ||
1087 | d = ep->desc; | 1069 | desc = ep->desc; |
1088 | if (!d) | 1070 | if (!desc) |
1089 | continue; | 1071 | continue; |
1090 | tmp = *dev->ep [i].reg_udccs; | 1072 | tmp = *dev->ep [i].reg_udccs; |
1091 | t = scnprintf(next, size, | 1073 | seq_printf(m, |
1092 | "%s max %d %s udccs %02x irqs %lu\n", | 1074 | "%s max %d %s udccs %02x irqs %lu\n", |
1093 | ep->ep.name, le16_to_cpu (d->wMaxPacketSize), | 1075 | ep->ep.name, le16_to_cpu(desc->wMaxPacketSize), |
1094 | "pio", tmp, ep->pio_irqs); | 1076 | "pio", tmp, ep->pio_irqs); |
1095 | /* TODO translate all five groups of udccs bits! */ | 1077 | /* TODO translate all five groups of udccs bits! */ |
1096 | 1078 | ||
1097 | } else /* ep0 should only have one transfer queued */ | 1079 | } else /* ep0 should only have one transfer queued */ |
1098 | t = scnprintf(next, size, "ep0 max 16 pio irqs %lu\n", | 1080 | seq_printf(m, "ep0 max 16 pio irqs %lu\n", |
1099 | ep->pio_irqs); | 1081 | ep->pio_irqs); |
1100 | if (t <= 0 || t > size) | ||
1101 | goto done; | ||
1102 | size -= t; | ||
1103 | next += t; | ||
1104 | 1082 | ||
1105 | if (list_empty(&ep->queue)) { | 1083 | if (list_empty(&ep->queue)) { |
1106 | t = scnprintf(next, size, "\t(nothing queued)\n"); | 1084 | seq_printf(m, "\t(nothing queued)\n"); |
1107 | if (t <= 0 || t > size) | ||
1108 | goto done; | ||
1109 | size -= t; | ||
1110 | next += t; | ||
1111 | continue; | 1085 | continue; |
1112 | } | 1086 | } |
1113 | list_for_each_entry(req, &ep->queue, queue) { | 1087 | list_for_each_entry(req, &ep->queue, queue) { |
1114 | t = scnprintf(next, size, | 1088 | seq_printf(m, |
1115 | "\treq %p len %d/%d buf %p\n", | 1089 | "\treq %p len %d/%d buf %p\n", |
1116 | &req->req, req->req.actual, | 1090 | &req->req, req->req.actual, |
1117 | req->req.length, req->req.buf); | 1091 | req->req.length, req->req.buf); |
1118 | if (t <= 0 || t > size) | ||
1119 | goto done; | ||
1120 | size -= t; | ||
1121 | next += t; | ||
1122 | } | 1092 | } |
1123 | } | 1093 | } |
1124 | 1094 | ||
1125 | done: | 1095 | done: |
1126 | local_irq_restore(flags); | 1096 | local_irq_restore(flags); |
1127 | *eof = 1; | 1097 | return 0; |
1128 | return count - size; | ||
1129 | } | 1098 | } |
1130 | 1099 | ||
1131 | #define create_proc_files() \ | 1100 | static int |
1132 | create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) | 1101 | udc_debugfs_open(struct inode *inode, struct file *file) |
1133 | #define remove_proc_files() \ | 1102 | { |
1134 | remove_proc_entry(proc_node_name, NULL) | 1103 | return single_open(file, udc_seq_show, inode->i_private); |
1104 | } | ||
1105 | |||
1106 | static const struct file_operations debug_fops = { | ||
1107 | .open = udc_debugfs_open, | ||
1108 | .read = seq_read, | ||
1109 | .llseek = seq_lseek, | ||
1110 | .release = single_release, | ||
1111 | .owner = THIS_MODULE, | ||
1112 | }; | ||
1113 | |||
1114 | #define create_debug_files(dev) \ | ||
1115 | do { \ | ||
1116 | dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ | ||
1117 | S_IRUGO, NULL, dev, &debug_fops); \ | ||
1118 | } while (0) | ||
1119 | #define remove_debug_files(dev) \ | ||
1120 | do { \ | ||
1121 | if (dev->debugfs_udc) \ | ||
1122 | debugfs_remove(dev->debugfs_udc); \ | ||
1123 | } while (0) | ||
1135 | 1124 | ||
1136 | #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ | 1125 | #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ |
1137 | 1126 | ||
1138 | #define create_proc_files() do {} while (0) | 1127 | #define create_debug_files(dev) do {} while (0) |
1139 | #define remove_proc_files() do {} while (0) | 1128 | #define remove_debug_files(dev) do {} while (0) |
1140 | 1129 | ||
1141 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ | 1130 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ |
1142 | 1131 | ||
@@ -1345,6 +1334,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1345 | local_irq_enable(); | 1334 | local_irq_enable(); |
1346 | 1335 | ||
1347 | driver->unbind(&dev->gadget); | 1336 | driver->unbind(&dev->gadget); |
1337 | dev->gadget.dev.driver = NULL; | ||
1348 | dev->driver = NULL; | 1338 | dev->driver = NULL; |
1349 | 1339 | ||
1350 | device_del (&dev->gadget.dev); | 1340 | device_del (&dev->gadget.dev); |
@@ -1397,6 +1387,9 @@ static irqreturn_t udc_vbus_irq(int irq, void *_dev) | |||
1397 | struct pxa2xx_udc *dev = _dev; | 1387 | struct pxa2xx_udc *dev = _dev; |
1398 | int vbus = gpio_get_value(dev->mach->gpio_vbus); | 1388 | int vbus = gpio_get_value(dev->mach->gpio_vbus); |
1399 | 1389 | ||
1390 | if (dev->mach->gpio_vbus_inverted) | ||
1391 | vbus = !vbus; | ||
1392 | |||
1400 | pxa2xx_udc_vbus_session(&dev->gadget, vbus); | 1393 | pxa2xx_udc_vbus_session(&dev->gadget, vbus); |
1401 | return IRQ_HANDLED; | 1394 | return IRQ_HANDLED; |
1402 | } | 1395 | } |
@@ -2099,7 +2092,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2099 | /* insist on Intel/ARM/XScale */ | 2092 | /* insist on Intel/ARM/XScale */ |
2100 | asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev)); | 2093 | asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev)); |
2101 | if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) { | 2094 | if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) { |
2102 | printk(KERN_ERR "%s: not XScale!\n", driver_name); | 2095 | pr_err("%s: not XScale!\n", driver_name); |
2103 | return -ENODEV; | 2096 | return -ENODEV; |
2104 | } | 2097 | } |
2105 | 2098 | ||
@@ -2128,7 +2121,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2128 | break; | 2121 | break; |
2129 | #endif | 2122 | #endif |
2130 | default: | 2123 | default: |
2131 | printk(KERN_ERR "%s: unrecognized processor: %08x\n", | 2124 | pr_err("%s: unrecognized processor: %08x\n", |
2132 | driver_name, chiprev); | 2125 | driver_name, chiprev); |
2133 | /* iop3xx, ixp4xx, ... */ | 2126 | /* iop3xx, ixp4xx, ... */ |
2134 | return -ENODEV; | 2127 | return -ENODEV; |
@@ -2199,7 +2192,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2199 | retval = request_irq(irq, pxa2xx_udc_irq, | 2192 | retval = request_irq(irq, pxa2xx_udc_irq, |
2200 | IRQF_DISABLED, driver_name, dev); | 2193 | IRQF_DISABLED, driver_name, dev); |
2201 | if (retval != 0) { | 2194 | if (retval != 0) { |
2202 | printk(KERN_ERR "%s: can't get irq %d, err %d\n", | 2195 | pr_err("%s: can't get irq %d, err %d\n", |
2203 | driver_name, irq, retval); | 2196 | driver_name, irq, retval); |
2204 | goto err_irq1; | 2197 | goto err_irq1; |
2205 | } | 2198 | } |
@@ -2212,7 +2205,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2212 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 2205 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, |
2213 | driver_name, dev); | 2206 | driver_name, dev); |
2214 | if (retval != 0) { | 2207 | if (retval != 0) { |
2215 | printk(KERN_ERR "%s: can't get irq %i, err %d\n", | 2208 | pr_err("%s: can't get irq %i, err %d\n", |
2216 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); | 2209 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); |
2217 | lubbock_fail0: | 2210 | lubbock_fail0: |
2218 | goto err_irq_lub; | 2211 | goto err_irq_lub; |
@@ -2222,7 +2215,7 @@ lubbock_fail0: | |||
2222 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 2215 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, |
2223 | driver_name, dev); | 2216 | driver_name, dev); |
2224 | if (retval != 0) { | 2217 | if (retval != 0) { |
2225 | printk(KERN_ERR "%s: can't get irq %i, err %d\n", | 2218 | pr_err("%s: can't get irq %i, err %d\n", |
2226 | driver_name, LUBBOCK_USB_IRQ, retval); | 2219 | driver_name, LUBBOCK_USB_IRQ, retval); |
2227 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | 2220 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); |
2228 | goto lubbock_fail0; | 2221 | goto lubbock_fail0; |
@@ -2235,12 +2228,12 @@ lubbock_fail0: | |||
2235 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 2228 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
2236 | driver_name, dev); | 2229 | driver_name, dev); |
2237 | if (retval != 0) { | 2230 | if (retval != 0) { |
2238 | printk(KERN_ERR "%s: can't get irq %i, err %d\n", | 2231 | pr_err("%s: can't get irq %i, err %d\n", |
2239 | driver_name, vbus_irq, retval); | 2232 | driver_name, vbus_irq, retval); |
2240 | goto err_vbus_irq; | 2233 | goto err_vbus_irq; |
2241 | } | 2234 | } |
2242 | } | 2235 | } |
2243 | create_proc_files(); | 2236 | create_debug_files(dev); |
2244 | 2237 | ||
2245 | return 0; | 2238 | return 0; |
2246 | 2239 | ||
@@ -2277,7 +2270,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
2277 | return -EBUSY; | 2270 | return -EBUSY; |
2278 | 2271 | ||
2279 | udc_disable(dev); | 2272 | udc_disable(dev); |
2280 | remove_proc_files(); | 2273 | remove_debug_files(dev); |
2281 | 2274 | ||
2282 | if (dev->got_irq) { | 2275 | if (dev->got_irq) { |
2283 | free_irq(platform_get_irq(pdev, 0), dev); | 2276 | free_irq(platform_get_irq(pdev, 0), dev); |
@@ -2361,7 +2354,7 @@ static struct platform_driver udc_driver = { | |||
2361 | 2354 | ||
2362 | static int __init udc_init(void) | 2355 | static int __init udc_init(void) |
2363 | { | 2356 | { |
2364 | printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); | 2357 | pr_info("%s: version %s\n", driver_name, DRIVER_VERSION); |
2365 | return platform_driver_probe(&udc_driver, pxa2xx_udc_probe); | 2358 | return platform_driver_probe(&udc_driver, pxa2xx_udc_probe); |
2366 | } | 2359 | } |
2367 | module_init(udc_init); | 2360 | module_init(udc_init); |
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index 1db46d705777..b67e3ff5e4eb 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h | |||
@@ -129,6 +129,10 @@ struct pxa2xx_udc { | |||
129 | struct pxa2xx_udc_mach_info *mach; | 129 | struct pxa2xx_udc_mach_info *mach; |
130 | u64 dma_mask; | 130 | u64 dma_mask; |
131 | struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS]; | 131 | struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS]; |
132 | |||
133 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
134 | struct dentry *debugfs_udc; | ||
135 | #endif | ||
132 | }; | 136 | }; |
133 | 137 | ||
134 | /*-------------------------------------------------------------------------*/ | 138 | /*-------------------------------------------------------------------------*/ |
@@ -151,17 +155,19 @@ static struct pxa2xx_udc *the_controller; | |||
151 | #define DBG_NOISY 3 /* ... even more: request level */ | 155 | #define DBG_NOISY 3 /* ... even more: request level */ |
152 | #define DBG_VERY_NOISY 4 /* ... even more: packet level */ | 156 | #define DBG_VERY_NOISY 4 /* ... even more: packet level */ |
153 | 157 | ||
158 | #define DMSG(stuff...) pr_debug("udc: " stuff) | ||
159 | |||
154 | #ifdef DEBUG | 160 | #ifdef DEBUG |
155 | 161 | ||
162 | static int is_vbus_present(void); | ||
163 | |||
156 | static const char *state_name[] = { | 164 | static const char *state_name[] = { |
157 | "EP0_IDLE", | 165 | "EP0_IDLE", |
158 | "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", | 166 | "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", |
159 | "EP0_END_XFER", "EP0_STALL" | 167 | "EP0_END_XFER", "EP0_STALL" |
160 | }; | 168 | }; |
161 | 169 | ||
162 | #define DMSG(stuff...) printk(KERN_DEBUG "udc: " stuff) | 170 | #ifdef VERBOSE_DEBUG |
163 | |||
164 | #ifdef VERBOSE | ||
165 | # define UDC_DEBUG DBG_VERBOSE | 171 | # define UDC_DEBUG DBG_VERBOSE |
166 | #else | 172 | #else |
167 | # define UDC_DEBUG DBG_NORMAL | 173 | # define UDC_DEBUG DBG_NORMAL |
@@ -207,7 +213,7 @@ dump_state(struct pxa2xx_udc *dev) | |||
207 | unsigned i; | 213 | unsigned i; |
208 | 214 | ||
209 | DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", | 215 | DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", |
210 | is_usb_connected() ? "host " : "disconnected", | 216 | is_vbus_present() ? "host " : "disconnected", |
211 | state_name[dev->ep0state], | 217 | state_name[dev->ep0state], |
212 | UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); | 218 | UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); |
213 | dump_udccr("udccr"); | 219 | dump_udccr("udccr"); |
@@ -224,7 +230,7 @@ dump_state(struct pxa2xx_udc *dev) | |||
224 | } else | 230 | } else |
225 | DMSG("ep0 driver '%s'\n", dev->driver->driver.name); | 231 | DMSG("ep0 driver '%s'\n", dev->driver->driver.name); |
226 | 232 | ||
227 | if (!is_usb_connected()) | 233 | if (!is_vbus_present()) |
228 | return; | 234 | return; |
229 | 235 | ||
230 | dump_udccs0 ("udccs0"); | 236 | dump_udccs0 ("udccs0"); |
@@ -233,7 +239,7 @@ dump_state(struct pxa2xx_udc *dev) | |||
233 | dev->stats.read.bytes, dev->stats.read.ops); | 239 | dev->stats.read.bytes, dev->stats.read.ops); |
234 | 240 | ||
235 | for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { | 241 | for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { |
236 | if (dev->ep [i].desc == 0) | 242 | if (dev->ep [i].desc == NULL) |
237 | continue; | 243 | continue; |
238 | DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); | 244 | DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); |
239 | } | 245 | } |
@@ -241,8 +247,6 @@ dump_state(struct pxa2xx_udc *dev) | |||
241 | 247 | ||
242 | #else | 248 | #else |
243 | 249 | ||
244 | #define DMSG(stuff...) do{}while(0) | ||
245 | |||
246 | #define dump_udccr(x) do{}while(0) | 250 | #define dump_udccr(x) do{}while(0) |
247 | #define dump_udccs0(x) do{}while(0) | 251 | #define dump_udccs0(x) do{}while(0) |
248 | #define dump_state(x) do{}while(0) | 252 | #define dump_state(x) do{}while(0) |
@@ -253,8 +257,9 @@ dump_state(struct pxa2xx_udc *dev) | |||
253 | 257 | ||
254 | #define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0) | 258 | #define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0) |
255 | 259 | ||
256 | #define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) | 260 | #define ERR(stuff...) pr_err("udc: " stuff) |
257 | #define INFO(stuff...) printk(KERN_INFO "udc: " stuff) | 261 | #define WARN(stuff...) pr_warning("udc: " stuff) |
262 | #define INFO(stuff...) pr_info("udc: " stuff) | ||
258 | 263 | ||
259 | 264 | ||
260 | #endif /* __LINUX_USB_GADGET_PXA2XX_H */ | 265 | #endif /* __LINUX_USB_GADGET_PXA2XX_H */ |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index db1b2bfcee4e..3d036647431f 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -53,21 +53,18 @@ | |||
53 | */ | 53 | */ |
54 | 54 | ||
55 | #if 0 | 55 | #if 0 |
56 | #define DBG(str,args...) do { \ | ||
57 | if (rndis_debug) \ | ||
58 | printk(KERN_DEBUG str , ## args ); \ | ||
59 | } while (0) | ||
60 | static int rndis_debug = 0; | 56 | static int rndis_debug = 0; |
61 | |||
62 | module_param (rndis_debug, int, 0); | 57 | module_param (rndis_debug, int, 0); |
63 | MODULE_PARM_DESC (rndis_debug, "enable debugging"); | 58 | MODULE_PARM_DESC (rndis_debug, "enable debugging"); |
64 | |||
65 | #else | 59 | #else |
66 | |||
67 | #define rndis_debug 0 | 60 | #define rndis_debug 0 |
68 | #define DBG(str,args...) do{}while(0) | ||
69 | #endif | 61 | #endif |
70 | 62 | ||
63 | #define DBG(str,args...) do { \ | ||
64 | if (rndis_debug) \ | ||
65 | pr_debug(str , ## args); \ | ||
66 | } while (0) | ||
67 | |||
71 | #define RNDIS_MAX_CONFIGS 1 | 68 | #define RNDIS_MAX_CONFIGS 1 |
72 | 69 | ||
73 | 70 | ||
@@ -679,7 +676,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
679 | #endif | 676 | #endif |
680 | 677 | ||
681 | default: | 678 | default: |
682 | printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", | 679 | pr_warning("%s: query unknown OID 0x%08X\n", |
683 | __FUNCTION__, OID); | 680 | __FUNCTION__, OID); |
684 | } | 681 | } |
685 | if (retval < 0) | 682 | if (retval < 0) |
@@ -804,7 +801,7 @@ update_linkstate: | |||
804 | #endif /* RNDIS_PM */ | 801 | #endif /* RNDIS_PM */ |
805 | 802 | ||
806 | default: | 803 | default: |
807 | printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", | 804 | pr_warning("%s: set unknown OID 0x%08X, size %d\n", |
808 | __FUNCTION__, OID, buf_len); | 805 | __FUNCTION__, OID, buf_len); |
809 | } | 806 | } |
810 | 807 | ||
@@ -1126,8 +1123,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) | |||
1126 | * In one case those messages seemed to relate to the host | 1123 | * In one case those messages seemed to relate to the host |
1127 | * suspending itself. | 1124 | * suspending itself. |
1128 | */ | 1125 | */ |
1129 | printk (KERN_WARNING | 1126 | pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", |
1130 | "%s: unknown RNDIS message 0x%08X len %d\n", | ||
1131 | __FUNCTION__ , MsgType, MsgLength); | 1127 | __FUNCTION__ , MsgType, MsgLength); |
1132 | { | 1128 | { |
1133 | unsigned i; | 1129 | unsigned i; |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 4ce050c3d13f..aadc4204d6f9 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -893,7 +893,7 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep) | |||
893 | /* | 893 | /* |
894 | * s3c2410_udc_irq - interrupt handler | 894 | * s3c2410_udc_irq - interrupt handler |
895 | */ | 895 | */ |
896 | static irqreturn_t s3c2410_udc_irq(int irq, void *_dev) | 896 | static irqreturn_t s3c2410_udc_irq(int dummy, void *_dev) |
897 | { | 897 | { |
898 | struct s3c2410_udc *dev = _dev; | 898 | struct s3c2410_udc *dev = _dev; |
899 | int usb_status; | 899 | int usb_status; |
@@ -1016,7 +1016,7 @@ static irqreturn_t s3c2410_udc_irq(int irq, void *_dev) | |||
1016 | } | 1016 | } |
1017 | } | 1017 | } |
1018 | 1018 | ||
1019 | dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", irq); | 1019 | dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", IRQ_USBD); |
1020 | 1020 | ||
1021 | /* Restore old index */ | 1021 | /* Restore old index */ |
1022 | udc_write(idx, S3C2410_UDC_INDEX_REG); | 1022 | udc_write(idx, S3C2410_UDC_INDEX_REG); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index f5738eb8e765..f5c3896b1d95 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -89,9 +89,9 @@ static int debug = 1; | |||
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | #define gs_debug(format, arg...) \ | 91 | #define gs_debug(format, arg...) \ |
92 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) | 92 | do { if (debug) pr_debug(format, ## arg); } while (0) |
93 | #define gs_debug_level(level, format, arg...) \ | 93 | #define gs_debug_level(level, format, arg...) \ |
94 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) | 94 | do { if (debug >= level) pr_debug(format, ## arg); } while (0) |
95 | 95 | ||
96 | 96 | ||
97 | /* Thanks to NetChip Technologies for donating this product ID. | 97 | /* Thanks to NetChip Technologies for donating this product ID. |
@@ -553,7 +553,8 @@ static int __init gs_module_init(void) | |||
553 | 553 | ||
554 | retval = usb_gadget_register_driver(&gs_gadget_driver); | 554 | retval = usb_gadget_register_driver(&gs_gadget_driver); |
555 | if (retval) { | 555 | if (retval) { |
556 | printk(KERN_ERR "gs_module_init: cannot register gadget driver, ret=%d\n", retval); | 556 | pr_err("gs_module_init: cannot register gadget driver, " |
557 | "ret=%d\n", retval); | ||
557 | return retval; | 558 | return retval; |
558 | } | 559 | } |
559 | 560 | ||
@@ -579,11 +580,13 @@ static int __init gs_module_init(void) | |||
579 | if (retval) { | 580 | if (retval) { |
580 | usb_gadget_unregister_driver(&gs_gadget_driver); | 581 | usb_gadget_unregister_driver(&gs_gadget_driver); |
581 | put_tty_driver(gs_tty_driver); | 582 | put_tty_driver(gs_tty_driver); |
582 | printk(KERN_ERR "gs_module_init: cannot register tty driver, ret=%d\n", retval); | 583 | pr_err("gs_module_init: cannot register tty driver, " |
584 | "ret=%d\n", retval); | ||
583 | return retval; | 585 | return retval; |
584 | } | 586 | } |
585 | 587 | ||
586 | printk(KERN_INFO "gs_module_init: %s %s loaded\n", GS_LONG_NAME, GS_VERSION_STR); | 588 | pr_info("gs_module_init: %s %s loaded\n", |
589 | GS_LONG_NAME, GS_VERSION_STR); | ||
587 | return 0; | 590 | return 0; |
588 | } | 591 | } |
589 | 592 | ||
@@ -598,7 +601,8 @@ static void __exit gs_module_exit(void) | |||
598 | put_tty_driver(gs_tty_driver); | 601 | put_tty_driver(gs_tty_driver); |
599 | usb_gadget_unregister_driver(&gs_gadget_driver); | 602 | usb_gadget_unregister_driver(&gs_gadget_driver); |
600 | 603 | ||
601 | printk(KERN_INFO "gs_module_exit: %s %s unloaded\n", GS_LONG_NAME, GS_VERSION_STR); | 604 | pr_info("gs_module_exit: %s %s unloaded\n", |
605 | GS_LONG_NAME, GS_VERSION_STR); | ||
602 | } | 606 | } |
603 | 607 | ||
604 | /* TTY Driver */ | 608 | /* TTY Driver */ |
@@ -621,7 +625,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
621 | gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file); | 625 | gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file); |
622 | 626 | ||
623 | if (port_num < 0 || port_num >= GS_NUM_PORTS) { | 627 | if (port_num < 0 || port_num >= GS_NUM_PORTS) { |
624 | printk(KERN_ERR "gs_open: (%d,%p,%p) invalid port number\n", | 628 | pr_err("gs_open: (%d,%p,%p) invalid port number\n", |
625 | port_num, tty, file); | 629 | port_num, tty, file); |
626 | return -ENODEV; | 630 | return -ENODEV; |
627 | } | 631 | } |
@@ -629,15 +633,14 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
629 | dev = gs_device; | 633 | dev = gs_device; |
630 | 634 | ||
631 | if (dev == NULL) { | 635 | if (dev == NULL) { |
632 | printk(KERN_ERR "gs_open: (%d,%p,%p) NULL device pointer\n", | 636 | pr_err("gs_open: (%d,%p,%p) NULL device pointer\n", |
633 | port_num, tty, file); | 637 | port_num, tty, file); |
634 | return -ENODEV; | 638 | return -ENODEV; |
635 | } | 639 | } |
636 | 640 | ||
637 | mtx = &gs_open_close_lock[port_num]; | 641 | mtx = &gs_open_close_lock[port_num]; |
638 | if (mutex_lock_interruptible(mtx)) { | 642 | if (mutex_lock_interruptible(mtx)) { |
639 | printk(KERN_ERR | 643 | pr_err("gs_open: (%d,%p,%p) interrupted waiting for mutex\n", |
640 | "gs_open: (%d,%p,%p) interrupted waiting for mutex\n", | ||
641 | port_num, tty, file); | 644 | port_num, tty, file); |
642 | return -ERESTARTSYS; | 645 | return -ERESTARTSYS; |
643 | } | 646 | } |
@@ -645,8 +648,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
645 | spin_lock_irqsave(&dev->dev_lock, flags); | 648 | spin_lock_irqsave(&dev->dev_lock, flags); |
646 | 649 | ||
647 | if (dev->dev_config == GS_NO_CONFIG_ID) { | 650 | if (dev->dev_config == GS_NO_CONFIG_ID) { |
648 | printk(KERN_ERR | 651 | pr_err("gs_open: (%d,%p,%p) device is not connected\n", |
649 | "gs_open: (%d,%p,%p) device is not connected\n", | ||
650 | port_num, tty, file); | 652 | port_num, tty, file); |
651 | ret = -ENODEV; | 653 | ret = -ENODEV; |
652 | goto exit_unlock_dev; | 654 | goto exit_unlock_dev; |
@@ -655,7 +657,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
655 | port = dev->dev_port[port_num]; | 657 | port = dev->dev_port[port_num]; |
656 | 658 | ||
657 | if (port == NULL) { | 659 | if (port == NULL) { |
658 | printk(KERN_ERR "gs_open: (%d,%p,%p) NULL port pointer\n", | 660 | pr_err("gs_open: (%d,%p,%p) NULL port pointer\n", |
659 | port_num, tty, file); | 661 | port_num, tty, file); |
660 | ret = -ENODEV; | 662 | ret = -ENODEV; |
661 | goto exit_unlock_dev; | 663 | goto exit_unlock_dev; |
@@ -665,7 +667,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
665 | spin_unlock(&dev->dev_lock); | 667 | spin_unlock(&dev->dev_lock); |
666 | 668 | ||
667 | if (port->port_dev == NULL) { | 669 | if (port->port_dev == NULL) { |
668 | printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (1)\n", | 670 | pr_err("gs_open: (%d,%p,%p) port disconnected (1)\n", |
669 | port_num, tty, file); | 671 | port_num, tty, file); |
670 | ret = -EIO; | 672 | ret = -EIO; |
671 | goto exit_unlock_port; | 673 | goto exit_unlock_port; |
@@ -692,8 +694,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
692 | 694 | ||
693 | /* might have been disconnected while asleep, check */ | 695 | /* might have been disconnected while asleep, check */ |
694 | if (port->port_dev == NULL) { | 696 | if (port->port_dev == NULL) { |
695 | printk(KERN_ERR | 697 | pr_err("gs_open: (%d,%p,%p) port disconnected (2)\n", |
696 | "gs_open: (%d,%p,%p) port disconnected (2)\n", | ||
697 | port_num, tty, file); | 698 | port_num, tty, file); |
698 | port->port_in_use = 0; | 699 | port->port_in_use = 0; |
699 | ret = -EIO; | 700 | ret = -EIO; |
@@ -701,7 +702,8 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
701 | } | 702 | } |
702 | 703 | ||
703 | if ((port->port_write_buf=buf) == NULL) { | 704 | if ((port->port_write_buf=buf) == NULL) { |
704 | printk(KERN_ERR "gs_open: (%d,%p,%p) cannot allocate port write buffer\n", | 705 | pr_err("gs_open: (%d,%p,%p) cannot allocate " |
706 | "port write buffer\n", | ||
705 | port_num, tty, file); | 707 | port_num, tty, file); |
706 | port->port_in_use = 0; | 708 | port->port_in_use = 0; |
707 | ret = -ENOMEM; | 709 | ret = -ENOMEM; |
@@ -714,7 +716,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
714 | 716 | ||
715 | /* might have been disconnected while asleep, check */ | 717 | /* might have been disconnected while asleep, check */ |
716 | if (port->port_dev == NULL) { | 718 | if (port->port_dev == NULL) { |
717 | printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (3)\n", | 719 | pr_err("gs_open: (%d,%p,%p) port disconnected (3)\n", |
718 | port_num, tty, file); | 720 | port_num, tty, file); |
719 | port->port_in_use = 0; | 721 | port->port_in_use = 0; |
720 | ret = -EIO; | 722 | ret = -EIO; |
@@ -762,7 +764,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
762 | struct mutex *mtx; | 764 | struct mutex *mtx; |
763 | 765 | ||
764 | if (port == NULL) { | 766 | if (port == NULL) { |
765 | printk(KERN_ERR "gs_close: NULL port pointer\n"); | 767 | pr_err("gs_close: NULL port pointer\n"); |
766 | return; | 768 | return; |
767 | } | 769 | } |
768 | 770 | ||
@@ -774,8 +776,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
774 | spin_lock_irq(&port->port_lock); | 776 | spin_lock_irq(&port->port_lock); |
775 | 777 | ||
776 | if (port->port_open_count == 0) { | 778 | if (port->port_open_count == 0) { |
777 | printk(KERN_ERR | 779 | pr_err("gs_close: (%d,%p,%p) port is already closed\n", |
778 | "gs_close: (%d,%p,%p) port is already closed\n", | ||
779 | port->port_num, tty, file); | 780 | port->port_num, tty, file); |
780 | goto exit; | 781 | goto exit; |
781 | } | 782 | } |
@@ -837,7 +838,7 @@ static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
837 | int ret; | 838 | int ret; |
838 | 839 | ||
839 | if (port == NULL) { | 840 | if (port == NULL) { |
840 | printk(KERN_ERR "gs_write: NULL port pointer\n"); | 841 | pr_err("gs_write: NULL port pointer\n"); |
841 | return -EIO; | 842 | return -EIO; |
842 | } | 843 | } |
843 | 844 | ||
@@ -850,14 +851,14 @@ static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
850 | spin_lock_irqsave(&port->port_lock, flags); | 851 | spin_lock_irqsave(&port->port_lock, flags); |
851 | 852 | ||
852 | if (port->port_dev == NULL) { | 853 | if (port->port_dev == NULL) { |
853 | printk(KERN_ERR "gs_write: (%d,%p) port is not connected\n", | 854 | pr_err("gs_write: (%d,%p) port is not connected\n", |
854 | port->port_num, tty); | 855 | port->port_num, tty); |
855 | ret = -EIO; | 856 | ret = -EIO; |
856 | goto exit; | 857 | goto exit; |
857 | } | 858 | } |
858 | 859 | ||
859 | if (port->port_open_count == 0) { | 860 | if (port->port_open_count == 0) { |
860 | printk(KERN_ERR "gs_write: (%d,%p) port is closed\n", | 861 | pr_err("gs_write: (%d,%p) port is closed\n", |
861 | port->port_num, tty); | 862 | port->port_num, tty); |
862 | ret = -EBADF; | 863 | ret = -EBADF; |
863 | goto exit; | 864 | goto exit; |
@@ -888,7 +889,7 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch) | |||
888 | struct gs_port *port = tty->driver_data; | 889 | struct gs_port *port = tty->driver_data; |
889 | 890 | ||
890 | if (port == NULL) { | 891 | if (port == NULL) { |
891 | printk(KERN_ERR "gs_put_char: NULL port pointer\n"); | 892 | pr_err("gs_put_char: NULL port pointer\n"); |
892 | return; | 893 | return; |
893 | } | 894 | } |
894 | 895 | ||
@@ -898,13 +899,13 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch) | |||
898 | spin_lock_irqsave(&port->port_lock, flags); | 899 | spin_lock_irqsave(&port->port_lock, flags); |
899 | 900 | ||
900 | if (port->port_dev == NULL) { | 901 | if (port->port_dev == NULL) { |
901 | printk(KERN_ERR "gs_put_char: (%d,%p) port is not connected\n", | 902 | pr_err("gs_put_char: (%d,%p) port is not connected\n", |
902 | port->port_num, tty); | 903 | port->port_num, tty); |
903 | goto exit; | 904 | goto exit; |
904 | } | 905 | } |
905 | 906 | ||
906 | if (port->port_open_count == 0) { | 907 | if (port->port_open_count == 0) { |
907 | printk(KERN_ERR "gs_put_char: (%d,%p) port is closed\n", | 908 | pr_err("gs_put_char: (%d,%p) port is closed\n", |
908 | port->port_num, tty); | 909 | port->port_num, tty); |
909 | goto exit; | 910 | goto exit; |
910 | } | 911 | } |
@@ -924,7 +925,7 @@ static void gs_flush_chars(struct tty_struct *tty) | |||
924 | struct gs_port *port = tty->driver_data; | 925 | struct gs_port *port = tty->driver_data; |
925 | 926 | ||
926 | if (port == NULL) { | 927 | if (port == NULL) { |
927 | printk(KERN_ERR "gs_flush_chars: NULL port pointer\n"); | 928 | pr_err("gs_flush_chars: NULL port pointer\n"); |
928 | return; | 929 | return; |
929 | } | 930 | } |
930 | 931 | ||
@@ -933,14 +934,13 @@ static void gs_flush_chars(struct tty_struct *tty) | |||
933 | spin_lock_irqsave(&port->port_lock, flags); | 934 | spin_lock_irqsave(&port->port_lock, flags); |
934 | 935 | ||
935 | if (port->port_dev == NULL) { | 936 | if (port->port_dev == NULL) { |
936 | printk(KERN_ERR | 937 | pr_err("gs_flush_chars: (%d,%p) port is not connected\n", |
937 | "gs_flush_chars: (%d,%p) port is not connected\n", | ||
938 | port->port_num, tty); | 938 | port->port_num, tty); |
939 | goto exit; | 939 | goto exit; |
940 | } | 940 | } |
941 | 941 | ||
942 | if (port->port_open_count == 0) { | 942 | if (port->port_open_count == 0) { |
943 | printk(KERN_ERR "gs_flush_chars: (%d,%p) port is closed\n", | 943 | pr_err("gs_flush_chars: (%d,%p) port is closed\n", |
944 | port->port_num, tty); | 944 | port->port_num, tty); |
945 | goto exit; | 945 | goto exit; |
946 | } | 946 | } |
@@ -1038,7 +1038,7 @@ static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, | |||
1038 | struct gs_port *port = tty->driver_data; | 1038 | struct gs_port *port = tty->driver_data; |
1039 | 1039 | ||
1040 | if (port == NULL) { | 1040 | if (port == NULL) { |
1041 | printk(KERN_ERR "gs_ioctl: NULL port pointer\n"); | 1041 | pr_err("gs_ioctl: NULL port pointer\n"); |
1042 | return -EIO; | 1042 | return -EIO; |
1043 | } | 1043 | } |
1044 | 1044 | ||
@@ -1076,7 +1076,7 @@ static int gs_send(struct gs_dev *dev) | |||
1076 | struct gs_req_entry *req_entry; | 1076 | struct gs_req_entry *req_entry; |
1077 | 1077 | ||
1078 | if (dev == NULL) { | 1078 | if (dev == NULL) { |
1079 | printk(KERN_ERR "gs_send: NULL device pointer\n"); | 1079 | pr_err("gs_send: NULL device pointer\n"); |
1080 | return -ENODEV; | 1080 | return -ENODEV; |
1081 | } | 1081 | } |
1082 | 1082 | ||
@@ -1103,7 +1103,7 @@ static int gs_send(struct gs_dev *dev) | |||
1103 | req->length = len; | 1103 | req->length = len; |
1104 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 1104 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
1105 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { | 1105 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { |
1106 | printk(KERN_ERR | 1106 | pr_err( |
1107 | "gs_send: cannot queue read request, ret=%d\n", | 1107 | "gs_send: cannot queue read request, ret=%d\n", |
1108 | ret); | 1108 | ret); |
1109 | spin_lock_irqsave(&dev->dev_lock, flags); | 1109 | spin_lock_irqsave(&dev->dev_lock, flags); |
@@ -1144,9 +1144,7 @@ static int gs_send_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1144 | port = dev->dev_port[0]; | 1144 | port = dev->dev_port[0]; |
1145 | 1145 | ||
1146 | if (port == NULL) { | 1146 | if (port == NULL) { |
1147 | printk(KERN_ERR | 1147 | pr_err("gs_send_packet: port=%d, NULL port pointer\n", 0); |
1148 | "gs_send_packet: port=%d, NULL port pointer\n", | ||
1149 | 0); | ||
1150 | return -EIO; | 1148 | return -EIO; |
1151 | } | 1149 | } |
1152 | 1150 | ||
@@ -1193,7 +1191,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1193 | port = dev->dev_port[0]; | 1191 | port = dev->dev_port[0]; |
1194 | 1192 | ||
1195 | if (port == NULL) { | 1193 | if (port == NULL) { |
1196 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL port pointer\n", | 1194 | pr_err("gs_recv_packet: port=%d, NULL port pointer\n", |
1197 | port->port_num); | 1195 | port->port_num); |
1198 | return -EIO; | 1196 | return -EIO; |
1199 | } | 1197 | } |
@@ -1201,7 +1199,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1201 | spin_lock(&port->port_lock); | 1199 | spin_lock(&port->port_lock); |
1202 | 1200 | ||
1203 | if (port->port_open_count == 0) { | 1201 | if (port->port_open_count == 0) { |
1204 | printk(KERN_ERR "gs_recv_packet: port=%d, port is closed\n", | 1202 | pr_err("gs_recv_packet: port=%d, port is closed\n", |
1205 | port->port_num); | 1203 | port->port_num); |
1206 | ret = -EIO; | 1204 | ret = -EIO; |
1207 | goto exit; | 1205 | goto exit; |
@@ -1211,14 +1209,14 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1211 | tty = port->port_tty; | 1209 | tty = port->port_tty; |
1212 | 1210 | ||
1213 | if (tty == NULL) { | 1211 | if (tty == NULL) { |
1214 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", | 1212 | pr_err("gs_recv_packet: port=%d, NULL tty pointer\n", |
1215 | port->port_num); | 1213 | port->port_num); |
1216 | ret = -EIO; | 1214 | ret = -EIO; |
1217 | goto exit; | 1215 | goto exit; |
1218 | } | 1216 | } |
1219 | 1217 | ||
1220 | if (port->port_tty->magic != TTY_MAGIC) { | 1218 | if (port->port_tty->magic != TTY_MAGIC) { |
1221 | printk(KERN_ERR "gs_recv_packet: port=%d, bad tty magic\n", | 1219 | pr_err("gs_recv_packet: port=%d, bad tty magic\n", |
1222 | port->port_num); | 1220 | port->port_num); |
1223 | ret = -EIO; | 1221 | ret = -EIO; |
1224 | goto exit; | 1222 | goto exit; |
@@ -1245,7 +1243,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) | |||
1245 | struct gs_dev *dev = ep->driver_data; | 1243 | struct gs_dev *dev = ep->driver_data; |
1246 | 1244 | ||
1247 | if (dev == NULL) { | 1245 | if (dev == NULL) { |
1248 | printk(KERN_ERR "gs_read_complete: NULL device pointer\n"); | 1246 | pr_err("gs_read_complete: NULL device pointer\n"); |
1249 | return; | 1247 | return; |
1250 | } | 1248 | } |
1251 | 1249 | ||
@@ -1256,7 +1254,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) | |||
1256 | requeue: | 1254 | requeue: |
1257 | req->length = ep->maxpacket; | 1255 | req->length = ep->maxpacket; |
1258 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { | 1256 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { |
1259 | printk(KERN_ERR | 1257 | pr_err( |
1260 | "gs_read_complete: cannot queue read request, ret=%d\n", | 1258 | "gs_read_complete: cannot queue read request, ret=%d\n", |
1261 | ret); | 1259 | ret); |
1262 | } | 1260 | } |
@@ -1270,7 +1268,7 @@ requeue: | |||
1270 | 1268 | ||
1271 | default: | 1269 | default: |
1272 | /* unexpected */ | 1270 | /* unexpected */ |
1273 | printk(KERN_ERR | 1271 | pr_err( |
1274 | "gs_read_complete: unexpected status error, status=%d\n", | 1272 | "gs_read_complete: unexpected status error, status=%d\n", |
1275 | req->status); | 1273 | req->status); |
1276 | goto requeue; | 1274 | goto requeue; |
@@ -1287,7 +1285,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) | |||
1287 | struct gs_req_entry *gs_req = req->context; | 1285 | struct gs_req_entry *gs_req = req->context; |
1288 | 1286 | ||
1289 | if (dev == NULL) { | 1287 | if (dev == NULL) { |
1290 | printk(KERN_ERR "gs_write_complete: NULL device pointer\n"); | 1288 | pr_err("gs_write_complete: NULL device pointer\n"); |
1291 | return; | 1289 | return; |
1292 | } | 1290 | } |
1293 | 1291 | ||
@@ -1296,8 +1294,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) | |||
1296 | /* normal completion */ | 1294 | /* normal completion */ |
1297 | requeue: | 1295 | requeue: |
1298 | if (gs_req == NULL) { | 1296 | if (gs_req == NULL) { |
1299 | printk(KERN_ERR | 1297 | pr_err("gs_write_complete: NULL request pointer\n"); |
1300 | "gs_write_complete: NULL request pointer\n"); | ||
1301 | return; | 1298 | return; |
1302 | } | 1299 | } |
1303 | 1300 | ||
@@ -1316,7 +1313,7 @@ requeue: | |||
1316 | break; | 1313 | break; |
1317 | 1314 | ||
1318 | default: | 1315 | default: |
1319 | printk(KERN_ERR | 1316 | pr_err( |
1320 | "gs_write_complete: unexpected status error, status=%d\n", | 1317 | "gs_write_complete: unexpected status error, status=%d\n", |
1321 | req->status); | 1318 | req->status); |
1322 | goto requeue; | 1319 | goto requeue; |
@@ -1351,7 +1348,7 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1351 | gs_device_desc.bcdDevice = | 1348 | gs_device_desc.bcdDevice = |
1352 | cpu_to_le16(GS_VERSION_NUM | gcnum); | 1349 | cpu_to_le16(GS_VERSION_NUM | gcnum); |
1353 | else { | 1350 | else { |
1354 | printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n", | 1351 | pr_warning("gs_bind: controller '%s' not recognized\n", |
1355 | gadget->name); | 1352 | gadget->name); |
1356 | /* unrecognized, but safe unless bulk is REALLY quirky */ | 1353 | /* unrecognized, but safe unless bulk is REALLY quirky */ |
1357 | gs_device_desc.bcdDevice = | 1354 | gs_device_desc.bcdDevice = |
@@ -1375,7 +1372,7 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1375 | if (use_acm) { | 1372 | if (use_acm) { |
1376 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); | 1373 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); |
1377 | if (!ep) { | 1374 | if (!ep) { |
1378 | printk(KERN_ERR "gs_bind: cannot run ACM on %s\n", gadget->name); | 1375 | pr_err("gs_bind: cannot run ACM on %s\n", gadget->name); |
1379 | goto autoconf_fail; | 1376 | goto autoconf_fail; |
1380 | } | 1377 | } |
1381 | gs_device_desc.idProduct = __constant_cpu_to_le16( | 1378 | gs_device_desc.idProduct = __constant_cpu_to_le16( |
@@ -1425,7 +1422,7 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1425 | set_gadget_data(gadget, dev); | 1422 | set_gadget_data(gadget, dev); |
1426 | 1423 | ||
1427 | if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) { | 1424 | if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) { |
1428 | printk(KERN_ERR "gs_bind: cannot allocate ports\n"); | 1425 | pr_err("gs_bind: cannot allocate ports\n"); |
1429 | gs_unbind(gadget); | 1426 | gs_unbind(gadget); |
1430 | return ret; | 1427 | return ret; |
1431 | } | 1428 | } |
@@ -1441,13 +1438,13 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1441 | 1438 | ||
1442 | gadget->ep0->driver_data = dev; | 1439 | gadget->ep0->driver_data = dev; |
1443 | 1440 | ||
1444 | printk(KERN_INFO "gs_bind: %s %s bound\n", | 1441 | pr_info("gs_bind: %s %s bound\n", |
1445 | GS_LONG_NAME, GS_VERSION_STR); | 1442 | GS_LONG_NAME, GS_VERSION_STR); |
1446 | 1443 | ||
1447 | return 0; | 1444 | return 0; |
1448 | 1445 | ||
1449 | autoconf_fail: | 1446 | autoconf_fail: |
1450 | printk(KERN_ERR "gs_bind: cannot autoconfigure on %s\n", gadget->name); | 1447 | pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name); |
1451 | return -ENODEV; | 1448 | return -ENODEV; |
1452 | } | 1449 | } |
1453 | 1450 | ||
@@ -1480,7 +1477,7 @@ static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) | |||
1480 | set_gadget_data(gadget, NULL); | 1477 | set_gadget_data(gadget, NULL); |
1481 | } | 1478 | } |
1482 | 1479 | ||
1483 | printk(KERN_INFO "gs_unbind: %s %s unbound\n", GS_LONG_NAME, | 1480 | pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME, |
1484 | GS_VERSION_STR); | 1481 | GS_VERSION_STR); |
1485 | } | 1482 | } |
1486 | 1483 | ||
@@ -1513,7 +1510,8 @@ static int gs_setup(struct usb_gadget *gadget, | |||
1513 | break; | 1510 | break; |
1514 | 1511 | ||
1515 | default: | 1512 | default: |
1516 | printk(KERN_ERR "gs_setup: unknown request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", | 1513 | pr_err("gs_setup: unknown request, type=%02x, request=%02x, " |
1514 | "value=%04x, index=%04x, length=%d\n", | ||
1517 | ctrl->bRequestType, ctrl->bRequest, | 1515 | ctrl->bRequestType, ctrl->bRequest, |
1518 | wValue, wIndex, wLength); | 1516 | wValue, wIndex, wLength); |
1519 | break; | 1517 | break; |
@@ -1526,7 +1524,7 @@ static int gs_setup(struct usb_gadget *gadget, | |||
1526 | && (ret % gadget->ep0->maxpacket) == 0; | 1524 | && (ret % gadget->ep0->maxpacket) == 0; |
1527 | ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | 1525 | ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); |
1528 | if (ret < 0) { | 1526 | if (ret < 0) { |
1529 | printk(KERN_ERR "gs_setup: cannot queue response, ret=%d\n", | 1527 | pr_err("gs_setup: cannot queue response, ret=%d\n", |
1530 | ret); | 1528 | ret); |
1531 | req->status = 0; | 1529 | req->status = 0; |
1532 | gs_setup_complete(gadget->ep0, req); | 1530 | gs_setup_complete(gadget->ep0, req); |
@@ -1656,7 +1654,8 @@ set_interface_done: | |||
1656 | break; | 1654 | break; |
1657 | 1655 | ||
1658 | default: | 1656 | default: |
1659 | printk(KERN_ERR "gs_setup: unknown standard request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", | 1657 | pr_err("gs_setup: unknown standard request, type=%02x, " |
1658 | "request=%02x, value=%04x, index=%04x, length=%d\n", | ||
1660 | ctrl->bRequestType, ctrl->bRequest, | 1659 | ctrl->bRequestType, ctrl->bRequest, |
1661 | wValue, wIndex, wLength); | 1660 | wValue, wIndex, wLength); |
1662 | break; | 1661 | break; |
@@ -1682,7 +1681,7 @@ static int gs_setup_class(struct usb_gadget *gadget, | |||
1682 | * handler copy that data to port->port_line_coding (iff | 1681 | * handler copy that data to port->port_line_coding (iff |
1683 | * it's valid) and maybe pass it on. Until then, fail. | 1682 | * it's valid) and maybe pass it on. Until then, fail. |
1684 | */ | 1683 | */ |
1685 | printk(KERN_WARNING "gs_setup: set_line_coding " | 1684 | pr_warning("gs_setup: set_line_coding " |
1686 | "unuspported\n"); | 1685 | "unuspported\n"); |
1687 | break; | 1686 | break; |
1688 | 1687 | ||
@@ -1702,12 +1701,12 @@ static int gs_setup_class(struct usb_gadget *gadget, | |||
1702 | * handler use that to set the state (iff it's valid) and | 1701 | * handler use that to set the state (iff it's valid) and |
1703 | * maybe pass it on. Until then, fail. | 1702 | * maybe pass it on. Until then, fail. |
1704 | */ | 1703 | */ |
1705 | printk(KERN_WARNING "gs_setup: set_control_line_state " | 1704 | pr_warning("gs_setup: set_control_line_state " |
1706 | "unuspported\n"); | 1705 | "unuspported\n"); |
1707 | break; | 1706 | break; |
1708 | 1707 | ||
1709 | default: | 1708 | default: |
1710 | printk(KERN_ERR "gs_setup: unknown class request, " | 1709 | pr_err("gs_setup: unknown class request, " |
1711 | "type=%02x, request=%02x, value=%04x, " | 1710 | "type=%02x, request=%02x, value=%04x, " |
1712 | "index=%04x, length=%d\n", | 1711 | "index=%04x, length=%d\n", |
1713 | ctrl->bRequestType, ctrl->bRequest, | 1712 | ctrl->bRequestType, ctrl->bRequest, |
@@ -1724,7 +1723,8 @@ static int gs_setup_class(struct usb_gadget *gadget, | |||
1724 | static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) | 1723 | static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) |
1725 | { | 1724 | { |
1726 | if (req->status || req->actual != req->length) { | 1725 | if (req->status || req->actual != req->length) { |
1727 | printk(KERN_ERR "gs_setup_complete: status error, status=%d, actual=%d, length=%d\n", | 1726 | pr_err("gs_setup_complete: status error, status=%d, " |
1727 | "actual=%d, length=%d\n", | ||
1728 | req->status, req->actual, req->length); | 1728 | req->status, req->actual, req->length); |
1729 | } | 1729 | } |
1730 | } | 1730 | } |
@@ -1751,11 +1751,11 @@ static void gs_disconnect(struct usb_gadget *gadget) | |||
1751 | 1751 | ||
1752 | /* re-allocate ports for the next connection */ | 1752 | /* re-allocate ports for the next connection */ |
1753 | if (gs_alloc_ports(dev, GFP_ATOMIC) != 0) | 1753 | if (gs_alloc_ports(dev, GFP_ATOMIC) != 0) |
1754 | printk(KERN_ERR "gs_disconnect: cannot re-allocate ports\n"); | 1754 | pr_err("gs_disconnect: cannot re-allocate ports\n"); |
1755 | 1755 | ||
1756 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 1756 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
1757 | 1757 | ||
1758 | printk(KERN_INFO "gs_disconnect: %s disconnected\n", GS_LONG_NAME); | 1758 | pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME); |
1759 | } | 1759 | } |
1760 | 1760 | ||
1761 | /* | 1761 | /* |
@@ -1778,7 +1778,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1778 | struct gs_req_entry *req_entry; | 1778 | struct gs_req_entry *req_entry; |
1779 | 1779 | ||
1780 | if (dev == NULL) { | 1780 | if (dev == NULL) { |
1781 | printk(KERN_ERR "gs_set_config: NULL device pointer\n"); | 1781 | pr_err("gs_set_config: NULL device pointer\n"); |
1782 | return 0; | 1782 | return 0; |
1783 | } | 1783 | } |
1784 | 1784 | ||
@@ -1823,7 +1823,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1823 | dev->dev_notify_ep = ep; | 1823 | dev->dev_notify_ep = ep; |
1824 | dev->dev_notify_ep_desc = ep_desc; | 1824 | dev->dev_notify_ep_desc = ep_desc; |
1825 | } else { | 1825 | } else { |
1826 | printk(KERN_ERR "gs_set_config: cannot enable notify endpoint %s, ret=%d\n", | 1826 | pr_err("gs_set_config: cannot enable NOTIFY " |
1827 | "endpoint %s, ret=%d\n", | ||
1827 | ep->name, ret); | 1828 | ep->name, ret); |
1828 | goto exit_reset_config; | 1829 | goto exit_reset_config; |
1829 | } | 1830 | } |
@@ -1839,7 +1840,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1839 | dev->dev_in_ep = ep; | 1840 | dev->dev_in_ep = ep; |
1840 | dev->dev_in_ep_desc = ep_desc; | 1841 | dev->dev_in_ep_desc = ep_desc; |
1841 | } else { | 1842 | } else { |
1842 | printk(KERN_ERR "gs_set_config: cannot enable in endpoint %s, ret=%d\n", | 1843 | pr_err("gs_set_config: cannot enable IN " |
1844 | "endpoint %s, ret=%d\n", | ||
1843 | ep->name, ret); | 1845 | ep->name, ret); |
1844 | goto exit_reset_config; | 1846 | goto exit_reset_config; |
1845 | } | 1847 | } |
@@ -1855,7 +1857,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1855 | dev->dev_out_ep = ep; | 1857 | dev->dev_out_ep = ep; |
1856 | dev->dev_out_ep_desc = ep_desc; | 1858 | dev->dev_out_ep_desc = ep_desc; |
1857 | } else { | 1859 | } else { |
1858 | printk(KERN_ERR "gs_set_config: cannot enable out endpoint %s, ret=%d\n", | 1860 | pr_err("gs_set_config: cannot enable OUT " |
1861 | "endpoint %s, ret=%d\n", | ||
1859 | ep->name, ret); | 1862 | ep->name, ret); |
1860 | goto exit_reset_config; | 1863 | goto exit_reset_config; |
1861 | } | 1864 | } |
@@ -1865,7 +1868,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1865 | 1868 | ||
1866 | if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL | 1869 | if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL |
1867 | || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) { | 1870 | || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) { |
1868 | printk(KERN_ERR "gs_set_config: cannot find endpoints\n"); | 1871 | pr_err("gs_set_config: cannot find endpoints\n"); |
1869 | ret = -ENODEV; | 1872 | ret = -ENODEV; |
1870 | goto exit_reset_config; | 1873 | goto exit_reset_config; |
1871 | } | 1874 | } |
@@ -1876,11 +1879,12 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1876 | if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) { | 1879 | if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) { |
1877 | req->complete = gs_read_complete; | 1880 | req->complete = gs_read_complete; |
1878 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { | 1881 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { |
1879 | printk(KERN_ERR "gs_set_config: cannot queue read request, ret=%d\n", | 1882 | pr_err("gs_set_config: cannot queue read " |
1880 | ret); | 1883 | "request, ret=%d\n", ret); |
1881 | } | 1884 | } |
1882 | } else { | 1885 | } else { |
1883 | printk(KERN_ERR "gs_set_config: cannot allocate read requests\n"); | 1886 | pr_err("gs_set_config: cannot allocate " |
1887 | "read requests\n"); | ||
1884 | ret = -ENOMEM; | 1888 | ret = -ENOMEM; |
1885 | goto exit_reset_config; | 1889 | goto exit_reset_config; |
1886 | } | 1890 | } |
@@ -1893,13 +1897,14 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1893 | req_entry->re_req->complete = gs_write_complete; | 1897 | req_entry->re_req->complete = gs_write_complete; |
1894 | list_add(&req_entry->re_entry, &dev->dev_req_list); | 1898 | list_add(&req_entry->re_entry, &dev->dev_req_list); |
1895 | } else { | 1899 | } else { |
1896 | printk(KERN_ERR "gs_set_config: cannot allocate write requests\n"); | 1900 | pr_err("gs_set_config: cannot allocate " |
1901 | "write requests\n"); | ||
1897 | ret = -ENOMEM; | 1902 | ret = -ENOMEM; |
1898 | goto exit_reset_config; | 1903 | goto exit_reset_config; |
1899 | } | 1904 | } |
1900 | } | 1905 | } |
1901 | 1906 | ||
1902 | printk(KERN_INFO "gs_set_config: %s configured, %s speed %s config\n", | 1907 | pr_info("gs_set_config: %s configured, %s speed %s config\n", |
1903 | GS_LONG_NAME, | 1908 | GS_LONG_NAME, |
1904 | gadget->speed == USB_SPEED_HIGH ? "high" : "full", | 1909 | gadget->speed == USB_SPEED_HIGH ? "high" : "full", |
1905 | config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM"); | 1910 | config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM"); |
@@ -1926,7 +1931,7 @@ static void gs_reset_config(struct gs_dev *dev) | |||
1926 | struct gs_req_entry *req_entry; | 1931 | struct gs_req_entry *req_entry; |
1927 | 1932 | ||
1928 | if (dev == NULL) { | 1933 | if (dev == NULL) { |
1929 | printk(KERN_ERR "gs_reset_config: NULL device pointer\n"); | 1934 | pr_err("gs_reset_config: NULL device pointer\n"); |
1930 | return; | 1935 | return; |
1931 | } | 1936 | } |
1932 | 1937 | ||
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index fcde5d9c87df..d3d4f4048e6c 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -1115,7 +1115,7 @@ zero_bind (struct usb_gadget *gadget) | |||
1115 | ep = usb_ep_autoconfig (gadget, &fs_source_desc); | 1115 | ep = usb_ep_autoconfig (gadget, &fs_source_desc); |
1116 | if (!ep) { | 1116 | if (!ep) { |
1117 | autoconf_fail: | 1117 | autoconf_fail: |
1118 | printk (KERN_ERR "%s: can't autoconfigure on %s\n", | 1118 | pr_err("%s: can't autoconfigure on %s\n", |
1119 | shortname, gadget->name); | 1119 | shortname, gadget->name); |
1120 | return -ENODEV; | 1120 | return -ENODEV; |
1121 | } | 1121 | } |
@@ -1139,7 +1139,7 @@ autoconf_fail: | |||
1139 | * things like configuration and altsetting numbering | 1139 | * things like configuration and altsetting numbering |
1140 | * can need hardware-specific attention though. | 1140 | * can need hardware-specific attention though. |
1141 | */ | 1141 | */ |
1142 | printk (KERN_WARNING "%s: controller '%s' not recognized\n", | 1142 | pr_warning("%s: controller '%s' not recognized\n", |
1143 | shortname, gadget->name); | 1143 | shortname, gadget->name); |
1144 | device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999); | 1144 | device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999); |
1145 | } | 1145 | } |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 49a91c5ee51b..d97b16b52efa 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -29,15 +29,6 @@ config USB_EHCI_HCD | |||
29 | To compile this driver as a module, choose M here: the | 29 | To compile this driver as a module, choose M here: the |
30 | module will be called ehci-hcd. | 30 | module will be called ehci-hcd. |
31 | 31 | ||
32 | config USB_EHCI_SPLIT_ISO | ||
33 | bool "Full speed ISO transactions (EXPERIMENTAL)" | ||
34 | depends on USB_EHCI_HCD && EXPERIMENTAL | ||
35 | default n | ||
36 | ---help--- | ||
37 | This code is new and hasn't been used with many different | ||
38 | EHCI or USB 2.0 transaction translator implementations. | ||
39 | It should work for ISO-OUT transfers, like audio. | ||
40 | |||
41 | config USB_EHCI_ROOT_HUB_TT | 32 | config USB_EHCI_ROOT_HUB_TT |
42 | bool "Root Hub Transaction Translators (EXPERIMENTAL)" | 33 | bool "Root Hub Transaction Translators (EXPERIMENTAL)" |
43 | depends on USB_EHCI_HCD && EXPERIMENTAL | 34 | depends on USB_EHCI_HCD && EXPERIMENTAL |
@@ -69,21 +60,30 @@ config USB_EHCI_TT_NEWSCHED | |||
69 | 60 | ||
70 | config USB_EHCI_BIG_ENDIAN_MMIO | 61 | config USB_EHCI_BIG_ENDIAN_MMIO |
71 | bool | 62 | bool |
72 | depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX) | 63 | depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX) |
73 | default y | 64 | default y |
74 | 65 | ||
75 | config USB_EHCI_BIG_ENDIAN_DESC | 66 | config USB_EHCI_BIG_ENDIAN_DESC |
76 | bool | 67 | bool |
77 | depends on USB_EHCI_HCD && 440EPX | 68 | depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX) |
78 | default y | 69 | default y |
79 | 70 | ||
80 | config USB_EHCI_FSL | 71 | config USB_EHCI_FSL |
81 | bool | 72 | bool |
73 | depends on USB_EHCI_HCD | ||
82 | select USB_EHCI_ROOT_HUB_TT | 74 | select USB_EHCI_ROOT_HUB_TT |
83 | default y if MPC834x || PPC_MPC831x | 75 | default y if MPC834x || PPC_MPC831x |
84 | ---help--- | 76 | ---help--- |
85 | Variation of ARC USB block used in some Freescale chips. | 77 | Variation of ARC USB block used in some Freescale chips. |
86 | 78 | ||
79 | config USB_EHCI_HCD_PPC_OF | ||
80 | bool "EHCI support for PPC USB controller on OF platform bus" | ||
81 | depends on USB_EHCI_HCD && PPC_OF | ||
82 | default y | ||
83 | ---help--- | ||
84 | Enables support for the USB controller present on the PowerPC | ||
85 | OpenFirmware platform bus. | ||
86 | |||
87 | config USB_ISP116X_HCD | 87 | config USB_ISP116X_HCD |
88 | tristate "ISP116X HCD support" | 88 | tristate "ISP116X HCD support" |
89 | depends on USB | 89 | depends on USB |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 766ef68a0b43..da7532d38bf1 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -222,6 +222,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
222 | .hub_control = ehci_hub_control, | 222 | .hub_control = ehci_hub_control, |
223 | .bus_suspend = ehci_bus_suspend, | 223 | .bus_suspend = ehci_bus_suspend, |
224 | .bus_resume = ehci_bus_resume, | 224 | .bus_resume = ehci_bus_resume, |
225 | .relinquish_port = ehci_relinquish_port, | ||
225 | }; | 226 | }; |
226 | 227 | ||
227 | /*-------------------------------------------------------------------------*/ | 228 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index c9cc4413198e..64ebfc5548a3 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -323,7 +323,43 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { } | |||
323 | 323 | ||
324 | #else | 324 | #else |
325 | 325 | ||
326 | /* troubleshooting help: expose state in sysfs */ | 326 | /* troubleshooting help: expose state in debugfs */ |
327 | |||
328 | static int debug_async_open(struct inode *, struct file *); | ||
329 | static int debug_periodic_open(struct inode *, struct file *); | ||
330 | static int debug_registers_open(struct inode *, struct file *); | ||
331 | static int debug_async_open(struct inode *, struct file *); | ||
332 | static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*); | ||
333 | static int debug_close(struct inode *, struct file *); | ||
334 | |||
335 | static const struct file_operations debug_async_fops = { | ||
336 | .owner = THIS_MODULE, | ||
337 | .open = debug_async_open, | ||
338 | .read = debug_output, | ||
339 | .release = debug_close, | ||
340 | }; | ||
341 | static const struct file_operations debug_periodic_fops = { | ||
342 | .owner = THIS_MODULE, | ||
343 | .open = debug_periodic_open, | ||
344 | .read = debug_output, | ||
345 | .release = debug_close, | ||
346 | }; | ||
347 | static const struct file_operations debug_registers_fops = { | ||
348 | .owner = THIS_MODULE, | ||
349 | .open = debug_registers_open, | ||
350 | .read = debug_output, | ||
351 | .release = debug_close, | ||
352 | }; | ||
353 | |||
354 | static struct dentry *ehci_debug_root; | ||
355 | |||
356 | struct debug_buffer { | ||
357 | ssize_t (*fill_func)(struct debug_buffer *); /* fill method */ | ||
358 | struct usb_bus *bus; | ||
359 | struct mutex mutex; /* protect filling of buffer */ | ||
360 | size_t count; /* number of characters filled into buffer */ | ||
361 | char *page; | ||
362 | }; | ||
327 | 363 | ||
328 | #define speed_char(info1) ({ char tmp; \ | 364 | #define speed_char(info1) ({ char tmp; \ |
329 | switch (info1 & (3 << 12)) { \ | 365 | switch (info1 & (3 << 12)) { \ |
@@ -441,10 +477,8 @@ done: | |||
441 | *nextp = next; | 477 | *nextp = next; |
442 | } | 478 | } |
443 | 479 | ||
444 | static ssize_t | 480 | static ssize_t fill_async_buffer(struct debug_buffer *buf) |
445 | show_async (struct class_device *class_dev, char *buf) | ||
446 | { | 481 | { |
447 | struct usb_bus *bus; | ||
448 | struct usb_hcd *hcd; | 482 | struct usb_hcd *hcd; |
449 | struct ehci_hcd *ehci; | 483 | struct ehci_hcd *ehci; |
450 | unsigned long flags; | 484 | unsigned long flags; |
@@ -452,14 +486,13 @@ show_async (struct class_device *class_dev, char *buf) | |||
452 | char *next; | 486 | char *next; |
453 | struct ehci_qh *qh; | 487 | struct ehci_qh *qh; |
454 | 488 | ||
455 | *buf = 0; | 489 | hcd = bus_to_hcd(buf->bus); |
456 | |||
457 | bus = class_get_devdata(class_dev); | ||
458 | hcd = bus_to_hcd(bus); | ||
459 | ehci = hcd_to_ehci (hcd); | 490 | ehci = hcd_to_ehci (hcd); |
460 | next = buf; | 491 | next = buf->page; |
461 | size = PAGE_SIZE; | 492 | size = PAGE_SIZE; |
462 | 493 | ||
494 | *next = 0; | ||
495 | |||
463 | /* dumps a snapshot of the async schedule. | 496 | /* dumps a snapshot of the async schedule. |
464 | * usually empty except for long-term bulk reads, or head. | 497 | * usually empty except for long-term bulk reads, or head. |
465 | * one QH per line, and TDs we know about | 498 | * one QH per line, and TDs we know about |
@@ -477,16 +510,12 @@ show_async (struct class_device *class_dev, char *buf) | |||
477 | } | 510 | } |
478 | spin_unlock_irqrestore (&ehci->lock, flags); | 511 | spin_unlock_irqrestore (&ehci->lock, flags); |
479 | 512 | ||
480 | return strlen (buf); | 513 | return strlen(buf->page); |
481 | } | 514 | } |
482 | static CLASS_DEVICE_ATTR (async, S_IRUGO, show_async, NULL); | ||
483 | 515 | ||
484 | #define DBG_SCHED_LIMIT 64 | 516 | #define DBG_SCHED_LIMIT 64 |
485 | 517 | static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |
486 | static ssize_t | ||
487 | show_periodic (struct class_device *class_dev, char *buf) | ||
488 | { | 518 | { |
489 | struct usb_bus *bus; | ||
490 | struct usb_hcd *hcd; | 519 | struct usb_hcd *hcd; |
491 | struct ehci_hcd *ehci; | 520 | struct ehci_hcd *ehci; |
492 | unsigned long flags; | 521 | unsigned long flags; |
@@ -500,10 +529,9 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
500 | return 0; | 529 | return 0; |
501 | seen_count = 0; | 530 | seen_count = 0; |
502 | 531 | ||
503 | bus = class_get_devdata(class_dev); | 532 | hcd = bus_to_hcd(buf->bus); |
504 | hcd = bus_to_hcd(bus); | ||
505 | ehci = hcd_to_ehci (hcd); | 533 | ehci = hcd_to_ehci (hcd); |
506 | next = buf; | 534 | next = buf->page; |
507 | size = PAGE_SIZE; | 535 | size = PAGE_SIZE; |
508 | 536 | ||
509 | temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size); | 537 | temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size); |
@@ -623,14 +651,10 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
623 | 651 | ||
624 | return PAGE_SIZE - size; | 652 | return PAGE_SIZE - size; |
625 | } | 653 | } |
626 | static CLASS_DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL); | ||
627 | |||
628 | #undef DBG_SCHED_LIMIT | 654 | #undef DBG_SCHED_LIMIT |
629 | 655 | ||
630 | static ssize_t | 656 | static ssize_t fill_registers_buffer(struct debug_buffer *buf) |
631 | show_registers (struct class_device *class_dev, char *buf) | ||
632 | { | 657 | { |
633 | struct usb_bus *bus; | ||
634 | struct usb_hcd *hcd; | 658 | struct usb_hcd *hcd; |
635 | struct ehci_hcd *ehci; | 659 | struct ehci_hcd *ehci; |
636 | unsigned long flags; | 660 | unsigned long flags; |
@@ -639,15 +663,14 @@ show_registers (struct class_device *class_dev, char *buf) | |||
639 | static char fmt [] = "%*s\n"; | 663 | static char fmt [] = "%*s\n"; |
640 | static char label [] = ""; | 664 | static char label [] = ""; |
641 | 665 | ||
642 | bus = class_get_devdata(class_dev); | 666 | hcd = bus_to_hcd(buf->bus); |
643 | hcd = bus_to_hcd(bus); | ||
644 | ehci = hcd_to_ehci (hcd); | 667 | ehci = hcd_to_ehci (hcd); |
645 | next = buf; | 668 | next = buf->page; |
646 | size = PAGE_SIZE; | 669 | size = PAGE_SIZE; |
647 | 670 | ||
648 | spin_lock_irqsave (&ehci->lock, flags); | 671 | spin_lock_irqsave (&ehci->lock, flags); |
649 | 672 | ||
650 | if (bus->controller->power.power_state.event) { | 673 | if (buf->bus->controller->power.power_state.event) { |
651 | size = scnprintf (next, size, | 674 | size = scnprintf (next, size, |
652 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" | 675 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" |
653 | "%s\n" | 676 | "%s\n" |
@@ -763,9 +786,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
763 | } | 786 | } |
764 | 787 | ||
765 | if (ehci->reclaim) { | 788 | if (ehci->reclaim) { |
766 | temp = scnprintf (next, size, "reclaim qh %p%s\n", | 789 | temp = scnprintf(next, size, "reclaim qh %p\n", ehci->reclaim); |
767 | ehci->reclaim, | ||
768 | ehci->reclaim_ready ? " ready" : ""); | ||
769 | size -= temp; | 790 | size -= temp; |
770 | next += temp; | 791 | next += temp; |
771 | } | 792 | } |
@@ -789,26 +810,150 @@ done: | |||
789 | 810 | ||
790 | return PAGE_SIZE - size; | 811 | return PAGE_SIZE - size; |
791 | } | 812 | } |
792 | static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); | ||
793 | 813 | ||
794 | static inline void create_debug_files (struct ehci_hcd *ehci) | 814 | static struct debug_buffer *alloc_buffer(struct usb_bus *bus, |
815 | ssize_t (*fill_func)(struct debug_buffer *)) | ||
795 | { | 816 | { |
796 | struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev; | 817 | struct debug_buffer *buf; |
797 | int retval; | 818 | |
819 | buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); | ||
798 | 820 | ||
799 | retval = class_device_create_file(cldev, &class_device_attr_async); | 821 | if (buf) { |
800 | retval = class_device_create_file(cldev, &class_device_attr_periodic); | 822 | buf->bus = bus; |
801 | retval = class_device_create_file(cldev, &class_device_attr_registers); | 823 | buf->fill_func = fill_func; |
824 | mutex_init(&buf->mutex); | ||
825 | } | ||
826 | |||
827 | return buf; | ||
802 | } | 828 | } |
803 | 829 | ||
804 | static inline void remove_debug_files (struct ehci_hcd *ehci) | 830 | static int fill_buffer(struct debug_buffer *buf) |
805 | { | 831 | { |
806 | struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev; | 832 | int ret = 0; |
833 | |||
834 | if (!buf->page) | ||
835 | buf->page = (char *)get_zeroed_page(GFP_KERNEL); | ||
836 | |||
837 | if (!buf->page) { | ||
838 | ret = -ENOMEM; | ||
839 | goto out; | ||
840 | } | ||
841 | |||
842 | ret = buf->fill_func(buf); | ||
807 | 843 | ||
808 | class_device_remove_file(cldev, &class_device_attr_async); | 844 | if (ret >= 0) { |
809 | class_device_remove_file(cldev, &class_device_attr_periodic); | 845 | buf->count = ret; |
810 | class_device_remove_file(cldev, &class_device_attr_registers); | 846 | ret = 0; |
847 | } | ||
848 | |||
849 | out: | ||
850 | return ret; | ||
811 | } | 851 | } |
812 | 852 | ||
813 | #endif /* STUB_DEBUG_FILES */ | 853 | static ssize_t debug_output(struct file *file, char __user *user_buf, |
854 | size_t len, loff_t *offset) | ||
855 | { | ||
856 | struct debug_buffer *buf = file->private_data; | ||
857 | int ret = 0; | ||
858 | |||
859 | mutex_lock(&buf->mutex); | ||
860 | if (buf->count == 0) { | ||
861 | ret = fill_buffer(buf); | ||
862 | if (ret != 0) { | ||
863 | mutex_unlock(&buf->mutex); | ||
864 | goto out; | ||
865 | } | ||
866 | } | ||
867 | mutex_unlock(&buf->mutex); | ||
868 | |||
869 | ret = simple_read_from_buffer(user_buf, len, offset, | ||
870 | buf->page, buf->count); | ||
871 | |||
872 | out: | ||
873 | return ret; | ||
874 | |||
875 | } | ||
876 | |||
877 | static int debug_close(struct inode *inode, struct file *file) | ||
878 | { | ||
879 | struct debug_buffer *buf = file->private_data; | ||
814 | 880 | ||
881 | if (buf) { | ||
882 | if (buf->page) | ||
883 | free_page((unsigned long)buf->page); | ||
884 | kfree(buf); | ||
885 | } | ||
886 | |||
887 | return 0; | ||
888 | } | ||
889 | static int debug_async_open(struct inode *inode, struct file *file) | ||
890 | { | ||
891 | file->private_data = alloc_buffer(inode->i_private, fill_async_buffer); | ||
892 | |||
893 | return file->private_data ? 0 : -ENOMEM; | ||
894 | } | ||
895 | |||
896 | static int debug_periodic_open(struct inode *inode, struct file *file) | ||
897 | { | ||
898 | file->private_data = alloc_buffer(inode->i_private, | ||
899 | fill_periodic_buffer); | ||
900 | |||
901 | return file->private_data ? 0 : -ENOMEM; | ||
902 | } | ||
903 | |||
904 | static int debug_registers_open(struct inode *inode, struct file *file) | ||
905 | { | ||
906 | file->private_data = alloc_buffer(inode->i_private, | ||
907 | fill_registers_buffer); | ||
908 | |||
909 | return file->private_data ? 0 : -ENOMEM; | ||
910 | } | ||
911 | |||
912 | static inline void create_debug_files (struct ehci_hcd *ehci) | ||
913 | { | ||
914 | struct usb_bus *bus = &ehci_to_hcd(ehci)->self; | ||
915 | |||
916 | ehci->debug_dir = debugfs_create_dir(bus->bus_name, ehci_debug_root); | ||
917 | if (!ehci->debug_dir) | ||
918 | goto dir_error; | ||
919 | |||
920 | ehci->debug_async = debugfs_create_file("async", S_IRUGO, | ||
921 | ehci->debug_dir, bus, | ||
922 | &debug_async_fops); | ||
923 | if (!ehci->debug_async) | ||
924 | goto async_error; | ||
925 | |||
926 | ehci->debug_periodic = debugfs_create_file("periodic", S_IRUGO, | ||
927 | ehci->debug_dir, bus, | ||
928 | &debug_periodic_fops); | ||
929 | if (!ehci->debug_periodic) | ||
930 | goto periodic_error; | ||
931 | |||
932 | ehci->debug_registers = debugfs_create_file("registers", S_IRUGO, | ||
933 | ehci->debug_dir, bus, | ||
934 | &debug_registers_fops); | ||
935 | if (!ehci->debug_registers) | ||
936 | goto registers_error; | ||
937 | return; | ||
938 | |||
939 | registers_error: | ||
940 | debugfs_remove(ehci->debug_periodic); | ||
941 | periodic_error: | ||
942 | debugfs_remove(ehci->debug_async); | ||
943 | async_error: | ||
944 | debugfs_remove(ehci->debug_dir); | ||
945 | dir_error: | ||
946 | ehci->debug_periodic = NULL; | ||
947 | ehci->debug_async = NULL; | ||
948 | ehci->debug_dir = NULL; | ||
949 | } | ||
950 | |||
951 | static inline void remove_debug_files (struct ehci_hcd *ehci) | ||
952 | { | ||
953 | debugfs_remove(ehci->debug_registers); | ||
954 | debugfs_remove(ehci->debug_periodic); | ||
955 | debugfs_remove(ehci->debug_async); | ||
956 | debugfs_remove(ehci->debug_dir); | ||
957 | } | ||
958 | |||
959 | #endif /* STUB_DEBUG_FILES */ | ||
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 430821cb95c8..adb0defa1631 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include "ehci-fsl.h" | 26 | #include "ehci-fsl.h" |
27 | 27 | ||
28 | /* FIXME: Power Managment is un-ported so temporarily disable it */ | 28 | /* FIXME: Power Management is un-ported so temporarily disable it */ |
29 | #undef CONFIG_PM | 29 | #undef CONFIG_PM |
30 | 30 | ||
31 | /* PCI-based HCs are common, but plenty of non-PCI HCs are used too */ | 31 | /* PCI-based HCs are common, but plenty of non-PCI HCs are used too */ |
@@ -323,6 +323,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
323 | .hub_control = ehci_hub_control, | 323 | .hub_control = ehci_hub_control, |
324 | .bus_suspend = ehci_bus_suspend, | 324 | .bus_suspend = ehci_bus_suspend, |
325 | .bus_resume = ehci_bus_resume, | 325 | .bus_resume = ehci_bus_resume, |
326 | .relinquish_port = ehci_relinquish_port, | ||
326 | }; | 327 | }; |
327 | 328 | ||
328 | static int ehci_fsl_drv_probe(struct platform_device *pdev) | 329 | static int ehci_fsl_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5f2d74ed5ad7..4caa6a8b9a37 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
35 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
36 | #include <linux/debugfs.h> | ||
36 | 37 | ||
37 | #include "../core/hcd.h" | 38 | #include "../core/hcd.h" |
38 | 39 | ||
@@ -109,7 +110,7 @@ static const char hcd_name [] = "ehci_hcd"; | |||
109 | #define EHCI_TUNE_MULT_TT 1 | 110 | #define EHCI_TUNE_MULT_TT 1 |
110 | #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ | 111 | #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ |
111 | 112 | ||
112 | #define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ | 113 | #define EHCI_IAA_MSECS 10 /* arbitrary */ |
113 | #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ | 114 | #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ |
114 | #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ | 115 | #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ |
115 | #define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ | 116 | #define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ |
@@ -266,6 +267,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci) | |||
266 | 267 | ||
267 | /*-------------------------------------------------------------------------*/ | 268 | /*-------------------------------------------------------------------------*/ |
268 | 269 | ||
270 | static void end_unlink_async(struct ehci_hcd *ehci); | ||
269 | static void ehci_work(struct ehci_hcd *ehci); | 271 | static void ehci_work(struct ehci_hcd *ehci); |
270 | 272 | ||
271 | #include "ehci-hub.c" | 273 | #include "ehci-hub.c" |
@@ -275,25 +277,41 @@ static void ehci_work(struct ehci_hcd *ehci); | |||
275 | 277 | ||
276 | /*-------------------------------------------------------------------------*/ | 278 | /*-------------------------------------------------------------------------*/ |
277 | 279 | ||
278 | static void ehci_watchdog (unsigned long param) | 280 | static void ehci_iaa_watchdog(unsigned long param) |
279 | { | 281 | { |
280 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; | 282 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; |
281 | unsigned long flags; | 283 | unsigned long flags; |
284 | u32 status, cmd; | ||
282 | 285 | ||
283 | spin_lock_irqsave (&ehci->lock, flags); | 286 | spin_lock_irqsave (&ehci->lock, flags); |
287 | WARN_ON(!ehci->reclaim); | ||
284 | 288 | ||
285 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ | 289 | status = ehci_readl(ehci, &ehci->regs->status); |
290 | cmd = ehci_readl(ehci, &ehci->regs->command); | ||
291 | ehci_dbg(ehci, "IAA watchdog: status %x cmd %x\n", status, cmd); | ||
292 | |||
293 | /* lost IAA irqs wedge things badly; seen first with a vt8235 */ | ||
286 | if (ehci->reclaim) { | 294 | if (ehci->reclaim) { |
287 | u32 status = ehci_readl(ehci, &ehci->regs->status); | ||
288 | if (status & STS_IAA) { | 295 | if (status & STS_IAA) { |
289 | ehci_vdbg (ehci, "lost IAA\n"); | 296 | ehci_vdbg (ehci, "lost IAA\n"); |
290 | COUNT (ehci->stats.lost_iaa); | 297 | COUNT (ehci->stats.lost_iaa); |
291 | ehci_writel(ehci, STS_IAA, &ehci->regs->status); | 298 | ehci_writel(ehci, STS_IAA, &ehci->regs->status); |
292 | ehci->reclaim_ready = 1; | ||
293 | } | 299 | } |
300 | ehci_writel(ehci, cmd & ~CMD_IAAD, &ehci->regs->command); | ||
301 | end_unlink_async(ehci); | ||
294 | } | 302 | } |
295 | 303 | ||
296 | /* stop async processing after it's idled a bit */ | 304 | spin_unlock_irqrestore(&ehci->lock, flags); |
305 | } | ||
306 | |||
307 | static void ehci_watchdog(unsigned long param) | ||
308 | { | ||
309 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; | ||
310 | unsigned long flags; | ||
311 | |||
312 | spin_lock_irqsave(&ehci->lock, flags); | ||
313 | |||
314 | /* stop async processing after it's idled a bit */ | ||
297 | if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) | 315 | if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) |
298 | start_unlink_async (ehci, ehci->async); | 316 | start_unlink_async (ehci, ehci->async); |
299 | 317 | ||
@@ -363,8 +381,6 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | |||
363 | static void ehci_work (struct ehci_hcd *ehci) | 381 | static void ehci_work (struct ehci_hcd *ehci) |
364 | { | 382 | { |
365 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | 383 | timer_action_done (ehci, TIMER_IO_WATCHDOG); |
366 | if (ehci->reclaim_ready) | ||
367 | end_unlink_async (ehci); | ||
368 | 384 | ||
369 | /* another CPU may drop ehci->lock during a schedule scan while | 385 | /* another CPU may drop ehci->lock during a schedule scan while |
370 | * it reports urb completions. this flag guards against bogus | 386 | * it reports urb completions. this flag guards against bogus |
@@ -399,6 +415,7 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
399 | 415 | ||
400 | /* no more interrupts ... */ | 416 | /* no more interrupts ... */ |
401 | del_timer_sync (&ehci->watchdog); | 417 | del_timer_sync (&ehci->watchdog); |
418 | del_timer_sync(&ehci->iaa_watchdog); | ||
402 | 419 | ||
403 | spin_lock_irq(&ehci->lock); | 420 | spin_lock_irq(&ehci->lock); |
404 | if (HC_IS_RUNNING (hcd->state)) | 421 | if (HC_IS_RUNNING (hcd->state)) |
@@ -447,6 +464,10 @@ static int ehci_init(struct usb_hcd *hcd) | |||
447 | ehci->watchdog.function = ehci_watchdog; | 464 | ehci->watchdog.function = ehci_watchdog; |
448 | ehci->watchdog.data = (unsigned long) ehci; | 465 | ehci->watchdog.data = (unsigned long) ehci; |
449 | 466 | ||
467 | init_timer(&ehci->iaa_watchdog); | ||
468 | ehci->iaa_watchdog.function = ehci_iaa_watchdog; | ||
469 | ehci->iaa_watchdog.data = (unsigned long) ehci; | ||
470 | |||
450 | /* | 471 | /* |
451 | * hw default: 1K periodic list heads, one per frame. | 472 | * hw default: 1K periodic list heads, one per frame. |
452 | * periodic_size can shrink by USBCMD update if hcc_params allows. | 473 | * periodic_size can shrink by USBCMD update if hcc_params allows. |
@@ -463,7 +484,6 @@ static int ehci_init(struct usb_hcd *hcd) | |||
463 | ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); | 484 | ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); |
464 | 485 | ||
465 | ehci->reclaim = NULL; | 486 | ehci->reclaim = NULL; |
466 | ehci->reclaim_ready = 0; | ||
467 | ehci->next_uframe = -1; | 487 | ehci->next_uframe = -1; |
468 | 488 | ||
469 | /* | 489 | /* |
@@ -654,8 +674,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
654 | /* complete the unlinking of some qh [4.15.2.3] */ | 674 | /* complete the unlinking of some qh [4.15.2.3] */ |
655 | if (status & STS_IAA) { | 675 | if (status & STS_IAA) { |
656 | COUNT (ehci->stats.reclaim); | 676 | COUNT (ehci->stats.reclaim); |
657 | ehci->reclaim_ready = 1; | 677 | end_unlink_async(ehci); |
658 | bh = 1; | ||
659 | } | 678 | } |
660 | 679 | ||
661 | /* remote wakeup [4.3.1] */ | 680 | /* remote wakeup [4.3.1] */ |
@@ -761,10 +780,16 @@ static int ehci_urb_enqueue ( | |||
761 | 780 | ||
762 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 781 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
763 | { | 782 | { |
764 | /* if we need to use IAA and it's busy, defer */ | 783 | /* failfast */ |
765 | if (qh->qh_state == QH_STATE_LINKED | 784 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) |
766 | && ehci->reclaim | 785 | end_unlink_async(ehci); |
767 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) { | 786 | |
787 | /* if it's not linked then there's nothing to do */ | ||
788 | if (qh->qh_state != QH_STATE_LINKED) | ||
789 | ; | ||
790 | |||
791 | /* defer till later if busy */ | ||
792 | else if (ehci->reclaim) { | ||
768 | struct ehci_qh *last; | 793 | struct ehci_qh *last; |
769 | 794 | ||
770 | for (last = ehci->reclaim; | 795 | for (last = ehci->reclaim; |
@@ -774,12 +799,8 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
774 | qh->qh_state = QH_STATE_UNLINK_WAIT; | 799 | qh->qh_state = QH_STATE_UNLINK_WAIT; |
775 | last->reclaim = qh; | 800 | last->reclaim = qh; |
776 | 801 | ||
777 | /* bypass IAA if the hc can't care */ | 802 | /* start IAA cycle */ |
778 | } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim) | 803 | } else |
779 | end_unlink_async (ehci); | ||
780 | |||
781 | /* something else might have unlinked the qh by now */ | ||
782 | if (qh->qh_state == QH_STATE_LINKED) | ||
783 | start_unlink_async (ehci, qh); | 804 | start_unlink_async (ehci, qh); |
784 | } | 805 | } |
785 | 806 | ||
@@ -806,7 +827,19 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
806 | qh = (struct ehci_qh *) urb->hcpriv; | 827 | qh = (struct ehci_qh *) urb->hcpriv; |
807 | if (!qh) | 828 | if (!qh) |
808 | break; | 829 | break; |
809 | unlink_async (ehci, qh); | 830 | switch (qh->qh_state) { |
831 | case QH_STATE_LINKED: | ||
832 | case QH_STATE_COMPLETING: | ||
833 | unlink_async(ehci, qh); | ||
834 | break; | ||
835 | case QH_STATE_UNLINK: | ||
836 | case QH_STATE_UNLINK_WAIT: | ||
837 | /* already started */ | ||
838 | break; | ||
839 | case QH_STATE_IDLE: | ||
840 | WARN_ON(1); | ||
841 | break; | ||
842 | } | ||
810 | break; | 843 | break; |
811 | 844 | ||
812 | case PIPE_INTERRUPT: | 845 | case PIPE_INTERRUPT: |
@@ -829,16 +862,16 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
829 | /* reschedule QH iff another request is queued */ | 862 | /* reschedule QH iff another request is queued */ |
830 | if (!list_empty (&qh->qtd_list) | 863 | if (!list_empty (&qh->qtd_list) |
831 | && HC_IS_RUNNING (hcd->state)) { | 864 | && HC_IS_RUNNING (hcd->state)) { |
832 | int status; | 865 | int schedule_status; |
833 | 866 | ||
834 | status = qh_schedule (ehci, qh); | 867 | schedule_status = qh_schedule (ehci, qh); |
835 | spin_unlock_irqrestore (&ehci->lock, flags); | 868 | spin_unlock_irqrestore (&ehci->lock, flags); |
836 | 869 | ||
837 | if (status != 0) { | 870 | if (schedule_status != 0) { |
838 | // shouldn't happen often, but ... | 871 | // shouldn't happen often, but ... |
839 | // FIXME kill those tds' urbs | 872 | // FIXME kill those tds' urbs |
840 | err ("can't reschedule qh %p, err %d", | 873 | err ("can't reschedule qh %p, err %d", |
841 | qh, status); | 874 | qh, schedule_status); |
842 | } | 875 | } |
843 | return status; | 876 | return status; |
844 | } | 877 | } |
@@ -898,6 +931,7 @@ rescan: | |||
898 | unlink_async (ehci, qh); | 931 | unlink_async (ehci, qh); |
899 | /* FALL THROUGH */ | 932 | /* FALL THROUGH */ |
900 | case QH_STATE_UNLINK: /* wait for hw to finish? */ | 933 | case QH_STATE_UNLINK: /* wait for hw to finish? */ |
934 | case QH_STATE_UNLINK_WAIT: | ||
901 | idle_timeout: | 935 | idle_timeout: |
902 | spin_unlock_irqrestore (&ehci->lock, flags); | 936 | spin_unlock_irqrestore (&ehci->lock, flags); |
903 | schedule_timeout_uninterruptible(1); | 937 | schedule_timeout_uninterruptible(1); |
@@ -959,11 +993,26 @@ MODULE_LICENSE ("GPL"); | |||
959 | #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver | 993 | #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver |
960 | #endif | 994 | #endif |
961 | 995 | ||
962 | #ifdef CONFIG_440EPX | 996 | #if defined(CONFIG_440EPX) && !defined(CONFIG_PPC_MERGE) |
963 | #include "ehci-ppc-soc.c" | 997 | #include "ehci-ppc-soc.c" |
964 | #define PLATFORM_DRIVER ehci_ppc_soc_driver | 998 | #define PLATFORM_DRIVER ehci_ppc_soc_driver |
965 | #endif | 999 | #endif |
966 | 1000 | ||
1001 | #ifdef CONFIG_USB_EHCI_HCD_PPC_OF | ||
1002 | #include "ehci-ppc-of.c" | ||
1003 | #define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver | ||
1004 | #endif | ||
1005 | |||
1006 | #ifdef CONFIG_ARCH_ORION | ||
1007 | #include "ehci-orion.c" | ||
1008 | #define PLATFORM_DRIVER ehci_orion_driver | ||
1009 | #endif | ||
1010 | |||
1011 | #ifdef CONFIG_ARCH_IXP4XX | ||
1012 | #include "ehci-ixp4xx.c" | ||
1013 | #define PLATFORM_DRIVER ixp4xx_ehci_driver | ||
1014 | #endif | ||
1015 | |||
967 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | 1016 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ |
968 | !defined(PS3_SYSTEM_BUS_DRIVER) | 1017 | !defined(PS3_SYSTEM_BUS_DRIVER) |
969 | #error "missing bus glue for ehci-hcd" | 1018 | #error "missing bus glue for ehci-hcd" |
@@ -978,41 +1027,66 @@ static int __init ehci_hcd_init(void) | |||
978 | sizeof(struct ehci_qh), sizeof(struct ehci_qtd), | 1027 | sizeof(struct ehci_qh), sizeof(struct ehci_qtd), |
979 | sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); | 1028 | sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); |
980 | 1029 | ||
1030 | #ifdef DEBUG | ||
1031 | ehci_debug_root = debugfs_create_dir("ehci", NULL); | ||
1032 | if (!ehci_debug_root) | ||
1033 | return -ENOENT; | ||
1034 | #endif | ||
1035 | |||
981 | #ifdef PLATFORM_DRIVER | 1036 | #ifdef PLATFORM_DRIVER |
982 | retval = platform_driver_register(&PLATFORM_DRIVER); | 1037 | retval = platform_driver_register(&PLATFORM_DRIVER); |
983 | if (retval < 0) | 1038 | if (retval < 0) |
984 | return retval; | 1039 | goto clean0; |
985 | #endif | 1040 | #endif |
986 | 1041 | ||
987 | #ifdef PCI_DRIVER | 1042 | #ifdef PCI_DRIVER |
988 | retval = pci_register_driver(&PCI_DRIVER); | 1043 | retval = pci_register_driver(&PCI_DRIVER); |
989 | if (retval < 0) { | 1044 | if (retval < 0) |
990 | #ifdef PLATFORM_DRIVER | 1045 | goto clean1; |
991 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
992 | #endif | ||
993 | return retval; | ||
994 | } | ||
995 | #endif | 1046 | #endif |
996 | 1047 | ||
997 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1048 | #ifdef PS3_SYSTEM_BUS_DRIVER |
998 | retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER); | 1049 | retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER); |
999 | if (retval < 0) { | 1050 | if (retval < 0) |
1000 | #ifdef PLATFORM_DRIVER | 1051 | goto clean2; |
1001 | platform_driver_unregister(&PLATFORM_DRIVER); | 1052 | #endif |
1053 | |||
1054 | #ifdef OF_PLATFORM_DRIVER | ||
1055 | retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); | ||
1056 | if (retval < 0) | ||
1057 | goto clean3; | ||
1058 | #endif | ||
1059 | return retval; | ||
1060 | |||
1061 | #ifdef OF_PLATFORM_DRIVER | ||
1062 | /* of_unregister_platform_driver(&OF_PLATFORM_DRIVER); */ | ||
1063 | clean3: | ||
1064 | #endif | ||
1065 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
1066 | ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
1067 | clean2: | ||
1002 | #endif | 1068 | #endif |
1003 | #ifdef PCI_DRIVER | 1069 | #ifdef PCI_DRIVER |
1004 | pci_unregister_driver(&PCI_DRIVER); | 1070 | pci_unregister_driver(&PCI_DRIVER); |
1071 | clean1: | ||
1005 | #endif | 1072 | #endif |
1006 | return retval; | 1073 | #ifdef PLATFORM_DRIVER |
1007 | } | 1074 | platform_driver_unregister(&PLATFORM_DRIVER); |
1075 | clean0: | ||
1076 | #endif | ||
1077 | #ifdef DEBUG | ||
1078 | debugfs_remove(ehci_debug_root); | ||
1079 | ehci_debug_root = NULL; | ||
1008 | #endif | 1080 | #endif |
1009 | |||
1010 | return retval; | 1081 | return retval; |
1011 | } | 1082 | } |
1012 | module_init(ehci_hcd_init); | 1083 | module_init(ehci_hcd_init); |
1013 | 1084 | ||
1014 | static void __exit ehci_hcd_cleanup(void) | 1085 | static void __exit ehci_hcd_cleanup(void) |
1015 | { | 1086 | { |
1087 | #ifdef OF_PLATFORM_DRIVER | ||
1088 | of_unregister_platform_driver(&OF_PLATFORM_DRIVER); | ||
1089 | #endif | ||
1016 | #ifdef PLATFORM_DRIVER | 1090 | #ifdef PLATFORM_DRIVER |
1017 | platform_driver_unregister(&PLATFORM_DRIVER); | 1091 | platform_driver_unregister(&PLATFORM_DRIVER); |
1018 | #endif | 1092 | #endif |
@@ -1022,6 +1096,9 @@ static void __exit ehci_hcd_cleanup(void) | |||
1022 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1096 | #ifdef PS3_SYSTEM_BUS_DRIVER |
1023 | ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | 1097 | ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); |
1024 | #endif | 1098 | #endif |
1099 | #ifdef DEBUG | ||
1100 | debugfs_remove(ehci_debug_root); | ||
1101 | #endif | ||
1025 | } | 1102 | } |
1026 | module_exit(ehci_hcd_cleanup); | 1103 | module_exit(ehci_hcd_cleanup); |
1027 | 1104 | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 735db4aec831..40e8240b7851 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -123,6 +123,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
123 | 123 | ||
124 | if (time_before (jiffies, ehci->next_statechange)) | 124 | if (time_before (jiffies, ehci->next_statechange)) |
125 | msleep(5); | 125 | msleep(5); |
126 | del_timer_sync(&ehci->watchdog); | ||
127 | del_timer_sync(&ehci->iaa_watchdog); | ||
126 | 128 | ||
127 | port = HCS_N_PORTS (ehci->hcs_params); | 129 | port = HCS_N_PORTS (ehci->hcs_params); |
128 | spin_lock_irq (&ehci->lock); | 130 | spin_lock_irq (&ehci->lock); |
@@ -134,7 +136,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
134 | } | 136 | } |
135 | ehci->command = ehci_readl(ehci, &ehci->regs->command); | 137 | ehci->command = ehci_readl(ehci, &ehci->regs->command); |
136 | if (ehci->reclaim) | 138 | if (ehci->reclaim) |
137 | ehci->reclaim_ready = 1; | 139 | end_unlink_async(ehci); |
138 | ehci_work(ehci); | 140 | ehci_work(ehci); |
139 | 141 | ||
140 | /* Unlike other USB host controller types, EHCI doesn't have | 142 | /* Unlike other USB host controller types, EHCI doesn't have |
@@ -170,8 +172,11 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
170 | } | 172 | } |
171 | } | 173 | } |
172 | 174 | ||
175 | /* Apparently some devices need a >= 1-uframe delay here */ | ||
176 | if (ehci->bus_suspended) | ||
177 | udelay(150); | ||
178 | |||
173 | /* turn off now-idle HC */ | 179 | /* turn off now-idle HC */ |
174 | del_timer_sync (&ehci->watchdog); | ||
175 | ehci_halt (ehci); | 180 | ehci_halt (ehci); |
176 | hcd->state = HC_STATE_SUSPENDED; | 181 | hcd->state = HC_STATE_SUSPENDED; |
177 | 182 | ||
@@ -291,14 +296,16 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
291 | /*-------------------------------------------------------------------------*/ | 296 | /*-------------------------------------------------------------------------*/ |
292 | 297 | ||
293 | /* Display the ports dedicated to the companion controller */ | 298 | /* Display the ports dedicated to the companion controller */ |
294 | static ssize_t show_companion(struct class_device *class_dev, char *buf) | 299 | static ssize_t show_companion(struct device *dev, |
300 | struct device_attribute *attr, | ||
301 | char *buf) | ||
295 | { | 302 | { |
296 | struct ehci_hcd *ehci; | 303 | struct ehci_hcd *ehci; |
297 | int nports, index, n; | 304 | int nports, index, n; |
298 | int count = PAGE_SIZE; | 305 | int count = PAGE_SIZE; |
299 | char *ptr = buf; | 306 | char *ptr = buf; |
300 | 307 | ||
301 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | 308 | ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev))); |
302 | nports = HCS_N_PORTS(ehci->hcs_params); | 309 | nports = HCS_N_PORTS(ehci->hcs_params); |
303 | 310 | ||
304 | for (index = 0; index < nports; ++index) { | 311 | for (index = 0; index < nports; ++index) { |
@@ -312,40 +319,21 @@ static ssize_t show_companion(struct class_device *class_dev, char *buf) | |||
312 | } | 319 | } |
313 | 320 | ||
314 | /* | 321 | /* |
315 | * Dedicate or undedicate a port to the companion controller. | 322 | * Sets the owner of a port |
316 | * Syntax is "[-]portnum", where a leading '-' sign means | ||
317 | * return control of the port to the EHCI controller. | ||
318 | */ | 323 | */ |
319 | static ssize_t store_companion(struct class_device *class_dev, | 324 | static void set_owner(struct ehci_hcd *ehci, int portnum, int new_owner) |
320 | const char *buf, size_t count) | ||
321 | { | 325 | { |
322 | struct ehci_hcd *ehci; | ||
323 | int portnum, new_owner, try; | ||
324 | u32 __iomem *status_reg; | 326 | u32 __iomem *status_reg; |
325 | u32 port_status; | 327 | u32 port_status; |
328 | int try; | ||
326 | 329 | ||
327 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | 330 | status_reg = &ehci->regs->port_status[portnum]; |
328 | new_owner = PORT_OWNER; /* Owned by companion */ | ||
329 | if (sscanf(buf, "%d", &portnum) != 1) | ||
330 | return -EINVAL; | ||
331 | if (portnum < 0) { | ||
332 | portnum = - portnum; | ||
333 | new_owner = 0; /* Owned by EHCI */ | ||
334 | } | ||
335 | if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params)) | ||
336 | return -ENOENT; | ||
337 | status_reg = &ehci->regs->port_status[--portnum]; | ||
338 | if (new_owner) | ||
339 | set_bit(portnum, &ehci->companion_ports); | ||
340 | else | ||
341 | clear_bit(portnum, &ehci->companion_ports); | ||
342 | 331 | ||
343 | /* | 332 | /* |
344 | * The controller won't set the OWNER bit if the port is | 333 | * The controller won't set the OWNER bit if the port is |
345 | * enabled, so this loop will sometimes require at least two | 334 | * enabled, so this loop will sometimes require at least two |
346 | * iterations: one to disable the port and one to set OWNER. | 335 | * iterations: one to disable the port and one to set OWNER. |
347 | */ | 336 | */ |
348 | |||
349 | for (try = 4; try > 0; --try) { | 337 | for (try = 4; try > 0; --try) { |
350 | spin_lock_irq(&ehci->lock); | 338 | spin_lock_irq(&ehci->lock); |
351 | port_status = ehci_readl(ehci, status_reg); | 339 | port_status = ehci_readl(ehci, status_reg); |
@@ -362,9 +350,39 @@ static ssize_t store_companion(struct class_device *class_dev, | |||
362 | if (try > 1) | 350 | if (try > 1) |
363 | msleep(5); | 351 | msleep(5); |
364 | } | 352 | } |
353 | } | ||
354 | |||
355 | /* | ||
356 | * Dedicate or undedicate a port to the companion controller. | ||
357 | * Syntax is "[-]portnum", where a leading '-' sign means | ||
358 | * return control of the port to the EHCI controller. | ||
359 | */ | ||
360 | static ssize_t store_companion(struct device *dev, | ||
361 | struct device_attribute *attr, | ||
362 | const char *buf, size_t count) | ||
363 | { | ||
364 | struct ehci_hcd *ehci; | ||
365 | int portnum, new_owner; | ||
366 | |||
367 | ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev))); | ||
368 | new_owner = PORT_OWNER; /* Owned by companion */ | ||
369 | if (sscanf(buf, "%d", &portnum) != 1) | ||
370 | return -EINVAL; | ||
371 | if (portnum < 0) { | ||
372 | portnum = - portnum; | ||
373 | new_owner = 0; /* Owned by EHCI */ | ||
374 | } | ||
375 | if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params)) | ||
376 | return -ENOENT; | ||
377 | portnum--; | ||
378 | if (new_owner) | ||
379 | set_bit(portnum, &ehci->companion_ports); | ||
380 | else | ||
381 | clear_bit(portnum, &ehci->companion_ports); | ||
382 | set_owner(ehci, portnum, new_owner); | ||
365 | return count; | 383 | return count; |
366 | } | 384 | } |
367 | static CLASS_DEVICE_ATTR(companion, 0644, show_companion, store_companion); | 385 | static DEVICE_ATTR(companion, 0644, show_companion, store_companion); |
368 | 386 | ||
369 | static inline void create_companion_file(struct ehci_hcd *ehci) | 387 | static inline void create_companion_file(struct ehci_hcd *ehci) |
370 | { | 388 | { |
@@ -372,16 +390,16 @@ static inline void create_companion_file(struct ehci_hcd *ehci) | |||
372 | 390 | ||
373 | /* with integrated TT there is no companion! */ | 391 | /* with integrated TT there is no companion! */ |
374 | if (!ehci_is_TDI(ehci)) | 392 | if (!ehci_is_TDI(ehci)) |
375 | i = class_device_create_file(ehci_to_hcd(ehci)->self.class_dev, | 393 | i = device_create_file(ehci_to_hcd(ehci)->self.dev, |
376 | &class_device_attr_companion); | 394 | &dev_attr_companion); |
377 | } | 395 | } |
378 | 396 | ||
379 | static inline void remove_companion_file(struct ehci_hcd *ehci) | 397 | static inline void remove_companion_file(struct ehci_hcd *ehci) |
380 | { | 398 | { |
381 | /* with integrated TT there is no companion! */ | 399 | /* with integrated TT there is no companion! */ |
382 | if (!ehci_is_TDI(ehci)) | 400 | if (!ehci_is_TDI(ehci)) |
383 | class_device_remove_file(ehci_to_hcd(ehci)->self.class_dev, | 401 | device_remove_file(ehci_to_hcd(ehci)->self.dev, |
384 | &class_device_attr_companion); | 402 | &dev_attr_companion); |
385 | } | 403 | } |
386 | 404 | ||
387 | 405 | ||
@@ -393,10 +411,8 @@ static int check_reset_complete ( | |||
393 | u32 __iomem *status_reg, | 411 | u32 __iomem *status_reg, |
394 | int port_status | 412 | int port_status |
395 | ) { | 413 | ) { |
396 | if (!(port_status & PORT_CONNECT)) { | 414 | if (!(port_status & PORT_CONNECT)) |
397 | ehci->reset_done [index] = 0; | ||
398 | return port_status; | 415 | return port_status; |
399 | } | ||
400 | 416 | ||
401 | /* if reset finished and it's still not enabled -- handoff */ | 417 | /* if reset finished and it's still not enabled -- handoff */ |
402 | if (!(port_status & PORT_PE)) { | 418 | if (!(port_status & PORT_PE)) { |
@@ -475,8 +491,6 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
475 | * controller by the user. | 491 | * controller by the user. |
476 | */ | 492 | */ |
477 | 493 | ||
478 | if (!(temp & PORT_CONNECT)) | ||
479 | ehci->reset_done [i] = 0; | ||
480 | if ((temp & mask) != 0 | 494 | if ((temp & mask) != 0 |
481 | || ((temp & PORT_RESUME) != 0 | 495 | || ((temp & PORT_RESUME) != 0 |
482 | && time_after_eq(jiffies, | 496 | && time_after_eq(jiffies, |
@@ -864,3 +878,13 @@ error: | |||
864 | spin_unlock_irqrestore (&ehci->lock, flags); | 878 | spin_unlock_irqrestore (&ehci->lock, flags); |
865 | return retval; | 879 | return retval; |
866 | } | 880 | } |
881 | |||
882 | static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum) | ||
883 | { | ||
884 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
885 | |||
886 | if (ehci_is_TDI(ehci)) | ||
887 | return; | ||
888 | set_owner(ehci, --portnum, PORT_OWNER); | ||
889 | } | ||
890 | |||
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c new file mode 100644 index 000000000000..3041d8f055f4 --- /dev/null +++ b/drivers/usb/host/ehci-ixp4xx.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * IXP4XX EHCI Host Controller Driver | ||
3 | * | ||
4 | * Author: Vladimir Barinov <vbarinov@ru.mvista.com> | ||
5 | * | ||
6 | * Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com> | ||
7 | * | ||
8 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | static int ixp4xx_ehci_init(struct usb_hcd *hcd) | ||
17 | { | ||
18 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
19 | int retval = 0; | ||
20 | |||
21 | ehci->big_endian_desc = 1; | ||
22 | ehci->big_endian_mmio = 1; | ||
23 | |||
24 | ehci->caps = hcd->regs + 0x100; | ||
25 | ehci->regs = hcd->regs + 0x100 | ||
26 | + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
27 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
28 | |||
29 | ehci->is_tdi_rh_tt = 1; | ||
30 | ehci_reset(ehci); | ||
31 | |||
32 | retval = ehci_init(hcd); | ||
33 | if (retval) | ||
34 | return retval; | ||
35 | |||
36 | ehci_port_power(ehci, 0); | ||
37 | |||
38 | return retval; | ||
39 | } | ||
40 | |||
41 | static const struct hc_driver ixp4xx_ehci_hc_driver = { | ||
42 | .description = hcd_name, | ||
43 | .product_desc = "IXP4XX EHCI Host Controller", | ||
44 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
45 | .irq = ehci_irq, | ||
46 | .flags = HCD_MEMORY | HCD_USB2, | ||
47 | .reset = ixp4xx_ehci_init, | ||
48 | .start = ehci_run, | ||
49 | .stop = ehci_stop, | ||
50 | .shutdown = ehci_shutdown, | ||
51 | .urb_enqueue = ehci_urb_enqueue, | ||
52 | .urb_dequeue = ehci_urb_dequeue, | ||
53 | .endpoint_disable = ehci_endpoint_disable, | ||
54 | .get_frame_number = ehci_get_frame, | ||
55 | .hub_status_data = ehci_hub_status_data, | ||
56 | .hub_control = ehci_hub_control, | ||
57 | #if defined(CONFIG_PM) | ||
58 | .bus_suspend = ehci_bus_suspend, | ||
59 | .bus_resume = ehci_bus_resume, | ||
60 | #endif | ||
61 | }; | ||
62 | |||
63 | static int ixp4xx_ehci_probe(struct platform_device *pdev) | ||
64 | { | ||
65 | struct usb_hcd *hcd; | ||
66 | const struct hc_driver *driver = &ixp4xx_ehci_hc_driver; | ||
67 | struct resource *res; | ||
68 | int irq; | ||
69 | int retval; | ||
70 | |||
71 | if (usb_disabled()) | ||
72 | return -ENODEV; | ||
73 | |||
74 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
75 | if (!res) { | ||
76 | dev_err(&pdev->dev, | ||
77 | "Found HC with no IRQ. Check %s setup!\n", | ||
78 | pdev->dev.bus_id); | ||
79 | return -ENODEV; | ||
80 | } | ||
81 | irq = res->start; | ||
82 | |||
83 | hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); | ||
84 | if (!hcd) { | ||
85 | retval = -ENOMEM; | ||
86 | goto fail_create_hcd; | ||
87 | } | ||
88 | |||
89 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
90 | if (!res) { | ||
91 | dev_err(&pdev->dev, | ||
92 | "Found HC with no register addr. Check %s setup!\n", | ||
93 | pdev->dev.bus_id); | ||
94 | retval = -ENODEV; | ||
95 | goto fail_request_resource; | ||
96 | } | ||
97 | hcd->rsrc_start = res->start; | ||
98 | hcd->rsrc_len = res->end - res->start + 1; | ||
99 | |||
100 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
101 | driver->description)) { | ||
102 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
103 | retval = -EBUSY; | ||
104 | goto fail_request_resource; | ||
105 | } | ||
106 | |||
107 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
108 | if (hcd->regs == NULL) { | ||
109 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
110 | retval = -EFAULT; | ||
111 | goto fail_ioremap; | ||
112 | } | ||
113 | |||
114 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
115 | if (retval) | ||
116 | goto fail_add_hcd; | ||
117 | |||
118 | return retval; | ||
119 | |||
120 | fail_add_hcd: | ||
121 | iounmap(hcd->regs); | ||
122 | fail_ioremap: | ||
123 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
124 | fail_request_resource: | ||
125 | usb_put_hcd(hcd); | ||
126 | fail_create_hcd: | ||
127 | dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval); | ||
128 | return retval; | ||
129 | } | ||
130 | |||
131 | static int ixp4xx_ehci_remove(struct platform_device *pdev) | ||
132 | { | ||
133 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
134 | |||
135 | usb_remove_hcd(hcd); | ||
136 | iounmap(hcd->regs); | ||
137 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
138 | usb_put_hcd(hcd); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | MODULE_ALIAS("ixp4xx-ehci"); | ||
144 | |||
145 | static struct platform_driver ixp4xx_ehci_driver = { | ||
146 | .probe = ixp4xx_ehci_probe, | ||
147 | .remove = ixp4xx_ehci_remove, | ||
148 | .driver = { | ||
149 | .name = "ixp4xx-ehci", | ||
150 | .bus = &platform_bus_type | ||
151 | }, | ||
152 | }; | ||
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c new file mode 100644 index 000000000000..e129981f139f --- /dev/null +++ b/drivers/usb/host/ehci-orion.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * drivers/usb/host/ehci-orion.c | ||
3 | * | ||
4 | * Tzachi Perelstein <tzachi@marvell.com> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <asm/arch/orion.h> | ||
15 | |||
16 | #define rdl(off) __raw_readl(hcd->regs + (off)) | ||
17 | #define wrl(off, val) __raw_writel((val), hcd->regs + (off)) | ||
18 | |||
19 | #define USB_CAUSE 0x310 | ||
20 | #define USB_MASK 0x314 | ||
21 | #define USB_CMD 0x140 | ||
22 | #define USB_MODE 0x1a8 | ||
23 | #define USB_IPG 0x360 | ||
24 | #define USB_PHY_PWR_CTRL 0x400 | ||
25 | #define USB_PHY_TX_CTRL 0x420 | ||
26 | #define USB_PHY_RX_CTRL 0x430 | ||
27 | #define USB_PHY_IVREF_CTRL 0x440 | ||
28 | #define USB_PHY_TST_GRP_CTRL 0x450 | ||
29 | |||
30 | /* | ||
31 | * Implement Orion USB controller specification guidelines | ||
32 | */ | ||
33 | static void orion_usb_setup(struct usb_hcd *hcd) | ||
34 | { | ||
35 | /* | ||
36 | * Clear interrupt cause and mask | ||
37 | */ | ||
38 | wrl(USB_CAUSE, 0); | ||
39 | wrl(USB_MASK, 0); | ||
40 | |||
41 | /* | ||
42 | * Reset controller | ||
43 | */ | ||
44 | wrl(USB_CMD, rdl(USB_CMD) | 0x2); | ||
45 | while (rdl(USB_CMD) & 0x2); | ||
46 | |||
47 | /* | ||
48 | * GL# USB-10: Set IPG for non start of frame packets | ||
49 | * Bits[14:8]=0xc | ||
50 | */ | ||
51 | wrl(USB_IPG, (rdl(USB_IPG) & ~0x7f00) | 0xc00); | ||
52 | |||
53 | /* | ||
54 | * GL# USB-9: USB 2.0 Power Control | ||
55 | * BG_VSEL[7:6]=0x1 | ||
56 | */ | ||
57 | wrl(USB_PHY_PWR_CTRL, (rdl(USB_PHY_PWR_CTRL) & ~0xc0)| 0x40); | ||
58 | |||
59 | /* | ||
60 | * GL# USB-1: USB PHY Tx Control - force calibration to '8' | ||
61 | * TXDATA_BLOCK_EN[21]=0x1, EXT_RCAL_EN[13]=0x1, IMP_CAL[6:3]=0x8 | ||
62 | */ | ||
63 | wrl(USB_PHY_TX_CTRL, (rdl(USB_PHY_TX_CTRL) & ~0x78) | 0x202040); | ||
64 | |||
65 | /* | ||
66 | * GL# USB-3 GL# USB-9: USB PHY Rx Control | ||
67 | * RXDATA_BLOCK_LENGHT[31:30]=0x3, EDGE_DET_SEL[27:26]=0, | ||
68 | * CDR_FASTLOCK_EN[21]=0, DISCON_THRESHOLD[9:8]=0, SQ_THRESH[7:4]=0x1 | ||
69 | */ | ||
70 | wrl(USB_PHY_RX_CTRL, (rdl(USB_PHY_RX_CTRL) & ~0xc2003f0) | 0xc0000010); | ||
71 | |||
72 | /* | ||
73 | * GL# USB-3 GL# USB-9: USB PHY IVREF Control | ||
74 | * PLLVDD12[1:0]=0x2, RXVDD[5:4]=0x3, Reserved[19]=0 | ||
75 | */ | ||
76 | wrl(USB_PHY_IVREF_CTRL, (rdl(USB_PHY_IVREF_CTRL) & ~0x80003 ) | 0x32); | ||
77 | |||
78 | /* | ||
79 | * GL# USB-3 GL# USB-9: USB PHY Test Group Control | ||
80 | * REG_FIFO_SQ_RST[15]=0 | ||
81 | */ | ||
82 | wrl(USB_PHY_TST_GRP_CTRL, rdl(USB_PHY_TST_GRP_CTRL) & ~0x8000); | ||
83 | |||
84 | /* | ||
85 | * Stop and reset controller | ||
86 | */ | ||
87 | wrl(USB_CMD, rdl(USB_CMD) & ~0x1); | ||
88 | wrl(USB_CMD, rdl(USB_CMD) | 0x2); | ||
89 | while (rdl(USB_CMD) & 0x2); | ||
90 | |||
91 | /* | ||
92 | * GL# USB-5 Streaming disable REG_USB_MODE[4]=1 | ||
93 | * TBD: This need to be done after each reset! | ||
94 | * GL# USB-4 Setup USB Host mode | ||
95 | */ | ||
96 | wrl(USB_MODE, 0x13); | ||
97 | } | ||
98 | |||
99 | static int ehci_orion_setup(struct usb_hcd *hcd) | ||
100 | { | ||
101 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
102 | int retval; | ||
103 | |||
104 | retval = ehci_halt(ehci); | ||
105 | if (retval) | ||
106 | return retval; | ||
107 | |||
108 | /* | ||
109 | * data structure init | ||
110 | */ | ||
111 | retval = ehci_init(hcd); | ||
112 | if (retval) | ||
113 | return retval; | ||
114 | |||
115 | ehci_reset(ehci); | ||
116 | ehci_port_power(ehci, 0); | ||
117 | |||
118 | return retval; | ||
119 | } | ||
120 | |||
121 | static const struct hc_driver ehci_orion_hc_driver = { | ||
122 | .description = hcd_name, | ||
123 | .product_desc = "Marvell Orion EHCI", | ||
124 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
125 | |||
126 | /* | ||
127 | * generic hardware linkage | ||
128 | */ | ||
129 | .irq = ehci_irq, | ||
130 | .flags = HCD_MEMORY | HCD_USB2, | ||
131 | |||
132 | /* | ||
133 | * basic lifecycle operations | ||
134 | */ | ||
135 | .reset = ehci_orion_setup, | ||
136 | .start = ehci_run, | ||
137 | #ifdef CONFIG_PM | ||
138 | .suspend = ehci_bus_suspend, | ||
139 | .resume = ehci_bus_resume, | ||
140 | #endif | ||
141 | .stop = ehci_stop, | ||
142 | .shutdown = ehci_shutdown, | ||
143 | |||
144 | /* | ||
145 | * managing i/o requests and associated device resources | ||
146 | */ | ||
147 | .urb_enqueue = ehci_urb_enqueue, | ||
148 | .urb_dequeue = ehci_urb_dequeue, | ||
149 | .endpoint_disable = ehci_endpoint_disable, | ||
150 | |||
151 | /* | ||
152 | * scheduling support | ||
153 | */ | ||
154 | .get_frame_number = ehci_get_frame, | ||
155 | |||
156 | /* | ||
157 | * root hub support | ||
158 | */ | ||
159 | .hub_status_data = ehci_hub_status_data, | ||
160 | .hub_control = ehci_hub_control, | ||
161 | .bus_suspend = ehci_bus_suspend, | ||
162 | .bus_resume = ehci_bus_resume, | ||
163 | }; | ||
164 | |||
165 | static int __init ehci_orion_drv_probe(struct platform_device *pdev) | ||
166 | { | ||
167 | struct resource *res; | ||
168 | struct usb_hcd *hcd; | ||
169 | struct ehci_hcd *ehci; | ||
170 | void __iomem *regs; | ||
171 | int irq, err; | ||
172 | |||
173 | if (usb_disabled()) | ||
174 | return -ENODEV; | ||
175 | |||
176 | pr_debug("Initializing Orion-SoC USB Host Controller\n"); | ||
177 | |||
178 | irq = platform_get_irq(pdev, 0); | ||
179 | if (irq <= 0) { | ||
180 | dev_err(&pdev->dev, | ||
181 | "Found HC with no IRQ. Check %s setup!\n", | ||
182 | pdev->dev.bus_id); | ||
183 | err = -ENODEV; | ||
184 | goto err1; | ||
185 | } | ||
186 | |||
187 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
188 | if (!res) { | ||
189 | dev_err(&pdev->dev, | ||
190 | "Found HC with no register addr. Check %s setup!\n", | ||
191 | pdev->dev.bus_id); | ||
192 | err = -ENODEV; | ||
193 | goto err1; | ||
194 | } | ||
195 | |||
196 | if (!request_mem_region(res->start, res->end - res->start + 1, | ||
197 | ehci_orion_hc_driver.description)) { | ||
198 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
199 | err = -EBUSY; | ||
200 | goto err1; | ||
201 | } | ||
202 | |||
203 | regs = ioremap(res->start, res->end - res->start + 1); | ||
204 | if (regs == NULL) { | ||
205 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
206 | err = -EFAULT; | ||
207 | goto err2; | ||
208 | } | ||
209 | |||
210 | hcd = usb_create_hcd(&ehci_orion_hc_driver, | ||
211 | &pdev->dev, pdev->dev.bus_id); | ||
212 | if (!hcd) { | ||
213 | err = -ENOMEM; | ||
214 | goto err3; | ||
215 | } | ||
216 | |||
217 | hcd->rsrc_start = res->start; | ||
218 | hcd->rsrc_len = res->end - res->start + 1; | ||
219 | hcd->regs = regs; | ||
220 | |||
221 | ehci = hcd_to_ehci(hcd); | ||
222 | ehci->caps = hcd->regs + 0x100; | ||
223 | ehci->regs = hcd->regs + 0x100 + | ||
224 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
225 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
226 | ehci->is_tdi_rh_tt = 1; | ||
227 | ehci->sbrn = 0x20; | ||
228 | |||
229 | /* | ||
230 | * setup Orion USB controller | ||
231 | */ | ||
232 | orion_usb_setup(hcd); | ||
233 | |||
234 | err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED); | ||
235 | if (err) | ||
236 | goto err4; | ||
237 | |||
238 | return 0; | ||
239 | |||
240 | err4: | ||
241 | usb_put_hcd(hcd); | ||
242 | err3: | ||
243 | iounmap(regs); | ||
244 | err2: | ||
245 | release_mem_region(res->start, res->end - res->start + 1); | ||
246 | err1: | ||
247 | dev_err(&pdev->dev, "init %s fail, %d\n", | ||
248 | pdev->dev.bus_id, err); | ||
249 | |||
250 | return err; | ||
251 | } | ||
252 | |||
253 | static int __exit ehci_orion_drv_remove(struct platform_device *pdev) | ||
254 | { | ||
255 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
256 | |||
257 | usb_remove_hcd(hcd); | ||
258 | iounmap(hcd->regs); | ||
259 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
260 | usb_put_hcd(hcd); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | MODULE_ALIAS("platform:orion-ehci"); | ||
266 | |||
267 | static struct platform_driver ehci_orion_driver = { | ||
268 | .probe = ehci_orion_drv_probe, | ||
269 | .remove = __exit_p(ehci_orion_drv_remove), | ||
270 | .shutdown = usb_hcd_platform_shutdown, | ||
271 | .driver.name = "orion-ehci", | ||
272 | }; | ||
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index ad0d4965f2fb..3ba01664f821 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -305,7 +305,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
305 | /* emptying the schedule aborts any urbs */ | 305 | /* emptying the schedule aborts any urbs */ |
306 | spin_lock_irq(&ehci->lock); | 306 | spin_lock_irq(&ehci->lock); |
307 | if (ehci->reclaim) | 307 | if (ehci->reclaim) |
308 | ehci->reclaim_ready = 1; | 308 | end_unlink_async(ehci); |
309 | ehci_work(ehci); | 309 | ehci_work(ehci); |
310 | spin_unlock_irq(&ehci->lock); | 310 | spin_unlock_irq(&ehci->lock); |
311 | 311 | ||
@@ -364,6 +364,7 @@ static const struct hc_driver ehci_pci_hc_driver = { | |||
364 | .hub_control = ehci_hub_control, | 364 | .hub_control = ehci_hub_control, |
365 | .bus_suspend = ehci_bus_suspend, | 365 | .bus_suspend = ehci_bus_suspend, |
366 | .bus_resume = ehci_bus_resume, | 366 | .bus_resume = ehci_bus_resume, |
367 | .relinquish_port = ehci_relinquish_port, | ||
367 | }; | 368 | }; |
368 | 369 | ||
369 | /*-------------------------------------------------------------------------*/ | 370 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c new file mode 100644 index 000000000000..ee305b1f99ff --- /dev/null +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * EHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * Bus Glue for PPC On-Chip EHCI driver on the of_platform bus | ||
5 | * Tested on AMCC PPC 440EPx | ||
6 | * | ||
7 | * Valentine Barshak <vbarshak@ru.mvista.com> | ||
8 | * | ||
9 | * Based on "ehci-ppc-soc.c" by Stefan Roese <sr@denx.de> | ||
10 | * and "ohci-ppc-of.c" by Sylvain Munaut <tnt@246tNt.com> | ||
11 | * | ||
12 | * This file is licenced under the GPL. | ||
13 | */ | ||
14 | |||
15 | #include <linux/signal.h> | ||
16 | |||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | |||
20 | /* called during probe() after chip reset completes */ | ||
21 | static int ehci_ppc_of_setup(struct usb_hcd *hcd) | ||
22 | { | ||
23 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
24 | int retval; | ||
25 | |||
26 | retval = ehci_halt(ehci); | ||
27 | if (retval) | ||
28 | return retval; | ||
29 | |||
30 | retval = ehci_init(hcd); | ||
31 | if (retval) | ||
32 | return retval; | ||
33 | |||
34 | ehci->sbrn = 0x20; | ||
35 | return ehci_reset(ehci); | ||
36 | } | ||
37 | |||
38 | |||
39 | static const struct hc_driver ehci_ppc_of_hc_driver = { | ||
40 | .description = hcd_name, | ||
41 | .product_desc = "OF EHCI", | ||
42 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
43 | |||
44 | /* | ||
45 | * generic hardware linkage | ||
46 | */ | ||
47 | .irq = ehci_irq, | ||
48 | .flags = HCD_MEMORY | HCD_USB2, | ||
49 | |||
50 | /* | ||
51 | * basic lifecycle operations | ||
52 | */ | ||
53 | .reset = ehci_ppc_of_setup, | ||
54 | .start = ehci_run, | ||
55 | .stop = ehci_stop, | ||
56 | .shutdown = ehci_shutdown, | ||
57 | |||
58 | /* | ||
59 | * managing i/o requests and associated device resources | ||
60 | */ | ||
61 | .urb_enqueue = ehci_urb_enqueue, | ||
62 | .urb_dequeue = ehci_urb_dequeue, | ||
63 | .endpoint_disable = ehci_endpoint_disable, | ||
64 | |||
65 | /* | ||
66 | * scheduling support | ||
67 | */ | ||
68 | .get_frame_number = ehci_get_frame, | ||
69 | |||
70 | /* | ||
71 | * root hub support | ||
72 | */ | ||
73 | .hub_status_data = ehci_hub_status_data, | ||
74 | .hub_control = ehci_hub_control, | ||
75 | #ifdef CONFIG_PM | ||
76 | .bus_suspend = ehci_bus_suspend, | ||
77 | .bus_resume = ehci_bus_resume, | ||
78 | #endif | ||
79 | }; | ||
80 | |||
81 | |||
82 | /* | ||
83 | * 440EPx Errata USBH_3 | ||
84 | * Fix: Enable Break Memory Transfer (BMT) in INSNREG3 | ||
85 | */ | ||
86 | #define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0) | ||
87 | static int __devinit | ||
88 | ppc44x_enable_bmt(struct device_node *dn) | ||
89 | { | ||
90 | __iomem u32 *insreg_virt; | ||
91 | |||
92 | insreg_virt = of_iomap(dn, 1); | ||
93 | if (!insreg_virt) | ||
94 | return -EINVAL; | ||
95 | |||
96 | out_be32(insreg_virt + 3, PPC440EPX_EHCI0_INSREG_BMT); | ||
97 | |||
98 | iounmap(insreg_virt); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | |||
103 | static int __devinit | ||
104 | ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | ||
105 | { | ||
106 | struct device_node *dn = op->node; | ||
107 | struct usb_hcd *hcd; | ||
108 | struct ehci_hcd *ehci; | ||
109 | struct resource res; | ||
110 | int irq; | ||
111 | int rv; | ||
112 | |||
113 | if (usb_disabled()) | ||
114 | return -ENODEV; | ||
115 | |||
116 | dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); | ||
117 | |||
118 | rv = of_address_to_resource(dn, 0, &res); | ||
119 | if (rv) | ||
120 | return rv; | ||
121 | |||
122 | hcd = usb_create_hcd(&ehci_ppc_of_hc_driver, &op->dev, "PPC-OF USB"); | ||
123 | if (!hcd) | ||
124 | return -ENOMEM; | ||
125 | |||
126 | hcd->rsrc_start = res.start; | ||
127 | hcd->rsrc_len = res.end - res.start + 1; | ||
128 | |||
129 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
130 | printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); | ||
131 | rv = -EBUSY; | ||
132 | goto err_rmr; | ||
133 | } | ||
134 | |||
135 | irq = irq_of_parse_and_map(dn, 0); | ||
136 | if (irq == NO_IRQ) { | ||
137 | printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); | ||
138 | rv = -EBUSY; | ||
139 | goto err_irq; | ||
140 | } | ||
141 | |||
142 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
143 | if (!hcd->regs) { | ||
144 | printk(KERN_ERR __FILE__ ": ioremap failed\n"); | ||
145 | rv = -ENOMEM; | ||
146 | goto err_ioremap; | ||
147 | } | ||
148 | |||
149 | ehci = hcd_to_ehci(hcd); | ||
150 | |||
151 | if (of_get_property(dn, "big-endian", NULL)) { | ||
152 | ehci->big_endian_mmio = 1; | ||
153 | ehci->big_endian_desc = 1; | ||
154 | } | ||
155 | if (of_get_property(dn, "big-endian-regs", NULL)) | ||
156 | ehci->big_endian_mmio = 1; | ||
157 | if (of_get_property(dn, "big-endian-desc", NULL)) | ||
158 | ehci->big_endian_desc = 1; | ||
159 | |||
160 | ehci->caps = hcd->regs; | ||
161 | ehci->regs = hcd->regs + | ||
162 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
163 | |||
164 | /* cache this readonly data; minimize chip reads */ | ||
165 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
166 | |||
167 | if (of_device_is_compatible(dn, "ibm,usb-ehci-440epx")) { | ||
168 | rv = ppc44x_enable_bmt(dn); | ||
169 | ehci_dbg(ehci, "Break Memory Transfer (BMT) is %senabled!\n", | ||
170 | rv ? "NOT ": ""); | ||
171 | } | ||
172 | |||
173 | rv = usb_add_hcd(hcd, irq, 0); | ||
174 | if (rv == 0) | ||
175 | return 0; | ||
176 | |||
177 | iounmap(hcd->regs); | ||
178 | err_ioremap: | ||
179 | irq_dispose_mapping(irq); | ||
180 | err_irq: | ||
181 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
182 | err_rmr: | ||
183 | usb_put_hcd(hcd); | ||
184 | |||
185 | return rv; | ||
186 | } | ||
187 | |||
188 | |||
189 | static int ehci_hcd_ppc_of_remove(struct of_device *op) | ||
190 | { | ||
191 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
192 | dev_set_drvdata(&op->dev, NULL); | ||
193 | |||
194 | dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n"); | ||
195 | |||
196 | usb_remove_hcd(hcd); | ||
197 | |||
198 | iounmap(hcd->regs); | ||
199 | irq_dispose_mapping(hcd->irq); | ||
200 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
201 | |||
202 | usb_put_hcd(hcd); | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | |||
208 | static int ehci_hcd_ppc_of_shutdown(struct of_device *op) | ||
209 | { | ||
210 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
211 | |||
212 | if (hcd->driver->shutdown) | ||
213 | hcd->driver->shutdown(hcd); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | |||
219 | static struct of_device_id ehci_hcd_ppc_of_match[] = { | ||
220 | { | ||
221 | .compatible = "usb-ehci", | ||
222 | }, | ||
223 | {}, | ||
224 | }; | ||
225 | MODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match); | ||
226 | |||
227 | |||
228 | static struct of_platform_driver ehci_hcd_ppc_of_driver = { | ||
229 | .name = "ppc-of-ehci", | ||
230 | .match_table = ehci_hcd_ppc_of_match, | ||
231 | .probe = ehci_hcd_ppc_of_probe, | ||
232 | .remove = ehci_hcd_ppc_of_remove, | ||
233 | .shutdown = ehci_hcd_ppc_of_shutdown, | ||
234 | .driver = { | ||
235 | .name = "ppc-of-ehci", | ||
236 | .owner = THIS_MODULE, | ||
237 | }, | ||
238 | }; | ||
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index 452d4b1bc859..a3249078c808 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c | |||
@@ -162,6 +162,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { | |||
162 | .hub_control = ehci_hub_control, | 162 | .hub_control = ehci_hub_control, |
163 | .bus_suspend = ehci_bus_suspend, | 163 | .bus_suspend = ehci_bus_suspend, |
164 | .bus_resume = ehci_bus_resume, | 164 | .bus_resume = ehci_bus_resume, |
165 | .relinquish_port = ehci_relinquish_port, | ||
165 | }; | 166 | }; |
166 | 167 | ||
167 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) | 168 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 03a6b2f4e6ed..bbda58eb8813 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -72,6 +72,7 @@ static const struct hc_driver ps3_ehci_hc_driver = { | |||
72 | .bus_suspend = ehci_bus_suspend, | 72 | .bus_suspend = ehci_bus_suspend, |
73 | .bus_resume = ehci_bus_resume, | 73 | .bus_resume = ehci_bus_resume, |
74 | #endif | 74 | #endif |
75 | .relinquish_port = ehci_relinquish_port, | ||
75 | }; | 76 | }; |
76 | 77 | ||
77 | static int ps3_ehci_probe(struct ps3_system_bus_device *dev) | 78 | static int ps3_ehci_probe(struct ps3_system_bus_device *dev) |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index b10f39c047e9..776a97f33914 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -198,7 +198,8 @@ static int qtd_copy_status ( | |||
198 | 198 | ||
199 | /* if async CSPLIT failed, try cleaning out the TT buffer */ | 199 | /* if async CSPLIT failed, try cleaning out the TT buffer */ |
200 | if (status != -EPIPE | 200 | if (status != -EPIPE |
201 | && urb->dev->tt && !usb_pipeint (urb->pipe) | 201 | && urb->dev->tt |
202 | && !usb_pipeint(urb->pipe) | ||
202 | && ((token & QTD_STS_MMF) != 0 | 203 | && ((token & QTD_STS_MMF) != 0 |
203 | || QTD_CERR(token) == 0) | 204 | || QTD_CERR(token) == 0) |
204 | && (!ehci_is_TDI(ehci) | 205 | && (!ehci_is_TDI(ehci) |
@@ -211,6 +212,9 @@ static int qtd_copy_status ( | |||
211 | urb->dev->ttport, urb->dev->devnum, | 212 | urb->dev->ttport, urb->dev->devnum, |
212 | usb_pipeendpoint (urb->pipe), token); | 213 | usb_pipeendpoint (urb->pipe), token); |
213 | #endif /* DEBUG */ | 214 | #endif /* DEBUG */ |
215 | /* REVISIT ARC-derived cores don't clear the root | ||
216 | * hub TT buffer in this way... | ||
217 | */ | ||
214 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); | 218 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); |
215 | } | 219 | } |
216 | } | 220 | } |
@@ -638,6 +642,7 @@ qh_make ( | |||
638 | u32 info1 = 0, info2 = 0; | 642 | u32 info1 = 0, info2 = 0; |
639 | int is_input, type; | 643 | int is_input, type; |
640 | int maxp = 0; | 644 | int maxp = 0; |
645 | struct usb_tt *tt = urb->dev->tt; | ||
641 | 646 | ||
642 | if (!qh) | 647 | if (!qh) |
643 | return qh; | 648 | return qh; |
@@ -661,8 +666,9 @@ qh_make ( | |||
661 | * For control/bulk requests, the HC or TT handles these. | 666 | * For control/bulk requests, the HC or TT handles these. |
662 | */ | 667 | */ |
663 | if (type == PIPE_INTERRUPT) { | 668 | if (type == PIPE_INTERRUPT) { |
664 | qh->usecs = NS_TO_US (usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0, | 669 | qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH, |
665 | hb_mult (maxp) * max_packet (maxp))); | 670 | is_input, 0, |
671 | hb_mult(maxp) * max_packet(maxp))); | ||
666 | qh->start = NO_FRAME; | 672 | qh->start = NO_FRAME; |
667 | 673 | ||
668 | if (urb->dev->speed == USB_SPEED_HIGH) { | 674 | if (urb->dev->speed == USB_SPEED_HIGH) { |
@@ -680,7 +686,6 @@ qh_make ( | |||
680 | goto done; | 686 | goto done; |
681 | } | 687 | } |
682 | } else { | 688 | } else { |
683 | struct usb_tt *tt = urb->dev->tt; | ||
684 | int think_time; | 689 | int think_time; |
685 | 690 | ||
686 | /* gap is f(FS/LS transfer times) */ | 691 | /* gap is f(FS/LS transfer times) */ |
@@ -736,10 +741,8 @@ qh_make ( | |||
736 | /* set the address of the TT; for TDI's integrated | 741 | /* set the address of the TT; for TDI's integrated |
737 | * root hub tt, leave it zeroed. | 742 | * root hub tt, leave it zeroed. |
738 | */ | 743 | */ |
739 | if (!ehci_is_TDI(ehci) | 744 | if (tt && tt->hub != ehci_to_hcd(ehci)->self.root_hub) |
740 | || urb->dev->tt->hub != | 745 | info2 |= tt->hub->devnum << 16; |
741 | ehci_to_hcd(ehci)->self.root_hub) | ||
742 | info2 |= urb->dev->tt->hub->devnum << 16; | ||
743 | 746 | ||
744 | /* NOTE: if (PIPE_INTERRUPT) { scheduler sets c-mask } */ | 747 | /* NOTE: if (PIPE_INTERRUPT) { scheduler sets c-mask } */ |
745 | 748 | ||
@@ -973,7 +976,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
973 | struct ehci_qh *qh = ehci->reclaim; | 976 | struct ehci_qh *qh = ehci->reclaim; |
974 | struct ehci_qh *next; | 977 | struct ehci_qh *next; |
975 | 978 | ||
976 | timer_action_done (ehci, TIMER_IAA_WATCHDOG); | 979 | iaa_watchdog_done(ehci); |
977 | 980 | ||
978 | // qh->hw_next = cpu_to_hc32(qh->qh_dma); | 981 | // qh->hw_next = cpu_to_hc32(qh->qh_dma); |
979 | qh->qh_state = QH_STATE_IDLE; | 982 | qh->qh_state = QH_STATE_IDLE; |
@@ -983,7 +986,6 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
983 | /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ | 986 | /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ |
984 | next = qh->reclaim; | 987 | next = qh->reclaim; |
985 | ehci->reclaim = next; | 988 | ehci->reclaim = next; |
986 | ehci->reclaim_ready = 0; | ||
987 | qh->reclaim = NULL; | 989 | qh->reclaim = NULL; |
988 | 990 | ||
989 | qh_completions (ehci, qh); | 991 | qh_completions (ehci, qh); |
@@ -1059,11 +1061,10 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1059 | return; | 1061 | return; |
1060 | } | 1062 | } |
1061 | 1063 | ||
1062 | ehci->reclaim_ready = 0; | ||
1063 | cmd |= CMD_IAAD; | 1064 | cmd |= CMD_IAAD; |
1064 | ehci_writel(ehci, cmd, &ehci->regs->command); | 1065 | ehci_writel(ehci, cmd, &ehci->regs->command); |
1065 | (void)ehci_readl(ehci, &ehci->regs->command); | 1066 | (void)ehci_readl(ehci, &ehci->regs->command); |
1066 | timer_action (ehci, TIMER_IAA_WATCHDOG); | 1067 | iaa_watchdog_start(ehci); |
1067 | } | 1068 | } |
1068 | 1069 | ||
1069 | /*-------------------------------------------------------------------------*/ | 1070 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 80d99bce2b38..8a8e08a51ba3 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -119,7 +119,8 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe) | |||
119 | q = &q->fstn->fstn_next; | 119 | q = &q->fstn->fstn_next; |
120 | break; | 120 | break; |
121 | case Q_TYPE_ITD: | 121 | case Q_TYPE_ITD: |
122 | usecs += q->itd->usecs [uframe]; | 122 | if (q->itd->hw_transaction[uframe]) |
123 | usecs += q->itd->stream->usecs; | ||
123 | hw_p = &q->itd->hw_next; | 124 | hw_p = &q->itd->hw_next; |
124 | q = &q->itd->itd_next; | 125 | q = &q->itd->itd_next; |
125 | break; | 126 | break; |
@@ -211,7 +212,7 @@ static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) | |||
211 | * low/fullspeed transfer can "carry over" from one uframe to the next, | 212 | * low/fullspeed transfer can "carry over" from one uframe to the next, |
212 | * since the TT just performs downstream transfers in sequence. | 213 | * since the TT just performs downstream transfers in sequence. |
213 | * | 214 | * |
214 | * For example two seperate 100 usec transfers can start in the same uframe, | 215 | * For example two separate 100 usec transfers can start in the same uframe, |
215 | * and the second one would "carry over" 75 usecs into the next uframe. | 216 | * and the second one would "carry over" 75 usecs into the next uframe. |
216 | */ | 217 | */ |
217 | static void | 218 | static void |
@@ -1536,7 +1537,6 @@ itd_link_urb ( | |||
1536 | uframe = next_uframe & 0x07; | 1537 | uframe = next_uframe & 0x07; |
1537 | frame = next_uframe >> 3; | 1538 | frame = next_uframe >> 3; |
1538 | 1539 | ||
1539 | itd->usecs [uframe] = stream->usecs; | ||
1540 | itd_patch(ehci, itd, iso_sched, packet, uframe); | 1540 | itd_patch(ehci, itd, iso_sched, packet, uframe); |
1541 | 1541 | ||
1542 | next_uframe += stream->interval; | 1542 | next_uframe += stream->interval; |
@@ -1565,6 +1565,16 @@ itd_link_urb ( | |||
1565 | 1565 | ||
1566 | #define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR) | 1566 | #define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR) |
1567 | 1567 | ||
1568 | /* Process and recycle a completed ITD. Return true iff its urb completed, | ||
1569 | * and hence its completion callback probably added things to the hardware | ||
1570 | * schedule. | ||
1571 | * | ||
1572 | * Note that we carefully avoid recycling this descriptor until after any | ||
1573 | * completion callback runs, so that it won't be reused quickly. That is, | ||
1574 | * assuming (a) no more than two urbs per frame on this endpoint, and also | ||
1575 | * (b) only this endpoint's completions submit URBs. It seems some silicon | ||
1576 | * corrupts things if you reuse completed descriptors very quickly... | ||
1577 | */ | ||
1568 | static unsigned | 1578 | static unsigned |
1569 | itd_complete ( | 1579 | itd_complete ( |
1570 | struct ehci_hcd *ehci, | 1580 | struct ehci_hcd *ehci, |
@@ -1577,6 +1587,7 @@ itd_complete ( | |||
1577 | int urb_index = -1; | 1587 | int urb_index = -1; |
1578 | struct ehci_iso_stream *stream = itd->stream; | 1588 | struct ehci_iso_stream *stream = itd->stream; |
1579 | struct usb_device *dev; | 1589 | struct usb_device *dev; |
1590 | unsigned retval = false; | ||
1580 | 1591 | ||
1581 | /* for each uframe with a packet */ | 1592 | /* for each uframe with a packet */ |
1582 | for (uframe = 0; uframe < 8; uframe++) { | 1593 | for (uframe = 0; uframe < 8; uframe++) { |
@@ -1610,30 +1621,21 @@ itd_complete ( | |||
1610 | } | 1621 | } |
1611 | } | 1622 | } |
1612 | 1623 | ||
1613 | usb_put_urb (urb); | ||
1614 | itd->urb = NULL; | ||
1615 | itd->stream = NULL; | ||
1616 | list_move (&itd->itd_list, &stream->free_list); | ||
1617 | iso_stream_put (ehci, stream); | ||
1618 | |||
1619 | /* handle completion now? */ | 1624 | /* handle completion now? */ |
1620 | if (likely ((urb_index + 1) != urb->number_of_packets)) | 1625 | if (likely ((urb_index + 1) != urb->number_of_packets)) |
1621 | return 0; | 1626 | goto done; |
1622 | 1627 | ||
1623 | /* ASSERT: it's really the last itd for this urb | 1628 | /* ASSERT: it's really the last itd for this urb |
1624 | list_for_each_entry (itd, &stream->td_list, itd_list) | 1629 | list_for_each_entry (itd, &stream->td_list, itd_list) |
1625 | BUG_ON (itd->urb == urb); | 1630 | BUG_ON (itd->urb == urb); |
1626 | */ | 1631 | */ |
1627 | 1632 | ||
1628 | /* give urb back to the driver ... can be out-of-order */ | 1633 | /* give urb back to the driver; completion often (re)submits */ |
1629 | dev = urb->dev; | 1634 | dev = urb->dev; |
1630 | ehci_urb_done(ehci, urb, 0); | 1635 | ehci_urb_done(ehci, urb, 0); |
1636 | retval = true; | ||
1631 | urb = NULL; | 1637 | urb = NULL; |
1632 | |||
1633 | /* defer stopping schedule; completion can submit */ | ||
1634 | ehci->periodic_sched--; | 1638 | ehci->periodic_sched--; |
1635 | if (unlikely (!ehci->periodic_sched)) | ||
1636 | (void) disable_periodic (ehci); | ||
1637 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 1639 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
1638 | 1640 | ||
1639 | if (unlikely (list_empty (&stream->td_list))) { | 1641 | if (unlikely (list_empty (&stream->td_list))) { |
@@ -1645,8 +1647,15 @@ itd_complete ( | |||
1645 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); | 1647 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); |
1646 | } | 1648 | } |
1647 | iso_stream_put (ehci, stream); | 1649 | iso_stream_put (ehci, stream); |
1650 | /* OK to recycle this ITD now that its completion callback ran. */ | ||
1651 | done: | ||
1652 | usb_put_urb(urb); | ||
1653 | itd->urb = NULL; | ||
1654 | itd->stream = NULL; | ||
1655 | list_move(&itd->itd_list, &stream->free_list); | ||
1656 | iso_stream_put(ehci, stream); | ||
1648 | 1657 | ||
1649 | return 1; | 1658 | return retval; |
1650 | } | 1659 | } |
1651 | 1660 | ||
1652 | /*-------------------------------------------------------------------------*/ | 1661 | /*-------------------------------------------------------------------------*/ |
@@ -1712,8 +1721,6 @@ done: | |||
1712 | return status; | 1721 | return status; |
1713 | } | 1722 | } |
1714 | 1723 | ||
1715 | #ifdef CONFIG_USB_EHCI_SPLIT_ISO | ||
1716 | |||
1717 | /*-------------------------------------------------------------------------*/ | 1724 | /*-------------------------------------------------------------------------*/ |
1718 | 1725 | ||
1719 | /* | 1726 | /* |
@@ -1950,6 +1957,16 @@ sitd_link_urb ( | |||
1950 | #define SITD_ERRS (SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE \ | 1957 | #define SITD_ERRS (SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE \ |
1951 | | SITD_STS_XACT | SITD_STS_MMF) | 1958 | | SITD_STS_XACT | SITD_STS_MMF) |
1952 | 1959 | ||
1960 | /* Process and recycle a completed SITD. Return true iff its urb completed, | ||
1961 | * and hence its completion callback probably added things to the hardware | ||
1962 | * schedule. | ||
1963 | * | ||
1964 | * Note that we carefully avoid recycling this descriptor until after any | ||
1965 | * completion callback runs, so that it won't be reused quickly. That is, | ||
1966 | * assuming (a) no more than two urbs per frame on this endpoint, and also | ||
1967 | * (b) only this endpoint's completions submit URBs. It seems some silicon | ||
1968 | * corrupts things if you reuse completed descriptors very quickly... | ||
1969 | */ | ||
1953 | static unsigned | 1970 | static unsigned |
1954 | sitd_complete ( | 1971 | sitd_complete ( |
1955 | struct ehci_hcd *ehci, | 1972 | struct ehci_hcd *ehci, |
@@ -1961,6 +1978,7 @@ sitd_complete ( | |||
1961 | int urb_index = -1; | 1978 | int urb_index = -1; |
1962 | struct ehci_iso_stream *stream = sitd->stream; | 1979 | struct ehci_iso_stream *stream = sitd->stream; |
1963 | struct usb_device *dev; | 1980 | struct usb_device *dev; |
1981 | unsigned retval = false; | ||
1964 | 1982 | ||
1965 | urb_index = sitd->index; | 1983 | urb_index = sitd->index; |
1966 | desc = &urb->iso_frame_desc [urb_index]; | 1984 | desc = &urb->iso_frame_desc [urb_index]; |
@@ -1981,32 +1999,23 @@ sitd_complete ( | |||
1981 | desc->status = 0; | 1999 | desc->status = 0; |
1982 | desc->actual_length = desc->length - SITD_LENGTH (t); | 2000 | desc->actual_length = desc->length - SITD_LENGTH (t); |
1983 | } | 2001 | } |
1984 | |||
1985 | usb_put_urb (urb); | ||
1986 | sitd->urb = NULL; | ||
1987 | sitd->stream = NULL; | ||
1988 | list_move (&sitd->sitd_list, &stream->free_list); | ||
1989 | stream->depth -= stream->interval << 3; | 2002 | stream->depth -= stream->interval << 3; |
1990 | iso_stream_put (ehci, stream); | ||
1991 | 2003 | ||
1992 | /* handle completion now? */ | 2004 | /* handle completion now? */ |
1993 | if ((urb_index + 1) != urb->number_of_packets) | 2005 | if ((urb_index + 1) != urb->number_of_packets) |
1994 | return 0; | 2006 | goto done; |
1995 | 2007 | ||
1996 | /* ASSERT: it's really the last sitd for this urb | 2008 | /* ASSERT: it's really the last sitd for this urb |
1997 | list_for_each_entry (sitd, &stream->td_list, sitd_list) | 2009 | list_for_each_entry (sitd, &stream->td_list, sitd_list) |
1998 | BUG_ON (sitd->urb == urb); | 2010 | BUG_ON (sitd->urb == urb); |
1999 | */ | 2011 | */ |
2000 | 2012 | ||
2001 | /* give urb back to the driver */ | 2013 | /* give urb back to the driver; completion often (re)submits */ |
2002 | dev = urb->dev; | 2014 | dev = urb->dev; |
2003 | ehci_urb_done(ehci, urb, 0); | 2015 | ehci_urb_done(ehci, urb, 0); |
2016 | retval = true; | ||
2004 | urb = NULL; | 2017 | urb = NULL; |
2005 | |||
2006 | /* defer stopping schedule; completion can submit */ | ||
2007 | ehci->periodic_sched--; | 2018 | ehci->periodic_sched--; |
2008 | if (!ehci->periodic_sched) | ||
2009 | (void) disable_periodic (ehci); | ||
2010 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 2019 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
2011 | 2020 | ||
2012 | if (list_empty (&stream->td_list)) { | 2021 | if (list_empty (&stream->td_list)) { |
@@ -2018,8 +2027,15 @@ sitd_complete ( | |||
2018 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); | 2027 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); |
2019 | } | 2028 | } |
2020 | iso_stream_put (ehci, stream); | 2029 | iso_stream_put (ehci, stream); |
2030 | /* OK to recycle this SITD now that its completion callback ran. */ | ||
2031 | done: | ||
2032 | usb_put_urb(urb); | ||
2033 | sitd->urb = NULL; | ||
2034 | sitd->stream = NULL; | ||
2035 | list_move(&sitd->sitd_list, &stream->free_list); | ||
2036 | iso_stream_put(ehci, stream); | ||
2021 | 2037 | ||
2022 | return 1; | 2038 | return retval; |
2023 | } | 2039 | } |
2024 | 2040 | ||
2025 | 2041 | ||
@@ -2082,26 +2098,6 @@ done: | |||
2082 | return status; | 2098 | return status; |
2083 | } | 2099 | } |
2084 | 2100 | ||
2085 | #else | ||
2086 | |||
2087 | static inline int | ||
2088 | sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags) | ||
2089 | { | ||
2090 | ehci_dbg (ehci, "split iso support is disabled\n"); | ||
2091 | return -ENOSYS; | ||
2092 | } | ||
2093 | |||
2094 | static inline unsigned | ||
2095 | sitd_complete ( | ||
2096 | struct ehci_hcd *ehci, | ||
2097 | struct ehci_sitd *sitd | ||
2098 | ) { | ||
2099 | ehci_err (ehci, "sitd_complete %p?\n", sitd); | ||
2100 | return 0; | ||
2101 | } | ||
2102 | |||
2103 | #endif /* USB_EHCI_SPLIT_ISO */ | ||
2104 | |||
2105 | /*-------------------------------------------------------------------------*/ | 2101 | /*-------------------------------------------------------------------------*/ |
2106 | 2102 | ||
2107 | static void | 2103 | static void |
@@ -2127,17 +2123,9 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2127 | for (;;) { | 2123 | for (;;) { |
2128 | union ehci_shadow q, *q_p; | 2124 | union ehci_shadow q, *q_p; |
2129 | __hc32 type, *hw_p; | 2125 | __hc32 type, *hw_p; |
2130 | unsigned uframes; | 2126 | unsigned incomplete = false; |
2131 | 2127 | ||
2132 | /* don't scan past the live uframe */ | ||
2133 | frame = now_uframe >> 3; | 2128 | frame = now_uframe >> 3; |
2134 | if (frame == (clock >> 3)) | ||
2135 | uframes = now_uframe & 0x07; | ||
2136 | else { | ||
2137 | /* safe to scan the whole frame at once */ | ||
2138 | now_uframe |= 0x07; | ||
2139 | uframes = 8; | ||
2140 | } | ||
2141 | 2129 | ||
2142 | restart: | 2130 | restart: |
2143 | /* scan each element in frame's queue for completions */ | 2131 | /* scan each element in frame's queue for completions */ |
@@ -2175,12 +2163,15 @@ restart: | |||
2175 | q = q.fstn->fstn_next; | 2163 | q = q.fstn->fstn_next; |
2176 | break; | 2164 | break; |
2177 | case Q_TYPE_ITD: | 2165 | case Q_TYPE_ITD: |
2178 | /* skip itds for later in the frame */ | 2166 | /* If this ITD is still active, leave it for |
2167 | * later processing ... check the next entry. | ||
2168 | */ | ||
2179 | rmb (); | 2169 | rmb (); |
2180 | for (uf = live ? uframes : 8; uf < 8; uf++) { | 2170 | for (uf = 0; uf < 8 && live; uf++) { |
2181 | if (0 == (q.itd->hw_transaction [uf] | 2171 | if (0 == (q.itd->hw_transaction [uf] |
2182 | & ITD_ACTIVE(ehci))) | 2172 | & ITD_ACTIVE(ehci))) |
2183 | continue; | 2173 | continue; |
2174 | incomplete = true; | ||
2184 | q_p = &q.itd->itd_next; | 2175 | q_p = &q.itd->itd_next; |
2185 | hw_p = &q.itd->hw_next; | 2176 | hw_p = &q.itd->hw_next; |
2186 | type = Q_NEXT_TYPE(ehci, | 2177 | type = Q_NEXT_TYPE(ehci, |
@@ -2188,10 +2179,12 @@ restart: | |||
2188 | q = *q_p; | 2179 | q = *q_p; |
2189 | break; | 2180 | break; |
2190 | } | 2181 | } |
2191 | if (uf != 8) | 2182 | if (uf < 8 && live) |
2192 | break; | 2183 | break; |
2193 | 2184 | ||
2194 | /* this one's ready ... HC won't cache the | 2185 | /* Take finished ITDs out of the schedule |
2186 | * and process them: recycle, maybe report | ||
2187 | * URB completion. HC won't cache the | ||
2195 | * pointer for much longer, if at all. | 2188 | * pointer for much longer, if at all. |
2196 | */ | 2189 | */ |
2197 | *q_p = q.itd->itd_next; | 2190 | *q_p = q.itd->itd_next; |
@@ -2202,8 +2195,12 @@ restart: | |||
2202 | q = *q_p; | 2195 | q = *q_p; |
2203 | break; | 2196 | break; |
2204 | case Q_TYPE_SITD: | 2197 | case Q_TYPE_SITD: |
2198 | /* If this SITD is still active, leave it for | ||
2199 | * later processing ... check the next entry. | ||
2200 | */ | ||
2205 | if ((q.sitd->hw_results & SITD_ACTIVE(ehci)) | 2201 | if ((q.sitd->hw_results & SITD_ACTIVE(ehci)) |
2206 | && live) { | 2202 | && live) { |
2203 | incomplete = true; | ||
2207 | q_p = &q.sitd->sitd_next; | 2204 | q_p = &q.sitd->sitd_next; |
2208 | hw_p = &q.sitd->hw_next; | 2205 | hw_p = &q.sitd->hw_next; |
2209 | type = Q_NEXT_TYPE(ehci, | 2206 | type = Q_NEXT_TYPE(ehci, |
@@ -2211,6 +2208,11 @@ restart: | |||
2211 | q = *q_p; | 2208 | q = *q_p; |
2212 | break; | 2209 | break; |
2213 | } | 2210 | } |
2211 | |||
2212 | /* Take finished SITDs out of the schedule | ||
2213 | * and process them: recycle, maybe report | ||
2214 | * URB completion. | ||
2215 | */ | ||
2214 | *q_p = q.sitd->sitd_next; | 2216 | *q_p = q.sitd->sitd_next; |
2215 | *hw_p = q.sitd->hw_next; | 2217 | *hw_p = q.sitd->hw_next; |
2216 | type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); | 2218 | type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); |
@@ -2226,11 +2228,24 @@ restart: | |||
2226 | } | 2228 | } |
2227 | 2229 | ||
2228 | /* assume completion callbacks modify the queue */ | 2230 | /* assume completion callbacks modify the queue */ |
2229 | if (unlikely (modified)) | 2231 | if (unlikely (modified)) { |
2230 | goto restart; | 2232 | if (likely(ehci->periodic_sched > 0)) |
2233 | goto restart; | ||
2234 | /* maybe we can short-circuit this scan! */ | ||
2235 | disable_periodic(ehci); | ||
2236 | now_uframe = clock; | ||
2237 | break; | ||
2238 | } | ||
2231 | } | 2239 | } |
2232 | 2240 | ||
2233 | /* stop when we catch up to the HC */ | 2241 | /* If we can tell we caught up to the hardware, stop now. |
2242 | * We can't advance our scan without collecting the ISO | ||
2243 | * transfers that are still pending in this frame. | ||
2244 | */ | ||
2245 | if (incomplete && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | ||
2246 | ehci->next_uframe = now_uframe; | ||
2247 | break; | ||
2248 | } | ||
2234 | 2249 | ||
2235 | // FIXME: this assumes we won't get lapped when | 2250 | // FIXME: this assumes we won't get lapped when |
2236 | // latencies climb; that should be rare, but... | 2251 | // latencies climb; that should be rare, but... |
@@ -2243,7 +2258,8 @@ restart: | |||
2243 | if (now_uframe == clock) { | 2258 | if (now_uframe == clock) { |
2244 | unsigned now; | 2259 | unsigned now; |
2245 | 2260 | ||
2246 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2261 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) |
2262 | || ehci->periodic_sched == 0) | ||
2247 | break; | 2263 | break; |
2248 | ehci->next_uframe = now_uframe; | 2264 | ehci->next_uframe = now_uframe; |
2249 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; | 2265 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 951d69fec513..bf92d209a1a9 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -74,7 +74,6 @@ struct ehci_hcd { /* one per controller */ | |||
74 | /* async schedule support */ | 74 | /* async schedule support */ |
75 | struct ehci_qh *async; | 75 | struct ehci_qh *async; |
76 | struct ehci_qh *reclaim; | 76 | struct ehci_qh *reclaim; |
77 | unsigned reclaim_ready : 1; | ||
78 | unsigned scanning : 1; | 77 | unsigned scanning : 1; |
79 | 78 | ||
80 | /* periodic schedule support */ | 79 | /* periodic schedule support */ |
@@ -105,6 +104,7 @@ struct ehci_hcd { /* one per controller */ | |||
105 | struct dma_pool *itd_pool; /* itd per iso urb */ | 104 | struct dma_pool *itd_pool; /* itd per iso urb */ |
106 | struct dma_pool *sitd_pool; /* sitd per split iso urb */ | 105 | struct dma_pool *sitd_pool; /* sitd per split iso urb */ |
107 | 106 | ||
107 | struct timer_list iaa_watchdog; | ||
108 | struct timer_list watchdog; | 108 | struct timer_list watchdog; |
109 | unsigned long actions; | 109 | unsigned long actions; |
110 | unsigned stamp; | 110 | unsigned stamp; |
@@ -127,6 +127,14 @@ struct ehci_hcd { /* one per controller */ | |||
127 | #else | 127 | #else |
128 | # define COUNT(x) do {} while (0) | 128 | # define COUNT(x) do {} while (0) |
129 | #endif | 129 | #endif |
130 | |||
131 | /* debug files */ | ||
132 | #ifdef DEBUG | ||
133 | struct dentry *debug_dir; | ||
134 | struct dentry *debug_async; | ||
135 | struct dentry *debug_periodic; | ||
136 | struct dentry *debug_registers; | ||
137 | #endif | ||
130 | }; | 138 | }; |
131 | 139 | ||
132 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 140 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
@@ -140,9 +148,21 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci) | |||
140 | } | 148 | } |
141 | 149 | ||
142 | 150 | ||
151 | static inline void | ||
152 | iaa_watchdog_start(struct ehci_hcd *ehci) | ||
153 | { | ||
154 | WARN_ON(timer_pending(&ehci->iaa_watchdog)); | ||
155 | mod_timer(&ehci->iaa_watchdog, | ||
156 | jiffies + msecs_to_jiffies(EHCI_IAA_MSECS)); | ||
157 | } | ||
158 | |||
159 | static inline void iaa_watchdog_done(struct ehci_hcd *ehci) | ||
160 | { | ||
161 | del_timer(&ehci->iaa_watchdog); | ||
162 | } | ||
163 | |||
143 | enum ehci_timer_action { | 164 | enum ehci_timer_action { |
144 | TIMER_IO_WATCHDOG, | 165 | TIMER_IO_WATCHDOG, |
145 | TIMER_IAA_WATCHDOG, | ||
146 | TIMER_ASYNC_SHRINK, | 166 | TIMER_ASYNC_SHRINK, |
147 | TIMER_ASYNC_OFF, | 167 | TIMER_ASYNC_OFF, |
148 | }; | 168 | }; |
@@ -160,9 +180,6 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
160 | unsigned long t; | 180 | unsigned long t; |
161 | 181 | ||
162 | switch (action) { | 182 | switch (action) { |
163 | case TIMER_IAA_WATCHDOG: | ||
164 | t = EHCI_IAA_JIFFIES; | ||
165 | break; | ||
166 | case TIMER_IO_WATCHDOG: | 183 | case TIMER_IO_WATCHDOG: |
167 | t = EHCI_IO_JIFFIES; | 184 | t = EHCI_IO_JIFFIES; |
168 | break; | 185 | break; |
@@ -179,8 +196,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
179 | // async queue SHRINK often precedes IAA. while it's ready | 196 | // async queue SHRINK often precedes IAA. while it's ready |
180 | // to go OFF neither can matter, and afterwards the IO | 197 | // to go OFF neither can matter, and afterwards the IO |
181 | // watchdog stops unless there's still periodic traffic. | 198 | // watchdog stops unless there's still periodic traffic. |
182 | if (action != TIMER_IAA_WATCHDOG | 199 | if (time_before_eq(t, ehci->watchdog.expires) |
183 | && t > ehci->watchdog.expires | ||
184 | && timer_pending (&ehci->watchdog)) | 200 | && timer_pending (&ehci->watchdog)) |
185 | return; | 201 | return; |
186 | mod_timer (&ehci->watchdog, t); | 202 | mod_timer (&ehci->watchdog, t); |
@@ -534,8 +550,8 @@ struct ehci_iso_stream { | |||
534 | * trusting urb->interval == f(epdesc->bInterval) and | 550 | * trusting urb->interval == f(epdesc->bInterval) and |
535 | * including the extra info for hw_bufp[0..2] | 551 | * including the extra info for hw_bufp[0..2] |
536 | */ | 552 | */ |
537 | u8 interval; | ||
538 | u8 usecs, c_usecs; | 553 | u8 usecs, c_usecs; |
554 | u16 interval; | ||
539 | u16 tt_usecs; | 555 | u16 tt_usecs; |
540 | u16 maxp; | 556 | u16 maxp; |
541 | u16 raw_mask; | 557 | u16 raw_mask; |
@@ -586,7 +602,6 @@ struct ehci_itd { | |||
586 | unsigned frame; /* where scheduled */ | 602 | unsigned frame; /* where scheduled */ |
587 | unsigned pg; | 603 | unsigned pg; |
588 | unsigned index[8]; /* in urb->iso_frame_desc */ | 604 | unsigned index[8]; /* in urb->iso_frame_desc */ |
589 | u8 usecs[8]; | ||
590 | } __attribute__ ((aligned (32))); | 605 | } __attribute__ ((aligned (32))); |
591 | 606 | ||
592 | /*-------------------------------------------------------------------------*/ | 607 | /*-------------------------------------------------------------------------*/ |
@@ -725,11 +740,16 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) | |||
725 | * definition below can die once the 4xx support is | 740 | * definition below can die once the 4xx support is |
726 | * finally ported over. | 741 | * finally ported over. |
727 | */ | 742 | */ |
728 | #if defined(CONFIG_PPC) | 743 | #if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) |
729 | #define readl_be(addr) in_be32((__force unsigned *)addr) | 744 | #define readl_be(addr) in_be32((__force unsigned *)addr) |
730 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) | 745 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) |
731 | #endif | 746 | #endif |
732 | 747 | ||
748 | #if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX) | ||
749 | #define readl_be(addr) __raw_readl((__force unsigned *)addr) | ||
750 | #define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr) | ||
751 | #endif | ||
752 | |||
733 | static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, | 753 | static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, |
734 | __u32 __iomem * regs) | 754 | __u32 __iomem * regs) |
735 | { | 755 | { |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index c27417f5b9d8..0130fd8571e4 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -918,7 +918,6 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
918 | | RH_PS_OCIC | RH_PS_PRSC)) { | 918 | | RH_PS_OCIC | RH_PS_PRSC)) { |
919 | changed = 1; | 919 | changed = 1; |
920 | buf[0] |= 1 << (i + 1); | 920 | buf[0] |= 1 << (i + 1); |
921 | continue; | ||
922 | } | 921 | } |
923 | } | 922 | } |
924 | spin_unlock_irqrestore(&isp116x->lock, flags); | 923 | spin_unlock_irqrestore(&isp116x->lock, flags); |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index d849c809acbd..126fcbdd6408 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -17,6 +17,8 @@ | |||
17 | 17 | ||
18 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
19 | #include <asm/hardware.h> | 19 | #include <asm/hardware.h> |
20 | #include <asm/gpio.h> | ||
21 | |||
20 | #include <asm/arch/board.h> | 22 | #include <asm/arch/board.h> |
21 | #include <asm/arch/cpu.h> | 23 | #include <asm/arch/cpu.h> |
22 | 24 | ||
@@ -271,12 +273,41 @@ static const struct hc_driver ohci_at91_hc_driver = { | |||
271 | 273 | ||
272 | static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) | 274 | static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) |
273 | { | 275 | { |
276 | struct at91_usbh_data *pdata = pdev->dev.platform_data; | ||
277 | int i; | ||
278 | |||
279 | if (pdata) { | ||
280 | /* REVISIT make the driver support per-port power switching, | ||
281 | * and also overcurrent detection. Here we assume the ports | ||
282 | * are always powered while this driver is active, and use | ||
283 | * active-low power switches. | ||
284 | */ | ||
285 | for (i = 0; i < pdata->ports; i++) { | ||
286 | if (pdata->vbus_pin[i] <= 0) | ||
287 | continue; | ||
288 | gpio_request(pdata->vbus_pin[i], "ohci_vbus"); | ||
289 | gpio_direction_output(pdata->vbus_pin[i], 0); | ||
290 | } | ||
291 | } | ||
292 | |||
274 | device_init_wakeup(&pdev->dev, 1); | 293 | device_init_wakeup(&pdev->dev, 1); |
275 | return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); | 294 | return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); |
276 | } | 295 | } |
277 | 296 | ||
278 | static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) | 297 | static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) |
279 | { | 298 | { |
299 | struct at91_usbh_data *pdata = pdev->dev.platform_data; | ||
300 | int i; | ||
301 | |||
302 | if (pdata) { | ||
303 | for (i = 0; i < pdata->ports; i++) { | ||
304 | if (pdata->vbus_pin[i] <= 0) | ||
305 | continue; | ||
306 | gpio_direction_output(pdata->vbus_pin[i], 1); | ||
307 | gpio_free(pdata->vbus_pin[i]); | ||
308 | } | ||
309 | } | ||
310 | |||
280 | device_init_wakeup(&pdev->dev, 0); | 311 | device_init_wakeup(&pdev->dev, 0); |
281 | return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev); | 312 | return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev); |
282 | } | 313 | } |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index ebab5ce8f5ce..a22c30aa745d 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -401,6 +401,42 @@ static inline void remove_debug_files (struct ohci_hcd *bus) { } | |||
401 | 401 | ||
402 | #else | 402 | #else |
403 | 403 | ||
404 | static int debug_async_open(struct inode *, struct file *); | ||
405 | static int debug_periodic_open(struct inode *, struct file *); | ||
406 | static int debug_registers_open(struct inode *, struct file *); | ||
407 | static int debug_async_open(struct inode *, struct file *); | ||
408 | static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*); | ||
409 | static int debug_close(struct inode *, struct file *); | ||
410 | |||
411 | static const struct file_operations debug_async_fops = { | ||
412 | .owner = THIS_MODULE, | ||
413 | .open = debug_async_open, | ||
414 | .read = debug_output, | ||
415 | .release = debug_close, | ||
416 | }; | ||
417 | static const struct file_operations debug_periodic_fops = { | ||
418 | .owner = THIS_MODULE, | ||
419 | .open = debug_periodic_open, | ||
420 | .read = debug_output, | ||
421 | .release = debug_close, | ||
422 | }; | ||
423 | static const struct file_operations debug_registers_fops = { | ||
424 | .owner = THIS_MODULE, | ||
425 | .open = debug_registers_open, | ||
426 | .read = debug_output, | ||
427 | .release = debug_close, | ||
428 | }; | ||
429 | |||
430 | static struct dentry *ohci_debug_root; | ||
431 | |||
432 | struct debug_buffer { | ||
433 | ssize_t (*fill_func)(struct debug_buffer *); /* fill method */ | ||
434 | struct device *dev; | ||
435 | struct mutex mutex; /* protect filling of buffer */ | ||
436 | size_t count; /* number of characters filled into buffer */ | ||
437 | char *page; | ||
438 | }; | ||
439 | |||
404 | static ssize_t | 440 | static ssize_t |
405 | show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) | 441 | show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) |
406 | { | 442 | { |
@@ -467,8 +503,7 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) | |||
467 | return count - size; | 503 | return count - size; |
468 | } | 504 | } |
469 | 505 | ||
470 | static ssize_t | 506 | static ssize_t fill_async_buffer(struct debug_buffer *buf) |
471 | show_async (struct class_device *class_dev, char *buf) | ||
472 | { | 507 | { |
473 | struct usb_bus *bus; | 508 | struct usb_bus *bus; |
474 | struct usb_hcd *hcd; | 509 | struct usb_hcd *hcd; |
@@ -476,25 +511,23 @@ show_async (struct class_device *class_dev, char *buf) | |||
476 | size_t temp; | 511 | size_t temp; |
477 | unsigned long flags; | 512 | unsigned long flags; |
478 | 513 | ||
479 | bus = class_get_devdata(class_dev); | 514 | bus = dev_get_drvdata(buf->dev); |
480 | hcd = bus_to_hcd(bus); | 515 | hcd = bus_to_hcd(bus); |
481 | ohci = hcd_to_ohci(hcd); | 516 | ohci = hcd_to_ohci(hcd); |
482 | 517 | ||
483 | /* display control and bulk lists together, for simplicity */ | 518 | /* display control and bulk lists together, for simplicity */ |
484 | spin_lock_irqsave (&ohci->lock, flags); | 519 | spin_lock_irqsave (&ohci->lock, flags); |
485 | temp = show_list (ohci, buf, PAGE_SIZE, ohci->ed_controltail); | 520 | temp = show_list(ohci, buf->page, buf->count, ohci->ed_controltail); |
486 | temp += show_list (ohci, buf + temp, PAGE_SIZE - temp, ohci->ed_bulktail); | 521 | temp += show_list(ohci, buf->page + temp, buf->count - temp, |
522 | ohci->ed_bulktail); | ||
487 | spin_unlock_irqrestore (&ohci->lock, flags); | 523 | spin_unlock_irqrestore (&ohci->lock, flags); |
488 | 524 | ||
489 | return temp; | 525 | return temp; |
490 | } | 526 | } |
491 | static CLASS_DEVICE_ATTR (async, S_IRUGO, show_async, NULL); | ||
492 | |||
493 | 527 | ||
494 | #define DBG_SCHED_LIMIT 64 | 528 | #define DBG_SCHED_LIMIT 64 |
495 | 529 | ||
496 | static ssize_t | 530 | static ssize_t fill_periodic_buffer(struct debug_buffer *buf) |
497 | show_periodic (struct class_device *class_dev, char *buf) | ||
498 | { | 531 | { |
499 | struct usb_bus *bus; | 532 | struct usb_bus *bus; |
500 | struct usb_hcd *hcd; | 533 | struct usb_hcd *hcd; |
@@ -509,10 +542,10 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
509 | return 0; | 542 | return 0; |
510 | seen_count = 0; | 543 | seen_count = 0; |
511 | 544 | ||
512 | bus = class_get_devdata(class_dev); | 545 | bus = (struct usb_bus *)dev_get_drvdata(buf->dev); |
513 | hcd = bus_to_hcd(bus); | 546 | hcd = bus_to_hcd(bus); |
514 | ohci = hcd_to_ohci(hcd); | 547 | ohci = hcd_to_ohci(hcd); |
515 | next = buf; | 548 | next = buf->page; |
516 | size = PAGE_SIZE; | 549 | size = PAGE_SIZE; |
517 | 550 | ||
518 | temp = scnprintf (next, size, "size = %d\n", NUM_INTS); | 551 | temp = scnprintf (next, size, "size = %d\n", NUM_INTS); |
@@ -589,13 +622,9 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
589 | 622 | ||
590 | return PAGE_SIZE - size; | 623 | return PAGE_SIZE - size; |
591 | } | 624 | } |
592 | static CLASS_DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL); | ||
593 | |||
594 | |||
595 | #undef DBG_SCHED_LIMIT | 625 | #undef DBG_SCHED_LIMIT |
596 | 626 | ||
597 | static ssize_t | 627 | static ssize_t fill_registers_buffer(struct debug_buffer *buf) |
598 | show_registers (struct class_device *class_dev, char *buf) | ||
599 | { | 628 | { |
600 | struct usb_bus *bus; | 629 | struct usb_bus *bus; |
601 | struct usb_hcd *hcd; | 630 | struct usb_hcd *hcd; |
@@ -606,11 +635,11 @@ show_registers (struct class_device *class_dev, char *buf) | |||
606 | char *next; | 635 | char *next; |
607 | u32 rdata; | 636 | u32 rdata; |
608 | 637 | ||
609 | bus = class_get_devdata(class_dev); | 638 | bus = (struct usb_bus *)dev_get_drvdata(buf->dev); |
610 | hcd = bus_to_hcd(bus); | 639 | hcd = bus_to_hcd(bus); |
611 | ohci = hcd_to_ohci(hcd); | 640 | ohci = hcd_to_ohci(hcd); |
612 | regs = ohci->regs; | 641 | regs = ohci->regs; |
613 | next = buf; | 642 | next = buf->page; |
614 | size = PAGE_SIZE; | 643 | size = PAGE_SIZE; |
615 | 644 | ||
616 | spin_lock_irqsave (&ohci->lock, flags); | 645 | spin_lock_irqsave (&ohci->lock, flags); |
@@ -677,29 +706,155 @@ show_registers (struct class_device *class_dev, char *buf) | |||
677 | 706 | ||
678 | done: | 707 | done: |
679 | spin_unlock_irqrestore (&ohci->lock, flags); | 708 | spin_unlock_irqrestore (&ohci->lock, flags); |
709 | |||
680 | return PAGE_SIZE - size; | 710 | return PAGE_SIZE - size; |
681 | } | 711 | } |
682 | static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); | ||
683 | 712 | ||
713 | static struct debug_buffer *alloc_buffer(struct device *dev, | ||
714 | ssize_t (*fill_func)(struct debug_buffer *)) | ||
715 | { | ||
716 | struct debug_buffer *buf; | ||
717 | |||
718 | buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); | ||
684 | 719 | ||
720 | if (buf) { | ||
721 | buf->dev = dev; | ||
722 | buf->fill_func = fill_func; | ||
723 | mutex_init(&buf->mutex); | ||
724 | } | ||
725 | |||
726 | return buf; | ||
727 | } | ||
728 | |||
729 | static int fill_buffer(struct debug_buffer *buf) | ||
730 | { | ||
731 | int ret = 0; | ||
732 | |||
733 | if (!buf->page) | ||
734 | buf->page = (char *)get_zeroed_page(GFP_KERNEL); | ||
735 | |||
736 | if (!buf->page) { | ||
737 | ret = -ENOMEM; | ||
738 | goto out; | ||
739 | } | ||
740 | |||
741 | ret = buf->fill_func(buf); | ||
742 | |||
743 | if (ret >= 0) { | ||
744 | buf->count = ret; | ||
745 | ret = 0; | ||
746 | } | ||
747 | |||
748 | out: | ||
749 | return ret; | ||
750 | } | ||
751 | |||
752 | static ssize_t debug_output(struct file *file, char __user *user_buf, | ||
753 | size_t len, loff_t *offset) | ||
754 | { | ||
755 | struct debug_buffer *buf = file->private_data; | ||
756 | int ret = 0; | ||
757 | |||
758 | mutex_lock(&buf->mutex); | ||
759 | if (buf->count == 0) { | ||
760 | ret = fill_buffer(buf); | ||
761 | if (ret != 0) { | ||
762 | mutex_unlock(&buf->mutex); | ||
763 | goto out; | ||
764 | } | ||
765 | } | ||
766 | mutex_unlock(&buf->mutex); | ||
767 | |||
768 | ret = simple_read_from_buffer(user_buf, len, offset, | ||
769 | buf->page, buf->count); | ||
770 | |||
771 | out: | ||
772 | return ret; | ||
773 | |||
774 | } | ||
775 | |||
776 | static int debug_close(struct inode *inode, struct file *file) | ||
777 | { | ||
778 | struct debug_buffer *buf = file->private_data; | ||
779 | |||
780 | if (buf) { | ||
781 | if (buf->page) | ||
782 | free_page((unsigned long)buf->page); | ||
783 | kfree(buf); | ||
784 | } | ||
785 | |||
786 | return 0; | ||
787 | } | ||
788 | static int debug_async_open(struct inode *inode, struct file *file) | ||
789 | { | ||
790 | file->private_data = alloc_buffer(inode->i_private, fill_async_buffer); | ||
791 | |||
792 | return file->private_data ? 0 : -ENOMEM; | ||
793 | } | ||
794 | |||
795 | static int debug_periodic_open(struct inode *inode, struct file *file) | ||
796 | { | ||
797 | file->private_data = alloc_buffer(inode->i_private, | ||
798 | fill_periodic_buffer); | ||
799 | |||
800 | return file->private_data ? 0 : -ENOMEM; | ||
801 | } | ||
802 | |||
803 | static int debug_registers_open(struct inode *inode, struct file *file) | ||
804 | { | ||
805 | file->private_data = alloc_buffer(inode->i_private, | ||
806 | fill_registers_buffer); | ||
807 | |||
808 | return file->private_data ? 0 : -ENOMEM; | ||
809 | } | ||
685 | static inline void create_debug_files (struct ohci_hcd *ohci) | 810 | static inline void create_debug_files (struct ohci_hcd *ohci) |
686 | { | 811 | { |
687 | struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev; | 812 | struct usb_bus *bus = &ohci_to_hcd(ohci)->self; |
688 | int retval; | 813 | struct device *dev = bus->dev; |
814 | |||
815 | ohci->debug_dir = debugfs_create_dir(bus->bus_name, ohci_debug_root); | ||
816 | if (!ohci->debug_dir) | ||
817 | goto dir_error; | ||
818 | |||
819 | ohci->debug_async = debugfs_create_file("async", S_IRUGO, | ||
820 | ohci->debug_dir, dev, | ||
821 | &debug_async_fops); | ||
822 | if (!ohci->debug_async) | ||
823 | goto async_error; | ||
824 | |||
825 | ohci->debug_periodic = debugfs_create_file("periodic", S_IRUGO, | ||
826 | ohci->debug_dir, dev, | ||
827 | &debug_periodic_fops); | ||
828 | if (!ohci->debug_periodic) | ||
829 | goto periodic_error; | ||
830 | |||
831 | ohci->debug_registers = debugfs_create_file("registers", S_IRUGO, | ||
832 | ohci->debug_dir, dev, | ||
833 | &debug_registers_fops); | ||
834 | if (!ohci->debug_registers) | ||
835 | goto registers_error; | ||
689 | 836 | ||
690 | retval = class_device_create_file(cldev, &class_device_attr_async); | ||
691 | retval = class_device_create_file(cldev, &class_device_attr_periodic); | ||
692 | retval = class_device_create_file(cldev, &class_device_attr_registers); | ||
693 | ohci_dbg (ohci, "created debug files\n"); | 837 | ohci_dbg (ohci, "created debug files\n"); |
838 | return; | ||
839 | |||
840 | registers_error: | ||
841 | debugfs_remove(ohci->debug_periodic); | ||
842 | periodic_error: | ||
843 | debugfs_remove(ohci->debug_async); | ||
844 | async_error: | ||
845 | debugfs_remove(ohci->debug_dir); | ||
846 | dir_error: | ||
847 | ohci->debug_periodic = NULL; | ||
848 | ohci->debug_async = NULL; | ||
849 | ohci->debug_dir = NULL; | ||
694 | } | 850 | } |
695 | 851 | ||
696 | static inline void remove_debug_files (struct ohci_hcd *ohci) | 852 | static inline void remove_debug_files (struct ohci_hcd *ohci) |
697 | { | 853 | { |
698 | struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev; | 854 | debugfs_remove(ohci->debug_registers); |
699 | 855 | debugfs_remove(ohci->debug_periodic); | |
700 | class_device_remove_file(cldev, &class_device_attr_async); | 856 | debugfs_remove(ohci->debug_async); |
701 | class_device_remove_file(cldev, &class_device_attr_periodic); | 857 | debugfs_remove(ohci->debug_dir); |
702 | class_device_remove_file(cldev, &class_device_attr_registers); | ||
703 | } | 858 | } |
704 | 859 | ||
705 | #endif | 860 | #endif |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index ddd4ee1f2413..dd4798ee028e 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/dmapool.h> | 36 | #include <linux/dmapool.h> |
37 | #include <linux/reboot.h> | 37 | #include <linux/reboot.h> |
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <linux/debugfs.h> | ||
39 | 40 | ||
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
@@ -809,13 +810,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
809 | } | 810 | } |
810 | 811 | ||
811 | if (ints & OHCI_INTR_WDH) { | 812 | if (ints & OHCI_INTR_WDH) { |
812 | if (HC_IS_RUNNING(hcd->state)) | ||
813 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable); | ||
814 | spin_lock (&ohci->lock); | 813 | spin_lock (&ohci->lock); |
815 | dl_done_list (ohci); | 814 | dl_done_list (ohci); |
816 | spin_unlock (&ohci->lock); | 815 | spin_unlock (&ohci->lock); |
817 | if (HC_IS_RUNNING(hcd->state)) | ||
818 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); | ||
819 | } | 816 | } |
820 | 817 | ||
821 | if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) { | 818 | if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) { |
@@ -1032,6 +1029,13 @@ MODULE_LICENSE ("GPL"); | |||
1032 | #define PLATFORM_DRIVER usb_hcd_pnx4008_driver | 1029 | #define PLATFORM_DRIVER usb_hcd_pnx4008_driver |
1033 | #endif | 1030 | #endif |
1034 | 1031 | ||
1032 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | ||
1033 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | ||
1034 | defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
1035 | #include "ohci-sh.c" | ||
1036 | #define PLATFORM_DRIVER ohci_hcd_sh_driver | ||
1037 | #endif | ||
1038 | |||
1035 | 1039 | ||
1036 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF | 1040 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF |
1037 | #include "ohci-ppc-of.c" | 1041 | #include "ohci-ppc-of.c" |
@@ -1048,6 +1052,11 @@ MODULE_LICENSE ("GPL"); | |||
1048 | #define SSB_OHCI_DRIVER ssb_ohci_driver | 1052 | #define SSB_OHCI_DRIVER ssb_ohci_driver |
1049 | #endif | 1053 | #endif |
1050 | 1054 | ||
1055 | #ifdef CONFIG_MFD_SM501 | ||
1056 | #include "ohci-sm501.c" | ||
1057 | #define PLATFORM_DRIVER ohci_hcd_sm501_driver | ||
1058 | #endif | ||
1059 | |||
1051 | #if !defined(PCI_DRIVER) && \ | 1060 | #if !defined(PCI_DRIVER) && \ |
1052 | !defined(PLATFORM_DRIVER) && \ | 1061 | !defined(PLATFORM_DRIVER) && \ |
1053 | !defined(OF_PLATFORM_DRIVER) && \ | 1062 | !defined(OF_PLATFORM_DRIVER) && \ |
@@ -1068,6 +1077,14 @@ static int __init ohci_hcd_mod_init(void) | |||
1068 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | 1077 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, |
1069 | sizeof (struct ed), sizeof (struct td)); | 1078 | sizeof (struct ed), sizeof (struct td)); |
1070 | 1079 | ||
1080 | #ifdef DEBUG | ||
1081 | ohci_debug_root = debugfs_create_dir("ohci", NULL); | ||
1082 | if (!ohci_debug_root) { | ||
1083 | retval = -ENOENT; | ||
1084 | goto error_debug; | ||
1085 | } | ||
1086 | #endif | ||
1087 | |||
1071 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1088 | #ifdef PS3_SYSTEM_BUS_DRIVER |
1072 | retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER); | 1089 | retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER); |
1073 | if (retval < 0) | 1090 | if (retval < 0) |
@@ -1130,6 +1147,12 @@ static int __init ohci_hcd_mod_init(void) | |||
1130 | ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | 1147 | ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); |
1131 | error_ps3: | 1148 | error_ps3: |
1132 | #endif | 1149 | #endif |
1150 | #ifdef DEBUG | ||
1151 | debugfs_remove(ohci_debug_root); | ||
1152 | ohci_debug_root = NULL; | ||
1153 | error_debug: | ||
1154 | #endif | ||
1155 | |||
1133 | return retval; | 1156 | return retval; |
1134 | } | 1157 | } |
1135 | module_init(ohci_hcd_mod_init); | 1158 | module_init(ohci_hcd_mod_init); |
@@ -1154,6 +1177,9 @@ static void __exit ohci_hcd_mod_exit(void) | |||
1154 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1177 | #ifdef PS3_SYSTEM_BUS_DRIVER |
1155 | ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | 1178 | ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); |
1156 | #endif | 1179 | #endif |
1180 | #ifdef DEBUG | ||
1181 | debugfs_remove(ohci_debug_root); | ||
1182 | #endif | ||
1157 | } | 1183 | } |
1158 | module_exit(ohci_hcd_mod_exit); | 1184 | module_exit(ohci_hcd_mod_exit); |
1159 | 1185 | ||
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c new file mode 100644 index 000000000000..5309ac039e15 --- /dev/null +++ b/drivers/usb/host/ohci-sh.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
5 | * | ||
6 | * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/platform_device.h> | ||
24 | |||
25 | static int ohci_sh_start(struct usb_hcd *hcd) | ||
26 | { | ||
27 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
28 | |||
29 | ohci_hcd_init(ohci); | ||
30 | ohci_init(ohci); | ||
31 | ohci_run(ohci); | ||
32 | hcd->state = HC_STATE_RUNNING; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static const struct hc_driver ohci_sh_hc_driver = { | ||
37 | .description = hcd_name, | ||
38 | .product_desc = "SuperH OHCI", | ||
39 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
40 | |||
41 | /* | ||
42 | * generic hardware linkage | ||
43 | */ | ||
44 | .irq = ohci_irq, | ||
45 | .flags = HCD_USB11 | HCD_MEMORY, | ||
46 | |||
47 | /* | ||
48 | * basic lifecycle operations | ||
49 | */ | ||
50 | .start = ohci_sh_start, | ||
51 | .stop = ohci_stop, | ||
52 | .shutdown = ohci_shutdown, | ||
53 | |||
54 | /* | ||
55 | * managing i/o requests and associated device resources | ||
56 | */ | ||
57 | .urb_enqueue = ohci_urb_enqueue, | ||
58 | .urb_dequeue = ohci_urb_dequeue, | ||
59 | .endpoint_disable = ohci_endpoint_disable, | ||
60 | |||
61 | /* | ||
62 | * scheduling support | ||
63 | */ | ||
64 | .get_frame_number = ohci_get_frame, | ||
65 | |||
66 | /* | ||
67 | * root hub support | ||
68 | */ | ||
69 | .hub_status_data = ohci_hub_status_data, | ||
70 | .hub_control = ohci_hub_control, | ||
71 | .hub_irq_enable = ohci_rhsc_enable, | ||
72 | #ifdef CONFIG_PM | ||
73 | .bus_suspend = ohci_bus_suspend, | ||
74 | .bus_resume = ohci_bus_resume, | ||
75 | #endif | ||
76 | .start_port_reset = ohci_start_port_reset, | ||
77 | }; | ||
78 | |||
79 | /*-------------------------------------------------------------------------*/ | ||
80 | |||
81 | #define resource_len(r) (((r)->end - (r)->start) + 1) | ||
82 | static int ohci_hcd_sh_probe(struct platform_device *pdev) | ||
83 | { | ||
84 | struct resource *res = NULL; | ||
85 | struct usb_hcd *hcd = NULL; | ||
86 | int irq = -1; | ||
87 | int ret; | ||
88 | |||
89 | if (usb_disabled()) | ||
90 | return -ENODEV; | ||
91 | |||
92 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
93 | if (!res) { | ||
94 | err("platform_get_resource error."); | ||
95 | return -ENODEV; | ||
96 | } | ||
97 | |||
98 | irq = platform_get_irq(pdev, 0); | ||
99 | if (irq < 0) { | ||
100 | err("platform_get_irq error."); | ||
101 | return -ENODEV; | ||
102 | } | ||
103 | |||
104 | /* initialize hcd */ | ||
105 | hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name); | ||
106 | if (!hcd) { | ||
107 | err("Failed to create hcd"); | ||
108 | return -ENOMEM; | ||
109 | } | ||
110 | |||
111 | hcd->regs = (void __iomem *)res->start; | ||
112 | hcd->rsrc_start = res->start; | ||
113 | hcd->rsrc_len = resource_len(res); | ||
114 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | ||
115 | if (ret != 0) { | ||
116 | err("Failed to add hcd"); | ||
117 | usb_put_hcd(hcd); | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | static int ohci_hcd_sh_remove(struct platform_device *pdev) | ||
125 | { | ||
126 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
127 | |||
128 | usb_remove_hcd(hcd); | ||
129 | usb_put_hcd(hcd); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct platform_driver ohci_hcd_sh_driver = { | ||
135 | .probe = ohci_hcd_sh_probe, | ||
136 | .remove = ohci_hcd_sh_remove, | ||
137 | .shutdown = usb_hcd_platform_shutdown, | ||
138 | .driver = { | ||
139 | .name = "sh_ohci", | ||
140 | .owner = THIS_MODULE, | ||
141 | }, | ||
142 | }; | ||
143 | |||
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c new file mode 100644 index 000000000000..a97070142869 --- /dev/null +++ b/drivers/usb/host/ohci-sm501.c | |||
@@ -0,0 +1,264 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2005 David Brownell | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2008 Magnus Damm | ||
8 | * | ||
9 | * SM501 Bus Glue - based on ohci-omap.c | ||
10 | * | ||
11 | * This file is licenced under the GPL. | ||
12 | */ | ||
13 | |||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/jiffies.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/sm501.h> | ||
19 | #include <linux/sm501-regs.h> | ||
20 | |||
21 | static int ohci_sm501_init(struct usb_hcd *hcd) | ||
22 | { | ||
23 | return ohci_init(hcd_to_ohci(hcd)); | ||
24 | } | ||
25 | |||
26 | static int ohci_sm501_start(struct usb_hcd *hcd) | ||
27 | { | ||
28 | struct device *dev = hcd->self.controller; | ||
29 | int ret; | ||
30 | |||
31 | ret = ohci_run(hcd_to_ohci(hcd)); | ||
32 | if (ret < 0) { | ||
33 | dev_err(dev, "can't start %s", hcd->self.bus_name); | ||
34 | ohci_stop(hcd); | ||
35 | } | ||
36 | |||
37 | return ret; | ||
38 | } | ||
39 | |||
40 | /*-------------------------------------------------------------------------*/ | ||
41 | |||
42 | static const struct hc_driver ohci_sm501_hc_driver = { | ||
43 | .description = hcd_name, | ||
44 | .product_desc = "SM501 OHCI", | ||
45 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
46 | |||
47 | /* | ||
48 | * generic hardware linkage | ||
49 | */ | ||
50 | .irq = ohci_irq, | ||
51 | .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM, | ||
52 | |||
53 | /* | ||
54 | * basic lifecycle operations | ||
55 | */ | ||
56 | .reset = ohci_sm501_init, | ||
57 | .start = ohci_sm501_start, | ||
58 | .stop = ohci_stop, | ||
59 | .shutdown = ohci_shutdown, | ||
60 | |||
61 | /* | ||
62 | * managing i/o requests and associated device resources | ||
63 | */ | ||
64 | .urb_enqueue = ohci_urb_enqueue, | ||
65 | .urb_dequeue = ohci_urb_dequeue, | ||
66 | .endpoint_disable = ohci_endpoint_disable, | ||
67 | |||
68 | /* | ||
69 | * scheduling support | ||
70 | */ | ||
71 | .get_frame_number = ohci_get_frame, | ||
72 | |||
73 | /* | ||
74 | * root hub support | ||
75 | */ | ||
76 | .hub_status_data = ohci_hub_status_data, | ||
77 | .hub_control = ohci_hub_control, | ||
78 | .hub_irq_enable = ohci_rhsc_enable, | ||
79 | #ifdef CONFIG_PM | ||
80 | .bus_suspend = ohci_bus_suspend, | ||
81 | .bus_resume = ohci_bus_resume, | ||
82 | #endif | ||
83 | .start_port_reset = ohci_start_port_reset, | ||
84 | }; | ||
85 | |||
86 | /*-------------------------------------------------------------------------*/ | ||
87 | |||
88 | static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) | ||
89 | { | ||
90 | const struct hc_driver *driver = &ohci_sm501_hc_driver; | ||
91 | struct device *dev = &pdev->dev; | ||
92 | struct resource *res, *mem; | ||
93 | int retval, irq; | ||
94 | struct usb_hcd *hcd = 0; | ||
95 | |||
96 | irq = retval = platform_get_irq(pdev, 0); | ||
97 | if (retval < 0) | ||
98 | goto err0; | ||
99 | |||
100 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
101 | if (mem == NULL) { | ||
102 | dev_err(dev, "no resource definition for memory\n"); | ||
103 | retval = -ENOENT; | ||
104 | goto err0; | ||
105 | } | ||
106 | |||
107 | if (!request_mem_region(mem->start, mem->end - mem->start + 1, | ||
108 | pdev->name)) { | ||
109 | dev_err(dev, "request_mem_region failed\n"); | ||
110 | retval = -EBUSY; | ||
111 | goto err0; | ||
112 | } | ||
113 | |||
114 | /* The sm501 chip is equipped with local memory that may be used | ||
115 | * by on-chip devices such as the video controller and the usb host. | ||
116 | * This driver uses dma_declare_coherent_memory() to make sure | ||
117 | * usb allocations with dma_alloc_coherent() allocate from | ||
118 | * this local memory. The dma_handle returned by dma_alloc_coherent() | ||
119 | * will be an offset starting from 0 for the first local memory byte. | ||
120 | * | ||
121 | * So as long as data is allocated using dma_alloc_coherent() all is | ||
122 | * fine. This is however not always the case - buffers may be allocated | ||
123 | * using kmalloc() - so the usb core needs to be told that it must copy | ||
124 | * data into our local memory if the buffers happen to be placed in | ||
125 | * regular memory. The HCD_LOCAL_MEM flag does just that. | ||
126 | */ | ||
127 | |||
128 | if (!dma_declare_coherent_memory(dev, mem->start, | ||
129 | mem->start - mem->parent->start, | ||
130 | (mem->end - mem->start) + 1, | ||
131 | DMA_MEMORY_MAP | | ||
132 | DMA_MEMORY_EXCLUSIVE)) { | ||
133 | dev_err(dev, "cannot declare coherent memory\n"); | ||
134 | retval = -ENXIO; | ||
135 | goto err1; | ||
136 | } | ||
137 | |||
138 | /* allocate, reserve and remap resources for registers */ | ||
139 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
140 | if (res == NULL) { | ||
141 | dev_err(dev, "no resource definition for registers\n"); | ||
142 | retval = -ENOENT; | ||
143 | goto err2; | ||
144 | } | ||
145 | |||
146 | hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); | ||
147 | if (!hcd) { | ||
148 | retval = -ENOMEM; | ||
149 | goto err2; | ||
150 | } | ||
151 | |||
152 | hcd->rsrc_start = res->start; | ||
153 | hcd->rsrc_len = res->end - res->start + 1; | ||
154 | |||
155 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, pdev->name)) { | ||
156 | dev_err(dev, "request_mem_region failed\n"); | ||
157 | retval = -EBUSY; | ||
158 | goto err3; | ||
159 | } | ||
160 | |||
161 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
162 | if (hcd->regs == NULL) { | ||
163 | dev_err(dev, "cannot remap registers\n"); | ||
164 | retval = -ENXIO; | ||
165 | goto err4; | ||
166 | } | ||
167 | |||
168 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
169 | |||
170 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | ||
171 | if (retval) | ||
172 | goto err4; | ||
173 | |||
174 | /* enable power and unmask interrupts */ | ||
175 | |||
176 | sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); | ||
177 | sm501_modify_reg(dev->parent, SM501_IRQ_MASK, 1 << 6, 0); | ||
178 | |||
179 | return 0; | ||
180 | err4: | ||
181 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
182 | err3: | ||
183 | usb_put_hcd(hcd); | ||
184 | err2: | ||
185 | dma_release_declared_memory(dev); | ||
186 | err1: | ||
187 | release_mem_region(mem->start, mem->end - mem->start + 1); | ||
188 | err0: | ||
189 | return retval; | ||
190 | } | ||
191 | |||
192 | static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev) | ||
193 | { | ||
194 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
195 | struct resource *mem; | ||
196 | |||
197 | usb_remove_hcd(hcd); | ||
198 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
199 | usb_put_hcd(hcd); | ||
200 | dma_release_declared_memory(&pdev->dev); | ||
201 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
202 | release_mem_region(mem->start, mem->end - mem->start + 1); | ||
203 | |||
204 | /* mask interrupts and disable power */ | ||
205 | |||
206 | sm501_modify_reg(pdev->dev.parent, SM501_IRQ_MASK, 0, 1 << 6); | ||
207 | sm501_unit_power(pdev->dev.parent, SM501_GATE_USB_HOST, 0); | ||
208 | |||
209 | platform_set_drvdata(pdev, NULL); | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /*-------------------------------------------------------------------------*/ | ||
214 | |||
215 | #ifdef CONFIG_PM | ||
216 | static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg) | ||
217 | { | ||
218 | struct device *dev = &pdev->dev; | ||
219 | struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev)); | ||
220 | |||
221 | if (time_before(jiffies, ohci->next_statechange)) | ||
222 | msleep(5); | ||
223 | ohci->next_statechange = jiffies; | ||
224 | |||
225 | sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0); | ||
226 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | ||
227 | dev->power.power_state = PMSG_SUSPEND; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int ohci_sm501_resume(struct platform_device *pdev) | ||
232 | { | ||
233 | struct device *dev = &pdev->dev; | ||
234 | struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev)); | ||
235 | |||
236 | if (time_before(jiffies, ohci->next_statechange)) | ||
237 | msleep(5); | ||
238 | ohci->next_statechange = jiffies; | ||
239 | |||
240 | sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); | ||
241 | dev->power.power_state = PMSG_ON; | ||
242 | usb_hcd_resume_root_hub(platform_get_drvdata(pdev)); | ||
243 | return 0; | ||
244 | } | ||
245 | #endif | ||
246 | |||
247 | /*-------------------------------------------------------------------------*/ | ||
248 | |||
249 | /* | ||
250 | * Driver definition to register with the SM501 bus | ||
251 | */ | ||
252 | static struct platform_driver ohci_hcd_sm501_driver = { | ||
253 | .probe = ohci_hcd_sm501_drv_probe, | ||
254 | .remove = ohci_hcd_sm501_drv_remove, | ||
255 | .shutdown = usb_hcd_platform_shutdown, | ||
256 | #ifdef CONFIG_PM | ||
257 | .suspend = ohci_sm501_suspend, | ||
258 | .resume = ohci_sm501_resume, | ||
259 | #endif | ||
260 | .driver = { | ||
261 | .owner = THIS_MODULE, | ||
262 | .name = "sm501-usb", | ||
263 | }, | ||
264 | }; | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 47c5c66a282c..dc544ddc7849 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -408,6 +408,13 @@ struct ohci_hcd { | |||
408 | unsigned eds_scheduled; | 408 | unsigned eds_scheduled; |
409 | struct ed *ed_to_check; | 409 | struct ed *ed_to_check; |
410 | unsigned zf_delay; | 410 | unsigned zf_delay; |
411 | |||
412 | #ifdef DEBUG | ||
413 | struct dentry *debug_dir; | ||
414 | struct dentry *debug_async; | ||
415 | struct dentry *debug_periodic; | ||
416 | struct dentry *debug_registers; | ||
417 | #endif | ||
411 | }; | 418 | }; |
412 | 419 | ||
413 | #ifdef CONFIG_PCI | 420 | #ifdef CONFIG_PCI |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index c225159ca3d3..0ee694f043cc 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -190,9 +190,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
190 | msleep(10); | 190 | msleep(10); |
191 | } | 191 | } |
192 | if (wait_time <= 0) | 192 | if (wait_time <= 0) |
193 | printk(KERN_WARNING "%s %s: BIOS handoff " | 193 | dev_warn(&pdev->dev, "OHCI: BIOS handoff failed" |
194 | "failed (BIOS bug ?) %08x\n", | 194 | " (BIOS bug?) %08x\n", |
195 | pdev->dev.bus_id, "OHCI", | ||
196 | readl(base + OHCI_CONTROL)); | 195 | readl(base + OHCI_CONTROL)); |
197 | 196 | ||
198 | /* reset controller, preserving RWC */ | 197 | /* reset controller, preserving RWC */ |
@@ -243,8 +242,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
243 | switch (cap & 0xff) { | 242 | switch (cap & 0xff) { |
244 | case 1: /* BIOS/SMM/... handoff support */ | 243 | case 1: /* BIOS/SMM/... handoff support */ |
245 | if ((cap & EHCI_USBLEGSUP_BIOS)) { | 244 | if ((cap & EHCI_USBLEGSUP_BIOS)) { |
246 | pr_debug("%s %s: BIOS handoff\n", | 245 | dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n"); |
247 | pdev->dev.bus_id, "EHCI"); | ||
248 | 246 | ||
249 | #if 0 | 247 | #if 0 |
250 | /* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, | 248 | /* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, |
@@ -285,9 +283,8 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
285 | /* well, possibly buggy BIOS... try to shut | 283 | /* well, possibly buggy BIOS... try to shut |
286 | * it down, and hope nothing goes too wrong | 284 | * it down, and hope nothing goes too wrong |
287 | */ | 285 | */ |
288 | printk(KERN_WARNING "%s %s: BIOS handoff " | 286 | dev_warn(&pdev->dev, "EHCI: BIOS handoff failed" |
289 | "failed (BIOS bug ?) %08x\n", | 287 | " (BIOS bug?) %08x\n", cap); |
290 | pdev->dev.bus_id, "EHCI", cap); | ||
291 | pci_write_config_byte(pdev, offset + 2, 0); | 288 | pci_write_config_byte(pdev, offset + 2, 0); |
292 | } | 289 | } |
293 | 290 | ||
@@ -306,17 +303,14 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
306 | cap = 0; | 303 | cap = 0; |
307 | /* FALLTHROUGH */ | 304 | /* FALLTHROUGH */ |
308 | default: | 305 | default: |
309 | printk(KERN_WARNING "%s %s: unrecognized " | 306 | dev_warn(&pdev->dev, "EHCI: unrecognized capability " |
310 | "capability %02x\n", | 307 | "%02x\n", cap & 0xff); |
311 | pdev->dev.bus_id, "EHCI", | ||
312 | cap & 0xff); | ||
313 | break; | 308 | break; |
314 | } | 309 | } |
315 | offset = (cap >> 8) & 0xff; | 310 | offset = (cap >> 8) & 0xff; |
316 | } | 311 | } |
317 | if (!count) | 312 | if (!count) |
318 | printk(KERN_DEBUG "%s %s: capability loop?\n", | 313 | dev_printk(KERN_DEBUG, &pdev->dev, "EHCI: capability loop?\n"); |
319 | pdev->dev.bus_id, "EHCI"); | ||
320 | 314 | ||
321 | /* | 315 | /* |
322 | * halt EHCI & disable its interrupts in any case | 316 | * halt EHCI & disable its interrupts in any case |
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index fe9ceb077d9b..57388252b693 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h | |||
@@ -405,7 +405,7 @@ | |||
405 | 405 | ||
406 | struct r8a66597_pipe_info { | 406 | struct r8a66597_pipe_info { |
407 | u16 pipenum; | 407 | u16 pipenum; |
408 | u16 address; /* R8A66597 HCD usb addres */ | 408 | u16 address; /* R8A66597 HCD usb address */ |
409 | u16 epnum; | 409 | u16 epnum; |
410 | u16 maxpacket; | 410 | u16 maxpacket; |
411 | u16 type; | 411 | u16 type; |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index d1131a87a5b1..0fb114ca1eba 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -478,8 +478,6 @@ static int mdc800_usb_probe (struct usb_interface *intf, | |||
478 | { | 478 | { |
479 | irq_interval=intf_desc->endpoint [j].desc.bInterval; | 479 | irq_interval=intf_desc->endpoint [j].desc.bInterval; |
480 | } | 480 | } |
481 | |||
482 | continue; | ||
483 | } | 481 | } |
484 | } | 482 | } |
485 | if (mdc800->endpoint[i] == -1) | 483 | if (mdc800->endpoint[i] == -1) |
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index d721380b242d..937940404b7a 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cypress_cy7c63.c | 2 | * cypress_cy7c63.c |
3 | * | 3 | * |
4 | * Copyright (c) 2006 Oliver Bock (o.bock@fh-wolfenbuettel.de) | 4 | * Copyright (c) 2006-2007 Oliver Bock (bock@tfh-berlin.de) |
5 | * | 5 | * |
6 | * This driver is based on the Cypress USB Driver by Marcus Maul | 6 | * This driver is based on the Cypress USB Driver by Marcus Maul |
7 | * (cyport) and the 2.0 version of Greg Kroah-Hartman's | 7 | * (cyport) and the 2.0 version of Greg Kroah-Hartman's |
@@ -21,6 +21,9 @@ | |||
21 | * Supported functions: Read/Write Ports | 21 | * Supported functions: Read/Write Ports |
22 | * | 22 | * |
23 | * | 23 | * |
24 | * For up-to-date information please visit: | ||
25 | * http://www.obock.de/kernel/cypress | ||
26 | * | ||
24 | * This program is free software; you can redistribute it and/or | 27 | * This program is free software; you can redistribute it and/or |
25 | * modify it under the terms of the GNU General Public License as | 28 | * modify it under the terms of the GNU General Public License as |
26 | * published by the Free Software Foundation, version 2. | 29 | * published by the Free Software Foundation, version 2. |
@@ -31,7 +34,7 @@ | |||
31 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
32 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
33 | 36 | ||
34 | #define DRIVER_AUTHOR "Oliver Bock (o.bock@fh-wolfenbuettel.de)" | 37 | #define DRIVER_AUTHOR "Oliver Bock (bock@tfh-berlin.de)" |
35 | #define DRIVER_DESC "Cypress CY7C63xxx USB driver" | 38 | #define DRIVER_DESC "Cypress CY7C63xxx USB driver" |
36 | 39 | ||
37 | #define CYPRESS_VENDOR_ID 0xa2c | 40 | #define CYPRESS_VENDOR_ID 0xa2c |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 764696ff1e8e..801070502cc1 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -715,7 +715,7 @@ static unsigned iowarrior_poll(struct file *file, poll_table * wait) | |||
715 | * would use "struct net_driver" instead, and a serial | 715 | * would use "struct net_driver" instead, and a serial |
716 | * device would use "struct tty_driver". | 716 | * device would use "struct tty_driver". |
717 | */ | 717 | */ |
718 | static struct file_operations iowarrior_fops = { | 718 | static const struct file_operations iowarrior_fops = { |
719 | .owner = THIS_MODULE, | 719 | .owner = THIS_MODULE, |
720 | .write = iowarrior_write, | 720 | .write = iowarrior_write, |
721 | .read = iowarrior_read, | 721 | .read = iowarrior_read, |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index aab320085ebf..6664043f4645 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -205,7 +205,7 @@ static DEFINE_MUTEX(open_disc_mutex); | |||
205 | 205 | ||
206 | /* Structure to hold all of our device specific stuff */ | 206 | /* Structure to hold all of our device specific stuff */ |
207 | struct lego_usb_tower { | 207 | struct lego_usb_tower { |
208 | struct semaphore sem; /* locks this structure */ | 208 | struct mutex lock; /* locks this structure */ |
209 | struct usb_device* udev; /* save off the usb device pointer */ | 209 | struct usb_device* udev; /* save off the usb device pointer */ |
210 | unsigned char minor; /* the starting minor number for this device */ | 210 | unsigned char minor; /* the starting minor number for this device */ |
211 | 211 | ||
@@ -361,7 +361,7 @@ static int tower_open (struct inode *inode, struct file *file) | |||
361 | } | 361 | } |
362 | 362 | ||
363 | /* lock this device */ | 363 | /* lock this device */ |
364 | if (down_interruptible (&dev->sem)) { | 364 | if (mutex_lock_interruptible(&dev->lock)) { |
365 | mutex_unlock(&open_disc_mutex); | 365 | mutex_unlock(&open_disc_mutex); |
366 | retval = -ERESTARTSYS; | 366 | retval = -ERESTARTSYS; |
367 | goto exit; | 367 | goto exit; |
@@ -421,7 +421,7 @@ static int tower_open (struct inode *inode, struct file *file) | |||
421 | file->private_data = dev; | 421 | file->private_data = dev; |
422 | 422 | ||
423 | unlock_exit: | 423 | unlock_exit: |
424 | up (&dev->sem); | 424 | mutex_unlock(&dev->lock); |
425 | 425 | ||
426 | exit: | 426 | exit: |
427 | dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval); | 427 | dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval); |
@@ -448,7 +448,7 @@ static int tower_release (struct inode *inode, struct file *file) | |||
448 | } | 448 | } |
449 | 449 | ||
450 | mutex_lock(&open_disc_mutex); | 450 | mutex_lock(&open_disc_mutex); |
451 | if (down_interruptible (&dev->sem)) { | 451 | if (mutex_lock_interruptible(&dev->lock)) { |
452 | retval = -ERESTARTSYS; | 452 | retval = -ERESTARTSYS; |
453 | goto exit; | 453 | goto exit; |
454 | } | 454 | } |
@@ -460,7 +460,9 @@ static int tower_release (struct inode *inode, struct file *file) | |||
460 | } | 460 | } |
461 | if (dev->udev == NULL) { | 461 | if (dev->udev == NULL) { |
462 | /* the device was unplugged before the file was released */ | 462 | /* the device was unplugged before the file was released */ |
463 | up (&dev->sem); /* unlock here as tower_delete frees dev */ | 463 | |
464 | /* unlock here as tower_delete frees dev */ | ||
465 | mutex_unlock(&dev->lock); | ||
464 | tower_delete (dev); | 466 | tower_delete (dev); |
465 | goto exit; | 467 | goto exit; |
466 | } | 468 | } |
@@ -473,7 +475,7 @@ static int tower_release (struct inode *inode, struct file *file) | |||
473 | dev->open_count = 0; | 475 | dev->open_count = 0; |
474 | 476 | ||
475 | unlock_exit: | 477 | unlock_exit: |
476 | up (&dev->sem); | 478 | mutex_unlock(&dev->lock); |
477 | 479 | ||
478 | exit: | 480 | exit: |
479 | mutex_unlock(&open_disc_mutex); | 481 | mutex_unlock(&open_disc_mutex); |
@@ -586,7 +588,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, | |||
586 | dev = (struct lego_usb_tower *)file->private_data; | 588 | dev = (struct lego_usb_tower *)file->private_data; |
587 | 589 | ||
588 | /* lock this object */ | 590 | /* lock this object */ |
589 | if (down_interruptible (&dev->sem)) { | 591 | if (mutex_lock_interruptible(&dev->lock)) { |
590 | retval = -ERESTARTSYS; | 592 | retval = -ERESTARTSYS; |
591 | goto exit; | 593 | goto exit; |
592 | } | 594 | } |
@@ -653,7 +655,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, | |||
653 | 655 | ||
654 | unlock_exit: | 656 | unlock_exit: |
655 | /* unlock the device */ | 657 | /* unlock the device */ |
656 | up (&dev->sem); | 658 | mutex_unlock(&dev->lock); |
657 | 659 | ||
658 | exit: | 660 | exit: |
659 | dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); | 661 | dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); |
@@ -675,7 +677,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t | |||
675 | dev = (struct lego_usb_tower *)file->private_data; | 677 | dev = (struct lego_usb_tower *)file->private_data; |
676 | 678 | ||
677 | /* lock this object */ | 679 | /* lock this object */ |
678 | if (down_interruptible (&dev->sem)) { | 680 | if (mutex_lock_interruptible(&dev->lock)) { |
679 | retval = -ERESTARTSYS; | 681 | retval = -ERESTARTSYS; |
680 | goto exit; | 682 | goto exit; |
681 | } | 683 | } |
@@ -737,7 +739,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t | |||
737 | 739 | ||
738 | unlock_exit: | 740 | unlock_exit: |
739 | /* unlock the device */ | 741 | /* unlock the device */ |
740 | up (&dev->sem); | 742 | mutex_unlock(&dev->lock); |
741 | 743 | ||
742 | exit: | 744 | exit: |
743 | dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); | 745 | dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); |
@@ -862,7 +864,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device | |||
862 | goto exit; | 864 | goto exit; |
863 | } | 865 | } |
864 | 866 | ||
865 | init_MUTEX (&dev->sem); | 867 | mutex_init(&dev->lock); |
866 | 868 | ||
867 | dev->udev = udev; | 869 | dev->udev = udev; |
868 | dev->open_count = 0; | 870 | dev->open_count = 0; |
@@ -1007,16 +1009,16 @@ static void tower_disconnect (struct usb_interface *interface) | |||
1007 | /* give back our minor */ | 1009 | /* give back our minor */ |
1008 | usb_deregister_dev (interface, &tower_class); | 1010 | usb_deregister_dev (interface, &tower_class); |
1009 | 1011 | ||
1010 | down (&dev->sem); | 1012 | mutex_lock(&dev->lock); |
1011 | mutex_unlock(&open_disc_mutex); | 1013 | mutex_unlock(&open_disc_mutex); |
1012 | 1014 | ||
1013 | /* if the device is not opened, then we clean up right now */ | 1015 | /* if the device is not opened, then we clean up right now */ |
1014 | if (!dev->open_count) { | 1016 | if (!dev->open_count) { |
1015 | up (&dev->sem); | 1017 | mutex_unlock(&dev->lock); |
1016 | tower_delete (dev); | 1018 | tower_delete (dev); |
1017 | } else { | 1019 | } else { |
1018 | dev->udev = NULL; | 1020 | dev->udev = NULL; |
1019 | up (&dev->sem); | 1021 | mutex_unlock(&dev->lock); |
1020 | } | 1022 | } |
1021 | 1023 | ||
1022 | info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE)); | 1024 | info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE)); |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 9244d067cec1..cb7fa0eaf3ae 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -323,7 +323,7 @@ sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, unsigned int pipe, void *data, | |||
323 | usb_kill_urb(urb); | 323 | usb_kill_urb(urb); |
324 | retval = -ETIMEDOUT; | 324 | retval = -ETIMEDOUT; |
325 | } else { | 325 | } else { |
326 | /* URB completed within timout */ | 326 | /* URB completed within timeout */ |
327 | retval = urb->status; | 327 | retval = urb->status; |
328 | readbytes = urb->actual_length; | 328 | readbytes = urb->actual_length; |
329 | } | 329 | } |
@@ -3195,20 +3195,6 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3195 | 3195 | ||
3196 | sisusb->present = 1; | 3196 | sisusb->present = 1; |
3197 | 3197 | ||
3198 | #ifdef SISUSB_OLD_CONFIG_COMPAT | ||
3199 | { | ||
3200 | int ret; | ||
3201 | /* Our ioctls are all "32/64bit compatible" */ | ||
3202 | ret = register_ioctl32_conversion(SISUSB_GET_CONFIG_SIZE, NULL); | ||
3203 | ret |= register_ioctl32_conversion(SISUSB_GET_CONFIG, NULL); | ||
3204 | ret |= register_ioctl32_conversion(SISUSB_COMMAND, NULL); | ||
3205 | if (ret) | ||
3206 | dev_err(&sisusb->sisusb_dev->dev, "Error registering ioctl32 translations\n"); | ||
3207 | else | ||
3208 | sisusb->ioctl32registered = 1; | ||
3209 | } | ||
3210 | #endif | ||
3211 | |||
3212 | if (dev->speed == USB_SPEED_HIGH) { | 3198 | if (dev->speed == USB_SPEED_HIGH) { |
3213 | int initscreen = 1; | 3199 | int initscreen = 1; |
3214 | #ifdef INCL_SISUSB_CON | 3200 | #ifdef INCL_SISUSB_CON |
@@ -3271,19 +3257,6 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3271 | 3257 | ||
3272 | usb_set_intfdata(intf, NULL); | 3258 | usb_set_intfdata(intf, NULL); |
3273 | 3259 | ||
3274 | #ifdef SISUSB_OLD_CONFIG_COMPAT | ||
3275 | if (sisusb->ioctl32registered) { | ||
3276 | int ret; | ||
3277 | sisusb->ioctl32registered = 0; | ||
3278 | ret = unregister_ioctl32_conversion(SISUSB_GET_CONFIG_SIZE); | ||
3279 | ret |= unregister_ioctl32_conversion(SISUSB_GET_CONFIG); | ||
3280 | ret |= unregister_ioctl32_conversion(SISUSB_COMMAND); | ||
3281 | if (ret) { | ||
3282 | dev_err(&sisusb->sisusb_dev->dev, "Error unregistering ioctl32 translations\n"); | ||
3283 | } | ||
3284 | } | ||
3285 | #endif | ||
3286 | |||
3287 | sisusb->present = 0; | 3260 | sisusb->present = 0; |
3288 | sisusb->ready = 0; | 3261 | sisusb->ready = 0; |
3289 | 3262 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h index d2d7872cd022..cf0b4a5883f6 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.h +++ b/drivers/usb/misc/sisusbvga/sisusb.h | |||
@@ -120,9 +120,6 @@ struct sisusb_usb_data { | |||
120 | int isopen; /* !=0 if open */ | 120 | int isopen; /* !=0 if open */ |
121 | int present; /* !=0 if device is present on the bus */ | 121 | int present; /* !=0 if device is present on the bus */ |
122 | int ready; /* !=0 if device is ready for userland */ | 122 | int ready; /* !=0 if device is ready for userland */ |
123 | #ifdef SISUSB_OLD_CONFIG_COMPAT | ||
124 | int ioctl32registered; | ||
125 | #endif | ||
126 | int numobufs; /* number of obufs = number of out urbs */ | 123 | int numobufs; /* number of obufs = number of out urbs */ |
127 | char *obuf[NUMOBUFS], *ibuf; /* transfer buffers */ | 124 | char *obuf[NUMOBUFS], *ibuf; /* transfer buffers */ |
128 | int obufsize, ibufsize; | 125 | int obufsize, ibufsize; |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index ea3162146481..da922dfc0dcc 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/moduleparam.h> | 7 | #include <linux/moduleparam.h> |
8 | #include <linux/scatterlist.h> | 8 | #include <linux/scatterlist.h> |
9 | #include <linux/mutex.h> | ||
9 | 10 | ||
10 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
11 | 12 | ||
@@ -64,7 +65,7 @@ struct usbtest_dev { | |||
64 | int in_iso_pipe; | 65 | int in_iso_pipe; |
65 | int out_iso_pipe; | 66 | int out_iso_pipe; |
66 | struct usb_endpoint_descriptor *iso_in, *iso_out; | 67 | struct usb_endpoint_descriptor *iso_in, *iso_out; |
67 | struct semaphore sem; | 68 | struct mutex lock; |
68 | 69 | ||
69 | #define TBUF_SIZE 256 | 70 | #define TBUF_SIZE 256 |
70 | u8 *buf; | 71 | u8 *buf; |
@@ -1151,6 +1152,7 @@ static int verify_halted (int ep, struct urb *urb) | |||
1151 | dbg ("ep %02x couldn't get halt status, %d", ep, retval); | 1152 | dbg ("ep %02x couldn't get halt status, %d", ep, retval); |
1152 | return retval; | 1153 | return retval; |
1153 | } | 1154 | } |
1155 | le16_to_cpus(&status); | ||
1154 | if (status != 1) { | 1156 | if (status != 1) { |
1155 | dbg ("ep %02x bogus status: %04x != 1", ep, status); | 1157 | dbg ("ep %02x bogus status: %04x != 1", ep, status); |
1156 | return -EINVAL; | 1158 | return -EINVAL; |
@@ -1310,7 +1312,7 @@ static int ctrl_out (struct usbtest_dev *dev, | |||
1310 | len += vary; | 1312 | len += vary; |
1311 | 1313 | ||
1312 | /* [real world] the "zero bytes IN" case isn't really used. | 1314 | /* [real world] the "zero bytes IN" case isn't really used. |
1313 | * hardware can easily trip up in this wierd case, since its | 1315 | * hardware can easily trip up in this weird case, since its |
1314 | * status stage is IN, not OUT like other ep0in transfers. | 1316 | * status stage is IN, not OUT like other ep0in transfers. |
1315 | */ | 1317 | */ |
1316 | if (len > length) | 1318 | if (len > length) |
@@ -1558,11 +1560,11 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1558 | || param->sglen < 0 || param->vary < 0) | 1560 | || param->sglen < 0 || param->vary < 0) |
1559 | return -EINVAL; | 1561 | return -EINVAL; |
1560 | 1562 | ||
1561 | if (down_interruptible (&dev->sem)) | 1563 | if (mutex_lock_interruptible(&dev->lock)) |
1562 | return -ERESTARTSYS; | 1564 | return -ERESTARTSYS; |
1563 | 1565 | ||
1564 | if (intf->dev.power.power_state.event != PM_EVENT_ON) { | 1566 | if (intf->dev.power.power_state.event != PM_EVENT_ON) { |
1565 | up (&dev->sem); | 1567 | mutex_unlock(&dev->lock); |
1566 | return -EHOSTUNREACH; | 1568 | return -EHOSTUNREACH; |
1567 | } | 1569 | } |
1568 | 1570 | ||
@@ -1574,7 +1576,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1574 | int res; | 1576 | int res; |
1575 | 1577 | ||
1576 | if (intf->altsetting->desc.bInterfaceNumber) { | 1578 | if (intf->altsetting->desc.bInterfaceNumber) { |
1577 | up (&dev->sem); | 1579 | mutex_unlock(&dev->lock); |
1578 | return -ENODEV; | 1580 | return -ENODEV; |
1579 | } | 1581 | } |
1580 | res = set_altsetting (dev, dev->info->alt); | 1582 | res = set_altsetting (dev, dev->info->alt); |
@@ -1582,7 +1584,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1582 | dev_err (&intf->dev, | 1584 | dev_err (&intf->dev, |
1583 | "set altsetting to %d failed, %d\n", | 1585 | "set altsetting to %d failed, %d\n", |
1584 | dev->info->alt, res); | 1586 | dev->info->alt, res); |
1585 | up (&dev->sem); | 1587 | mutex_unlock(&dev->lock); |
1586 | return res; | 1588 | return res; |
1587 | } | 1589 | } |
1588 | } | 1590 | } |
@@ -1855,7 +1857,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1855 | param->duration.tv_usec += 1000 * 1000; | 1857 | param->duration.tv_usec += 1000 * 1000; |
1856 | param->duration.tv_sec -= 1; | 1858 | param->duration.tv_sec -= 1; |
1857 | } | 1859 | } |
1858 | up (&dev->sem); | 1860 | mutex_unlock(&dev->lock); |
1859 | return retval; | 1861 | return retval; |
1860 | } | 1862 | } |
1861 | 1863 | ||
@@ -1905,7 +1907,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) | |||
1905 | return -ENOMEM; | 1907 | return -ENOMEM; |
1906 | info = (struct usbtest_info *) id->driver_info; | 1908 | info = (struct usbtest_info *) id->driver_info; |
1907 | dev->info = info; | 1909 | dev->info = info; |
1908 | init_MUTEX (&dev->sem); | 1910 | mutex_init(&dev->lock); |
1909 | 1911 | ||
1910 | dev->intf = intf; | 1912 | dev->intf = intf; |
1911 | 1913 | ||
@@ -1990,8 +1992,6 @@ static void usbtest_disconnect (struct usb_interface *intf) | |||
1990 | { | 1992 | { |
1991 | struct usbtest_dev *dev = usb_get_intfdata (intf); | 1993 | struct usbtest_dev *dev = usb_get_intfdata (intf); |
1992 | 1994 | ||
1993 | down (&dev->sem); | ||
1994 | |||
1995 | usb_set_intfdata (intf, NULL); | 1995 | usb_set_intfdata (intf, NULL); |
1996 | dev_dbg (&intf->dev, "disconnect\n"); | 1996 | dev_dbg (&intf->dev, "disconnect\n"); |
1997 | kfree (dev); | 1997 | kfree (dev); |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index f06e4e2b49d3..1774ba5c4c3b 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -1026,6 +1026,8 @@ mon_bin_poll(struct file *file, struct poll_table_struct *wait) | |||
1026 | return mask; | 1026 | return mask; |
1027 | } | 1027 | } |
1028 | 1028 | ||
1029 | #if 0 | ||
1030 | |||
1029 | /* | 1031 | /* |
1030 | * open and close: just keep track of how many times the device is | 1032 | * open and close: just keep track of how many times the device is |
1031 | * mapped, to use the proper memory allocation function. | 1033 | * mapped, to use the proper memory allocation function. |
@@ -1045,33 +1047,31 @@ static void mon_bin_vma_close(struct vm_area_struct *vma) | |||
1045 | /* | 1047 | /* |
1046 | * Map ring pages to user space. | 1048 | * Map ring pages to user space. |
1047 | */ | 1049 | */ |
1048 | struct page *mon_bin_vma_nopage(struct vm_area_struct *vma, | 1050 | static int mon_bin_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
1049 | unsigned long address, int *type) | ||
1050 | { | 1051 | { |
1051 | struct mon_reader_bin *rp = vma->vm_private_data; | 1052 | struct mon_reader_bin *rp = vma->vm_private_data; |
1052 | unsigned long offset, chunk_idx; | 1053 | unsigned long offset, chunk_idx; |
1053 | struct page *pageptr; | 1054 | struct page *pageptr; |
1054 | 1055 | ||
1055 | offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); | 1056 | offset = vmf->pgoff << PAGE_SHIFT; |
1056 | if (offset >= rp->b_size) | 1057 | if (offset >= rp->b_size) |
1057 | return NOPAGE_SIGBUS; | 1058 | return VM_FAULT_SIGBUS; |
1058 | chunk_idx = offset / CHUNK_SIZE; | 1059 | chunk_idx = offset / CHUNK_SIZE; |
1059 | pageptr = rp->b_vec[chunk_idx].pg; | 1060 | pageptr = rp->b_vec[chunk_idx].pg; |
1060 | get_page(pageptr); | 1061 | get_page(pageptr); |
1061 | if (type) | 1062 | vmf->page = pageptr; |
1062 | *type = VM_FAULT_MINOR; | 1063 | return 0; |
1063 | return pageptr; | ||
1064 | } | 1064 | } |
1065 | 1065 | ||
1066 | struct vm_operations_struct mon_bin_vm_ops = { | 1066 | struct vm_operations_struct mon_bin_vm_ops = { |
1067 | .open = mon_bin_vma_open, | 1067 | .open = mon_bin_vma_open, |
1068 | .close = mon_bin_vma_close, | 1068 | .close = mon_bin_vma_close, |
1069 | .nopage = mon_bin_vma_nopage, | 1069 | .fault = mon_bin_vma_fault, |
1070 | }; | 1070 | }; |
1071 | 1071 | ||
1072 | int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) | 1072 | int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) |
1073 | { | 1073 | { |
1074 | /* don't do anything here: "nopage" will set up page table entries */ | 1074 | /* don't do anything here: "fault" will set up page table entries */ |
1075 | vma->vm_ops = &mon_bin_vm_ops; | 1075 | vma->vm_ops = &mon_bin_vm_ops; |
1076 | vma->vm_flags |= VM_RESERVED; | 1076 | vma->vm_flags |= VM_RESERVED; |
1077 | vma->vm_private_data = filp->private_data; | 1077 | vma->vm_private_data = filp->private_data; |
@@ -1079,7 +1079,9 @@ int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) | |||
1079 | return 0; | 1079 | return 0; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | struct file_operations mon_fops_binary = { | 1082 | #endif /* 0 */ |
1083 | |||
1084 | static const struct file_operations mon_fops_binary = { | ||
1083 | .owner = THIS_MODULE, | 1085 | .owner = THIS_MODULE, |
1084 | .open = mon_bin_open, | 1086 | .open = mon_bin_open, |
1085 | .llseek = no_llseek, | 1087 | .llseek = no_llseek, |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 4a86696e6c7d..c1e65dfd9353 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -2,10 +2,7 @@ | |||
2 | # USB Serial device configuration | 2 | # USB Serial device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "USB Serial Converter support" | 5 | menuconfig USB_SERIAL |
6 | depends on USB!=n | ||
7 | |||
8 | config USB_SERIAL | ||
9 | tristate "USB Serial Converter support" | 6 | tristate "USB Serial Converter support" |
10 | depends on USB | 7 | depends on USB |
11 | ---help--- | 8 | ---help--- |
@@ -20,6 +17,8 @@ config USB_SERIAL | |||
20 | To compile this driver as a module, choose M here: the | 17 | To compile this driver as a module, choose M here: the |
21 | module will be called usbserial. | 18 | module will be called usbserial. |
22 | 19 | ||
20 | if USB_SERIAL | ||
21 | |||
23 | config USB_SERIAL_CONSOLE | 22 | config USB_SERIAL_CONSOLE |
24 | bool "USB Serial Console device support (EXPERIMENTAL)" | 23 | bool "USB Serial Console device support (EXPERIMENTAL)" |
25 | depends on USB_SERIAL=y && EXPERIMENTAL | 24 | depends on USB_SERIAL=y && EXPERIMENTAL |
@@ -43,6 +42,12 @@ config USB_SERIAL_CONSOLE | |||
43 | 42 | ||
44 | If unsure, say N. | 43 | If unsure, say N. |
45 | 44 | ||
45 | config USB_EZUSB | ||
46 | bool "Functions for loading firmware on EZUSB chips" | ||
47 | depends on USB_SERIAL | ||
48 | help | ||
49 | Say Y here if you need EZUSB device support. | ||
50 | |||
46 | config USB_SERIAL_GENERIC | 51 | config USB_SERIAL_GENERIC |
47 | bool "USB Generic Serial Driver" | 52 | bool "USB Generic Serial Driver" |
48 | depends on USB_SERIAL | 53 | depends on USB_SERIAL |
@@ -105,6 +110,7 @@ config USB_SERIAL_CH341 | |||
105 | config USB_SERIAL_WHITEHEAT | 110 | config USB_SERIAL_WHITEHEAT |
106 | tristate "USB ConnectTech WhiteHEAT Serial Driver" | 111 | tristate "USB ConnectTech WhiteHEAT Serial Driver" |
107 | depends on USB_SERIAL | 112 | depends on USB_SERIAL |
113 | select USB_EZUSB | ||
108 | help | 114 | help |
109 | Say Y here if you want to use a ConnectTech WhiteHEAT 4 port | 115 | Say Y here if you want to use a ConnectTech WhiteHEAT 4 port |
110 | USB to serial converter device. | 116 | USB to serial converter device. |
@@ -282,9 +288,21 @@ config USB_SERIAL_IPW | |||
282 | To compile this driver as a module, choose M here: the | 288 | To compile this driver as a module, choose M here: the |
283 | module will be called ipw. | 289 | module will be called ipw. |
284 | 290 | ||
291 | config USB_SERIAL_IUU | ||
292 | tristate "USB Infinity USB Unlimited Phoenix Driver (Experimental)" | ||
293 | depends on USB_SERIAL && EXPERIMENTAL | ||
294 | help | ||
295 | Say Y here if you want to use a IUU in phoenix mode and get | ||
296 | an extra ttyUSBx device. More information available on | ||
297 | http://eczema.ecze.com/iuu_phoenix.html | ||
298 | |||
299 | To compile this driver as a module, choose M here: the | ||
300 | module will be called iuu_phoenix.o | ||
301 | |||
285 | config USB_SERIAL_KEYSPAN_PDA | 302 | config USB_SERIAL_KEYSPAN_PDA |
286 | tristate "USB Keyspan PDA Single Port Serial Driver" | 303 | tristate "USB Keyspan PDA Single Port Serial Driver" |
287 | depends on USB_SERIAL | 304 | depends on USB_SERIAL |
305 | select USB_EZUSB | ||
288 | help | 306 | help |
289 | Say Y here if you want to use a Keyspan PDA single port USB to | 307 | Say Y here if you want to use a Keyspan PDA single port USB to |
290 | serial converter device. This driver makes use of firmware | 308 | serial converter device. This driver makes use of firmware |
@@ -296,6 +314,7 @@ config USB_SERIAL_KEYSPAN_PDA | |||
296 | config USB_SERIAL_KEYSPAN | 314 | config USB_SERIAL_KEYSPAN |
297 | tristate "USB Keyspan USA-xxx Serial Driver" | 315 | tristate "USB Keyspan USA-xxx Serial Driver" |
298 | depends on USB_SERIAL | 316 | depends on USB_SERIAL |
317 | select USB_EZUSB | ||
299 | ---help--- | 318 | ---help--- |
300 | Say Y here if you want to use Keyspan USB to serial converter | 319 | Say Y here if you want to use Keyspan USB to serial converter |
301 | devices. This driver makes use of Keyspan's official firmware | 320 | devices. This driver makes use of Keyspan's official firmware |
@@ -538,6 +557,7 @@ config USB_SERIAL_CYBERJACK | |||
538 | config USB_SERIAL_XIRCOM | 557 | config USB_SERIAL_XIRCOM |
539 | tristate "USB Xircom / Entregra Single Port Serial Driver" | 558 | tristate "USB Xircom / Entregra Single Port Serial Driver" |
540 | depends on USB_SERIAL | 559 | depends on USB_SERIAL |
560 | select USB_EZUSB | ||
541 | help | 561 | help |
542 | Say Y here if you want to use a Xircom or Entregra single port USB to | 562 | Say Y here if you want to use a Xircom or Entregra single port USB to |
543 | serial converter device. This driver makes use of firmware | 563 | serial converter device. This driver makes use of firmware |
@@ -585,11 +605,4 @@ config USB_SERIAL_DEBUG | |||
585 | To compile this driver as a module, choose M here: the | 605 | To compile this driver as a module, choose M here: the |
586 | module will be called usb-debug. | 606 | module will be called usb-debug. |
587 | 607 | ||
588 | config USB_EZUSB | 608 | endif # USB_SERIAL |
589 | bool | ||
590 | depends on USB_SERIAL_KEYSPAN_PDA || USB_SERIAL_XIRCOM || USB_SERIAL_KEYSPAN || USB_SERIAL_WHITEHEAT | ||
591 | default y | ||
592 | |||
593 | |||
594 | endmenu | ||
595 | |||
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index d6fb384e52b2..0db109a54d10 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -30,6 +30,7 @@ obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o | |||
30 | obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o | 30 | obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o |
31 | obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o | 31 | obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o |
32 | obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o | 32 | obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o |
33 | obj-$(CONFIG_USB_SERIAL_IUU) += iuu_phoenix.o | ||
33 | obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o | 34 | obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o |
34 | obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o | 35 | obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o |
35 | obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o | 36 | obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 77bb893bf2e9..f156dba0300f 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -217,7 +217,10 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) | |||
217 | priv->rts_state = 0; | 217 | priv->rts_state = 0; |
218 | priv->dtr_state = 0; | 218 | priv->dtr_state = 0; |
219 | 219 | ||
220 | airprime_send_setup(port); | 220 | mutex_lock(&port->serial->disc_mutex); |
221 | if (!port->serial->disconnected) | ||
222 | airprime_send_setup(port); | ||
223 | mutex_lock(&port->serial->disc_mutex); | ||
221 | 224 | ||
222 | for (i = 0; i < NUM_READ_URBS; ++i) { | 225 | for (i = 0; i < NUM_READ_URBS; ++i) { |
223 | usb_kill_urb (priv->read_urbp[i]); | 226 | usb_kill_urb (priv->read_urbp[i]); |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index ddfee918000d..fe2bfd67ba8e 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -151,8 +151,10 @@ static int ark3116_attach(struct usb_serial *serial) | |||
151 | return 0; | 151 | return 0; |
152 | 152 | ||
153 | cleanup: | 153 | cleanup: |
154 | for (--i; i >= 0; --i) | 154 | for (--i; i >= 0; --i) { |
155 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
155 | usb_set_serial_port_data(serial->port[i], NULL); | 156 | usb_set_serial_port_data(serial->port[i], NULL); |
157 | } | ||
156 | return -ENOMEM; | 158 | return -ENOMEM; |
157 | } | 159 | } |
158 | 160 | ||
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 86724e885704..df0a2b3b0294 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -350,14 +350,12 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios | |||
350 | unsigned long control_state; | 350 | unsigned long control_state; |
351 | int bad_flow_control; | 351 | int bad_flow_control; |
352 | speed_t baud; | 352 | speed_t baud; |
353 | struct ktermios *termios = port->tty->termios; | ||
353 | 354 | ||
354 | if ((!port->tty) || (!port->tty->termios)) { | 355 | iflag = termios->c_iflag; |
355 | dbg ("%s - no tty or termios structure", __FUNCTION__); | 356 | cflag = termios->c_cflag; |
356 | return; | ||
357 | } | ||
358 | 357 | ||
359 | iflag = port->tty->termios->c_iflag; | 358 | termios->c_cflag &= ~CMSPAR; |
360 | cflag = port->tty->termios->c_cflag; | ||
361 | 359 | ||
362 | /* get a local copy of the current port settings */ | 360 | /* get a local copy of the current port settings */ |
363 | spin_lock_irqsave(&priv->lock, flags); | 361 | spin_lock_irqsave(&priv->lock, flags); |
@@ -369,33 +367,30 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios | |||
369 | old_cflag = old_termios->c_cflag; | 367 | old_cflag = old_termios->c_cflag; |
370 | 368 | ||
371 | /* Set the baud rate */ | 369 | /* Set the baud rate */ |
372 | if( (cflag&CBAUD) != (old_cflag&CBAUD) ) { | 370 | if ((cflag & CBAUD) != (old_cflag & CBAUD)) { |
373 | /* reassert DTR and (maybe) RTS on transition from B0 */ | 371 | /* reassert DTR and (maybe) RTS on transition from B0 */ |
374 | if( (old_cflag&CBAUD) == B0 ) { | 372 | if( (old_cflag&CBAUD) == B0 ) { |
375 | control_state |= (TIOCM_DTR|TIOCM_RTS); | 373 | control_state |= (TIOCM_DTR|TIOCM_RTS); |
376 | if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0) | 374 | if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0) |
377 | err("Set DTR error"); | 375 | err("Set DTR error"); |
378 | /* don't set RTS if using hardware flow control */ | 376 | /* don't set RTS if using hardware flow control */ |
379 | if (!(old_cflag&CRTSCTS) ) | 377 | if (!(old_cflag & CRTSCTS)) |
380 | if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0) | 378 | if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0) |
381 | err("Set RTS error"); | 379 | err("Set RTS error"); |
382 | } | 380 | } |
383 | } | 381 | } |
384 | 382 | ||
385 | baud = tty_get_baud_rate(port->tty); | 383 | baud = tty_get_baud_rate(port->tty); |
386 | if (baud == 0) { | 384 | if (baud) { |
387 | dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__); | 385 | urb_value = BELKIN_SA_BAUD(baud); |
388 | return; | 386 | /* Clip to maximum speed */ |
389 | } | 387 | if (urb_value == 0) |
390 | urb_value = BELKIN_SA_BAUD(baud); | 388 | urb_value = 1; |
391 | /* Clip to maximum speed */ | 389 | /* Turn it back into a resulting real baud rate */ |
392 | if (urb_value == 0) | 390 | baud = BELKIN_SA_BAUD(urb_value); |
393 | urb_value = 1; | 391 | |
394 | /* Turn it back into a resulting real baud rate */ | 392 | /* Report the actual baud rate back to the caller */ |
395 | baud = BELKIN_SA_BAUD(urb_value); | 393 | tty_encode_baud_rate(port->tty, baud, baud); |
396 | /* FIXME: Once the tty updates are done then push this back to the tty */ | ||
397 | |||
398 | if ((cflag & CBAUD) != B0 ) { | ||
399 | if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) | 394 | if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) |
400 | err("Set baudrate error"); | 395 | err("Set baudrate error"); |
401 | } else { | 396 | } else { |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 0362654d3b52..66ce30c1b75b 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -64,8 +64,8 @@ static int usb_console_setup(struct console *co, char *options) | |||
64 | struct usb_serial *serial; | 64 | struct usb_serial *serial; |
65 | struct usb_serial_port *port; | 65 | struct usb_serial_port *port; |
66 | int retval = 0; | 66 | int retval = 0; |
67 | struct tty_struct *tty; | 67 | struct tty_struct *tty = NULL; |
68 | struct ktermios *termios; | 68 | struct ktermios *termios = NULL, dummy; |
69 | 69 | ||
70 | dbg ("%s", __FUNCTION__); | 70 | dbg ("%s", __FUNCTION__); |
71 | 71 | ||
@@ -133,11 +133,14 @@ static int usb_console_setup(struct console *co, char *options) | |||
133 | } | 133 | } |
134 | co->cflag = cflag; | 134 | co->cflag = cflag; |
135 | 135 | ||
136 | /* grab the first serial port that happens to be connected */ | 136 | /* |
137 | serial = usb_serial_get_by_index(0); | 137 | * no need to check the index here: if the index is wrong, console |
138 | * code won't call us | ||
139 | */ | ||
140 | serial = usb_serial_get_by_index(co->index); | ||
138 | if (serial == NULL) { | 141 | if (serial == NULL) { |
139 | /* no device is connected yet, sorry :( */ | 142 | /* no device is connected yet, sorry :( */ |
140 | err ("No USB device connected to ttyUSB0"); | 143 | err ("No USB device connected to ttyUSB%i", co->index); |
141 | return -ENODEV; | 144 | return -ENODEV; |
142 | } | 145 | } |
143 | 146 | ||
@@ -148,49 +151,64 @@ static int usb_console_setup(struct console *co, char *options) | |||
148 | 151 | ||
149 | ++port->open_count; | 152 | ++port->open_count; |
150 | if (port->open_count == 1) { | 153 | if (port->open_count == 1) { |
154 | if (serial->type->set_termios) { | ||
155 | /* | ||
156 | * allocate a fake tty so the driver can initialize | ||
157 | * the termios structure, then later call set_termios to | ||
158 | * configure according to command line arguments | ||
159 | */ | ||
160 | tty = kzalloc(sizeof(*tty), GFP_KERNEL); | ||
161 | if (!tty) { | ||
162 | retval = -ENOMEM; | ||
163 | err("no more memory"); | ||
164 | goto reset_open_count; | ||
165 | } | ||
166 | termios = kzalloc(sizeof(*termios), GFP_KERNEL); | ||
167 | if (!termios) { | ||
168 | retval = -ENOMEM; | ||
169 | err("no more memory"); | ||
170 | goto free_tty; | ||
171 | } | ||
172 | memset(&dummy, 0, sizeof(struct ktermios)); | ||
173 | tty->termios = termios; | ||
174 | port->tty = tty; | ||
175 | } | ||
176 | |||
151 | /* only call the device specific open if this | 177 | /* only call the device specific open if this |
152 | * is the first time the port is opened */ | 178 | * is the first time the port is opened */ |
153 | if (serial->type->open) | 179 | if (serial->type->open) |
154 | retval = serial->type->open(port, NULL); | 180 | retval = serial->type->open(port, NULL); |
155 | else | 181 | else |
156 | retval = usb_serial_generic_open(port, NULL); | 182 | retval = usb_serial_generic_open(port, NULL); |
157 | if (retval) | ||
158 | port->open_count = 0; | ||
159 | } | ||
160 | 183 | ||
161 | if (retval) { | 184 | if (retval) { |
162 | err ("could not open USB console port"); | 185 | err("could not open USB console port"); |
163 | return retval; | 186 | goto free_termios; |
164 | } | ||
165 | |||
166 | if (serial->type->set_termios) { | ||
167 | struct ktermios dummy; | ||
168 | /* build up a fake tty structure so that the open call has something | ||
169 | * to look at to get the cflag value */ | ||
170 | tty = kzalloc(sizeof(*tty), GFP_KERNEL); | ||
171 | if (!tty) { | ||
172 | err ("no more memory"); | ||
173 | return -ENOMEM; | ||
174 | } | 187 | } |
175 | termios = kzalloc(sizeof(*termios), GFP_KERNEL); | ||
176 | if (!termios) { | ||
177 | err ("no more memory"); | ||
178 | kfree (tty); | ||
179 | return -ENOMEM; | ||
180 | } | ||
181 | memset(&dummy, 0, sizeof(struct ktermios)); | ||
182 | termios->c_cflag = cflag; | ||
183 | tty->termios = termios; | ||
184 | port->tty = tty; | ||
185 | 188 | ||
186 | /* set up the initial termios settings */ | 189 | if (serial->type->set_termios) { |
187 | serial->type->set_termios(port, &dummy); | 190 | termios->c_cflag = cflag; |
188 | port->tty = NULL; | 191 | serial->type->set_termios(port, &dummy); |
189 | kfree (termios); | 192 | |
190 | kfree (tty); | 193 | port->tty = NULL; |
194 | kfree(termios); | ||
195 | kfree(tty); | ||
196 | } | ||
191 | } | 197 | } |
192 | 198 | ||
199 | port->console = 1; | ||
200 | retval = 0; | ||
201 | |||
202 | out: | ||
193 | return retval; | 203 | return retval; |
204 | free_termios: | ||
205 | kfree(termios); | ||
206 | port->tty = NULL; | ||
207 | free_tty: | ||
208 | kfree(tty); | ||
209 | reset_open_count: | ||
210 | port->open_count = 0; | ||
211 | goto out; | ||
194 | } | 212 | } |
195 | 213 | ||
196 | static void usb_console_write(struct console *co, const char *buf, unsigned count) | 214 | static void usb_console_write(struct console *co, const char *buf, unsigned count) |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 22833589c4be..f3ca66017a03 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -59,6 +59,7 @@ static struct usb_device_id id_table [] = { | |||
59 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ | 59 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ |
60 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 60 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
61 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ | 61 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ |
62 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ | ||
62 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ | 63 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ |
63 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ | 64 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ |
64 | { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ | 65 | { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ |
@@ -76,8 +77,13 @@ static struct usb_device_id id_table [] = { | |||
76 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | 77 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ |
77 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 78 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
78 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 79 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
80 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ | ||
81 | { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ | ||
82 | { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ | ||
83 | { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */ | ||
79 | { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */ | 84 | { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */ |
80 | { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ | 85 | { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ |
86 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ | ||
81 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 87 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
82 | { } /* Terminating Entry */ | 88 | { } /* Terminating Entry */ |
83 | }; | 89 | }; |
@@ -342,7 +348,10 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp) | |||
342 | usb_kill_urb(port->write_urb); | 348 | usb_kill_urb(port->write_urb); |
343 | usb_kill_urb(port->read_urb); | 349 | usb_kill_urb(port->read_urb); |
344 | 350 | ||
345 | cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); | 351 | mutex_lock(&port->serial->disc_mutex); |
352 | if (!port->serial->disconnected) | ||
353 | cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); | ||
354 | mutex_unlock(&port->serial->disc_mutex); | ||
346 | } | 355 | } |
347 | 356 | ||
348 | /* | 357 | /* |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 4353df92487f..8d9b045aa7e8 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -319,7 +319,6 @@ static void cyberjack_read_int_callback( struct urb *urb ) | |||
319 | /* React only to interrupts signaling a bulk_in transfer */ | 319 | /* React only to interrupts signaling a bulk_in transfer */ |
320 | if( (urb->actual_length==4) && (data[0]==0x01) ) { | 320 | if( (urb->actual_length==4) && (data[0]==0x01) ) { |
321 | short old_rdtodo; | 321 | short old_rdtodo; |
322 | int result; | ||
323 | 322 | ||
324 | /* This is a announcement of coming bulk_ins. */ | 323 | /* This is a announcement of coming bulk_ins. */ |
325 | unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3; | 324 | unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3; |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 163386336a5d..08c65c1a3771 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -682,7 +682,6 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) | |||
682 | { | 682 | { |
683 | struct cypress_private *priv = usb_get_serial_port_data(port); | 683 | struct cypress_private *priv = usb_get_serial_port_data(port); |
684 | unsigned int c_cflag; | 684 | unsigned int c_cflag; |
685 | unsigned long flags; | ||
686 | int bps; | 685 | int bps; |
687 | long timeout; | 686 | long timeout; |
688 | wait_queue_t wait; | 687 | wait_queue_t wait; |
@@ -690,7 +689,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) | |||
690 | dbg("%s - port %d", __FUNCTION__, port->number); | 689 | dbg("%s - port %d", __FUNCTION__, port->number); |
691 | 690 | ||
692 | /* wait for data to drain from buffer */ | 691 | /* wait for data to drain from buffer */ |
693 | spin_lock_irqsave(&priv->lock, flags); | 692 | spin_lock_irq(&priv->lock); |
694 | timeout = CYPRESS_CLOSING_WAIT; | 693 | timeout = CYPRESS_CLOSING_WAIT; |
695 | init_waitqueue_entry(&wait, current); | 694 | init_waitqueue_entry(&wait, current); |
696 | add_wait_queue(&port->tty->write_wait, &wait); | 695 | add_wait_queue(&port->tty->write_wait, &wait); |
@@ -698,18 +697,25 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) | |||
698 | set_current_state(TASK_INTERRUPTIBLE); | 697 | set_current_state(TASK_INTERRUPTIBLE); |
699 | if (cypress_buf_data_avail(priv->buf) == 0 | 698 | if (cypress_buf_data_avail(priv->buf) == 0 |
700 | || timeout == 0 || signal_pending(current) | 699 | || timeout == 0 || signal_pending(current) |
701 | || !usb_get_intfdata(port->serial->interface)) | 700 | /* without mutex, allowed due to harmless failure mode */ |
701 | || port->serial->disconnected) | ||
702 | break; | 702 | break; |
703 | spin_unlock_irqrestore(&priv->lock, flags); | 703 | spin_unlock_irq(&priv->lock); |
704 | timeout = schedule_timeout(timeout); | 704 | timeout = schedule_timeout(timeout); |
705 | spin_lock_irqsave(&priv->lock, flags); | 705 | spin_lock_irq(&priv->lock); |
706 | } | 706 | } |
707 | set_current_state(TASK_RUNNING); | 707 | set_current_state(TASK_RUNNING); |
708 | remove_wait_queue(&port->tty->write_wait, &wait); | 708 | remove_wait_queue(&port->tty->write_wait, &wait); |
709 | /* clear out any remaining data in the buffer */ | 709 | /* clear out any remaining data in the buffer */ |
710 | cypress_buf_clear(priv->buf); | 710 | cypress_buf_clear(priv->buf); |
711 | spin_unlock_irqrestore(&priv->lock, flags); | 711 | spin_unlock_irq(&priv->lock); |
712 | 712 | ||
713 | /* writing is potentially harmful, lock must be taken */ | ||
714 | mutex_lock(&port->serial->disc_mutex); | ||
715 | if (port->serial->disconnected) { | ||
716 | mutex_unlock(&port->serial->disc_mutex); | ||
717 | return; | ||
718 | } | ||
713 | /* wait for characters to drain from device */ | 719 | /* wait for characters to drain from device */ |
714 | bps = tty_get_baud_rate(port->tty); | 720 | bps = tty_get_baud_rate(port->tty); |
715 | if (bps > 1200) | 721 | if (bps > 1200) |
@@ -727,10 +733,10 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) | |||
727 | if (c_cflag & HUPCL) { | 733 | if (c_cflag & HUPCL) { |
728 | /* drop dtr and rts */ | 734 | /* drop dtr and rts */ |
729 | priv = usb_get_serial_port_data(port); | 735 | priv = usb_get_serial_port_data(port); |
730 | spin_lock_irqsave(&priv->lock, flags); | 736 | spin_lock_irq(&priv->lock); |
731 | priv->line_control = 0; | 737 | priv->line_control = 0; |
732 | priv->cmd_ctrl = 1; | 738 | priv->cmd_ctrl = 1; |
733 | spin_unlock_irqrestore(&priv->lock, flags); | 739 | spin_unlock_irq(&priv->lock); |
734 | cypress_write(port, NULL, 0); | 740 | cypress_write(port, NULL, 0); |
735 | } | 741 | } |
736 | } | 742 | } |
@@ -738,6 +744,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) | |||
738 | if (stats) | 744 | if (stats) |
739 | dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", | 745 | dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", |
740 | priv->bytes_in, priv->bytes_out, priv->cmd_count); | 746 | priv->bytes_in, priv->bytes_out, priv->cmd_count); |
747 | mutex_unlock(&port->serial->disc_mutex); | ||
741 | } /* cypress_close */ | 748 | } /* cypress_close */ |
742 | 749 | ||
743 | 750 | ||
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index ae410c4678ea..5f9c6e46bee5 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -1405,19 +1405,19 @@ static void digi_close(struct usb_serial_port *port, struct file *filp) | |||
1405 | unsigned char buf[32]; | 1405 | unsigned char buf[32]; |
1406 | struct tty_struct *tty = port->tty; | 1406 | struct tty_struct *tty = port->tty; |
1407 | struct digi_port *priv = usb_get_serial_port_data(port); | 1407 | struct digi_port *priv = usb_get_serial_port_data(port); |
1408 | unsigned long flags = 0; | ||
1409 | 1408 | ||
1410 | dbg("digi_close: TOP: port=%d, open_count=%d", | 1409 | dbg("digi_close: TOP: port=%d, open_count=%d", |
1411 | priv->dp_port_num, port->open_count); | 1410 | priv->dp_port_num, port->open_count); |
1412 | 1411 | ||
1412 | mutex_lock(&port->serial->disc_mutex); | ||
1413 | /* if disconnected, just clear flags */ | 1413 | /* if disconnected, just clear flags */ |
1414 | if (!usb_get_intfdata(port->serial->interface)) | 1414 | if (port->serial->disconnected) |
1415 | goto exit; | 1415 | goto exit; |
1416 | 1416 | ||
1417 | /* do cleanup only after final close on this port */ | 1417 | /* do cleanup only after final close on this port */ |
1418 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 1418 | spin_lock_irq(&priv->dp_port_lock); |
1419 | priv->dp_in_close = 1; | 1419 | priv->dp_in_close = 1; |
1420 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | 1420 | spin_unlock_irq(&priv->dp_port_lock); |
1421 | 1421 | ||
1422 | /* tell line discipline to process only XON/XOFF */ | 1422 | /* tell line discipline to process only XON/XOFF */ |
1423 | tty->closing = 1; | 1423 | tty->closing = 1; |
@@ -1482,11 +1482,12 @@ static void digi_close(struct usb_serial_port *port, struct file *filp) | |||
1482 | } | 1482 | } |
1483 | tty->closing = 0; | 1483 | tty->closing = 0; |
1484 | exit: | 1484 | exit: |
1485 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 1485 | spin_lock_irq(&priv->dp_port_lock); |
1486 | priv->dp_write_urb_in_use = 0; | 1486 | priv->dp_write_urb_in_use = 0; |
1487 | priv->dp_in_close = 0; | 1487 | priv->dp_in_close = 0; |
1488 | wake_up_interruptible(&priv->dp_close_wait); | 1488 | wake_up_interruptible(&priv->dp_close_wait); |
1489 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | 1489 | spin_unlock_irq(&priv->dp_port_lock); |
1490 | mutex_unlock(&port->serial->disc_mutex); | ||
1490 | dbg("digi_close: done"); | 1491 | dbg("digi_close: done"); |
1491 | } | 1492 | } |
1492 | 1493 | ||
diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c index 97ee718b1da2..3f698baa0abb 100644 --- a/drivers/usb/serial/ezusb.c +++ b/drivers/usb/serial/ezusb.c | |||
@@ -53,6 +53,6 @@ int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | 55 | ||
56 | EXPORT_SYMBOL(ezusb_writememory); | 56 | EXPORT_SYMBOL_GPL(ezusb_writememory); |
57 | EXPORT_SYMBOL(ezusb_set_reset); | 57 | EXPORT_SYMBOL_GPL(ezusb_set_reset); |
58 | 58 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c40e77dccf8e..90dcc625f70d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -17,226 +17,8 @@ | |||
17 | * See http://ftdi-usb-sio.sourceforge.net for upto date testing info | 17 | * See http://ftdi-usb-sio.sourceforge.net for upto date testing info |
18 | * and extra documentation | 18 | * and extra documentation |
19 | * | 19 | * |
20 | * (21/Jul/2004) Ian Abbott | 20 | * Change entries from 2004 and earlier can be found in versions of this |
21 | * Incorporated Steven Turner's code to add support for the FT2232C chip. | 21 | * file in kernel versions prior to the 2.6.24 release. |
22 | * The prelimilary port to the 2.6 kernel was by Rus V. Brushkoff. I have | ||
23 | * fixed a couple of things. | ||
24 | * | ||
25 | * (27/May/2004) Ian Abbott | ||
26 | * Improved throttling code, mostly stolen from the WhiteHEAT driver. | ||
27 | * | ||
28 | * (26/Mar/2004) Jan Capek | ||
29 | * Added PID's for ICD-U20/ICD-U40 - incircuit PIC debuggers from CCS Inc. | ||
30 | * | ||
31 | * (09/Feb/2004) Ian Abbott | ||
32 | * Changed full name of USB-UIRT device to avoid "/" character. | ||
33 | * Added FTDI's alternate PID (0x6006) for FT232/245 devices. | ||
34 | * Added PID for "ELV USB Module UO100" from Stefan Frings. | ||
35 | * | ||
36 | * (21/Oct/2003) Ian Abbott | ||
37 | * Renamed some VID/PID macros for Matrix Orbital and Perle Systems | ||
38 | * devices. Removed Matrix Orbital and Perle Systems devices from the | ||
39 | * 8U232AM device table, but left them in the FT232BM table, as they are | ||
40 | * known to use only FT232BM. | ||
41 | * | ||
42 | * (17/Oct/2003) Scott Allen | ||
43 | * Added vid/pid for Perle Systems UltraPort USB serial converters | ||
44 | * | ||
45 | * (21/Sep/2003) Ian Abbott | ||
46 | * Added VID/PID for Omnidirectional Control Technology US101 USB to | ||
47 | * RS-232 adapter (also rebadged as Dick Smith Electronics XH6381). | ||
48 | * VID/PID supplied by Donald Gordon. | ||
49 | * | ||
50 | * (19/Aug/2003) Ian Abbott | ||
51 | * Freed urb's transfer buffer in write bulk callback. | ||
52 | * Omitted some paranoid checks in write bulk callback that don't matter. | ||
53 | * Scheduled work in write bulk callback regardless of port's open count. | ||
54 | * | ||
55 | * (05/Aug/2003) Ian Abbott | ||
56 | * Added VID/PID for ID TECH IDT1221U USB to RS-232 adapter. | ||
57 | * VID/PID provided by Steve Briggs. | ||
58 | * | ||
59 | * (23/Jul/2003) Ian Abbott | ||
60 | * Added PIDs for CrystalFontz 547, 633, 631, 635, 640 and 640 from | ||
61 | * Wayne Wylupski. | ||
62 | * | ||
63 | * (10/Jul/2003) David Glance | ||
64 | * Added PID for DSS-20 SyncStation cradle for Sony-Ericsson P800. | ||
65 | * | ||
66 | * (27/Jun/2003) Ian Abbott | ||
67 | * Reworked the urb handling logic. We have no more pool, but dynamically | ||
68 | * allocate the urb and the transfer buffer on the fly. In testing this | ||
69 | * does not incure any measurable overhead. This also relies on the fact | ||
70 | * that we have proper reference counting logic for urbs. I nicked this | ||
71 | * from Greg KH's Visor driver. | ||
72 | * | ||
73 | * (23/Jun/2003) Ian Abbott | ||
74 | * Reduced flip buffer pushes and corrected a data length test in | ||
75 | * ftdi_read_bulk_callback. | ||
76 | * Defererence pointers after any paranoid checks, not before. | ||
77 | * | ||
78 | * (21/Jun/2003) Erik Nygren | ||
79 | * Added support for Home Electronics Tira-1 IR transceiver using FT232BM chip. | ||
80 | * See <http://www.home-electro.com/tira1.htm>. Only operates properly | ||
81 | * at 100000 and RTS-CTS, so set custom divisor mode on startup. | ||
82 | * Also force the Tira-1 and USB-UIRT to only use their custom baud rates. | ||
83 | * | ||
84 | * (18/Jun/2003) Ian Abbott | ||
85 | * Added Device ID of the USB relais from Rudolf Gugler (backported from | ||
86 | * Philipp Gühring's patch for 2.5.x kernel). | ||
87 | * Moved read transfer buffer reallocation into startup function. | ||
88 | * Free existing write urb and transfer buffer in startup function. | ||
89 | * Only use urbs in write urb pool that were successfully allocated. | ||
90 | * Moved some constant macros out of functions. | ||
91 | * Minor whitespace and comment changes. | ||
92 | * | ||
93 | * (12/Jun/2003) David Norwood | ||
94 | * Added support for USB-UIRT IR transceiver using 8U232AM chip. | ||
95 | * See <http://home.earthlink.net/~jrhees/USBUIRT/index.htm>. Only | ||
96 | * operates properly at 312500, so set custom divisor mode on startup. | ||
97 | * | ||
98 | * (12/Jun/2003) Ian Abbott | ||
99 | * Added Sealevel SeaLINK+ 210x, 220x, 240x, 280x vid/pids from Tuan Hoang | ||
100 | * - I've eliminated some that don't seem to exist! | ||
101 | * Added Home Electronics Tira-1 IR transceiver pid from Chris Horn | ||
102 | * Some whitespace/coding-style cleanups | ||
103 | * | ||
104 | * (11/Jun/2003) Ian Abbott | ||
105 | * Fixed unsafe spinlock usage in ftdi_write | ||
106 | * | ||
107 | * (24/Feb/2003) Richard Shooter | ||
108 | * Increase read buffer size to improve read speeds at higher baud rates | ||
109 | * (specifically tested with up to 1Mb/sec at 1.5M baud) | ||
110 | * | ||
111 | * (23/Feb/2003) John Wilkins | ||
112 | * Added Xon/xoff flow control (activating support in the ftdi device) | ||
113 | * Added vid/pid for Videonetworks/Homechoice (UK ISP) | ||
114 | * | ||
115 | * (23/Feb/2003) Bill Ryder | ||
116 | * Added matrix orb device vid/pids from Wayne Wylupski | ||
117 | * | ||
118 | * (19/Feb/2003) Ian Abbott | ||
119 | * For TIOCSSERIAL, set alt_speed to 0 when ASYNC_SPD_MASK value has | ||
120 | * changed to something other than ASYNC_SPD_HI, ASYNC_SPD_VHI, | ||
121 | * ASYNC_SPD_SHI or ASYNC_SPD_WARP. Also, unless ASYNC_SPD_CUST is in | ||
122 | * force, don't bother changing baud rate when custom_divisor has changed. | ||
123 | * | ||
124 | * (18/Feb/2003) Ian Abbott | ||
125 | * Fixed TIOCMGET handling to include state of DTR and RTS, the state | ||
126 | * of which are now saved by set_dtr() and set_rts(). | ||
127 | * Fixed improper storage class for buf in set_dtr() and set_rts(). | ||
128 | * Added FT232BM chip type and support for its extra baud rates (compared | ||
129 | * to FT8U232AM). | ||
130 | * Took account of special case divisor values for highest baud rates of | ||
131 | * FT8U232AM and FT232BM. | ||
132 | * For TIOCSSERIAL, forced alt_speed to 0 when ASYNC_SPD_CUST kludge used, | ||
133 | * as previous alt_speed setting is now stale. | ||
134 | * Moved startup code common between the startup routines for the | ||
135 | * different chip types into a common subroutine. | ||
136 | * | ||
137 | * (17/Feb/2003) Bill Ryder | ||
138 | * Added write urb buffer pool on a per device basis | ||
139 | * Added more checking for open file on callbacks (fixed OOPS) | ||
140 | * Added CrystalFontz 632 and 634 PIDs | ||
141 | * (thanx to CrystalFontz for the sample devices - they flushed out | ||
142 | * some driver bugs) | ||
143 | * Minor debugging message changes | ||
144 | * Added throttle, unthrottle and chars_in_buffer functions | ||
145 | * Fixed FTDI_SIO (the original device) bug | ||
146 | * Fixed some shutdown handling | ||
147 | * | ||
148 | * | ||
149 | * | ||
150 | * | ||
151 | * (07/Jun/2002) Kuba Ober | ||
152 | * Changed FTDI_SIO_BASE_BAUD_TO_DIVISOR macro into ftdi_baud_to_divisor | ||
153 | * function. It was getting too complex. | ||
154 | * Fix the divisor calculation logic which was setting divisor of 0.125 | ||
155 | * instead of 0.5 for fractional parts of divisor equal to 5/8, 6/8, 7/8. | ||
156 | * Also make it bump up the divisor to next integer in case of 7/8 - it's | ||
157 | * a better approximation. | ||
158 | * | ||
159 | * (25/Jul/2002) Bill Ryder inserted Dmitri's TIOCMIWAIT patch | ||
160 | * Not tested by me but it doesn't break anything I use. | ||
161 | * | ||
162 | * (04/Jan/2002) Kuba Ober | ||
163 | * Implemented 38400 baudrate kludge, where it can be substituted with other | ||
164 | * values. That's the only way to set custom baudrates. | ||
165 | * Implemented TIOCSSERIAL, TIOCGSERIAL ioctl's so that setserial is happy. | ||
166 | * FIXME: both baudrate things should eventually go to usbserial.c as other | ||
167 | * devices may need that functionality too. Actually, it can probably be | ||
168 | * merged in serial.c somehow - too many drivers repeat this code over | ||
169 | * and over. | ||
170 | * Fixed baudrate forgetfulness - open() used to reset baudrate to 9600 every time. | ||
171 | * Divisors for baudrates are calculated by a macro. | ||
172 | * Small code cleanups. Ugly whitespace changes for Plato's sake only ;-]. | ||
173 | * | ||
174 | * (04/Nov/2001) Bill Ryder | ||
175 | * Fixed bug in read_bulk_callback where incorrect urb buffer was used. | ||
176 | * Cleaned up write offset calculation | ||
177 | * Added write_room since default values can be incorrect for sio | ||
178 | * Changed write_bulk_callback to use same queue_task as other drivers | ||
179 | * (the previous version caused panics) | ||
180 | * Removed port iteration code since the device only has one I/O port and it | ||
181 | * was wrong anyway. | ||
182 | * | ||
183 | * (31/May/2001) gkh | ||
184 | * Switched from using spinlock to a semaphore, which fixes lots of problems. | ||
185 | * | ||
186 | * (23/May/2001) Bill Ryder | ||
187 | * Added runtime debug patch (thanx Tyson D Sawyer). | ||
188 | * Cleaned up comments for 8U232 | ||
189 | * Added parity, framing and overrun error handling | ||
190 | * Added receive break handling. | ||
191 | * | ||
192 | * (04/08/2001) gb | ||
193 | * Identify version on module load. | ||
194 | * | ||
195 | * (18/March/2001) Bill Ryder | ||
196 | * (Not released) | ||
197 | * Added send break handling. (requires kernel patch too) | ||
198 | * Fixed 8U232AM hardware RTS/CTS etc status reporting. | ||
199 | * Added flipbuf fix copied from generic device | ||
200 | * | ||
201 | * (12/3/2000) Bill Ryder | ||
202 | * Added support for 8U232AM device. | ||
203 | * Moved PID and VIDs into header file only. | ||
204 | * Turned on low-latency for the tty (device will do high baudrates) | ||
205 | * Added shutdown routine to close files when device removed. | ||
206 | * More debug and error message cleanups. | ||
207 | * | ||
208 | * (11/13/2000) Bill Ryder | ||
209 | * Added spinlock protected open code and close code. | ||
210 | * Multiple opens work (sort of - see webpage mentioned above). | ||
211 | * Cleaned up comments. Removed multiple PID/VID definitions. | ||
212 | * Factorised cts/dtr code | ||
213 | * Made use of __FUNCTION__ in dbg's | ||
214 | * | ||
215 | * (11/01/2000) Adam J. Richter | ||
216 | * usb_device_id table support | ||
217 | * | ||
218 | * (10/05/2000) gkh | ||
219 | * Fixed bug with urb->dev not being set properly, now that the usb | ||
220 | * core needs it. | ||
221 | * | ||
222 | * (09/11/2000) gkh | ||
223 | * Removed DEBUG #ifdefs with call to usb_serial_debug_data | ||
224 | * | ||
225 | * (07/19/2000) gkh | ||
226 | * Added module_init and module_exit functions to handle the fact that this | ||
227 | * driver is a loadable module now. | ||
228 | * | ||
229 | * (04/04/2000) Bill Ryder | ||
230 | * Fixed bugs in TCGET/TCSET ioctls (by removing them - they are | ||
231 | * handled elsewhere in the tty io driver chain). | ||
232 | * | ||
233 | * (03/30/2000) Bill Ryder | ||
234 | * Implemented lots of ioctls | ||
235 | * Fixed a race condition in write | ||
236 | * Changed some dbg's to errs | ||
237 | * | ||
238 | * (03/26/2000) gkh | ||
239 | * Split driver up into device specific pieces. | ||
240 | * | 22 | * |
241 | */ | 23 | */ |
242 | 24 | ||
@@ -309,12 +91,12 @@ struct ftdi_sio_quirk { | |||
309 | void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */ | 91 | void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */ |
310 | }; | 92 | }; |
311 | 93 | ||
312 | static int ftdi_olimex_probe (struct usb_serial *serial); | 94 | static int ftdi_jtag_probe (struct usb_serial *serial); |
313 | static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); | 95 | static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); |
314 | static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); | 96 | static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); |
315 | 97 | ||
316 | static struct ftdi_sio_quirk ftdi_olimex_quirk = { | 98 | static struct ftdi_sio_quirk ftdi_jtag_quirk = { |
317 | .probe = ftdi_olimex_probe, | 99 | .probe = ftdi_jtag_probe, |
318 | }; | 100 | }; |
319 | 101 | ||
320 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 102 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
@@ -471,30 +253,28 @@ static struct usb_device_id id_table_combined [] = { | |||
471 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, | 253 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, |
472 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, | 254 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, |
473 | /* | 255 | /* |
474 | * These will probably use user-space drivers. Uncomment them if | 256 | * Due to many user requests for multiple ELV devices we enable |
475 | * you need them or use the user-specified vendor/product module | 257 | * them by default. |
476 | * parameters (see ftdi_sio.h for the numbers). Make a fuss if | ||
477 | * you think the driver should recognize any of them by default. | ||
478 | */ | 258 | */ |
479 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, */ | 259 | { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, |
480 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, */ | 260 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, |
481 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, */ | 261 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, |
482 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, */ | 262 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, |
483 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, */ | 263 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, |
484 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, */ | 264 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, |
485 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, */ | 265 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, |
486 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, */ | 266 | { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, |
487 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */ | 267 | { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, |
488 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */ | 268 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, |
489 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */ | 269 | { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, |
490 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */ | 270 | { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, |
491 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */ | 271 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, |
492 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */ | 272 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, |
493 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, */ | 273 | { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, |
494 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, */ | 274 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, |
495 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */ | 275 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, |
496 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */ | 276 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, |
497 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */ | 277 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, |
498 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, | 278 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, |
499 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, | 279 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, |
500 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, | 280 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, |
@@ -545,6 +325,7 @@ static struct usb_device_id id_table_combined [] = { | |||
545 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, | 325 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, |
546 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, | 326 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, |
547 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) }, | 327 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) }, |
328 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16IC_PID) }, | ||
548 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, | 329 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, |
549 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, | 330 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, |
550 | { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, | 331 | { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, |
@@ -569,8 +350,13 @@ static struct usb_device_id id_table_combined [] = { | |||
569 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 350 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
570 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | 351 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, |
571 | { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, | 352 | { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, |
353 | { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, | ||
572 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), | 354 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), |
573 | .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk }, | 355 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
356 | { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), | ||
357 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
358 | { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), | ||
359 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
574 | { }, /* Optional parameter entry */ | 360 | { }, /* Optional parameter entry */ |
575 | { } /* Terminating entry */ | 361 | { } /* Terminating entry */ |
576 | }; | 362 | }; |
@@ -1283,10 +1069,11 @@ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv) | |||
1283 | } /* ftdi_HE_TIRA1_setup */ | 1069 | } /* ftdi_HE_TIRA1_setup */ |
1284 | 1070 | ||
1285 | /* | 1071 | /* |
1286 | * First port on Olimex arm-usb-ocd is reserved for JTAG interface | 1072 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko |
1287 | * and can be accessed from userspace using openocd. | 1073 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from |
1074 | * userspace using openocd. | ||
1288 | */ | 1075 | */ |
1289 | static int ftdi_olimex_probe(struct usb_serial *serial) | 1076 | static int ftdi_jtag_probe(struct usb_serial *serial) |
1290 | { | 1077 | { |
1291 | struct usb_device *udev = serial->dev; | 1078 | struct usb_device *udev = serial->dev; |
1292 | struct usb_interface *interface = serial->interface; | 1079 | struct usb_interface *interface = serial->interface; |
@@ -1294,7 +1081,7 @@ static int ftdi_olimex_probe(struct usb_serial *serial) | |||
1294 | dbg("%s",__FUNCTION__); | 1081 | dbg("%s",__FUNCTION__); |
1295 | 1082 | ||
1296 | if (interface == udev->actconfig->interface[0]) { | 1083 | if (interface == udev->actconfig->interface[0]) { |
1297 | info("Ignoring reserved serial port on Olimex arm-usb-ocd\n"); | 1084 | info("Ignoring serial port reserved for JTAG"); |
1298 | return -ENODEV; | 1085 | return -ENODEV; |
1299 | } | 1086 | } |
1300 | 1087 | ||
@@ -1411,7 +1198,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) | |||
1411 | 1198 | ||
1412 | dbg("%s", __FUNCTION__); | 1199 | dbg("%s", __FUNCTION__); |
1413 | 1200 | ||
1414 | if (c_cflag & HUPCL){ | 1201 | mutex_lock(&port->serial->disc_mutex); |
1202 | if (c_cflag & HUPCL && !port->serial->disconnected){ | ||
1415 | /* Disable flow control */ | 1203 | /* Disable flow control */ |
1416 | if (usb_control_msg(port->serial->dev, | 1204 | if (usb_control_msg(port->serial->dev, |
1417 | usb_sndctrlpipe(port->serial->dev, 0), | 1205 | usb_sndctrlpipe(port->serial->dev, 0), |
@@ -1425,6 +1213,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) | |||
1425 | /* drop RTS and DTR */ | 1213 | /* drop RTS and DTR */ |
1426 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 1214 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
1427 | } /* Note change no line if hupcl is off */ | 1215 | } /* Note change no line if hupcl is off */ |
1216 | mutex_unlock(&port->serial->disc_mutex); | ||
1428 | 1217 | ||
1429 | /* cancel any scheduled reading */ | 1218 | /* cancel any scheduled reading */ |
1430 | cancel_delayed_work(&priv->rx_work); | 1219 | cancel_delayed_work(&priv->rx_work); |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index b51cbb0eaa05..6eee2ab914ec 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -98,6 +98,10 @@ | |||
98 | #define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ | 98 | #define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ |
99 | #define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ | 99 | #define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ |
100 | 100 | ||
101 | /* OOCDlink by Joern Kaipf <joernk@web.de> | ||
102 | * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ | ||
103 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ | ||
104 | |||
101 | /* Interbiometrics USB I/O Board */ | 105 | /* Interbiometrics USB I/O Board */ |
102 | /* Developed for Interbiometrics by Rudolf Gugler */ | 106 | /* Developed for Interbiometrics by Rudolf Gugler */ |
103 | #define INTERBIOMETRICS_VID 0x1209 | 107 | #define INTERBIOMETRICS_VID 0x1209 |
@@ -245,6 +249,7 @@ | |||
245 | #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ | 249 | #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ |
246 | #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ | 250 | #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ |
247 | #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ | 251 | #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ |
252 | #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ | ||
248 | 253 | ||
249 | /* | 254 | /* |
250 | * Definitions for ID TECH (www.idt-net.com) devices | 255 | * Definitions for ID TECH (www.idt-net.com) devices |
@@ -278,6 +283,7 @@ | |||
278 | #define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ | 283 | #define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ |
279 | #define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ | 284 | #define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ |
280 | #define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ | 285 | #define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ |
286 | #define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ | ||
281 | 287 | ||
282 | /* | 288 | /* |
283 | * Protego product ids | 289 | * Protego product ids |
@@ -534,6 +540,8 @@ | |||
534 | #define OLIMEX_VID 0x15BA | 540 | #define OLIMEX_VID 0x15BA |
535 | #define OLIMEX_ARM_USB_OCD_PID 0x0003 | 541 | #define OLIMEX_ARM_USB_OCD_PID 0x0003 |
536 | 542 | ||
543 | /* www.elsterelectricity.com Elster Unicom III Optical Probe */ | ||
544 | #define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ | ||
537 | 545 | ||
538 | /* | 546 | /* |
539 | * The Mobility Lab (TML) | 547 | * The Mobility Lab (TML) |
@@ -556,6 +564,13 @@ | |||
556 | 564 | ||
557 | 565 | ||
558 | /* | 566 | /* |
567 | * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 | ||
568 | * Submitted by Harald Welte <laforge@openmoko.org> | ||
569 | */ | ||
570 | #define FIC_VID 0x1457 | ||
571 | #define FIC_NEO1973_DEBUG_PID 0x5118 | ||
572 | |||
573 | /* | ||
559 | * BmRequestType: 1100 0000b | 574 | * BmRequestType: 1100 0000b |
560 | * bRequest: FTDI_E2_READ | 575 | * bRequest: FTDI_E2_READ |
561 | * wValue: 0 | 576 | * wValue: 0 |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index f1c90cfe7251..d74e43d69230 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -1020,19 +1020,26 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) | |||
1020 | if (!serial) | 1020 | if (!serial) |
1021 | return; | 1021 | return; |
1022 | 1022 | ||
1023 | garmin_clear(garmin_data_p); | 1023 | mutex_lock(&port->serial->disc_mutex); |
1024 | if (!port->serial->disconnected) | ||
1025 | garmin_clear(garmin_data_p); | ||
1024 | 1026 | ||
1025 | /* shutdown our urbs */ | 1027 | /* shutdown our urbs */ |
1026 | usb_kill_urb (port->read_urb); | 1028 | usb_kill_urb (port->read_urb); |
1027 | usb_kill_urb (port->write_urb); | 1029 | usb_kill_urb (port->write_urb); |
1028 | 1030 | ||
1029 | if (noResponseFromAppLayer(garmin_data_p) || | 1031 | if (!port->serial->disconnected) { |
1030 | ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) { | 1032 | if (noResponseFromAppLayer(garmin_data_p) || |
1031 | process_resetdev_request(port); | 1033 | ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) { |
1032 | garmin_data_p->state = STATE_RESET; | 1034 | process_resetdev_request(port); |
1035 | garmin_data_p->state = STATE_RESET; | ||
1036 | } else { | ||
1037 | garmin_data_p->state = STATE_DISCONNECTED; | ||
1038 | } | ||
1033 | } else { | 1039 | } else { |
1034 | garmin_data_p->state = STATE_DISCONNECTED; | 1040 | garmin_data_p->state = STATE_DISCONNECTED; |
1035 | } | 1041 | } |
1042 | mutex_unlock(&port->serial->disc_mutex); | ||
1036 | } | 1043 | } |
1037 | 1044 | ||
1038 | 1045 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index d41531139c55..97fa3c428435 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -175,6 +175,14 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
175 | struct usb_serial_port *port; | 175 | struct usb_serial_port *port; |
176 | int i, c = 0, r; | 176 | int i, c = 0, r; |
177 | 177 | ||
178 | #ifdef CONFIG_PM | ||
179 | /* | ||
180 | * If this is an autoresume, don't submit URBs. | ||
181 | * They will be submitted in the open function instead. | ||
182 | */ | ||
183 | if (serial->dev->auto_pm) | ||
184 | return 0; | ||
185 | #endif | ||
178 | for (i = 0; i < serial->num_ports; i++) { | 186 | for (i = 0; i < serial->num_ports; i++) { |
179 | port = serial->port[i]; | 187 | port = serial->port[i]; |
180 | if (port->open_count && port->read_urb) { | 188 | if (port->open_count && port->read_urb) { |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index a5d2e115e167..3428ccc28da7 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -959,7 +959,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) | |||
959 | * | 959 | * |
960 | * This function will block the close until one of the following: | 960 | * This function will block the close until one of the following: |
961 | * 1. Response to our Chase comes from Edgeport | 961 | * 1. Response to our Chase comes from Edgeport |
962 | * 2. A timout of 10 seconds without activity has expired | 962 | * 2. A timeout of 10 seconds without activity has expired |
963 | * (1K of Edgeport data @ 2400 baud ==> 4 sec to empty) | 963 | * (1K of Edgeport data @ 2400 baud ==> 4 sec to empty) |
964 | * | 964 | * |
965 | ************************************************************************/ | 965 | ************************************************************************/ |
@@ -999,7 +999,7 @@ static void block_until_chase_response(struct edgeport_port *edge_port) | |||
999 | return; | 999 | return; |
1000 | } | 1000 | } |
1001 | } else { | 1001 | } else { |
1002 | // Reset timout value back to 10 seconds | 1002 | // Reset timeout value back to 10 seconds |
1003 | dbg("%s - Last %d, Current %d", __FUNCTION__, lastCredits, edge_port->txCredits); | 1003 | dbg("%s - Last %d, Current %d", __FUNCTION__, lastCredits, edge_port->txCredits); |
1004 | loop = 10; | 1004 | loop = 10; |
1005 | } | 1005 | } |
@@ -1014,7 +1014,7 @@ static void block_until_chase_response(struct edgeport_port *edge_port) | |||
1014 | * This function will block the close until one of the following: | 1014 | * This function will block the close until one of the following: |
1015 | * 1. TX count are 0 | 1015 | * 1. TX count are 0 |
1016 | * 2. The edgeport has stopped | 1016 | * 2. The edgeport has stopped |
1017 | * 3. A timout of 3 seconds without activity has expired | 1017 | * 3. A timeout of 3 seconds without activity has expired |
1018 | * | 1018 | * |
1019 | ************************************************************************/ | 1019 | ************************************************************************/ |
1020 | static void block_until_tx_empty (struct edgeport_port *edge_port) | 1020 | static void block_until_tx_empty (struct edgeport_port *edge_port) |
@@ -1050,7 +1050,7 @@ static void block_until_tx_empty (struct edgeport_port *edge_port) | |||
1050 | return; | 1050 | return; |
1051 | } | 1051 | } |
1052 | } else { | 1052 | } else { |
1053 | // Reset timout value back to seconds | 1053 | // Reset timeout value back to seconds |
1054 | loop = 30; | 1054 | loop = 30; |
1055 | } | 1055 | } |
1056 | } | 1056 | } |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index b8670905bc3a..cd3405953f74 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/mutex.h> | ||
37 | #include <linux/serial.h> | 38 | #include <linux/serial.h> |
38 | #include <linux/ioctl.h> | 39 | #include <linux/ioctl.h> |
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
@@ -133,7 +134,7 @@ struct edgeport_serial { | |||
133 | struct product_info product_info; | 134 | struct product_info product_info; |
134 | u8 TI_I2C_Type; // Type of I2C in UMP | 135 | u8 TI_I2C_Type; // Type of I2C in UMP |
135 | u8 TiReadI2C; // Set to TRUE if we have read the I2c in Boot Mode | 136 | u8 TiReadI2C; // Set to TRUE if we have read the I2c in Boot Mode |
136 | struct semaphore es_sem; | 137 | struct mutex es_lock; |
137 | int num_ports_open; | 138 | int num_ports_open; |
138 | struct usb_serial *serial; | 139 | struct usb_serial *serial; |
139 | }; | 140 | }; |
@@ -1978,7 +1979,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) | |||
1978 | } | 1979 | } |
1979 | 1980 | ||
1980 | /* set up the port settings */ | 1981 | /* set up the port settings */ |
1981 | edge_set_termios (port, NULL); | 1982 | edge_set_termios (port, port->tty->termios); |
1982 | 1983 | ||
1983 | /* open up the port */ | 1984 | /* open up the port */ |
1984 | 1985 | ||
@@ -2044,7 +2045,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) | |||
2044 | dbg ("ShadowMCR 0x%X", edge_port->shadow_mcr); | 2045 | dbg ("ShadowMCR 0x%X", edge_port->shadow_mcr); |
2045 | 2046 | ||
2046 | edge_serial = edge_port->edge_serial; | 2047 | edge_serial = edge_port->edge_serial; |
2047 | if (down_interruptible(&edge_serial->es_sem)) | 2048 | if (mutex_lock_interruptible(&edge_serial->es_lock)) |
2048 | return -ERESTARTSYS; | 2049 | return -ERESTARTSYS; |
2049 | if (edge_serial->num_ports_open == 0) { | 2050 | if (edge_serial->num_ports_open == 0) { |
2050 | /* we are the first port to be opened, let's post the interrupt urb */ | 2051 | /* we are the first port to be opened, let's post the interrupt urb */ |
@@ -2052,7 +2053,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) | |||
2052 | if (!urb) { | 2053 | if (!urb) { |
2053 | dev_err (&port->dev, "%s - no interrupt urb present, exiting\n", __FUNCTION__); | 2054 | dev_err (&port->dev, "%s - no interrupt urb present, exiting\n", __FUNCTION__); |
2054 | status = -EINVAL; | 2055 | status = -EINVAL; |
2055 | goto up_es_sem; | 2056 | goto release_es_lock; |
2056 | } | 2057 | } |
2057 | urb->complete = edge_interrupt_callback; | 2058 | urb->complete = edge_interrupt_callback; |
2058 | urb->context = edge_serial; | 2059 | urb->context = edge_serial; |
@@ -2060,7 +2061,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) | |||
2060 | status = usb_submit_urb (urb, GFP_KERNEL); | 2061 | status = usb_submit_urb (urb, GFP_KERNEL); |
2061 | if (status) { | 2062 | if (status) { |
2062 | dev_err (&port->dev, "%s - usb_submit_urb failed with value %d\n", __FUNCTION__, status); | 2063 | dev_err (&port->dev, "%s - usb_submit_urb failed with value %d\n", __FUNCTION__, status); |
2063 | goto up_es_sem; | 2064 | goto release_es_lock; |
2064 | } | 2065 | } |
2065 | } | 2066 | } |
2066 | 2067 | ||
@@ -2092,13 +2093,13 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) | |||
2092 | 2093 | ||
2093 | dbg("%s - exited", __FUNCTION__); | 2094 | dbg("%s - exited", __FUNCTION__); |
2094 | 2095 | ||
2095 | goto up_es_sem; | 2096 | goto release_es_lock; |
2096 | 2097 | ||
2097 | unlink_int_urb: | 2098 | unlink_int_urb: |
2098 | if (edge_port->edge_serial->num_ports_open == 0) | 2099 | if (edge_port->edge_serial->num_ports_open == 0) |
2099 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); | 2100 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); |
2100 | up_es_sem: | 2101 | release_es_lock: |
2101 | up(&edge_serial->es_sem); | 2102 | mutex_unlock(&edge_serial->es_lock); |
2102 | return status; | 2103 | return status; |
2103 | } | 2104 | } |
2104 | 2105 | ||
@@ -2137,14 +2138,14 @@ static void edge_close (struct usb_serial_port *port, struct file *filp) | |||
2137 | 0, | 2138 | 0, |
2138 | NULL, | 2139 | NULL, |
2139 | 0); | 2140 | 0); |
2140 | down(&edge_serial->es_sem); | 2141 | mutex_lock(&edge_serial->es_lock); |
2141 | --edge_port->edge_serial->num_ports_open; | 2142 | --edge_port->edge_serial->num_ports_open; |
2142 | if (edge_port->edge_serial->num_ports_open <= 0) { | 2143 | if (edge_port->edge_serial->num_ports_open <= 0) { |
2143 | /* last port is now closed, let's shut down our interrupt urb */ | 2144 | /* last port is now closed, let's shut down our interrupt urb */ |
2144 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); | 2145 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); |
2145 | edge_port->edge_serial->num_ports_open = 0; | 2146 | edge_port->edge_serial->num_ports_open = 0; |
2146 | } | 2147 | } |
2147 | up(&edge_serial->es_sem); | 2148 | mutex_unlock(&edge_serial->es_lock); |
2148 | edge_port->close_pending = 0; | 2149 | edge_port->close_pending = 0; |
2149 | 2150 | ||
2150 | dbg("%s - exited", __FUNCTION__); | 2151 | dbg("%s - exited", __FUNCTION__); |
@@ -2393,11 +2394,6 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi | |||
2393 | dbg("%s - port %d", __FUNCTION__, edge_port->port->number); | 2394 | dbg("%s - port %d", __FUNCTION__, edge_port->port->number); |
2394 | 2395 | ||
2395 | tty = edge_port->port->tty; | 2396 | tty = edge_port->port->tty; |
2396 | if ((!tty) || | ||
2397 | (!tty->termios)) { | ||
2398 | dbg("%s - no tty structures", __FUNCTION__); | ||
2399 | return; | ||
2400 | } | ||
2401 | 2397 | ||
2402 | config = kmalloc (sizeof (*config), GFP_KERNEL); | 2398 | config = kmalloc (sizeof (*config), GFP_KERNEL); |
2403 | if (!config) { | 2399 | if (!config) { |
@@ -2492,15 +2488,21 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi | |||
2492 | } | 2488 | } |
2493 | } | 2489 | } |
2494 | 2490 | ||
2491 | tty->termios->c_cflag &= ~CMSPAR; | ||
2492 | |||
2495 | /* Round the baud rate */ | 2493 | /* Round the baud rate */ |
2496 | baud = tty_get_baud_rate(tty); | 2494 | baud = tty_get_baud_rate(tty); |
2497 | if (!baud) { | 2495 | if (!baud) { |
2498 | /* pick a default, any default... */ | 2496 | /* pick a default, any default... */ |
2499 | baud = 9600; | 2497 | baud = 9600; |
2500 | } | 2498 | } else |
2499 | tty_encode_baud_rate(tty, baud, baud); | ||
2500 | |||
2501 | edge_port->baud_rate = baud; | 2501 | edge_port->baud_rate = baud; |
2502 | config->wBaudRate = (__u16)((461550L + baud/2) / baud); | 2502 | config->wBaudRate = (__u16)((461550L + baud/2) / baud); |
2503 | 2503 | ||
2504 | /* FIXME: Recompute actual baud from divisor here */ | ||
2505 | |||
2504 | dbg ("%s - baud rate = %d, wBaudRate = %d", __FUNCTION__, baud, config->wBaudRate); | 2506 | dbg ("%s - baud rate = %d, wBaudRate = %d", __FUNCTION__, baud, config->wBaudRate); |
2505 | 2507 | ||
2506 | dbg ("wBaudRate: %d", (int)(461550L / config->wBaudRate)); | 2508 | dbg ("wBaudRate: %d", (int)(461550L / config->wBaudRate)); |
@@ -2538,19 +2540,12 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old | |||
2538 | struct tty_struct *tty = port->tty; | 2540 | struct tty_struct *tty = port->tty; |
2539 | unsigned int cflag; | 2541 | unsigned int cflag; |
2540 | 2542 | ||
2541 | if (!port->tty || !port->tty->termios) { | ||
2542 | dbg ("%s - no tty or termios", __FUNCTION__); | ||
2543 | return; | ||
2544 | } | ||
2545 | |||
2546 | cflag = tty->termios->c_cflag; | 2543 | cflag = tty->termios->c_cflag; |
2547 | 2544 | ||
2548 | dbg("%s - clfag %08x iflag %08x", __FUNCTION__, | 2545 | dbg("%s - clfag %08x iflag %08x", __FUNCTION__, |
2549 | tty->termios->c_cflag, tty->termios->c_iflag); | 2546 | tty->termios->c_cflag, tty->termios->c_iflag); |
2550 | if (old_termios) { | 2547 | dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, |
2551 | dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, | 2548 | old_termios->c_cflag, old_termios->c_iflag); |
2552 | old_termios->c_cflag, old_termios->c_iflag); | ||
2553 | } | ||
2554 | 2549 | ||
2555 | dbg("%s - port %d", __FUNCTION__, port->number); | 2550 | dbg("%s - port %d", __FUNCTION__, port->number); |
2556 | 2551 | ||
@@ -2743,7 +2738,7 @@ static int edge_startup (struct usb_serial *serial) | |||
2743 | dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); | 2738 | dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); |
2744 | return -ENOMEM; | 2739 | return -ENOMEM; |
2745 | } | 2740 | } |
2746 | sema_init(&edge_serial->es_sem, 1); | 2741 | mutex_init(&edge_serial->es_lock); |
2747 | edge_serial->serial = serial; | 2742 | edge_serial->serial = serial; |
2748 | usb_set_serial_data(serial, edge_serial); | 2743 | usb_set_serial_data(serial, edge_serial); |
2749 | 2744 | ||
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c new file mode 100644 index 000000000000..fde188e23ce1 --- /dev/null +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -0,0 +1,1217 @@ | |||
1 | /* | ||
2 | * Infinity Unlimited USB Phoenix driver | ||
3 | * | ||
4 | * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) | ||
5 | * | ||
6 | * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * And tested with help of WB Electronics | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/tty.h> | ||
21 | #include <linux/tty_driver.h> | ||
22 | #include <linux/tty_flip.h> | ||
23 | #include <linux/serial.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/moduleparam.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/uaccess.h> | ||
28 | #include <linux/usb.h> | ||
29 | #include <linux/usb/serial.h> | ||
30 | #include "iuu_phoenix.h" | ||
31 | #include <linux/random.h> | ||
32 | |||
33 | |||
34 | #ifdef CONFIG_USB_SERIAL_DEBUG | ||
35 | static int debug = 1; | ||
36 | #else | ||
37 | static int debug; | ||
38 | #endif | ||
39 | |||
40 | /* | ||
41 | * Version Information | ||
42 | */ | ||
43 | #define DRIVER_VERSION "v0.5" | ||
44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" | ||
45 | |||
46 | static struct usb_device_id id_table[] = { | ||
47 | {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, | ||
48 | {} /* Terminating entry */ | ||
49 | }; | ||
50 | MODULE_DEVICE_TABLE(usb, id_table); | ||
51 | |||
52 | static struct usb_driver iuu_driver = { | ||
53 | .name = "iuu_phoenix", | ||
54 | .probe = usb_serial_probe, | ||
55 | .disconnect = usb_serial_disconnect, | ||
56 | .id_table = id_table, | ||
57 | .no_dynamic_id = 1, | ||
58 | }; | ||
59 | |||
60 | /* turbo parameter */ | ||
61 | static int boost = 100; | ||
62 | static int clockmode = 1; | ||
63 | static int cdmode = 1; | ||
64 | static int iuu_cardin; | ||
65 | static int iuu_cardout; | ||
66 | static int xmas; | ||
67 | |||
68 | static void read_rxcmd_callback(struct urb *urb); | ||
69 | |||
70 | struct iuu_private { | ||
71 | spinlock_t lock; /* store irq state */ | ||
72 | wait_queue_head_t delta_msr_wait; | ||
73 | u8 line_control; | ||
74 | u8 line_status; | ||
75 | u8 termios_initialized; | ||
76 | int tiostatus; /* store IUART SIGNAL for tiocmget call */ | ||
77 | u8 reset; /* if 1 reset is needed */ | ||
78 | int poll; /* number of poll */ | ||
79 | u8 *writebuf; /* buffer for writing to device */ | ||
80 | int writelen; /* num of byte to write to device */ | ||
81 | u8 *buf; /* used for initialize speed */ | ||
82 | u8 *dbgbuf; /* debug buffer */ | ||
83 | u8 len; | ||
84 | }; | ||
85 | |||
86 | |||
87 | static void iuu_free_buf(struct iuu_private *priv) | ||
88 | { | ||
89 | kfree(priv->buf); | ||
90 | kfree(priv->dbgbuf); | ||
91 | kfree(priv->writebuf); | ||
92 | } | ||
93 | |||
94 | static int iuu_alloc_buf(struct iuu_private *priv) | ||
95 | { | ||
96 | priv->buf = kzalloc(256, GFP_KERNEL); | ||
97 | priv->dbgbuf = kzalloc(256, GFP_KERNEL); | ||
98 | priv->writebuf = kzalloc(256, GFP_KERNEL); | ||
99 | if (!priv->buf || !priv->dbgbuf || !priv->writebuf) { | ||
100 | iuu_free_buf(priv); | ||
101 | dbg("%s problem allocation buffer", __FUNCTION__); | ||
102 | return -ENOMEM; | ||
103 | } | ||
104 | dbg("%s - Privates buffers allocation success", __FUNCTION__); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int iuu_startup(struct usb_serial *serial) | ||
109 | { | ||
110 | struct iuu_private *priv; | ||
111 | priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); | ||
112 | dbg("%s- priv allocation success", __FUNCTION__); | ||
113 | if (!priv) | ||
114 | return -ENOMEM; | ||
115 | if (iuu_alloc_buf(priv)) { | ||
116 | kfree(priv); | ||
117 | return -ENOMEM; | ||
118 | } | ||
119 | spin_lock_init(&priv->lock); | ||
120 | init_waitqueue_head(&priv->delta_msr_wait); | ||
121 | usb_set_serial_port_data(serial->port[0], priv); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | /* Shutdown function */ | ||
126 | static void iuu_shutdown(struct usb_serial *serial) | ||
127 | { | ||
128 | struct usb_serial_port *port = serial->port[0]; | ||
129 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
130 | if (!port) | ||
131 | return; | ||
132 | |||
133 | dbg("%s", __FUNCTION__); | ||
134 | |||
135 | if (priv) { | ||
136 | iuu_free_buf(priv); | ||
137 | dbg("%s - I will free all", __FUNCTION__); | ||
138 | usb_set_serial_port_data(port, NULL); | ||
139 | |||
140 | dbg("%s - priv is not anymore in port structure", __FUNCTION__); | ||
141 | kfree(priv); | ||
142 | |||
143 | dbg("%s priv is now kfree", __FUNCTION__); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, | ||
148 | unsigned int set, unsigned int clear) | ||
149 | { | ||
150 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
151 | struct tty_struct *tty; | ||
152 | tty = port->tty; | ||
153 | |||
154 | dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __FUNCTION__, | ||
155 | port->number, set, clear); | ||
156 | if (set & TIOCM_RTS) | ||
157 | priv->tiostatus = TIOCM_RTS; | ||
158 | |||
159 | if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) { | ||
160 | dbg("%s TIOCMSET RESET called !!!", __FUNCTION__); | ||
161 | priv->reset = 1; | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /* This is used to provide a carrier detect mechanism | ||
169 | * When a card is present, the response is 0x00 | ||
170 | * When no card , the reader respond with TIOCM_CD | ||
171 | * This is known as CD autodetect mechanism | ||
172 | */ | ||
173 | static int iuu_tiocmget(struct usb_serial_port *port, struct file *file) | ||
174 | { | ||
175 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
176 | return priv->tiostatus; | ||
177 | } | ||
178 | |||
179 | static void iuu_rxcmd(struct urb *urb) | ||
180 | { | ||
181 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
182 | int result; | ||
183 | dbg("%s - enter", __FUNCTION__); | ||
184 | |||
185 | if (urb->status) { | ||
186 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
187 | /* error stop all */ | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | |||
192 | memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); | ||
193 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
194 | usb_sndbulkpipe(port->serial->dev, | ||
195 | port->bulk_out_endpointAddress), | ||
196 | port->write_urb->transfer_buffer, 1, | ||
197 | read_rxcmd_callback, port); | ||
198 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
199 | } | ||
200 | |||
201 | static int iuu_reset(struct usb_serial_port *port, u8 wt) | ||
202 | { | ||
203 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
204 | int result; | ||
205 | char *buf_ptr = port->write_urb->transfer_buffer; | ||
206 | dbg("%s - enter", __FUNCTION__); | ||
207 | |||
208 | /* Prepare the reset sequence */ | ||
209 | |||
210 | *buf_ptr++ = IUU_RST_SET; | ||
211 | *buf_ptr++ = IUU_DELAY_MS; | ||
212 | *buf_ptr++ = wt; | ||
213 | *buf_ptr = IUU_RST_CLEAR; | ||
214 | |||
215 | /* send the sequence */ | ||
216 | |||
217 | usb_fill_bulk_urb(port->write_urb, | ||
218 | port->serial->dev, | ||
219 | usb_sndbulkpipe(port->serial->dev, | ||
220 | port->bulk_out_endpointAddress), | ||
221 | port->write_urb->transfer_buffer, 4, iuu_rxcmd, port); | ||
222 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
223 | priv->reset = 0; | ||
224 | return result; | ||
225 | } | ||
226 | |||
227 | /* Status Function | ||
228 | * Return value is | ||
229 | * 0x00 = no card | ||
230 | * 0x01 = smartcard | ||
231 | * 0x02 = sim card | ||
232 | */ | ||
233 | static void iuu_update_status_callback(struct urb *urb) | ||
234 | { | ||
235 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
236 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
237 | u8 *st; | ||
238 | dbg("%s - enter", __FUNCTION__); | ||
239 | |||
240 | if (urb->status) { | ||
241 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
242 | /* error stop all */ | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | st = urb->transfer_buffer; | ||
247 | dbg("%s - enter", __FUNCTION__); | ||
248 | if (urb->actual_length == 1) { | ||
249 | switch (st[0]) { | ||
250 | case 0x1: | ||
251 | priv->tiostatus = iuu_cardout; | ||
252 | break; | ||
253 | case 0x0: | ||
254 | priv->tiostatus = iuu_cardin; | ||
255 | break; | ||
256 | default: | ||
257 | priv->tiostatus = iuu_cardin; | ||
258 | } | ||
259 | } | ||
260 | iuu_rxcmd(urb); | ||
261 | } | ||
262 | |||
263 | static void iuu_status_callback(struct urb *urb) | ||
264 | { | ||
265 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
266 | int result; | ||
267 | dbg("%s - enter", __FUNCTION__); | ||
268 | |||
269 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
270 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
271 | usb_rcvbulkpipe(port->serial->dev, | ||
272 | port->bulk_in_endpointAddress), | ||
273 | port->read_urb->transfer_buffer, 256, | ||
274 | iuu_update_status_callback, port); | ||
275 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
276 | } | ||
277 | |||
278 | static int iuu_status(struct usb_serial_port *port) | ||
279 | { | ||
280 | int result; | ||
281 | |||
282 | dbg("%s - enter", __FUNCTION__); | ||
283 | |||
284 | memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1); | ||
285 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
286 | usb_sndbulkpipe(port->serial->dev, | ||
287 | port->bulk_out_endpointAddress), | ||
288 | port->write_urb->transfer_buffer, 1, | ||
289 | iuu_status_callback, port); | ||
290 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
291 | return result; | ||
292 | |||
293 | } | ||
294 | |||
295 | static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count) | ||
296 | { | ||
297 | int status; | ||
298 | struct usb_serial *serial = port->serial; | ||
299 | int actual = 0; | ||
300 | |||
301 | dbg("%s - enter", __FUNCTION__); | ||
302 | |||
303 | /* send the data out the bulk port */ | ||
304 | |||
305 | status = | ||
306 | usb_bulk_msg(serial->dev, | ||
307 | usb_sndbulkpipe(serial->dev, | ||
308 | port->bulk_out_endpointAddress), buf, | ||
309 | count, &actual, HZ * 1); | ||
310 | |||
311 | if (status != IUU_OPERATION_OK) { | ||
312 | dbg("%s - error = %2x", __FUNCTION__, status); | ||
313 | } else { | ||
314 | dbg("%s - write OK !", __FUNCTION__); | ||
315 | } | ||
316 | return status; | ||
317 | } | ||
318 | |||
319 | static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count) | ||
320 | { | ||
321 | int status; | ||
322 | struct usb_serial *serial = port->serial; | ||
323 | int actual = 0; | ||
324 | |||
325 | dbg("%s - enter", __FUNCTION__); | ||
326 | |||
327 | /* send the data out the bulk port */ | ||
328 | |||
329 | status = | ||
330 | usb_bulk_msg(serial->dev, | ||
331 | usb_rcvbulkpipe(serial->dev, | ||
332 | port->bulk_in_endpointAddress), buf, | ||
333 | count, &actual, HZ * 1); | ||
334 | |||
335 | if (status != IUU_OPERATION_OK) { | ||
336 | dbg("%s - error = %2x", __FUNCTION__, status); | ||
337 | } else { | ||
338 | dbg("%s - read OK !", __FUNCTION__); | ||
339 | } | ||
340 | |||
341 | return status; | ||
342 | } | ||
343 | |||
344 | static int iuu_led(struct usb_serial_port *port, unsigned int R, | ||
345 | unsigned int G, unsigned int B, u8 f) | ||
346 | { | ||
347 | int status; | ||
348 | u8 *buf; | ||
349 | buf = kmalloc(8, GFP_KERNEL); | ||
350 | if (!buf) | ||
351 | return -ENOMEM; | ||
352 | |||
353 | dbg("%s - enter", __FUNCTION__); | ||
354 | |||
355 | buf[0] = IUU_SET_LED; | ||
356 | buf[1] = R & 0xFF; | ||
357 | buf[2] = (R >> 8) & 0xFF; | ||
358 | buf[3] = G & 0xFF; | ||
359 | buf[4] = (G >> 8) & 0xFF; | ||
360 | buf[5] = B & 0xFF; | ||
361 | buf[6] = (B >> 8) & 0xFF; | ||
362 | buf[7] = f; | ||
363 | status = bulk_immediate(port, buf, 8); | ||
364 | kfree(buf); | ||
365 | if (status != IUU_OPERATION_OK) | ||
366 | dbg("%s - led error status = %2x", __FUNCTION__, status); | ||
367 | else | ||
368 | dbg("%s - led OK !", __FUNCTION__); | ||
369 | return IUU_OPERATION_OK; | ||
370 | } | ||
371 | |||
372 | static void iuu_rgbf_fill_buffer(u8 *buf, u8 r1, u8 r2, u8 g1, u8 g2, u8 b1, | ||
373 | u8 b2, u8 freq) | ||
374 | { | ||
375 | *buf++ = IUU_SET_LED; | ||
376 | *buf++ = r1; | ||
377 | *buf++ = r2; | ||
378 | *buf++ = g1; | ||
379 | *buf++ = g2; | ||
380 | *buf++ = b1; | ||
381 | *buf++ = b2; | ||
382 | *buf = freq; | ||
383 | } | ||
384 | |||
385 | static void iuu_led_activity_on(struct urb *urb) | ||
386 | { | ||
387 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
388 | int result; | ||
389 | char *buf_ptr = port->write_urb->transfer_buffer; | ||
390 | *buf_ptr++ = IUU_SET_LED; | ||
391 | if (xmas == 1) { | ||
392 | get_random_bytes(buf_ptr, 6); | ||
393 | *(buf_ptr+7) = 1; | ||
394 | } else { | ||
395 | iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255); | ||
396 | } | ||
397 | |||
398 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
399 | usb_sndbulkpipe(port->serial->dev, | ||
400 | port->bulk_out_endpointAddress), | ||
401 | port->write_urb->transfer_buffer, 8 , | ||
402 | iuu_rxcmd, port); | ||
403 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
404 | } | ||
405 | |||
406 | static void iuu_led_activity_off(struct urb *urb) | ||
407 | { | ||
408 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
409 | int result; | ||
410 | char *buf_ptr = port->write_urb->transfer_buffer; | ||
411 | if (xmas == 1) { | ||
412 | iuu_rxcmd(urb); | ||
413 | return; | ||
414 | } else { | ||
415 | *buf_ptr++ = IUU_SET_LED; | ||
416 | iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255); | ||
417 | } | ||
418 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
419 | usb_sndbulkpipe(port->serial->dev, | ||
420 | port->bulk_out_endpointAddress), | ||
421 | port->write_urb->transfer_buffer, 8 , | ||
422 | iuu_rxcmd, port); | ||
423 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
424 | } | ||
425 | |||
426 | |||
427 | |||
428 | static int iuu_clk(struct usb_serial_port *port, int dwFrq) | ||
429 | { | ||
430 | int status; | ||
431 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
432 | int Count = 0; | ||
433 | u8 FrqGenAdr = 0x69; | ||
434 | u8 DIV = 0; /* 8bit */ | ||
435 | u8 XDRV = 0; /* 8bit */ | ||
436 | u8 PUMP = 0; /* 3bit */ | ||
437 | u8 PBmsb = 0; /* 2bit */ | ||
438 | u8 PBlsb = 0; /* 8bit */ | ||
439 | u8 PO = 0; /* 1bit */ | ||
440 | u8 Q = 0; /* 7bit */ | ||
441 | /* 24bit = 3bytes */ | ||
442 | unsigned int P = 0; | ||
443 | unsigned int P2 = 0; | ||
444 | int frq = (int)dwFrq; | ||
445 | |||
446 | dbg("%s - enter", __FUNCTION__); | ||
447 | |||
448 | if (frq == 0) { | ||
449 | priv->buf[Count++] = IUU_UART_WRITE_I2C; | ||
450 | priv->buf[Count++] = FrqGenAdr << 1; | ||
451 | priv->buf[Count++] = 0x09; | ||
452 | priv->buf[Count++] = 0x00; | ||
453 | |||
454 | status = bulk_immediate(port, (u8 *) priv->buf, Count); | ||
455 | if (status != 0) { | ||
456 | dbg("%s - write error ", __FUNCTION__); | ||
457 | return status; | ||
458 | } | ||
459 | } else if (frq == 3579000) { | ||
460 | DIV = 100; | ||
461 | P = 1193; | ||
462 | Q = 40; | ||
463 | XDRV = 0; | ||
464 | } else if (frq == 3680000) { | ||
465 | DIV = 105; | ||
466 | P = 161; | ||
467 | Q = 5; | ||
468 | XDRV = 0; | ||
469 | } else if (frq == 6000000) { | ||
470 | DIV = 66; | ||
471 | P = 66; | ||
472 | Q = 2; | ||
473 | XDRV = 0x28; | ||
474 | } else { | ||
475 | unsigned int result = 0; | ||
476 | unsigned int tmp = 0; | ||
477 | unsigned int check; | ||
478 | unsigned int check2; | ||
479 | char found = 0x00; | ||
480 | unsigned int lQ = 2; | ||
481 | unsigned int lP = 2055; | ||
482 | unsigned int lDiv = 4; | ||
483 | |||
484 | for (lQ = 2; lQ <= 47 && !found; lQ++) | ||
485 | for (lP = 2055; lP >= 8 && !found; lP--) | ||
486 | for (lDiv = 4; lDiv <= 127 && !found; lDiv++) { | ||
487 | tmp = (12000000 / lDiv) * (lP / lQ); | ||
488 | if (abs((int)(tmp - frq)) < | ||
489 | abs((int)(frq - result))) { | ||
490 | check2 = (12000000 / lQ); | ||
491 | if (check2 < 250000) | ||
492 | continue; | ||
493 | check = (12000000 / lQ) * lP; | ||
494 | if (check > 400000000) | ||
495 | continue; | ||
496 | if (check < 100000000) | ||
497 | continue; | ||
498 | if (lDiv < 4 || lDiv > 127) | ||
499 | continue; | ||
500 | result = tmp; | ||
501 | P = lP; | ||
502 | DIV = lDiv; | ||
503 | Q = lQ; | ||
504 | if (result == frq) | ||
505 | found = 0x01; | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | P2 = ((P - PO) / 2) - 4; | ||
510 | DIV = DIV; | ||
511 | PUMP = 0x04; | ||
512 | PBmsb = (P2 >> 8 & 0x03); | ||
513 | PBlsb = P2 & 0xFF; | ||
514 | PO = (P >> 10) & 0x01; | ||
515 | Q = Q - 2; | ||
516 | |||
517 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
518 | priv->buf[Count++] = FrqGenAdr << 1; | ||
519 | priv->buf[Count++] = 0x09; | ||
520 | priv->buf[Count++] = 0x20; /* Adr = 0x09 */ | ||
521 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
522 | priv->buf[Count++] = FrqGenAdr << 1; | ||
523 | priv->buf[Count++] = 0x0C; | ||
524 | priv->buf[Count++] = DIV; /* Adr = 0x0C */ | ||
525 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
526 | priv->buf[Count++] = FrqGenAdr << 1; | ||
527 | priv->buf[Count++] = 0x12; | ||
528 | priv->buf[Count++] = XDRV; /* Adr = 0x12 */ | ||
529 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
530 | priv->buf[Count++] = FrqGenAdr << 1; | ||
531 | priv->buf[Count++] = 0x13; | ||
532 | priv->buf[Count++] = 0x6B; /* Adr = 0x13 */ | ||
533 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
534 | priv->buf[Count++] = FrqGenAdr << 1; | ||
535 | priv->buf[Count++] = 0x40; | ||
536 | priv->buf[Count++] = (0xC0 | ((PUMP & 0x07) << 2)) | | ||
537 | (PBmsb & 0x03); /* Adr = 0x40 */ | ||
538 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
539 | priv->buf[Count++] = FrqGenAdr << 1; | ||
540 | priv->buf[Count++] = 0x41; | ||
541 | priv->buf[Count++] = PBlsb; /* Adr = 0x41 */ | ||
542 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
543 | priv->buf[Count++] = FrqGenAdr << 1; | ||
544 | priv->buf[Count++] = 0x42; | ||
545 | priv->buf[Count++] = Q | (((PO & 0x01) << 7)); /* Adr = 0x42 */ | ||
546 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
547 | priv->buf[Count++] = FrqGenAdr << 1; | ||
548 | priv->buf[Count++] = 0x44; | ||
549 | priv->buf[Count++] = (char)0xFF; /* Adr = 0x44 */ | ||
550 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
551 | priv->buf[Count++] = FrqGenAdr << 1; | ||
552 | priv->buf[Count++] = 0x45; | ||
553 | priv->buf[Count++] = (char)0xFE; /* Adr = 0x45 */ | ||
554 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
555 | priv->buf[Count++] = FrqGenAdr << 1; | ||
556 | priv->buf[Count++] = 0x46; | ||
557 | priv->buf[Count++] = 0x7F; /* Adr = 0x46 */ | ||
558 | priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ | ||
559 | priv->buf[Count++] = FrqGenAdr << 1; | ||
560 | priv->buf[Count++] = 0x47; | ||
561 | priv->buf[Count++] = (char)0x84; /* Adr = 0x47 */ | ||
562 | |||
563 | status = bulk_immediate(port, (u8 *) priv->buf, Count); | ||
564 | if (status != IUU_OPERATION_OK) | ||
565 | dbg("%s - write error ", __FUNCTION__); | ||
566 | return status; | ||
567 | } | ||
568 | |||
569 | static int iuu_uart_flush(struct usb_serial_port *port) | ||
570 | { | ||
571 | int i; | ||
572 | int status; | ||
573 | u8 rxcmd = IUU_UART_RX; | ||
574 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
575 | |||
576 | dbg("%s - enter", __FUNCTION__); | ||
577 | |||
578 | if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) | ||
579 | return -EIO; | ||
580 | |||
581 | for (i = 0; i < 2; i++) { | ||
582 | status = bulk_immediate(port, &rxcmd, 1); | ||
583 | if (status != IUU_OPERATION_OK) { | ||
584 | dbg("%s - uart_flush_write error", __FUNCTION__); | ||
585 | return status; | ||
586 | } | ||
587 | |||
588 | status = read_immediate(port, &priv->len, 1); | ||
589 | if (status != IUU_OPERATION_OK) { | ||
590 | dbg("%s - uart_flush_read error", __FUNCTION__); | ||
591 | return status; | ||
592 | } | ||
593 | |||
594 | if (priv->len > 0) { | ||
595 | dbg("%s - uart_flush datalen is : %i ", __FUNCTION__, | ||
596 | priv->len); | ||
597 | status = read_immediate(port, priv->buf, priv->len); | ||
598 | if (status != IUU_OPERATION_OK) { | ||
599 | dbg("%s - uart_flush_read error", __FUNCTION__); | ||
600 | return status; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | dbg("%s - uart_flush_read OK!", __FUNCTION__); | ||
605 | iuu_led(port, 0, 0xF000, 0, 0xFF); | ||
606 | return status; | ||
607 | } | ||
608 | |||
609 | static void read_buf_callback(struct urb *urb) | ||
610 | { | ||
611 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
612 | unsigned char *data = urb->transfer_buffer; | ||
613 | struct tty_struct *tty; | ||
614 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
615 | |||
616 | if (urb->status) { | ||
617 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
618 | if (urb->status == -EPROTO) { | ||
619 | /* reschedule needed */ | ||
620 | } | ||
621 | return; | ||
622 | } | ||
623 | |||
624 | dbg("%s - %i chars to write", __FUNCTION__, urb->actual_length); | ||
625 | tty = port->tty; | ||
626 | if (data == NULL) | ||
627 | dbg("%s - data is NULL !!!", __FUNCTION__); | ||
628 | if (tty && urb->actual_length && data) { | ||
629 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
630 | tty_flip_buffer_push(tty); | ||
631 | } | ||
632 | iuu_led_activity_on(urb); | ||
633 | } | ||
634 | |||
635 | static int iuu_bulk_write(struct usb_serial_port *port) | ||
636 | { | ||
637 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
638 | unsigned int flags; | ||
639 | int result; | ||
640 | int i; | ||
641 | char *buf_ptr = port->write_urb->transfer_buffer; | ||
642 | dbg("%s - enter", __FUNCTION__); | ||
643 | |||
644 | *buf_ptr++ = IUU_UART_ESC; | ||
645 | *buf_ptr++ = IUU_UART_TX; | ||
646 | *buf_ptr++ = priv->writelen; | ||
647 | |||
648 | memcpy(buf_ptr, priv->writebuf, | ||
649 | priv->writelen); | ||
650 | if (debug == 1) { | ||
651 | for (i = 0; i < priv->writelen; i++) | ||
652 | sprintf(priv->dbgbuf + i*2 , | ||
653 | "%02X", priv->writebuf[i]); | ||
654 | priv->dbgbuf[priv->writelen+i*2] = 0; | ||
655 | dbg("%s - writing %i chars : %s", __FUNCTION__, | ||
656 | priv->writelen, priv->dbgbuf); | ||
657 | } | ||
658 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
659 | usb_sndbulkpipe(port->serial->dev, | ||
660 | port->bulk_out_endpointAddress), | ||
661 | port->write_urb->transfer_buffer, priv->writelen + 3, | ||
662 | iuu_rxcmd, port); | ||
663 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
664 | spin_lock_irqsave(&priv->lock, flags); | ||
665 | priv->writelen = 0; | ||
666 | spin_unlock_irqrestore(&priv->lock, flags); | ||
667 | usb_serial_port_softint(port); | ||
668 | return result; | ||
669 | } | ||
670 | |||
671 | static int iuu_read_buf(struct usb_serial_port *port, int len) | ||
672 | { | ||
673 | int result; | ||
674 | dbg("%s - enter", __FUNCTION__); | ||
675 | |||
676 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
677 | usb_rcvbulkpipe(port->serial->dev, | ||
678 | port->bulk_in_endpointAddress), | ||
679 | port->read_urb->transfer_buffer, len, | ||
680 | read_buf_callback, port); | ||
681 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
682 | return result; | ||
683 | } | ||
684 | |||
685 | static void iuu_uart_read_callback(struct urb *urb) | ||
686 | { | ||
687 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
688 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
689 | unsigned int flags; | ||
690 | int status; | ||
691 | int error = 0; | ||
692 | int len = 0; | ||
693 | unsigned char *data = urb->transfer_buffer; | ||
694 | priv->poll++; | ||
695 | |||
696 | dbg("%s - enter", __FUNCTION__); | ||
697 | |||
698 | if (urb->status) { | ||
699 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
700 | /* error stop all */ | ||
701 | return; | ||
702 | } | ||
703 | if (data == NULL) | ||
704 | dbg("%s - data is NULL !!!", __FUNCTION__); | ||
705 | |||
706 | if (urb->actual_length == 1 && data != NULL) | ||
707 | len = (int) data[0]; | ||
708 | |||
709 | if (urb->actual_length > 1) { | ||
710 | dbg("%s - urb->actual_length = %i", __FUNCTION__, | ||
711 | urb->actual_length); | ||
712 | error = 1; | ||
713 | return; | ||
714 | } | ||
715 | /* if len > 0 call readbuf */ | ||
716 | |||
717 | if (len > 0 && error == 0) { | ||
718 | dbg("%s - call read buf - len to read is %i ", | ||
719 | __FUNCTION__, len); | ||
720 | status = iuu_read_buf(port, len); | ||
721 | return; | ||
722 | } | ||
723 | /* need to update status ? */ | ||
724 | if (priv->poll > 99) { | ||
725 | status = iuu_status(port); | ||
726 | priv->poll = 0; | ||
727 | return; | ||
728 | } | ||
729 | |||
730 | /* reset waiting ? */ | ||
731 | |||
732 | if (priv->reset == 1) { | ||
733 | status = iuu_reset(port, 0xC); | ||
734 | return; | ||
735 | } | ||
736 | /* Writebuf is waiting */ | ||
737 | spin_lock_irqsave(&priv->lock, flags); | ||
738 | if (priv->writelen > 0) { | ||
739 | spin_unlock_irqrestore(&priv->lock, flags); | ||
740 | status = iuu_bulk_write(port); | ||
741 | return; | ||
742 | } | ||
743 | spin_unlock_irqrestore(&priv->lock, flags); | ||
744 | /* if nothing to write call again rxcmd */ | ||
745 | dbg("%s - rxcmd recall", __FUNCTION__); | ||
746 | iuu_led_activity_off(urb); | ||
747 | return; | ||
748 | } | ||
749 | |||
750 | static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, | ||
751 | int count) | ||
752 | { | ||
753 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
754 | unsigned int flags; | ||
755 | dbg("%s - enter", __FUNCTION__); | ||
756 | |||
757 | if (count > 256) | ||
758 | return -ENOMEM; | ||
759 | |||
760 | spin_lock_irqsave(&priv->lock, flags); | ||
761 | if (priv->writelen > 0) { | ||
762 | /* buffer already filled but not commited */ | ||
763 | spin_unlock_irqrestore(&priv->lock, flags); | ||
764 | return (0); | ||
765 | } | ||
766 | /* fill the buffer */ | ||
767 | memcpy(priv->writebuf, buf, count); | ||
768 | priv->writelen = count; | ||
769 | spin_unlock_irqrestore(&priv->lock, flags); | ||
770 | |||
771 | return (count); | ||
772 | } | ||
773 | |||
774 | static void read_rxcmd_callback(struct urb *urb) | ||
775 | { | ||
776 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | ||
777 | int result; | ||
778 | dbg("%s - enter", __FUNCTION__); | ||
779 | |||
780 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
781 | |||
782 | if (urb->status) { | ||
783 | dbg("%s - urb->status = %d", __FUNCTION__, urb->status); | ||
784 | /* error stop all */ | ||
785 | return; | ||
786 | } | ||
787 | |||
788 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
789 | usb_rcvbulkpipe(port->serial->dev, | ||
790 | port->bulk_in_endpointAddress), | ||
791 | port->read_urb->transfer_buffer, 256, | ||
792 | iuu_uart_read_callback, port); | ||
793 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
794 | dbg("%s - submit result = %d", __FUNCTION__, result); | ||
795 | return; | ||
796 | } | ||
797 | |||
798 | static int iuu_uart_on(struct usb_serial_port *port) | ||
799 | { | ||
800 | int status; | ||
801 | u8 *buf; | ||
802 | |||
803 | buf = kmalloc(sizeof(u8) * 4, GFP_KERNEL); | ||
804 | |||
805 | if (!buf) | ||
806 | return -ENOMEM; | ||
807 | |||
808 | buf[0] = IUU_UART_ENABLE; | ||
809 | buf[1] = (u8) ((IUU_BAUD_9600 >> 8) & 0x00FF); | ||
810 | buf[2] = (u8) (0x00FF & IUU_BAUD_9600); | ||
811 | buf[3] = (u8) (0x0F0 & IUU_TWO_STOP_BITS) | (0x07 & IUU_PARITY_EVEN); | ||
812 | |||
813 | status = bulk_immediate(port, buf, 4); | ||
814 | if (status != IUU_OPERATION_OK) { | ||
815 | dbg("%s - uart_on error", __FUNCTION__); | ||
816 | goto uart_enable_failed; | ||
817 | } | ||
818 | /* iuu_reset() the card after iuu_uart_on() */ | ||
819 | status = iuu_uart_flush(port); | ||
820 | if (status != IUU_OPERATION_OK) | ||
821 | dbg("%s - uart_flush error", __FUNCTION__); | ||
822 | uart_enable_failed: | ||
823 | kfree(buf); | ||
824 | return status; | ||
825 | } | ||
826 | |||
827 | /* Diables the IUU UART (a.k.a. the Phoenix voiderface) */ | ||
828 | static int iuu_uart_off(struct usb_serial_port *port) | ||
829 | { | ||
830 | int status; | ||
831 | u8 *buf; | ||
832 | buf = kmalloc(1, GFP_KERNEL); | ||
833 | if (!buf) | ||
834 | return -ENOMEM; | ||
835 | buf[0] = IUU_UART_DISABLE; | ||
836 | |||
837 | status = bulk_immediate(port, buf, 1); | ||
838 | if (status != IUU_OPERATION_OK) | ||
839 | dbg("%s - uart_off error", __FUNCTION__); | ||
840 | |||
841 | kfree(buf); | ||
842 | return status; | ||
843 | } | ||
844 | |||
845 | static int iuu_uart_baud(struct usb_serial_port *port, u32 baud, | ||
846 | u32 *actual, u8 parity) | ||
847 | { | ||
848 | int status; | ||
849 | u8 *dataout; | ||
850 | u8 DataCount = 0; | ||
851 | u8 T1Frekvens = 0; | ||
852 | u8 T1reload = 0; | ||
853 | unsigned int T1FrekvensHZ = 0; | ||
854 | |||
855 | dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL); | ||
856 | |||
857 | if (!dataout) | ||
858 | return -ENOMEM; | ||
859 | |||
860 | if (baud < 1200 || baud > 230400) { | ||
861 | kfree(dataout); | ||
862 | return IUU_INVALID_PARAMETER; | ||
863 | } | ||
864 | if (baud > 977) { | ||
865 | T1Frekvens = 3; | ||
866 | T1FrekvensHZ = 500000; | ||
867 | } | ||
868 | |||
869 | if (baud > 3906) { | ||
870 | T1Frekvens = 2; | ||
871 | T1FrekvensHZ = 2000000; | ||
872 | } | ||
873 | |||
874 | if (baud > 11718) { | ||
875 | T1Frekvens = 1; | ||
876 | T1FrekvensHZ = 6000000; | ||
877 | } | ||
878 | |||
879 | if (baud > 46875) { | ||
880 | T1Frekvens = 0; | ||
881 | T1FrekvensHZ = 24000000; | ||
882 | } | ||
883 | |||
884 | T1reload = 256 - (u8) (T1FrekvensHZ / (baud * 2)); | ||
885 | |||
886 | /* magic number here: ENTER_FIRMWARE_UPDATE; */ | ||
887 | dataout[DataCount++] = IUU_UART_ESC; | ||
888 | /* magic number here: CHANGE_BAUD; */ | ||
889 | dataout[DataCount++] = IUU_UART_CHANGE; | ||
890 | dataout[DataCount++] = T1Frekvens; | ||
891 | dataout[DataCount++] = T1reload; | ||
892 | |||
893 | *actual = (T1FrekvensHZ / (256 - T1reload)) / 2; | ||
894 | |||
895 | switch (parity & 0x0F) { | ||
896 | case IUU_PARITY_NONE: | ||
897 | dataout[DataCount++] = 0x00; | ||
898 | break; | ||
899 | case IUU_PARITY_EVEN: | ||
900 | dataout[DataCount++] = 0x01; | ||
901 | break; | ||
902 | case IUU_PARITY_ODD: | ||
903 | dataout[DataCount++] = 0x02; | ||
904 | break; | ||
905 | case IUU_PARITY_MARK: | ||
906 | dataout[DataCount++] = 0x03; | ||
907 | break; | ||
908 | case IUU_PARITY_SPACE: | ||
909 | dataout[DataCount++] = 0x04; | ||
910 | break; | ||
911 | default: | ||
912 | kfree(dataout); | ||
913 | return IUU_INVALID_PARAMETER; | ||
914 | break; | ||
915 | } | ||
916 | |||
917 | switch (parity & 0xF0) { | ||
918 | case IUU_ONE_STOP_BIT: | ||
919 | dataout[DataCount - 1] |= IUU_ONE_STOP_BIT; | ||
920 | break; | ||
921 | |||
922 | case IUU_TWO_STOP_BITS: | ||
923 | dataout[DataCount - 1] |= IUU_TWO_STOP_BITS; | ||
924 | break; | ||
925 | default: | ||
926 | kfree(dataout); | ||
927 | return IUU_INVALID_PARAMETER; | ||
928 | break; | ||
929 | } | ||
930 | |||
931 | status = bulk_immediate(port, dataout, DataCount); | ||
932 | if (status != IUU_OPERATION_OK) | ||
933 | dbg("%s - uart_off error", __FUNCTION__); | ||
934 | kfree(dataout); | ||
935 | return status; | ||
936 | } | ||
937 | |||
938 | static int set_control_lines(struct usb_device *dev, u8 value) | ||
939 | { | ||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | static void iuu_close(struct usb_serial_port *port, struct file *filp) | ||
944 | { | ||
945 | /* iuu_led (port,255,0,0,0); */ | ||
946 | struct usb_serial *serial; | ||
947 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
948 | unsigned long flags; | ||
949 | unsigned int c_cflag; | ||
950 | |||
951 | serial = port->serial; | ||
952 | if (!serial) | ||
953 | return; | ||
954 | |||
955 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
956 | |||
957 | iuu_uart_off(port); | ||
958 | if (serial->dev) { | ||
959 | if (port->tty) { | ||
960 | c_cflag = port->tty->termios->c_cflag; | ||
961 | if (c_cflag & HUPCL) { | ||
962 | /* drop DTR and RTS */ | ||
963 | priv = usb_get_serial_port_data(port); | ||
964 | spin_lock_irqsave(&priv->lock, flags); | ||
965 | priv->line_control = 0; | ||
966 | spin_unlock_irqrestore(&priv->lock, flags); | ||
967 | set_control_lines(port->serial->dev, 0); | ||
968 | } | ||
969 | } | ||
970 | /* free writebuf */ | ||
971 | /* shutdown our urbs */ | ||
972 | dbg("%s - shutting down urbs", __FUNCTION__); | ||
973 | usb_kill_urb(port->write_urb); | ||
974 | usb_kill_urb(port->read_urb); | ||
975 | usb_kill_urb(port->interrupt_in_urb); | ||
976 | msleep(1000); | ||
977 | /* wait one second to free all buffers */ | ||
978 | iuu_led(port, 0, 0, 0xF000, 0xFF); | ||
979 | msleep(1000); | ||
980 | usb_reset_device(port->serial->dev); | ||
981 | } | ||
982 | } | ||
983 | |||
984 | static int iuu_open(struct usb_serial_port *port, struct file *filp) | ||
985 | { | ||
986 | struct usb_serial *serial = port->serial; | ||
987 | u8 *buf; | ||
988 | int result; | ||
989 | u32 actual; | ||
990 | unsigned long flags; | ||
991 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
992 | |||
993 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
994 | usb_clear_halt(serial->dev, port->write_urb->pipe); | ||
995 | usb_clear_halt(serial->dev, port->read_urb->pipe); | ||
996 | |||
997 | buf = kmalloc(10, GFP_KERNEL); | ||
998 | if (buf == NULL) | ||
999 | return -ENOMEM; | ||
1000 | |||
1001 | /* fixup the endpoint buffer size */ | ||
1002 | kfree(port->bulk_out_buffer); | ||
1003 | port->bulk_out_buffer = kmalloc(512, GFP_KERNEL); | ||
1004 | port->bulk_out_size = 512; | ||
1005 | kfree(port->bulk_in_buffer); | ||
1006 | port->bulk_in_buffer = kmalloc(512, GFP_KERNEL); | ||
1007 | port->bulk_in_size = 512; | ||
1008 | |||
1009 | if (!port->bulk_out_buffer || !port->bulk_in_buffer) { | ||
1010 | kfree(port->bulk_out_buffer); | ||
1011 | kfree(port->bulk_in_buffer); | ||
1012 | kfree(buf); | ||
1013 | return -ENOMEM; | ||
1014 | } | ||
1015 | |||
1016 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
1017 | usb_sndbulkpipe(port->serial->dev, | ||
1018 | port->bulk_out_endpointAddress), | ||
1019 | port->bulk_out_buffer, 512, | ||
1020 | NULL, NULL); | ||
1021 | |||
1022 | |||
1023 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
1024 | usb_rcvbulkpipe(port->serial->dev, | ||
1025 | port->bulk_in_endpointAddress), | ||
1026 | port->bulk_in_buffer, 512, | ||
1027 | NULL, NULL); | ||
1028 | |||
1029 | /* set the termios structure */ | ||
1030 | spin_lock_irqsave(&priv->lock, flags); | ||
1031 | if (!priv->termios_initialized) { | ||
1032 | *(port->tty->termios) = tty_std_termios; | ||
1033 | port->tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 | ||
1034 | | TIOCM_CTS | CSTOPB | PARENB; | ||
1035 | port->tty->termios->c_lflag = 0; | ||
1036 | port->tty->termios->c_oflag = 0; | ||
1037 | port->tty->termios->c_iflag = 0; | ||
1038 | priv->termios_initialized = 1; | ||
1039 | port->tty->low_latency = 1; | ||
1040 | priv->poll = 0; | ||
1041 | } | ||
1042 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1043 | |||
1044 | /* initialize writebuf */ | ||
1045 | #define FISH(a, b, c, d) do { \ | ||
1046 | result = usb_control_msg(port->serial->dev, \ | ||
1047 | usb_rcvctrlpipe(port->serial->dev, 0), \ | ||
1048 | b, a, c, d, buf, 1, 1000); \ | ||
1049 | dbg("0x%x:0x%x:0x%x:0x%x %d - %x", a, b, c, d, result, \ | ||
1050 | buf[0]); } while (0); | ||
1051 | |||
1052 | #define SOUP(a, b, c, d) do { \ | ||
1053 | result = usb_control_msg(port->serial->dev, \ | ||
1054 | usb_sndctrlpipe(port->serial->dev, 0), \ | ||
1055 | b, a, c, d, NULL, 0, 1000); \ | ||
1056 | dbg("0x%x:0x%x:0x%x:0x%x %d", a, b, c, d, result); } while (0) | ||
1057 | |||
1058 | /* This is not UART related but IUU USB driver related or something */ | ||
1059 | /* like that. Basically no IUU will accept any commands from the USB */ | ||
1060 | /* host unless it has received the following message */ | ||
1061 | /* sprintf(buf ,"%c%c%c%c",0x03,0x02,0x02,0x0); */ | ||
1062 | |||
1063 | SOUP(0x03, 0x02, 0x02, 0x0); | ||
1064 | kfree(buf); | ||
1065 | iuu_led(port, 0xF000, 0xF000, 0, 0xFF); | ||
1066 | iuu_uart_on(port); | ||
1067 | if (boost < 100) | ||
1068 | boost = 100; | ||
1069 | switch (clockmode) { | ||
1070 | case 2: /* 3.680 Mhz */ | ||
1071 | iuu_clk(port, IUU_CLK_3680000 * boost / 100); | ||
1072 | result = | ||
1073 | iuu_uart_baud(port, 9600 * boost / 100, &actual, | ||
1074 | IUU_PARITY_EVEN); | ||
1075 | break; | ||
1076 | case 3: /* 6.00 Mhz */ | ||
1077 | iuu_clk(port, IUU_CLK_6000000 * boost / 100); | ||
1078 | result = | ||
1079 | iuu_uart_baud(port, 16457 * boost / 100, &actual, | ||
1080 | IUU_PARITY_EVEN); | ||
1081 | break; | ||
1082 | default: /* 3.579 Mhz */ | ||
1083 | iuu_clk(port, IUU_CLK_3579000 * boost / 100); | ||
1084 | result = | ||
1085 | iuu_uart_baud(port, 9600 * boost / 100, &actual, | ||
1086 | IUU_PARITY_EVEN); | ||
1087 | } | ||
1088 | |||
1089 | /* set the cardin cardout signals */ | ||
1090 | switch (cdmode) { | ||
1091 | case 0: | ||
1092 | iuu_cardin = 0; | ||
1093 | iuu_cardout = 0; | ||
1094 | break; | ||
1095 | case 1: | ||
1096 | iuu_cardin = TIOCM_CD; | ||
1097 | iuu_cardout = 0; | ||
1098 | break; | ||
1099 | case 2: | ||
1100 | iuu_cardin = 0; | ||
1101 | iuu_cardout = TIOCM_CD; | ||
1102 | break; | ||
1103 | case 3: | ||
1104 | iuu_cardin = TIOCM_DSR; | ||
1105 | iuu_cardout = 0; | ||
1106 | break; | ||
1107 | case 4: | ||
1108 | iuu_cardin = 0; | ||
1109 | iuu_cardout = TIOCM_DSR; | ||
1110 | break; | ||
1111 | case 5: | ||
1112 | iuu_cardin = TIOCM_CTS; | ||
1113 | iuu_cardout = 0; | ||
1114 | break; | ||
1115 | case 6: | ||
1116 | iuu_cardin = 0; | ||
1117 | iuu_cardout = TIOCM_CTS; | ||
1118 | break; | ||
1119 | case 7: | ||
1120 | iuu_cardin = TIOCM_RNG; | ||
1121 | iuu_cardout = 0; | ||
1122 | break; | ||
1123 | case 8: | ||
1124 | iuu_cardin = 0; | ||
1125 | iuu_cardout = TIOCM_RNG; | ||
1126 | } | ||
1127 | |||
1128 | iuu_uart_flush(port); | ||
1129 | |||
1130 | dbg("%s - initialization done", __FUNCTION__); | ||
1131 | |||
1132 | memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); | ||
1133 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
1134 | usb_sndbulkpipe(port->serial->dev, | ||
1135 | port->bulk_out_endpointAddress), | ||
1136 | port->write_urb->transfer_buffer, 1, | ||
1137 | read_rxcmd_callback, port); | ||
1138 | result = usb_submit_urb(port->write_urb, GFP_KERNEL); | ||
1139 | |||
1140 | if (result) { | ||
1141 | dev_err(&port->dev, "%s - failed submitting read urb," | ||
1142 | " error %d\n", __FUNCTION__, result); | ||
1143 | iuu_close(port, NULL); | ||
1144 | return -EPROTO; | ||
1145 | } else { | ||
1146 | dbg("%s - rxcmd OK", __FUNCTION__); | ||
1147 | } | ||
1148 | return result; | ||
1149 | } | ||
1150 | |||
1151 | static struct usb_serial_driver iuu_device = { | ||
1152 | .driver = { | ||
1153 | .owner = THIS_MODULE, | ||
1154 | .name = "iuu_phoenix", | ||
1155 | }, | ||
1156 | .id_table = id_table, | ||
1157 | .num_interrupt_in = NUM_DONT_CARE, | ||
1158 | .num_bulk_in = 1, | ||
1159 | .num_bulk_out = 1, | ||
1160 | .num_ports = 1, | ||
1161 | .open = iuu_open, | ||
1162 | .close = iuu_close, | ||
1163 | .write = iuu_uart_write, | ||
1164 | .read_bulk_callback = iuu_uart_read_callback, | ||
1165 | .tiocmget = iuu_tiocmget, | ||
1166 | .tiocmset = iuu_tiocmset, | ||
1167 | .attach = iuu_startup, | ||
1168 | .shutdown = iuu_shutdown, | ||
1169 | }; | ||
1170 | |||
1171 | static int __init iuu_init(void) | ||
1172 | { | ||
1173 | int retval; | ||
1174 | retval = usb_serial_register(&iuu_device); | ||
1175 | if (retval) | ||
1176 | goto failed_usb_serial_register; | ||
1177 | retval = usb_register(&iuu_driver); | ||
1178 | if (retval) | ||
1179 | goto failed_usb_register; | ||
1180 | info(DRIVER_DESC " " DRIVER_VERSION); | ||
1181 | return 0; | ||
1182 | failed_usb_register: | ||
1183 | usb_serial_deregister(&iuu_device); | ||
1184 | failed_usb_serial_register: | ||
1185 | return retval; | ||
1186 | } | ||
1187 | |||
1188 | static void __exit iuu_exit(void) | ||
1189 | { | ||
1190 | usb_deregister(&iuu_driver); | ||
1191 | usb_serial_deregister(&iuu_device); | ||
1192 | } | ||
1193 | |||
1194 | module_init(iuu_init); | ||
1195 | module_exit(iuu_exit); | ||
1196 | |||
1197 | MODULE_AUTHOR("Alain Degreffe eczema@ecze.com"); | ||
1198 | |||
1199 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1200 | MODULE_LICENSE("GPL"); | ||
1201 | |||
1202 | MODULE_VERSION(DRIVER_VERSION); | ||
1203 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
1204 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
1205 | |||
1206 | module_param(xmas, bool, S_IRUGO | S_IWUSR); | ||
1207 | MODULE_PARM_DESC(xmas, "xmas color enabled or not"); | ||
1208 | |||
1209 | module_param(boost, int, S_IRUGO | S_IWUSR); | ||
1210 | MODULE_PARM_DESC(boost, "overclock boost percent 100 to 500"); | ||
1211 | |||
1212 | module_param(clockmode, int, S_IRUGO | S_IWUSR); | ||
1213 | MODULE_PARM_DESC(clockmode, "1=3Mhz579,2=3Mhz680,3=6Mhz"); | ||
1214 | |||
1215 | module_param(cdmode, int, S_IRUGO | S_IWUSR); | ||
1216 | MODULE_PARM_DESC(cdmode, "Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, " | ||
1217 | "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING"); | ||
diff --git a/drivers/usb/serial/iuu_phoenix.h b/drivers/usb/serial/iuu_phoenix.h new file mode 100644 index 000000000000..b82630a3b8fd --- /dev/null +++ b/drivers/usb/serial/iuu_phoenix.h | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * Infinity Unlimited USB Phoenix driver | ||
3 | * | ||
4 | * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) | ||
5 | * | ||
6 | * | ||
7 | * Original code taken from iuutool ( Copyright (C) 2006 Juan Carlos Borrás ) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * And tested with help of WB Electronics | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #define IUU_USB_VENDOR_ID 0x104f | ||
19 | #define IUU_USB_PRODUCT_ID 0x0004 | ||
20 | #define IUU_USB_OP_TIMEOUT 0x0200 | ||
21 | |||
22 | /* Programmer commands */ | ||
23 | |||
24 | #define IUU_NO_OPERATION 0x00 | ||
25 | #define IUU_GET_FIRMWARE_VERSION 0x01 | ||
26 | #define IUU_GET_PRODUCT_NAME 0x02 | ||
27 | #define IUU_GET_STATE_REGISTER 0x03 | ||
28 | #define IUU_SET_LED 0x04 | ||
29 | #define IUU_WAIT_MUS 0x05 | ||
30 | #define IUU_WAIT_MS 0x06 | ||
31 | #define IUU_GET_LOADER_VERSION 0x50 | ||
32 | #define IUU_RST_SET 0x52 | ||
33 | #define IUU_RST_CLEAR 0x53 | ||
34 | #define IUU_SET_VCC 0x59 | ||
35 | #define IUU_UART_ENABLE 0x49 | ||
36 | #define IUU_UART_DISABLE 0x4A | ||
37 | #define IUU_UART_WRITE_I2C 0x4C | ||
38 | #define IUU_UART_ESC 0x5E | ||
39 | #define IUU_UART_TRAP 0x54 | ||
40 | #define IUU_UART_TRAP_BREAK 0x5B | ||
41 | #define IUU_UART_RX 0x56 | ||
42 | #define IUU_AVR_ON 0x21 | ||
43 | #define IUU_AVR_OFF 0x22 | ||
44 | #define IUU_AVR_1CLK 0x23 | ||
45 | #define IUU_AVR_RESET 0x24 | ||
46 | #define IUU_AVR_RESET_PC 0x25 | ||
47 | #define IUU_AVR_INC_PC 0x26 | ||
48 | #define IUU_AVR_INCN_PC 0x27 | ||
49 | #define IUU_AVR_PREAD 0x29 | ||
50 | #define IUU_AVR_PREADN 0x2A | ||
51 | #define IUU_AVR_PWRITE 0x28 | ||
52 | #define IUU_AVR_DREAD 0x2C | ||
53 | #define IUU_AVR_DREADN 0x2D | ||
54 | #define IUU_AVR_DWRITE 0x2B | ||
55 | #define IUU_AVR_PWRITEN 0x2E | ||
56 | #define IUU_EEPROM_ON 0x37 | ||
57 | #define IUU_EEPROM_OFF 0x38 | ||
58 | #define IUU_EEPROM_WRITE 0x39 | ||
59 | #define IUU_EEPROM_WRITEX 0x3A | ||
60 | #define IUU_EEPROM_WRITE8 0x3B | ||
61 | #define IUU_EEPROM_WRITE16 0x3C | ||
62 | #define IUU_EEPROM_WRITEX32 0x3D | ||
63 | #define IUU_EEPROM_WRITEX64 0x3E | ||
64 | #define IUU_EEPROM_READ 0x3F | ||
65 | #define IUU_EEPROM_READX 0x40 | ||
66 | #define IUU_EEPROM_BREAD 0x41 | ||
67 | #define IUU_EEPROM_BREADX 0x42 | ||
68 | #define IUU_PIC_CMD 0x0A | ||
69 | #define IUU_PIC_CMD_LOAD 0x0B | ||
70 | #define IUU_PIC_CMD_READ 0x0C | ||
71 | #define IUU_PIC_ON 0x0D | ||
72 | #define IUU_PIC_OFF 0x0E | ||
73 | #define IUU_PIC_RESET 0x16 | ||
74 | #define IUU_PIC_INC_PC 0x0F | ||
75 | #define IUU_PIC_INCN_PC 0x10 | ||
76 | #define IUU_PIC_PWRITE 0x11 | ||
77 | #define IUU_PIC_PREAD 0x12 | ||
78 | #define IUU_PIC_PREADN 0x13 | ||
79 | #define IUU_PIC_DWRITE 0x14 | ||
80 | #define IUU_PIC_DREAD 0x15 | ||
81 | #define IUU_UART_NOP 0x00 | ||
82 | #define IUU_UART_CHANGE 0x02 | ||
83 | #define IUU_UART_TX 0x04 | ||
84 | #define IUU_DELAY_MS 0x06 | ||
85 | |||
86 | #define IUU_OPERATION_OK 0x00 | ||
87 | #define IUU_DEVICE_NOT_FOUND 0x01 | ||
88 | #define IUU_INVALID_HANDLE 0x02 | ||
89 | #define IUU_INVALID_PARAMETER 0x03 | ||
90 | #define IUU_INVALID_voidERFACE 0x04 | ||
91 | #define IUU_INVALID_REQUEST_LENGTH 0x05 | ||
92 | #define IUU_UART_NOT_ENABLED 0x06 | ||
93 | #define IUU_WRITE_ERROR 0x07 | ||
94 | #define IUU_READ_ERROR 0x08 | ||
95 | #define IUU_TX_ERROR 0x09 | ||
96 | #define IUU_RX_ERROR 0x0A | ||
97 | |||
98 | #define IUU_PARITY_NONE 0x00 | ||
99 | #define IUU_PARITY_EVEN 0x01 | ||
100 | #define IUU_PARITY_ODD 0x02 | ||
101 | #define IUU_PARITY_MARK 0x03 | ||
102 | #define IUU_PARITY_SPACE 0x04 | ||
103 | #define IUU_SC_INSERTED 0x01 | ||
104 | #define IUU_VERIFY_ERROR 0x02 | ||
105 | #define IUU_SIM_INSERTED 0x04 | ||
106 | #define IUU_TWO_STOP_BITS 0x00 | ||
107 | #define IUU_ONE_STOP_BIT 0x20 | ||
108 | #define IUU_BAUD_2400 0x0398 | ||
109 | #define IUU_BAUD_9600 0x0298 | ||
110 | #define IUU_BAUD_19200 0x0164 | ||
111 | #define IUU_BAUD_28800 0x0198 | ||
112 | #define IUU_BAUD_38400 0x01B2 | ||
113 | #define IUU_BAUD_57600 0x0030 | ||
114 | #define IUU_BAUD_115200 0x0098 | ||
115 | #define IUU_CLK_3579000 3579000 | ||
116 | #define IUU_CLK_3680000 3680000 | ||
117 | #define IUU_CLK_6000000 6000000 | ||
118 | #define IUU_FULLCARD_IN 0x01 | ||
119 | #define IUU_DEV_ERROR 0x02 | ||
120 | #define IUU_MINICARD_IN 0x04 | ||
121 | #define IUU_VCC_5V 0x00 | ||
122 | #define IUU_VCC_3V 0x01 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7c069a02c1dd..ea7bba69f4da 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -838,7 +838,7 @@ static void usa49_indat_callback(struct urb *urb) | |||
838 | 838 | ||
839 | port = (struct usb_serial_port *) urb->context; | 839 | port = (struct usb_serial_port *) urb->context; |
840 | tty = port->tty; | 840 | tty = port->tty; |
841 | if (urb->actual_length) { | 841 | if (tty && urb->actual_length) { |
842 | /* 0x80 bit is error flag */ | 842 | /* 0x80 bit is error flag */ |
843 | if ((data[0] & 0x80) == 0) { | 843 | if ((data[0] & 0x80) == 0) { |
844 | /* no error on any byte */ | 844 | /* no error on any byte */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index be9ac20a8f10..b1fa5a376e96 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -303,7 +303,7 @@ static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port) | |||
303 | } | 303 | } |
304 | 304 | ||
305 | 305 | ||
306 | static int keyspan_pda_setbaud (struct usb_serial *serial, int baud) | 306 | static speed_t keyspan_pda_setbaud (struct usb_serial *serial, speed_t baud) |
307 | { | 307 | { |
308 | int rc; | 308 | int rc; |
309 | int bindex; | 309 | int bindex; |
@@ -319,7 +319,9 @@ static int keyspan_pda_setbaud (struct usb_serial *serial, int baud) | |||
319 | case 38400: bindex = 7; break; | 319 | case 38400: bindex = 7; break; |
320 | case 57600: bindex = 8; break; | 320 | case 57600: bindex = 8; break; |
321 | case 115200: bindex = 9; break; | 321 | case 115200: bindex = 9; break; |
322 | default: return -EINVAL; | 322 | default: |
323 | bindex = 5; /* Default to 9600 */ | ||
324 | baud = 9600; | ||
323 | } | 325 | } |
324 | 326 | ||
325 | /* rather than figure out how to sleep while waiting for this | 327 | /* rather than figure out how to sleep while waiting for this |
@@ -334,7 +336,9 @@ static int keyspan_pda_setbaud (struct usb_serial *serial, int baud) | |||
334 | NULL, /* &data */ | 336 | NULL, /* &data */ |
335 | 0, /* size */ | 337 | 0, /* size */ |
336 | 2000); /* timeout */ | 338 | 2000); /* timeout */ |
337 | return(rc); | 339 | if (rc < 0) |
340 | return 0; | ||
341 | return baud; | ||
338 | } | 342 | } |
339 | 343 | ||
340 | 344 | ||
@@ -366,7 +370,7 @@ static void keyspan_pda_set_termios (struct usb_serial_port *port, | |||
366 | struct ktermios *old_termios) | 370 | struct ktermios *old_termios) |
367 | { | 371 | { |
368 | struct usb_serial *serial = port->serial; | 372 | struct usb_serial *serial = port->serial; |
369 | unsigned int cflag = port->tty->termios->c_cflag; | 373 | speed_t speed; |
370 | 374 | ||
371 | /* cflag specifies lots of stuff: number of stop bits, parity, number | 375 | /* cflag specifies lots of stuff: number of stop bits, parity, number |
372 | of data bits, baud. What can the device actually handle?: | 376 | of data bits, baud. What can the device actually handle?: |
@@ -388,22 +392,18 @@ static void keyspan_pda_set_termios (struct usb_serial_port *port, | |||
388 | 392 | ||
389 | For now, just do baud. */ | 393 | For now, just do baud. */ |
390 | 394 | ||
391 | switch (cflag & CBAUD) { | 395 | speed = tty_get_baud_rate(port->tty); |
392 | /* we could support more values here, just need to calculate | 396 | speed = keyspan_pda_setbaud(serial, speed); |
393 | the necessary divisors in the firmware. <asm/termbits.h> | 397 | |
394 | has the Bnnn constants. */ | 398 | if (speed == 0) { |
395 | case B110: keyspan_pda_setbaud(serial, 110); break; | 399 | dbg("can't handle requested baud rate"); |
396 | case B300: keyspan_pda_setbaud(serial, 300); break; | 400 | /* It hasn't changed so.. */ |
397 | case B1200: keyspan_pda_setbaud(serial, 1200); break; | 401 | speed = tty_termios_baud_rate(old_termios); |
398 | case B2400: keyspan_pda_setbaud(serial, 2400); break; | ||
399 | case B4800: keyspan_pda_setbaud(serial, 4800); break; | ||
400 | case B9600: keyspan_pda_setbaud(serial, 9600); break; | ||
401 | case B19200: keyspan_pda_setbaud(serial, 19200); break; | ||
402 | case B38400: keyspan_pda_setbaud(serial, 38400); break; | ||
403 | case B57600: keyspan_pda_setbaud(serial, 57600); break; | ||
404 | case B115200: keyspan_pda_setbaud(serial, 115200); break; | ||
405 | default: dbg("can't handle requested baud rate"); break; | ||
406 | } | 402 | } |
403 | /* Only speed can change so copy the old h/w parameters | ||
404 | then encode the new speed */ | ||
405 | tty_termios_copy_hw(port->tty->termios, old_termios); | ||
406 | tty_encode_baud_rate(port->tty, speed, speed); | ||
407 | } | 407 | } |
408 | 408 | ||
409 | 409 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 90e3216abd1f..55736df7d2f4 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -461,17 +461,21 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp) | |||
461 | 461 | ||
462 | dbg("%s port %d", __FUNCTION__, port->number); | 462 | dbg("%s port %d", __FUNCTION__, port->number); |
463 | 463 | ||
464 | /* send READ_OFF */ | 464 | mutex_lock(&port->serial->disc_mutex); |
465 | rc = usb_control_msg (port->serial->dev, | 465 | if (!port->serial->disconnected) { |
466 | usb_sndctrlpipe(port->serial->dev, 0), | 466 | /* send READ_OFF */ |
467 | KL5KUSB105A_SIO_CONFIGURE, | 467 | rc = usb_control_msg (port->serial->dev, |
468 | USB_TYPE_VENDOR | USB_DIR_OUT, | 468 | usb_sndctrlpipe(port->serial->dev, 0), |
469 | KL5KUSB105A_SIO_CONFIGURE_READ_OFF, | 469 | KL5KUSB105A_SIO_CONFIGURE, |
470 | 0, /* index */ | 470 | USB_TYPE_VENDOR | USB_DIR_OUT, |
471 | NULL, 0, | 471 | KL5KUSB105A_SIO_CONFIGURE_READ_OFF, |
472 | KLSI_TIMEOUT); | 472 | 0, /* index */ |
473 | if (rc < 0) | 473 | NULL, 0, |
474 | err("Disabling read failed (error = %d)", rc); | 474 | KLSI_TIMEOUT); |
475 | if (rc < 0) | ||
476 | err("Disabling read failed (error = %d)", rc); | ||
477 | } | ||
478 | mutex_unlock(&port->serial->disc_mutex); | ||
475 | 479 | ||
476 | /* shutdown our bulk reads and writes */ | 480 | /* shutdown our bulk reads and writes */ |
477 | usb_kill_urb(port->write_urb); | 481 | usb_kill_urb(port->write_urb); |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index aee450246bfd..17b3baead4ad 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -114,6 +114,7 @@ static struct usb_serial_driver kobil_device = { | |||
114 | .usb_driver = &kobil_driver, | 114 | .usb_driver = &kobil_driver, |
115 | .id_table = id_table, | 115 | .id_table = id_table, |
116 | .num_interrupt_in = NUM_DONT_CARE, | 116 | .num_interrupt_in = NUM_DONT_CARE, |
117 | .num_interrupt_out = NUM_DONT_CARE, | ||
117 | .num_bulk_in = 0, | 118 | .num_bulk_in = 0, |
118 | .num_bulk_out = 0, | 119 | .num_bulk_out = 0, |
119 | .num_ports = 1, | 120 | .num_ports = 1, |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 0dc99f75bb09..fc1cea4aba13 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -182,10 +182,11 @@ struct mct_u232_private { | |||
182 | /* | 182 | /* |
183 | * Later day 2.6.0-test kernels have new baud rates like B230400 which | 183 | * Later day 2.6.0-test kernels have new baud rates like B230400 which |
184 | * we do not know how to support. We ignore them for the moment. | 184 | * we do not know how to support. We ignore them for the moment. |
185 | * XXX Rate-limit the error message, it's user triggerable. | ||
186 | */ | 185 | */ |
187 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value) | 186 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value, speed_t *result) |
188 | { | 187 | { |
188 | *result = value; | ||
189 | |||
189 | if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID | 190 | if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID |
190 | || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) { | 191 | || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) { |
191 | switch (value) { | 192 | switch (value) { |
@@ -200,11 +201,13 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
200 | case 57600: return 0x0b; | 201 | case 57600: return 0x0b; |
201 | case 115200: return 0x0c; | 202 | case 115200: return 0x0c; |
202 | default: | 203 | default: |
203 | err("MCT USB-RS232: unsupported baudrate request 0x%x," | 204 | *result = 9600; |
204 | " using default of B9600", value); | ||
205 | return 0x08; | 205 | return 0x08; |
206 | } | 206 | } |
207 | } else { | 207 | } else { |
208 | /* FIXME: Can we use any divider - should we do | ||
209 | divider = 115200/value; | ||
210 | real baud = 115200/divider */ | ||
208 | switch (value) { | 211 | switch (value) { |
209 | case 300: break; | 212 | case 300: break; |
210 | case 600: break; | 213 | case 600: break; |
@@ -217,9 +220,8 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
217 | case 57600: break; | 220 | case 57600: break; |
218 | case 115200: break; | 221 | case 115200: break; |
219 | default: | 222 | default: |
220 | err("MCT USB-RS232: unsupported baudrate request 0x%x," | ||
221 | " using default of B9600", value); | ||
222 | value = 9600; | 223 | value = 9600; |
224 | *result = 9600; | ||
223 | } | 225 | } |
224 | return 115200/value; | 226 | return 115200/value; |
225 | } | 227 | } |
@@ -232,16 +234,19 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_p | |||
232 | int rc; | 234 | int rc; |
233 | unsigned char zero_byte = 0; | 235 | unsigned char zero_byte = 0; |
234 | unsigned char cts_enable_byte = 0; | 236 | unsigned char cts_enable_byte = 0; |
237 | speed_t speed; | ||
235 | 238 | ||
236 | divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value)); | 239 | divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value, &speed)); |
237 | 240 | ||
238 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 241 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
239 | MCT_U232_SET_BAUD_RATE_REQUEST, | 242 | MCT_U232_SET_BAUD_RATE_REQUEST, |
240 | MCT_U232_SET_REQUEST_TYPE, | 243 | MCT_U232_SET_REQUEST_TYPE, |
241 | 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE, | 244 | 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE, |
242 | WDR_TIMEOUT); | 245 | WDR_TIMEOUT); |
243 | if (rc < 0) | 246 | if (rc < 0) /*FIXME: What value speed results */ |
244 | err("Set BAUD RATE %d failed (error = %d)", value, rc); | 247 | err("Set BAUD RATE %d failed (error = %d)", value, rc); |
248 | else | ||
249 | tty_encode_baud_rate(port->tty, speed, speed); | ||
245 | dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor); | 250 | dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor); |
246 | 251 | ||
247 | /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which | 252 | /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which |
@@ -482,21 +487,22 @@ error: | |||
482 | static void mct_u232_close (struct usb_serial_port *port, struct file *filp) | 487 | static void mct_u232_close (struct usb_serial_port *port, struct file *filp) |
483 | { | 488 | { |
484 | unsigned int c_cflag; | 489 | unsigned int c_cflag; |
485 | unsigned long flags; | ||
486 | unsigned int control_state; | 490 | unsigned int control_state; |
487 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 491 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
488 | dbg("%s port %d", __FUNCTION__, port->number); | 492 | dbg("%s port %d", __FUNCTION__, port->number); |
489 | 493 | ||
490 | if (port->tty) { | 494 | if (port->tty) { |
491 | c_cflag = port->tty->termios->c_cflag; | 495 | c_cflag = port->tty->termios->c_cflag; |
492 | if (c_cflag & HUPCL) { | 496 | mutex_lock(&port->serial->disc_mutex); |
493 | /* drop DTR and RTS */ | 497 | if (c_cflag & HUPCL && !port->serial->disconnected) { |
494 | spin_lock_irqsave(&priv->lock, flags); | 498 | /* drop DTR and RTS */ |
495 | priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); | 499 | spin_lock_irq(&priv->lock); |
496 | control_state = priv->control_state; | 500 | priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); |
497 | spin_unlock_irqrestore(&priv->lock, flags); | 501 | control_state = priv->control_state; |
498 | mct_u232_set_modem_ctrl(port->serial, control_state); | 502 | spin_unlock_irq(&priv->lock); |
503 | mct_u232_set_modem_ctrl(port->serial, control_state); | ||
499 | } | 504 | } |
505 | mutex_unlock(&port->serial->disc_mutex); | ||
500 | } | 506 | } |
501 | 507 | ||
502 | 508 | ||
@@ -608,7 +614,8 @@ static void mct_u232_set_termios (struct usb_serial_port *port, | |||
608 | { | 614 | { |
609 | struct usb_serial *serial = port->serial; | 615 | struct usb_serial *serial = port->serial; |
610 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 616 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
611 | unsigned int cflag = port->tty->termios->c_cflag; | 617 | struct ktermios *termios = port->tty->termios; |
618 | unsigned int cflag = termios->c_cflag; | ||
612 | unsigned int old_cflag = old_termios->c_cflag; | 619 | unsigned int old_cflag = old_termios->c_cflag; |
613 | unsigned long flags; | 620 | unsigned long flags; |
614 | unsigned int control_state; | 621 | unsigned int control_state; |
@@ -670,6 +677,8 @@ static void mct_u232_set_termios (struct usb_serial_port *port, | |||
670 | break; | 677 | break; |
671 | } | 678 | } |
672 | 679 | ||
680 | termios->c_cflag &= ~CMSPAR; | ||
681 | |||
673 | /* set the number of stop bits */ | 682 | /* set the number of stop bits */ |
674 | last_lcr |= (cflag & CSTOPB) ? | 683 | last_lcr |= (cflag & CSTOPB) ? |
675 | MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; | 684 | MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; |
diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h index aae10c8174d6..07b6bec31dc8 100644 --- a/drivers/usb/serial/mct_u232.h +++ b/drivers/usb/serial/mct_u232.h | |||
@@ -79,7 +79,7 @@ | |||
79 | * and "Intel solution". They are the regular MCT and "Sitecom" for us. | 79 | * and "Intel solution". They are the regular MCT and "Sitecom" for us. |
80 | * This is pointless to document in the header, see the code for the bits. | 80 | * This is pointless to document in the header, see the code for the bits. |
81 | */ | 81 | */ |
82 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value); | 82 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value, speed_t *result); |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Line Control Register (LCR) | 85 | * Line Control Register (LCR) |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e02c198016b0..40f3a0188807 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -564,22 +564,25 @@ static void mos7720_close(struct usb_serial_port *port, struct file *filp) | |||
564 | } | 564 | } |
565 | 565 | ||
566 | /* While closing port, shutdown all bulk read, write * | 566 | /* While closing port, shutdown all bulk read, write * |
567 | * and interrupt read if they exists */ | 567 | * and interrupt read if they exists, otherwise nop */ |
568 | if (serial->dev) { | 568 | dbg("Shutdown bulk write"); |
569 | dbg("Shutdown bulk write"); | 569 | usb_kill_urb(port->write_urb); |
570 | usb_kill_urb(port->write_urb); | 570 | dbg("Shutdown bulk read"); |
571 | dbg("Shutdown bulk read"); | 571 | usb_kill_urb(port->read_urb); |
572 | usb_kill_urb(port->read_urb); | 572 | |
573 | mutex_lock(&serial->disc_mutex); | ||
574 | /* these commands must not be issued if the device has | ||
575 | * been disconnected */ | ||
576 | if (!serial->disconnected) { | ||
577 | data = 0x00; | ||
578 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | ||
579 | 0x04, &data); | ||
580 | |||
581 | data = 0x00; | ||
582 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | ||
583 | 0x01, &data); | ||
573 | } | 584 | } |
574 | 585 | mutex_unlock(&serial->disc_mutex); | |
575 | data = 0x00; | ||
576 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | ||
577 | 0x04, &data); | ||
578 | |||
579 | data = 0x00; | ||
580 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | ||
581 | 0x01, &data); | ||
582 | |||
583 | mos7720_port->open = 0; | 586 | mos7720_port->open = 0; |
584 | 587 | ||
585 | dbg("Leaving %s", __FUNCTION__); | 588 | dbg("Leaving %s", __FUNCTION__); |
@@ -1040,11 +1043,6 @@ static void change_port_settings(struct moschip_port *mos7720_port, | |||
1040 | 1043 | ||
1041 | tty = mos7720_port->port->tty; | 1044 | tty = mos7720_port->port->tty; |
1042 | 1045 | ||
1043 | if ((!tty) || (!tty->termios)) { | ||
1044 | dbg("%s - no tty structures", __FUNCTION__); | ||
1045 | return; | ||
1046 | } | ||
1047 | |||
1048 | dbg("%s: Entering ..........", __FUNCTION__); | 1046 | dbg("%s: Entering ..........", __FUNCTION__); |
1049 | 1047 | ||
1050 | lData = UART_LCR_WLEN8; | 1048 | lData = UART_LCR_WLEN8; |
@@ -1175,7 +1173,10 @@ static void change_port_settings(struct moschip_port *mos7720_port, | |||
1175 | 1173 | ||
1176 | dbg("%s - baud rate = %d", __FUNCTION__, baud); | 1174 | dbg("%s - baud rate = %d", __FUNCTION__, baud); |
1177 | status = send_cmd_write_baud_rate(mos7720_port, baud); | 1175 | status = send_cmd_write_baud_rate(mos7720_port, baud); |
1178 | 1176 | /* FIXME: needs to write actual resulting baud back not just | |
1177 | blindly do so */ | ||
1178 | if (cflag & CBAUD) | ||
1179 | tty_encode_baud_rate(tty, baud, baud); | ||
1179 | /* Enable Interrupts */ | 1180 | /* Enable Interrupts */ |
1180 | data = 0x0c; | 1181 | data = 0x0c; |
1181 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); | 1182 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); |
@@ -1214,10 +1215,6 @@ static void mos7720_set_termios(struct usb_serial_port *port, | |||
1214 | 1215 | ||
1215 | tty = port->tty; | 1216 | tty = port->tty; |
1216 | 1217 | ||
1217 | if (!port->tty || !port->tty->termios) { | ||
1218 | dbg("%s - no tty or termios", __FUNCTION__); | ||
1219 | return; | ||
1220 | } | ||
1221 | 1218 | ||
1222 | if (!mos7720_port->open) { | 1219 | if (!mos7720_port->open) { |
1223 | dbg("%s - port not opened", __FUNCTION__); | 1220 | dbg("%s - port not opened", __FUNCTION__); |
@@ -1228,19 +1225,13 @@ static void mos7720_set_termios(struct usb_serial_port *port, | |||
1228 | 1225 | ||
1229 | cflag = tty->termios->c_cflag; | 1226 | cflag = tty->termios->c_cflag; |
1230 | 1227 | ||
1231 | if (!cflag) { | 1228 | dbg("%s - cflag %08x iflag %08x", __FUNCTION__, |
1232 | printk("%s %s\n",__FUNCTION__,"cflag is NULL"); | ||
1233 | return; | ||
1234 | } | ||
1235 | |||
1236 | dbg("%s - clfag %08x iflag %08x", __FUNCTION__, | ||
1237 | tty->termios->c_cflag, | 1229 | tty->termios->c_cflag, |
1238 | RELEVANT_IFLAG(tty->termios->c_iflag)); | 1230 | RELEVANT_IFLAG(tty->termios->c_iflag)); |
1239 | 1231 | ||
1240 | if (old_termios) | 1232 | dbg("%s - old cflag %08x old iflag %08x", __FUNCTION__, |
1241 | dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, | 1233 | old_termios->c_cflag, |
1242 | old_termios->c_cflag, | 1234 | RELEVANT_IFLAG(old_termios->c_iflag)); |
1243 | RELEVANT_IFLAG(old_termios->c_iflag)); | ||
1244 | 1235 | ||
1245 | dbg("%s - port %d", __FUNCTION__, port->number); | 1236 | dbg("%s - port %d", __FUNCTION__, port->number); |
1246 | 1237 | ||
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index c29c91271133..869ecd374cb4 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1133,7 +1133,7 @@ static int mos7840_chars_in_buffer(struct usb_serial_port *port) | |||
1133 | * This function will block the close until one of the following: | 1133 | * This function will block the close until one of the following: |
1134 | * 1. TX count are 0 | 1134 | * 1. TX count are 0 |
1135 | * 2. The mos7840 has stopped | 1135 | * 2. The mos7840 has stopped |
1136 | * 3. A timout of 3 seconds without activity has expired | 1136 | * 3. A timeout of 3 seconds without activity has expired |
1137 | * | 1137 | * |
1138 | ************************************************************************/ | 1138 | ************************************************************************/ |
1139 | static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port) | 1139 | static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port) |
@@ -1161,7 +1161,7 @@ static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port) | |||
1161 | dbg("%s - TIMEOUT", __FUNCTION__); | 1161 | dbg("%s - TIMEOUT", __FUNCTION__); |
1162 | return; | 1162 | return; |
1163 | } else { | 1163 | } else { |
1164 | /* Reset timout value back to seconds */ | 1164 | /* Reset timeout value back to seconds */ |
1165 | wait = 30; | 1165 | wait = 30; |
1166 | } | 1166 | } |
1167 | } | 1167 | } |
@@ -1275,7 +1275,7 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp) | |||
1275 | * | 1275 | * |
1276 | * This function will block the close until one of the following: | 1276 | * This function will block the close until one of the following: |
1277 | * 1. Response to our Chase comes from mos7840 | 1277 | * 1. Response to our Chase comes from mos7840 |
1278 | * 2. A timout of 10 seconds without activity has expired | 1278 | * 2. A timeout of 10 seconds without activity has expired |
1279 | * (1K of mos7840 data @ 2400 baud ==> 4 sec to empty) | 1279 | * (1K of mos7840 data @ 2400 baud ==> 4 sec to empty) |
1280 | * | 1280 | * |
1281 | ************************************************************************/ | 1281 | ************************************************************************/ |
@@ -1304,7 +1304,7 @@ static void mos7840_block_until_chase_response(struct moschip_port | |||
1304 | dbg("%s - TIMEOUT", __FUNCTION__); | 1304 | dbg("%s - TIMEOUT", __FUNCTION__); |
1305 | return; | 1305 | return; |
1306 | } else { | 1306 | } else { |
1307 | /* Reset timout value back to seconds */ | 1307 | /* Reset timeout value back to seconds */ |
1308 | wait = 10; | 1308 | wait = 10; |
1309 | } | 1309 | } |
1310 | } | 1310 | } |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d1185f53447b..5e8bf1bc1e50 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -180,6 +180,7 @@ static struct usb_device_id option_ids[] = { | |||
180 | { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ | 180 | { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ |
181 | { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ | 181 | { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ |
182 | { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ | 182 | { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ |
183 | { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ | ||
183 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ | 184 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ |
184 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, | 185 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, |
185 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 186 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
@@ -640,7 +641,10 @@ static void option_close(struct usb_serial_port *port, struct file *filp) | |||
640 | portdata->dtr_state = 0; | 641 | portdata->dtr_state = 0; |
641 | 642 | ||
642 | if (serial->dev) { | 643 | if (serial->dev) { |
643 | option_send_setup(port); | 644 | mutex_lock(&serial->disc_mutex); |
645 | if (!serial->disconnected) | ||
646 | option_send_setup(port); | ||
647 | mutex_unlock(&serial->disc_mutex); | ||
644 | 648 | ||
645 | /* Stop reading/writing urbs */ | 649 | /* Stop reading/writing urbs */ |
646 | for (i = 0; i < N_IN_URB; i++) | 650 | for (i = 0; i < N_IN_URB; i++) |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index eea226ae37bd..a3847d6c946e 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -79,7 +79,7 @@ static int debug; | |||
79 | #define PL2303_BUF_SIZE 1024 | 79 | #define PL2303_BUF_SIZE 1024 |
80 | #define PL2303_TMP_BUF_SIZE 1024 | 80 | #define PL2303_TMP_BUF_SIZE 1024 |
81 | 81 | ||
82 | struct pl2303_buf { | 82 | struct oti6858_buf { |
83 | unsigned int buf_size; | 83 | unsigned int buf_size; |
84 | char *buf_buf; | 84 | char *buf_buf; |
85 | char *buf_get; | 85 | char *buf_get; |
@@ -161,14 +161,14 @@ static int oti6858_startup(struct usb_serial *serial); | |||
161 | static void oti6858_shutdown(struct usb_serial *serial); | 161 | static void oti6858_shutdown(struct usb_serial *serial); |
162 | 162 | ||
163 | /* functions operating on buffers */ | 163 | /* functions operating on buffers */ |
164 | static struct pl2303_buf *pl2303_buf_alloc(unsigned int size); | 164 | static struct oti6858_buf *oti6858_buf_alloc(unsigned int size); |
165 | static void pl2303_buf_free(struct pl2303_buf *pb); | 165 | static void oti6858_buf_free(struct oti6858_buf *pb); |
166 | static void pl2303_buf_clear(struct pl2303_buf *pb); | 166 | static void oti6858_buf_clear(struct oti6858_buf *pb); |
167 | static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb); | 167 | static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb); |
168 | static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb); | 168 | static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb); |
169 | static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf, | 169 | static unsigned int oti6858_buf_put(struct oti6858_buf *pb, const char *buf, |
170 | unsigned int count); | 170 | unsigned int count); |
171 | static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, | 171 | static unsigned int oti6858_buf_get(struct oti6858_buf *pb, char *buf, |
172 | unsigned int count); | 172 | unsigned int count); |
173 | 173 | ||
174 | 174 | ||
@@ -203,7 +203,7 @@ static struct usb_serial_driver oti6858_device = { | |||
203 | struct oti6858_private { | 203 | struct oti6858_private { |
204 | spinlock_t lock; | 204 | spinlock_t lock; |
205 | 205 | ||
206 | struct pl2303_buf *buf; | 206 | struct oti6858_buf *buf; |
207 | struct oti6858_control_pkt status; | 207 | struct oti6858_control_pkt status; |
208 | 208 | ||
209 | struct { | 209 | struct { |
@@ -316,7 +316,7 @@ void send_data(struct work_struct *work) | |||
316 | } | 316 | } |
317 | priv->flags.write_urb_in_use = 1; | 317 | priv->flags.write_urb_in_use = 1; |
318 | 318 | ||
319 | count = pl2303_buf_data_avail(priv->buf); | 319 | count = oti6858_buf_data_avail(priv->buf); |
320 | spin_unlock_irqrestore(&priv->lock, flags); | 320 | spin_unlock_irqrestore(&priv->lock, flags); |
321 | if (count > port->bulk_out_size) | 321 | if (count > port->bulk_out_size) |
322 | count = port->bulk_out_size; | 322 | count = port->bulk_out_size; |
@@ -345,7 +345,7 @@ void send_data(struct work_struct *work) | |||
345 | } | 345 | } |
346 | 346 | ||
347 | spin_lock_irqsave(&priv->lock, flags); | 347 | spin_lock_irqsave(&priv->lock, flags); |
348 | pl2303_buf_get(priv->buf, port->write_urb->transfer_buffer, count); | 348 | oti6858_buf_get(priv->buf, port->write_urb->transfer_buffer, count); |
349 | spin_unlock_irqrestore(&priv->lock, flags); | 349 | spin_unlock_irqrestore(&priv->lock, flags); |
350 | 350 | ||
351 | port->write_urb->transfer_buffer_length = count; | 351 | port->write_urb->transfer_buffer_length = count; |
@@ -370,7 +370,7 @@ static int oti6858_startup(struct usb_serial *serial) | |||
370 | priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); | 370 | priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); |
371 | if (!priv) | 371 | if (!priv) |
372 | break; | 372 | break; |
373 | priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE); | 373 | priv->buf = oti6858_buf_alloc(PL2303_BUF_SIZE); |
374 | if (priv->buf == NULL) { | 374 | if (priv->buf == NULL) { |
375 | kfree(priv); | 375 | kfree(priv); |
376 | break; | 376 | break; |
@@ -391,7 +391,7 @@ static int oti6858_startup(struct usb_serial *serial) | |||
391 | 391 | ||
392 | for (--i; i >= 0; --i) { | 392 | for (--i; i >= 0; --i) { |
393 | priv = usb_get_serial_port_data(serial->port[i]); | 393 | priv = usb_get_serial_port_data(serial->port[i]); |
394 | pl2303_buf_free(priv->buf); | 394 | oti6858_buf_free(priv->buf); |
395 | kfree(priv); | 395 | kfree(priv); |
396 | usb_set_serial_port_data(serial->port[i], NULL); | 396 | usb_set_serial_port_data(serial->port[i], NULL); |
397 | } | 397 | } |
@@ -410,7 +410,7 @@ static int oti6858_write(struct usb_serial_port *port, | |||
410 | return count; | 410 | return count; |
411 | 411 | ||
412 | spin_lock_irqsave(&priv->lock, flags); | 412 | spin_lock_irqsave(&priv->lock, flags); |
413 | count = pl2303_buf_put(priv->buf, buf, count); | 413 | count = oti6858_buf_put(priv->buf, buf, count); |
414 | spin_unlock_irqrestore(&priv->lock, flags); | 414 | spin_unlock_irqrestore(&priv->lock, flags); |
415 | 415 | ||
416 | return count; | 416 | return count; |
@@ -425,7 +425,7 @@ static int oti6858_write_room(struct usb_serial_port *port) | |||
425 | dbg("%s(port = %d)", __FUNCTION__, port->number); | 425 | dbg("%s(port = %d)", __FUNCTION__, port->number); |
426 | 426 | ||
427 | spin_lock_irqsave(&priv->lock, flags); | 427 | spin_lock_irqsave(&priv->lock, flags); |
428 | room = pl2303_buf_space_avail(priv->buf); | 428 | room = oti6858_buf_space_avail(priv->buf); |
429 | spin_unlock_irqrestore(&priv->lock, flags); | 429 | spin_unlock_irqrestore(&priv->lock, flags); |
430 | 430 | ||
431 | return room; | 431 | return room; |
@@ -440,7 +440,7 @@ static int oti6858_chars_in_buffer(struct usb_serial_port *port) | |||
440 | dbg("%s(port = %d)", __FUNCTION__, port->number); | 440 | dbg("%s(port = %d)", __FUNCTION__, port->number); |
441 | 441 | ||
442 | spin_lock_irqsave(&priv->lock, flags); | 442 | spin_lock_irqsave(&priv->lock, flags); |
443 | chars = pl2303_buf_data_avail(priv->buf); | 443 | chars = oti6858_buf_data_avail(priv->buf); |
444 | spin_unlock_irqrestore(&priv->lock, flags); | 444 | spin_unlock_irqrestore(&priv->lock, flags); |
445 | 445 | ||
446 | return chars; | 446 | return chars; |
@@ -458,7 +458,7 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
458 | 458 | ||
459 | dbg("%s(port = %d)", __FUNCTION__, port->number); | 459 | dbg("%s(port = %d)", __FUNCTION__, port->number); |
460 | 460 | ||
461 | if ((!port->tty) || (!port->tty->termios)) { | 461 | if (!port->tty || !port->tty->termios) { |
462 | dbg("%s(): no tty structures", __FUNCTION__); | 462 | dbg("%s(): no tty structures", __FUNCTION__); |
463 | return; | 463 | return; |
464 | } | 464 | } |
@@ -468,6 +468,8 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
468 | *(port->tty->termios) = tty_std_termios; | 468 | *(port->tty->termios) = tty_std_termios; |
469 | port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; | 469 | port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; |
470 | priv->flags.termios_initialized = 1; | 470 | priv->flags.termios_initialized = 1; |
471 | port->tty->termios->c_ispeed = 38400; | ||
472 | port->tty->termios->c_ospeed = 38400; | ||
471 | } | 473 | } |
472 | spin_unlock_irqrestore(&priv->lock, flags); | 474 | spin_unlock_irqrestore(&priv->lock, flags); |
473 | 475 | ||
@@ -504,19 +506,14 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
504 | br = tty_get_baud_rate(port->tty); | 506 | br = tty_get_baud_rate(port->tty); |
505 | if (br == 0) { | 507 | if (br == 0) { |
506 | divisor = 0; | 508 | divisor = 0; |
507 | } else if (br <= OTI6858_MAX_BAUD_RATE) { | 509 | } else { |
508 | int real_br; | 510 | int real_br; |
511 | br = min(br, OTI6858_MAX_BAUD_RATE); | ||
509 | 512 | ||
510 | divisor = (96000000 + 8 * br) / (16 * br); | 513 | divisor = (96000000 + 8 * br) / (16 * br); |
511 | real_br = 96000000 / (16 * divisor); | 514 | real_br = 96000000 / (16 * divisor); |
512 | if ((((real_br - br) * 100 + br - 1) / br) > 2) { | ||
513 | dbg("%s(): baud rate %d is invalid", __FUNCTION__, br); | ||
514 | return; | ||
515 | } | ||
516 | divisor = cpu_to_le16(divisor); | 515 | divisor = cpu_to_le16(divisor); |
517 | } else { | 516 | tty_encode_baud_rate(port->tty, real_br, real_br); |
518 | dbg("%s(): baud rate %d is too high", __FUNCTION__, br); | ||
519 | return; | ||
520 | } | 517 | } |
521 | 518 | ||
522 | frame_fmt &= ~FMT_STOP_BITS_MASK; | 519 | frame_fmt &= ~FMT_STOP_BITS_MASK; |
@@ -650,9 +647,9 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
650 | dbg("%s(): entering wait loop", __FUNCTION__); | 647 | dbg("%s(): entering wait loop", __FUNCTION__); |
651 | for (;;) { | 648 | for (;;) { |
652 | set_current_state(TASK_INTERRUPTIBLE); | 649 | set_current_state(TASK_INTERRUPTIBLE); |
653 | if (pl2303_buf_data_avail(priv->buf) == 0 | 650 | if (oti6858_buf_data_avail(priv->buf) == 0 |
654 | || timeout == 0 || signal_pending(current) | 651 | || timeout == 0 || signal_pending(current) |
655 | || !usb_get_intfdata(port->serial->interface)) /* disconnect */ | 652 | || port->serial->disconnected) |
656 | break; | 653 | break; |
657 | spin_unlock_irqrestore(&priv->lock, flags); | 654 | spin_unlock_irqrestore(&priv->lock, flags); |
658 | timeout = schedule_timeout(timeout); | 655 | timeout = schedule_timeout(timeout); |
@@ -663,7 +660,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
663 | dbg("%s(): after wait loop", __FUNCTION__); | 660 | dbg("%s(): after wait loop", __FUNCTION__); |
664 | 661 | ||
665 | /* clear out any remaining data in the buffer */ | 662 | /* clear out any remaining data in the buffer */ |
666 | pl2303_buf_clear(priv->buf); | 663 | oti6858_buf_clear(priv->buf); |
667 | spin_unlock_irqrestore(&priv->lock, flags); | 664 | spin_unlock_irqrestore(&priv->lock, flags); |
668 | 665 | ||
669 | /* wait for characters to drain from the device */ | 666 | /* wait for characters to drain from the device */ |
@@ -831,21 +828,6 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, | |||
831 | return -EFAULT; | 828 | return -EFAULT; |
832 | return oti6858_tiocmset(port, NULL, 0, x); | 829 | return oti6858_tiocmset(port, NULL, 0, x); |
833 | 830 | ||
834 | case TIOCGSERIAL: | ||
835 | if (copy_to_user(user_arg, port->tty->termios, | ||
836 | sizeof(struct ktermios))) { | ||
837 | return -EFAULT; | ||
838 | } | ||
839 | return 0; | ||
840 | |||
841 | case TIOCSSERIAL: | ||
842 | if (copy_from_user(port->tty->termios, user_arg, | ||
843 | sizeof(struct ktermios))) { | ||
844 | return -EFAULT; | ||
845 | } | ||
846 | oti6858_set_termios(port, NULL); | ||
847 | return 0; | ||
848 | |||
849 | case TIOCMIWAIT: | 831 | case TIOCMIWAIT: |
850 | dbg("%s(): TIOCMIWAIT", __FUNCTION__); | 832 | dbg("%s(): TIOCMIWAIT", __FUNCTION__); |
851 | return wait_modem_info(port, arg); | 833 | return wait_modem_info(port, arg); |
@@ -887,7 +869,7 @@ static void oti6858_shutdown(struct usb_serial *serial) | |||
887 | for (i = 0; i < serial->num_ports; ++i) { | 869 | for (i = 0; i < serial->num_ports; ++i) { |
888 | priv = usb_get_serial_port_data(serial->port[i]); | 870 | priv = usb_get_serial_port_data(serial->port[i]); |
889 | if (priv) { | 871 | if (priv) { |
890 | pl2303_buf_free(priv->buf); | 872 | oti6858_buf_free(priv->buf); |
891 | kfree(priv); | 873 | kfree(priv); |
892 | usb_set_serial_port_data(serial->port[i], NULL); | 874 | usb_set_serial_port_data(serial->port[i], NULL); |
893 | } | 875 | } |
@@ -987,7 +969,7 @@ static void oti6858_read_int_callback(struct urb *urb) | |||
987 | 969 | ||
988 | spin_lock_irqsave(&priv->lock, flags); | 970 | spin_lock_irqsave(&priv->lock, flags); |
989 | if (priv->flags.write_urb_in_use == 0 | 971 | if (priv->flags.write_urb_in_use == 0 |
990 | && pl2303_buf_data_avail(priv->buf) != 0) { | 972 | && oti6858_buf_data_avail(priv->buf) != 0) { |
991 | schedule_delayed_work(&priv->delayed_write_work,0); | 973 | schedule_delayed_work(&priv->delayed_write_work,0); |
992 | resubmit = 0; | 974 | resubmit = 0; |
993 | } | 975 | } |
@@ -1015,9 +997,8 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
1015 | struct tty_struct *tty; | 997 | struct tty_struct *tty; |
1016 | unsigned char *data = urb->transfer_buffer; | 998 | unsigned char *data = urb->transfer_buffer; |
1017 | unsigned long flags; | 999 | unsigned long flags; |
1018 | int i, result; | ||
1019 | int status = urb->status; | 1000 | int status = urb->status; |
1020 | char tty_flag; | 1001 | int result; |
1021 | 1002 | ||
1022 | dbg("%s(port = %d, status = %d)", | 1003 | dbg("%s(port = %d, status = %d)", |
1023 | __FUNCTION__, port->number, status); | 1004 | __FUNCTION__, port->number, status); |
@@ -1045,27 +1026,9 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
1045 | return; | 1026 | return; |
1046 | } | 1027 | } |
1047 | 1028 | ||
1048 | // get tty_flag from status | ||
1049 | tty_flag = TTY_NORMAL; | ||
1050 | |||
1051 | /* FIXME: probably, errors will be signalled using interrupt pipe! */ | ||
1052 | /* | ||
1053 | // break takes precedence over parity, | ||
1054 | // which takes precedence over framing errors | ||
1055 | if (status & UART_BREAK_ERROR ) | ||
1056 | tty_flag = TTY_BREAK; | ||
1057 | else if (status & UART_PARITY_ERROR) | ||
1058 | tty_flag = TTY_PARITY; | ||
1059 | else if (status & UART_FRAME_ERROR) | ||
1060 | tty_flag = TTY_FRAME; | ||
1061 | dbg("%s - tty_flag = %d", __FUNCTION__, tty_flag); | ||
1062 | */ | ||
1063 | |||
1064 | tty = port->tty; | 1029 | tty = port->tty; |
1065 | if (tty != NULL && urb->actual_length > 0) { | 1030 | if (tty != NULL && urb->actual_length > 0) { |
1066 | tty_buffer_request_room(tty, urb->actual_length); | 1031 | tty_insert_flip_string(tty, data, urb->actual_length); |
1067 | for (i = 0; i < urb->actual_length; ++i) | ||
1068 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1069 | tty_flip_buffer_push(tty); | 1032 | tty_flip_buffer_push(tty); |
1070 | } | 1033 | } |
1071 | 1034 | ||
@@ -1133,18 +1096,18 @@ static void oti6858_write_bulk_callback(struct urb *urb) | |||
1133 | 1096 | ||
1134 | 1097 | ||
1135 | /* | 1098 | /* |
1136 | * pl2303_buf_alloc | 1099 | * oti6858_buf_alloc |
1137 | * | 1100 | * |
1138 | * Allocate a circular buffer and all associated memory. | 1101 | * Allocate a circular buffer and all associated memory. |
1139 | */ | 1102 | */ |
1140 | static struct pl2303_buf *pl2303_buf_alloc(unsigned int size) | 1103 | static struct oti6858_buf *oti6858_buf_alloc(unsigned int size) |
1141 | { | 1104 | { |
1142 | struct pl2303_buf *pb; | 1105 | struct oti6858_buf *pb; |
1143 | 1106 | ||
1144 | if (size == 0) | 1107 | if (size == 0) |
1145 | return NULL; | 1108 | return NULL; |
1146 | 1109 | ||
1147 | pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); | 1110 | pb = kmalloc(sizeof(struct oti6858_buf), GFP_KERNEL); |
1148 | if (pb == NULL) | 1111 | if (pb == NULL) |
1149 | return NULL; | 1112 | return NULL; |
1150 | 1113 | ||
@@ -1161,11 +1124,11 @@ static struct pl2303_buf *pl2303_buf_alloc(unsigned int size) | |||
1161 | } | 1124 | } |
1162 | 1125 | ||
1163 | /* | 1126 | /* |
1164 | * pl2303_buf_free | 1127 | * oti6858_buf_free |
1165 | * | 1128 | * |
1166 | * Free the buffer and all associated memory. | 1129 | * Free the buffer and all associated memory. |
1167 | */ | 1130 | */ |
1168 | static void pl2303_buf_free(struct pl2303_buf *pb) | 1131 | static void oti6858_buf_free(struct oti6858_buf *pb) |
1169 | { | 1132 | { |
1170 | if (pb) { | 1133 | if (pb) { |
1171 | kfree(pb->buf_buf); | 1134 | kfree(pb->buf_buf); |
@@ -1174,11 +1137,11 @@ static void pl2303_buf_free(struct pl2303_buf *pb) | |||
1174 | } | 1137 | } |
1175 | 1138 | ||
1176 | /* | 1139 | /* |
1177 | * pl2303_buf_clear | 1140 | * oti6858_buf_clear |
1178 | * | 1141 | * |
1179 | * Clear out all data in the circular buffer. | 1142 | * Clear out all data in the circular buffer. |
1180 | */ | 1143 | */ |
1181 | static void pl2303_buf_clear(struct pl2303_buf *pb) | 1144 | static void oti6858_buf_clear(struct oti6858_buf *pb) |
1182 | { | 1145 | { |
1183 | if (pb != NULL) { | 1146 | if (pb != NULL) { |
1184 | /* equivalent to a get of all data available */ | 1147 | /* equivalent to a get of all data available */ |
@@ -1187,12 +1150,12 @@ static void pl2303_buf_clear(struct pl2303_buf *pb) | |||
1187 | } | 1150 | } |
1188 | 1151 | ||
1189 | /* | 1152 | /* |
1190 | * pl2303_buf_data_avail | 1153 | * oti6858_buf_data_avail |
1191 | * | 1154 | * |
1192 | * Return the number of bytes of data available in the circular | 1155 | * Return the number of bytes of data available in the circular |
1193 | * buffer. | 1156 | * buffer. |
1194 | */ | 1157 | */ |
1195 | static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb) | 1158 | static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb) |
1196 | { | 1159 | { |
1197 | if (pb == NULL) | 1160 | if (pb == NULL) |
1198 | return 0; | 1161 | return 0; |
@@ -1200,12 +1163,12 @@ static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb) | |||
1200 | } | 1163 | } |
1201 | 1164 | ||
1202 | /* | 1165 | /* |
1203 | * pl2303_buf_space_avail | 1166 | * oti6858_buf_space_avail |
1204 | * | 1167 | * |
1205 | * Return the number of bytes of space available in the circular | 1168 | * Return the number of bytes of space available in the circular |
1206 | * buffer. | 1169 | * buffer. |
1207 | */ | 1170 | */ |
1208 | static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb) | 1171 | static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb) |
1209 | { | 1172 | { |
1210 | if (pb == NULL) | 1173 | if (pb == NULL) |
1211 | return 0; | 1174 | return 0; |
@@ -1213,14 +1176,14 @@ static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb) | |||
1213 | } | 1176 | } |
1214 | 1177 | ||
1215 | /* | 1178 | /* |
1216 | * pl2303_buf_put | 1179 | * oti6858_buf_put |
1217 | * | 1180 | * |
1218 | * Copy data data from a user buffer and put it into the circular buffer. | 1181 | * Copy data data from a user buffer and put it into the circular buffer. |
1219 | * Restrict to the amount of space available. | 1182 | * Restrict to the amount of space available. |
1220 | * | 1183 | * |
1221 | * Return the number of bytes copied. | 1184 | * Return the number of bytes copied. |
1222 | */ | 1185 | */ |
1223 | static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf, | 1186 | static unsigned int oti6858_buf_put(struct oti6858_buf *pb, const char *buf, |
1224 | unsigned int count) | 1187 | unsigned int count) |
1225 | { | 1188 | { |
1226 | unsigned int len; | 1189 | unsigned int len; |
@@ -1228,7 +1191,7 @@ static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf, | |||
1228 | if (pb == NULL) | 1191 | if (pb == NULL) |
1229 | return 0; | 1192 | return 0; |
1230 | 1193 | ||
1231 | len = pl2303_buf_space_avail(pb); | 1194 | len = oti6858_buf_space_avail(pb); |
1232 | if (count > len) | 1195 | if (count > len) |
1233 | count = len; | 1196 | count = len; |
1234 | 1197 | ||
@@ -1252,14 +1215,14 @@ static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf, | |||
1252 | } | 1215 | } |
1253 | 1216 | ||
1254 | /* | 1217 | /* |
1255 | * pl2303_buf_get | 1218 | * oti6858_buf_get |
1256 | * | 1219 | * |
1257 | * Get data from the circular buffer and copy to the given buffer. | 1220 | * Get data from the circular buffer and copy to the given buffer. |
1258 | * Restrict to the amount of data available. | 1221 | * Restrict to the amount of data available. |
1259 | * | 1222 | * |
1260 | * Return the number of bytes copied. | 1223 | * Return the number of bytes copied. |
1261 | */ | 1224 | */ |
1262 | static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, | 1225 | static unsigned int oti6858_buf_get(struct oti6858_buf *pb, char *buf, |
1263 | unsigned int count) | 1226 | unsigned int count) |
1264 | { | 1227 | { |
1265 | unsigned int len; | 1228 | unsigned int len; |
@@ -1267,7 +1230,7 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, | |||
1267 | if (pb == NULL) | 1230 | if (pb == NULL) |
1268 | return 0; | 1231 | return 0; |
1269 | 1232 | ||
1270 | len = pl2303_buf_data_avail(pb); | 1233 | len = oti6858_buf_data_avail(pb); |
1271 | if (count > len) | 1234 | if (count > len) |
1272 | count = len; | 1235 | count = len; |
1273 | 1236 | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 0da1df9c79bf..ae3ec1a64008 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -65,6 +65,7 @@ static struct usb_device_id id_table [] = { | |||
65 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, | 65 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, |
66 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, | 66 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, |
67 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, | 67 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, |
68 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | ||
68 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, | 69 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, |
69 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, | 70 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, |
70 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, | 71 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, |
@@ -84,9 +85,10 @@ static struct usb_device_id id_table [] = { | |||
84 | { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, | 85 | { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, |
85 | { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, | 86 | { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, |
86 | { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, | 87 | { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, |
87 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) }, | ||
88 | { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) }, | 88 | { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) }, |
89 | { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) }, | 89 | { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) }, |
90 | { USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) }, | ||
91 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, | ||
90 | { } /* Terminating entry */ | 92 | { } /* Terminating entry */ |
91 | }; | 93 | }; |
92 | 94 | ||
@@ -97,7 +99,10 @@ static struct usb_driver pl2303_driver = { | |||
97 | .probe = usb_serial_probe, | 99 | .probe = usb_serial_probe, |
98 | .disconnect = usb_serial_disconnect, | 100 | .disconnect = usb_serial_disconnect, |
99 | .id_table = id_table, | 101 | .id_table = id_table, |
102 | .suspend = usb_serial_suspend, | ||
103 | .resume = usb_serial_resume, | ||
100 | .no_dynamic_id = 1, | 104 | .no_dynamic_id = 1, |
105 | .supports_autosuspend = 1, | ||
101 | }; | 106 | }; |
102 | 107 | ||
103 | #define SET_LINE_REQUEST_TYPE 0x21 | 108 | #define SET_LINE_REQUEST_TYPE 0x21 |
@@ -310,12 +315,39 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, | |||
310 | return count; | 315 | return count; |
311 | } | 316 | } |
312 | 317 | ||
318 | static int pl2303_vendor_read(__u16 value, __u16 index, | ||
319 | struct usb_serial *serial, unsigned char *buf) | ||
320 | { | ||
321 | int res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
322 | VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, | ||
323 | value, index, buf, 1, 100); | ||
324 | dbg("0x%x:0x%x:0x%x:0x%x %d - %x", VENDOR_READ_REQUEST_TYPE, | ||
325 | VENDOR_READ_REQUEST, value, index, res, buf[0]); | ||
326 | return res; | ||
327 | } | ||
328 | |||
329 | static int pl2303_vendor_write(__u16 value, __u16 index, | ||
330 | struct usb_serial *serial) | ||
331 | { | ||
332 | int res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
333 | VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, | ||
334 | value, index, NULL, 0, 100); | ||
335 | dbg("0x%x:0x%x:0x%x:0x%x %d", VENDOR_WRITE_REQUEST_TYPE, | ||
336 | VENDOR_WRITE_REQUEST, value, index, res); | ||
337 | return res; | ||
338 | } | ||
339 | |||
313 | static int pl2303_startup(struct usb_serial *serial) | 340 | static int pl2303_startup(struct usb_serial *serial) |
314 | { | 341 | { |
315 | struct pl2303_private *priv; | 342 | struct pl2303_private *priv; |
316 | enum pl2303_type type = type_0; | 343 | enum pl2303_type type = type_0; |
344 | unsigned char *buf; | ||
317 | int i; | 345 | int i; |
318 | 346 | ||
347 | buf = kmalloc(10, GFP_KERNEL); | ||
348 | if (buf == NULL) | ||
349 | return -ENOMEM; | ||
350 | |||
319 | if (serial->dev->descriptor.bDeviceClass == 0x02) | 351 | if (serial->dev->descriptor.bDeviceClass == 0x02) |
320 | type = type_0; | 352 | type = type_0; |
321 | else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) | 353 | else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) |
@@ -340,9 +372,27 @@ static int pl2303_startup(struct usb_serial *serial) | |||
340 | priv->type = type; | 372 | priv->type = type; |
341 | usb_set_serial_port_data(serial->port[i], priv); | 373 | usb_set_serial_port_data(serial->port[i], priv); |
342 | } | 374 | } |
375 | |||
376 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
377 | pl2303_vendor_write(0x0404, 0, serial); | ||
378 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
379 | pl2303_vendor_read(0x8383, 0, serial, buf); | ||
380 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
381 | pl2303_vendor_write(0x0404, 1, serial); | ||
382 | pl2303_vendor_read(0x8484, 0, serial, buf); | ||
383 | pl2303_vendor_read(0x8383, 0, serial, buf); | ||
384 | pl2303_vendor_write(0, 1, serial); | ||
385 | pl2303_vendor_write(1, 0, serial); | ||
386 | if (type == HX) | ||
387 | pl2303_vendor_write(2, 0x44, serial); | ||
388 | else | ||
389 | pl2303_vendor_write(2, 0x24, serial); | ||
390 | |||
391 | kfree(buf); | ||
343 | return 0; | 392 | return 0; |
344 | 393 | ||
345 | cleanup: | 394 | cleanup: |
395 | kfree(buf); | ||
346 | for (--i; i>=0; --i) { | 396 | for (--i; i>=0; --i) { |
347 | priv = usb_get_serial_port_data(serial->port[i]); | 397 | priv = usb_get_serial_port_data(serial->port[i]); |
348 | pl2303_buf_free(priv->buf); | 398 | pl2303_buf_free(priv->buf); |
@@ -582,24 +632,12 @@ static void pl2303_set_termios(struct usb_serial_port *port, | |||
582 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); | 632 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); |
583 | 633 | ||
584 | if (cflag & CRTSCTS) { | 634 | if (cflag & CRTSCTS) { |
585 | __u16 index; | ||
586 | if (priv->type == HX) | 635 | if (priv->type == HX) |
587 | index = 0x61; | 636 | pl2303_vendor_write(0x0, 0x61, serial); |
588 | else | 637 | else |
589 | index = 0x41; | 638 | pl2303_vendor_write(0x0, 0x41, serial); |
590 | i = usb_control_msg(serial->dev, | ||
591 | usb_sndctrlpipe(serial->dev, 0), | ||
592 | VENDOR_WRITE_REQUEST, | ||
593 | VENDOR_WRITE_REQUEST_TYPE, | ||
594 | 0x0, index, NULL, 0, 100); | ||
595 | dbg("0x40:0x1:0x0:0x%x %d", index, i); | ||
596 | } else { | 639 | } else { |
597 | i = usb_control_msg(serial->dev, | 640 | pl2303_vendor_write(0x0, 0x0, serial); |
598 | usb_sndctrlpipe(serial->dev, 0), | ||
599 | VENDOR_WRITE_REQUEST, | ||
600 | VENDOR_WRITE_REQUEST_TYPE, | ||
601 | 0x0, 0x0, NULL, 0, 100); | ||
602 | dbg ("0x40:0x1:0x0:0x0 %d", i); | ||
603 | } | 641 | } |
604 | 642 | ||
605 | /* FIXME: Need to read back resulting baud rate */ | 643 | /* FIXME: Need to read back resulting baud rate */ |
@@ -629,7 +667,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp) | |||
629 | set_current_state(TASK_INTERRUPTIBLE); | 667 | set_current_state(TASK_INTERRUPTIBLE); |
630 | if (pl2303_buf_data_avail(priv->buf) == 0 || | 668 | if (pl2303_buf_data_avail(priv->buf) == 0 || |
631 | timeout == 0 || signal_pending(current) || | 669 | timeout == 0 || signal_pending(current) || |
632 | !usb_get_intfdata(port->serial->interface)) /* disconnect */ | 670 | port->serial->disconnected) |
633 | break; | 671 | break; |
634 | spin_unlock_irqrestore(&priv->lock, flags); | 672 | spin_unlock_irqrestore(&priv->lock, flags); |
635 | timeout = schedule_timeout(timeout); | 673 | timeout = schedule_timeout(timeout); |
@@ -678,7 +716,6 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp) | |||
678 | struct ktermios tmp_termios; | 716 | struct ktermios tmp_termios; |
679 | struct usb_serial *serial = port->serial; | 717 | struct usb_serial *serial = port->serial; |
680 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 718 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
681 | unsigned char *buf; | ||
682 | int result; | 719 | int result; |
683 | 720 | ||
684 | dbg("%s - port %d", __FUNCTION__, port->number); | 721 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -686,45 +723,12 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp) | |||
686 | if (priv->type != HX) { | 723 | if (priv->type != HX) { |
687 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 724 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
688 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 725 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
689 | } | ||
690 | |||
691 | buf = kmalloc(10, GFP_KERNEL); | ||
692 | if (buf==NULL) | ||
693 | return -ENOMEM; | ||
694 | |||
695 | #define FISH(a,b,c,d) \ | ||
696 | result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \ | ||
697 | b, a, c, d, buf, 1, 100); \ | ||
698 | dbg("0x%x:0x%x:0x%x:0x%x %d - %x",a,b,c,d,result,buf[0]); | ||
699 | |||
700 | #define SOUP(a,b,c,d) \ | ||
701 | result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \ | ||
702 | b, a, c, d, NULL, 0, 100); \ | ||
703 | dbg("0x%x:0x%x:0x%x:0x%x %d",a,b,c,d,result); | ||
704 | |||
705 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
706 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0); | ||
707 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
708 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); | ||
709 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
710 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1); | ||
711 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0); | ||
712 | FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); | ||
713 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1); | ||
714 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0); | ||
715 | |||
716 | if (priv->type == HX) { | ||
717 | /* HX chip */ | ||
718 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x44); | ||
719 | /* reset upstream data pipes */ | ||
720 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 8, 0); | ||
721 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 9, 0); | ||
722 | } else { | 726 | } else { |
723 | SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x24); | 727 | /* reset upstream data pipes */ |
728 | pl2303_vendor_write(8, 0, serial); | ||
729 | pl2303_vendor_write(9, 0, serial); | ||
724 | } | 730 | } |
725 | 731 | ||
726 | kfree(buf); | ||
727 | |||
728 | /* Setup termios */ | 732 | /* Setup termios */ |
729 | if (port->tty) { | 733 | if (port->tty) { |
730 | pl2303_set_termios(port, &tmp_termios); | 734 | pl2303_set_termios(port, &tmp_termios); |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index d31f5d299989..237a41f6638a 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #define RATOC_VENDOR_ID 0x0584 | 36 | #define RATOC_VENDOR_ID 0x0584 |
37 | #define RATOC_PRODUCT_ID 0xb000 | 37 | #define RATOC_PRODUCT_ID 0xb000 |
38 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
38 | 39 | ||
39 | #define TRIPP_VENDOR_ID 0x2478 | 40 | #define TRIPP_VENDOR_ID 0x2478 |
40 | #define TRIPP_PRODUCT_ID 0x2008 | 41 | #define TRIPP_PRODUCT_ID 0x2008 |
@@ -96,10 +97,6 @@ | |||
96 | #define ALCOR_VENDOR_ID 0x058F | 97 | #define ALCOR_VENDOR_ID 0x058F |
97 | #define ALCOR_PRODUCT_ID 0x9720 | 98 | #define ALCOR_PRODUCT_ID 0x9720 |
98 | 99 | ||
99 | /* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */ | ||
100 | #define HUAWEI_VENDOR_ID 0x12d1 | ||
101 | #define HUAWEI_PRODUCT_ID 0x1001 | ||
102 | |||
103 | /* Willcom WS002IN Data Driver (by NetIndex Inc.) */ | 100 | /* Willcom WS002IN Data Driver (by NetIndex Inc.) */ |
104 | #define WS002IN_VENDOR_ID 0x11f6 | 101 | #define WS002IN_VENDOR_ID 0x11f6 |
105 | #define WS002IN_PRODUCT_ID 0x2001 | 102 | #define WS002IN_PRODUCT_ID 0x2001 |
@@ -107,3 +104,11 @@ | |||
107 | /* Corega CG-USBRS232R Serial Adapter */ | 104 | /* Corega CG-USBRS232R Serial Adapter */ |
108 | #define COREGA_VENDOR_ID 0x07aa | 105 | #define COREGA_VENDOR_ID 0x07aa |
109 | #define COREGA_PRODUCT_ID 0x002a | 106 | #define COREGA_PRODUCT_ID 0x002a |
107 | |||
108 | /* HL HL-340 (ID: 4348:5523) */ | ||
109 | #define HL340_VENDOR_ID 0x4348 | ||
110 | #define HL340_PRODUCT_ID 0x5523 | ||
111 | |||
112 | /* Y.C. Cable U.S.A., Inc - USB to RS-232 */ | ||
113 | #define YCCABLE_VENDOR_ID 0x05ad | ||
114 | #define YCCABLE_PRODUCT_ID 0x0fba | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index c295d0495f96..4c925e3e8a63 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | USB Driver for Sierra Wireless | 2 | USB Driver for Sierra Wireless |
3 | 3 | ||
4 | Copyright (C) 2006, 2007 Kevin Lloyd <linux@sierrawireless.com> | 4 | Copyright (C) 2006, 2007, 2008 Kevin Lloyd <linux@sierrawireless.com> |
5 | 5 | ||
6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by | 6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by |
7 | Sierra Wireless. Use at your own risk. | 7 | Sierra Wireless. Use at your own risk. |
@@ -14,7 +14,7 @@ | |||
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define DRIVER_VERSION "v.1.2.5b" | 17 | #define DRIVER_VERSION "v.1.2.7" |
18 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" | 18 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" |
19 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 19 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
20 | 20 | ||
@@ -26,10 +26,12 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/usb/serial.h> | 28 | #include <linux/usb/serial.h> |
29 | #include <linux/usb/ch9.h> | ||
29 | 30 | ||
31 | #define SWIMS_USB_REQUEST_SetPower 0x00 | ||
32 | #define SWIMS_USB_REQUEST_SetNmea 0x07 | ||
30 | #define SWIMS_USB_REQUEST_SetMode 0x0B | 33 | #define SWIMS_USB_REQUEST_SetMode 0x0B |
31 | #define SWIMS_USB_REQUEST_TYPE_SetMode 0x40 | 34 | #define SWIMS_USB_REQUEST_TYPE_VSC_SET 0x40 |
32 | #define SWIMS_USB_INDEX_SetMode 0x0000 | ||
33 | #define SWIMS_SET_MODE_Modem 0x0001 | 35 | #define SWIMS_SET_MODE_Modem 0x0001 |
34 | 36 | ||
35 | /* per port private data */ | 37 | /* per port private data */ |
@@ -38,6 +40,8 @@ | |||
38 | #define IN_BUFLEN 4096 | 40 | #define IN_BUFLEN 4096 |
39 | 41 | ||
40 | static int debug; | 42 | static int debug; |
43 | static int nmea; | ||
44 | static int truinstall = 1; | ||
41 | 45 | ||
42 | enum devicetype { | 46 | enum devicetype { |
43 | DEVICE_3_PORT = 0, | 47 | DEVICE_3_PORT = 0, |
@@ -50,48 +54,96 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | |||
50 | int result; | 54 | int result; |
51 | dev_dbg(&udev->dev, "%s", "SET POWER STATE\n"); | 55 | dev_dbg(&udev->dev, "%s", "SET POWER STATE\n"); |
52 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 56 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
53 | 0x00, /* __u8 request */ | 57 | SWIMS_USB_REQUEST_SetPower, /* __u8 request */ |
54 | 0x40, /* __u8 request type */ | 58 | SWIMS_USB_REQUEST_TYPE_VSC_SET, /* __u8 request type */ |
55 | swiState, /* __u16 value */ | 59 | swiState, /* __u16 value */ |
56 | 0, /* __u16 index */ | 60 | 0, /* __u16 index */ |
57 | NULL, /* void *data */ | 61 | NULL, /* void *data */ |
58 | 0, /* __u16 size */ | 62 | 0, /* __u16 size */ |
59 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | 63 | USB_CTRL_SET_TIMEOUT); /* int timeout */ |
60 | return result; | 64 | return result; |
61 | } | 65 | } |
62 | 66 | ||
63 | static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) | 67 | static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode) |
64 | { | 68 | { |
65 | int result; | 69 | int result; |
66 | dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n"); | 70 | dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n"); |
67 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 71 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
68 | SWIMS_USB_REQUEST_SetMode, /* __u8 request */ | 72 | SWIMS_USB_REQUEST_SetMode, /* __u8 request */ |
69 | SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ | 73 | SWIMS_USB_REQUEST_TYPE_VSC_SET, /* __u8 request type */ |
70 | eSocMode, /* __u16 value */ | 74 | eSWocMode, /* __u16 value */ |
71 | SWIMS_USB_INDEX_SetMode, /* __u16 index */ | 75 | 0x0000, /* __u16 index */ |
72 | NULL, /* void *data */ | 76 | NULL, /* void *data */ |
73 | 0, /* __u16 size */ | 77 | 0, /* __u16 size */ |
74 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | 78 | USB_CTRL_SET_TIMEOUT); /* int timeout */ |
75 | return result; | 79 | return result; |
76 | } | 80 | } |
77 | 81 | ||
78 | static int sierra_probe(struct usb_interface *iface, | 82 | static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) |
79 | const struct usb_device_id *id) | 83 | { |
84 | int result; | ||
85 | dev_dbg(&udev->dev, "%s", "NMEA Enable sent\n"); | ||
86 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
87 | SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ | ||
88 | SWIMS_USB_REQUEST_TYPE_VSC_SET, /* __u8 request type */ | ||
89 | enable, /* __u16 value */ | ||
90 | 0x0000, /* __u16 index */ | ||
91 | NULL, /* void *data */ | ||
92 | 0, /* __u16 size */ | ||
93 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | ||
94 | return result; | ||
95 | } | ||
96 | |||
97 | static int sierra_calc_num_ports(struct usb_serial *serial) | ||
80 | { | 98 | { |
81 | int result; | 99 | int result; |
100 | int *num_ports = usb_get_serial_data(serial); | ||
101 | |||
102 | result = *num_ports; | ||
103 | |||
104 | if (result) { | ||
105 | kfree(num_ports); | ||
106 | usb_set_serial_data(serial, NULL); | ||
107 | } | ||
108 | |||
109 | return result; | ||
110 | } | ||
111 | |||
112 | static int sierra_probe(struct usb_serial *serial, | ||
113 | const struct usb_device_id *id) | ||
114 | { | ||
115 | int result = 0; | ||
82 | struct usb_device *udev; | 116 | struct usb_device *udev; |
117 | int *num_ports; | ||
118 | u8 ifnum; | ||
119 | |||
120 | num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); | ||
121 | if (!num_ports) | ||
122 | return -ENOMEM; | ||
83 | 123 | ||
84 | udev = usb_get_dev(interface_to_usbdev(iface)); | 124 | ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; |
125 | udev = serial->dev; | ||
85 | 126 | ||
86 | /* Check if in installer mode */ | 127 | /* Check if in installer mode */ |
87 | if (id->driver_info == DEVICE_INSTALLER) { | 128 | if (truinstall && id->driver_info == DEVICE_INSTALLER) { |
88 | dev_dbg(&udev->dev, "%s", "FOUND DEVICE(SW)\n"); | 129 | dev_dbg(&udev->dev, "%s", "FOUND TRU-INSTALL DEVICE(SW)\n"); |
89 | result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem); | 130 | result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem); |
90 | /*We do not want to bind to the device when in installer mode*/ | 131 | /* Don't bind to the device when in installer mode */ |
132 | kfree(num_ports); | ||
91 | return -EIO; | 133 | return -EIO; |
92 | } | 134 | } else if (id->driver_info == DEVICE_1_PORT) |
135 | *num_ports = 1; | ||
136 | else if (ifnum == 0x99) | ||
137 | *num_ports = 0; | ||
138 | else | ||
139 | *num_ports = 3; | ||
140 | /* | ||
141 | * save off our num_ports info so that we can use it in the | ||
142 | * calc_num_ports callback | ||
143 | */ | ||
144 | usb_set_serial_data(serial, (void *)num_ports); | ||
93 | 145 | ||
94 | return usb_serial_probe(iface, id); | 146 | return result; |
95 | } | 147 | } |
96 | 148 | ||
97 | static struct usb_device_id id_table [] = { | 149 | static struct usb_device_id id_table [] = { |
@@ -104,6 +156,7 @@ static struct usb_device_id id_table [] = { | |||
104 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 156 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
105 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 157 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
106 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ | 158 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ |
159 | { USB_DEVICE(0x1199, 0x0023) }, /* Sierra Wireless AirCard */ | ||
107 | 160 | ||
108 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 161 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
109 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | 162 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ |
@@ -117,56 +170,29 @@ static struct usb_device_id id_table [] = { | |||
117 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ | 170 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ |
118 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ | 171 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ |
119 | { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ | 172 | { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ |
173 | { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ | ||
174 | { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ | ||
175 | |||
176 | { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */ | ||
177 | { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */ | ||
120 | 178 | ||
121 | { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ | 179 | { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ |
122 | { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ | 180 | { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ |
181 | { USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */ | ||
123 | 182 | ||
124 | { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, | 183 | { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, |
125 | { } | 184 | { } |
126 | }; | 185 | }; |
127 | MODULE_DEVICE_TABLE(usb, id_table); | 186 | MODULE_DEVICE_TABLE(usb, id_table); |
128 | 187 | ||
129 | static struct usb_device_id id_table_1port [] = { | ||
130 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
131 | { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ | ||
132 | { } | ||
133 | }; | ||
134 | |||
135 | static struct usb_device_id id_table_3port [] = { | ||
136 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
137 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | ||
138 | { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ | ||
139 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
140 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | ||
141 | { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ | ||
142 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | ||
143 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | ||
144 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/ | ||
145 | |||
146 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | ||
147 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
148 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | ||
149 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ | ||
150 | { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Thinkpad internal) */ | ||
151 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | ||
152 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ | ||
153 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ | ||
154 | { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ | ||
155 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ | ||
156 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880E */ | ||
157 | { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881E */ | ||
158 | { } | ||
159 | }; | ||
160 | |||
161 | static struct usb_driver sierra_driver = { | 188 | static struct usb_driver sierra_driver = { |
162 | .name = "sierra", | 189 | .name = "sierra", |
163 | .probe = sierra_probe, | 190 | .probe = usb_serial_probe, |
164 | .disconnect = usb_serial_disconnect, | 191 | .disconnect = usb_serial_disconnect, |
165 | .id_table = id_table, | 192 | .id_table = id_table, |
166 | .no_dynamic_id = 1, | 193 | .no_dynamic_id = 1, |
167 | }; | 194 | }; |
168 | 195 | ||
169 | |||
170 | struct sierra_port_private { | 196 | struct sierra_port_private { |
171 | spinlock_t lock; /* lock the structure */ | 197 | spinlock_t lock; /* lock the structure */ |
172 | int outstanding_urbs; /* number of out urbs in flight */ | 198 | int outstanding_urbs; /* number of out urbs in flight */ |
@@ -188,6 +214,7 @@ static int sierra_send_setup(struct usb_serial_port *port) | |||
188 | { | 214 | { |
189 | struct usb_serial *serial = port->serial; | 215 | struct usb_serial *serial = port->serial; |
190 | struct sierra_port_private *portdata; | 216 | struct sierra_port_private *portdata; |
217 | __u16 interface = 0; | ||
191 | 218 | ||
192 | dbg("%s", __FUNCTION__); | 219 | dbg("%s", __FUNCTION__); |
193 | 220 | ||
@@ -200,9 +227,18 @@ static int sierra_send_setup(struct usb_serial_port *port) | |||
200 | if (portdata->rts_state) | 227 | if (portdata->rts_state) |
201 | val |= 0x02; | 228 | val |= 0x02; |
202 | 229 | ||
230 | /* Determine which port is targeted */ | ||
231 | if (port->bulk_out_endpointAddress == 2) | ||
232 | interface = 0; | ||
233 | else if (port->bulk_out_endpointAddress == 4) | ||
234 | interface = 1; | ||
235 | else if (port->bulk_out_endpointAddress == 5) | ||
236 | interface = 2; | ||
237 | |||
203 | return usb_control_msg(serial->dev, | 238 | return usb_control_msg(serial->dev, |
204 | usb_rcvctrlpipe(serial->dev, 0), | 239 | usb_rcvctrlpipe(serial->dev, 0), |
205 | 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); | 240 | 0x22, 0x21, val, interface, |
241 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
206 | } | 242 | } |
207 | 243 | ||
208 | return 0; | 244 | return 0; |
@@ -561,7 +597,10 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp) | |||
561 | portdata->dtr_state = 0; | 597 | portdata->dtr_state = 0; |
562 | 598 | ||
563 | if (serial->dev) { | 599 | if (serial->dev) { |
564 | sierra_send_setup(port); | 600 | mutex_lock(&serial->disc_mutex); |
601 | if (!serial->disconnected) | ||
602 | sierra_send_setup(port); | ||
603 | mutex_unlock(&serial->disc_mutex); | ||
565 | 604 | ||
566 | /* Stop reading/writing urbs */ | 605 | /* Stop reading/writing urbs */ |
567 | for (i = 0; i < N_IN_URB; i++) | 606 | for (i = 0; i < N_IN_URB; i++) |
@@ -583,9 +622,13 @@ static int sierra_startup(struct usb_serial *serial) | |||
583 | 622 | ||
584 | dbg("%s", __FUNCTION__); | 623 | dbg("%s", __FUNCTION__); |
585 | 624 | ||
586 | /*Set Device mode to D0 */ | 625 | /* Set Device mode to D0 */ |
587 | sierra_set_power_state(serial->dev, 0x0000); | 626 | sierra_set_power_state(serial->dev, 0x0000); |
588 | 627 | ||
628 | /* Check NMEA and set */ | ||
629 | if (nmea) | ||
630 | sierra_vsc_set_nmea(serial->dev, 1); | ||
631 | |||
589 | /* Now setup per port private data */ | 632 | /* Now setup per port private data */ |
590 | for (i = 0; i < serial->num_ports; i++) { | 633 | for (i = 0; i < serial->num_ports; i++) { |
591 | port = serial->port[i]; | 634 | port = serial->port[i]; |
@@ -646,47 +689,19 @@ static void sierra_shutdown(struct usb_serial *serial) | |||
646 | } | 689 | } |
647 | } | 690 | } |
648 | 691 | ||
649 | static struct usb_serial_driver sierra_1port_device = { | 692 | static struct usb_serial_driver sierra_device = { |
650 | .driver = { | 693 | .driver = { |
651 | .owner = THIS_MODULE, | 694 | .owner = THIS_MODULE, |
652 | .name = "sierra1", | 695 | .name = "sierra1", |
653 | }, | 696 | }, |
654 | .description = "Sierra USB modem (1 port)", | 697 | .description = "Sierra USB modem", |
655 | .id_table = id_table_1port, | 698 | .id_table = id_table, |
656 | .usb_driver = &sierra_driver, | ||
657 | .num_interrupt_in = NUM_DONT_CARE, | ||
658 | .num_bulk_in = 1, | ||
659 | .num_bulk_out = 1, | ||
660 | .num_ports = 1, | ||
661 | .open = sierra_open, | ||
662 | .close = sierra_close, | ||
663 | .write = sierra_write, | ||
664 | .write_room = sierra_write_room, | ||
665 | .chars_in_buffer = sierra_chars_in_buffer, | ||
666 | .throttle = sierra_rx_throttle, | ||
667 | .unthrottle = sierra_rx_unthrottle, | ||
668 | .ioctl = sierra_ioctl, | ||
669 | .set_termios = sierra_set_termios, | ||
670 | .break_ctl = sierra_break_ctl, | ||
671 | .tiocmget = sierra_tiocmget, | ||
672 | .tiocmset = sierra_tiocmset, | ||
673 | .attach = sierra_startup, | ||
674 | .shutdown = sierra_shutdown, | ||
675 | .read_int_callback = sierra_instat_callback, | ||
676 | }; | ||
677 | |||
678 | static struct usb_serial_driver sierra_3port_device = { | ||
679 | .driver = { | ||
680 | .owner = THIS_MODULE, | ||
681 | .name = "sierra3", | ||
682 | }, | ||
683 | .description = "Sierra USB modem (3 port)", | ||
684 | .id_table = id_table_3port, | ||
685 | .usb_driver = &sierra_driver, | 699 | .usb_driver = &sierra_driver, |
686 | .num_interrupt_in = NUM_DONT_CARE, | 700 | .num_interrupt_in = NUM_DONT_CARE, |
687 | .num_bulk_in = 3, | 701 | .num_bulk_in = NUM_DONT_CARE, |
688 | .num_bulk_out = 3, | 702 | .num_bulk_out = NUM_DONT_CARE, |
689 | .num_ports = 3, | 703 | .calc_num_ports = sierra_calc_num_ports, |
704 | .probe = sierra_probe, | ||
690 | .open = sierra_open, | 705 | .open = sierra_open, |
691 | .close = sierra_close, | 706 | .close = sierra_close, |
692 | .write = sierra_write, | 707 | .write = sierra_write, |
@@ -708,12 +723,9 @@ static struct usb_serial_driver sierra_3port_device = { | |||
708 | static int __init sierra_init(void) | 723 | static int __init sierra_init(void) |
709 | { | 724 | { |
710 | int retval; | 725 | int retval; |
711 | retval = usb_serial_register(&sierra_1port_device); | 726 | retval = usb_serial_register(&sierra_device); |
712 | if (retval) | ||
713 | goto failed_1port_device_register; | ||
714 | retval = usb_serial_register(&sierra_3port_device); | ||
715 | if (retval) | 727 | if (retval) |
716 | goto failed_3port_device_register; | 728 | goto failed_device_register; |
717 | 729 | ||
718 | 730 | ||
719 | retval = usb_register(&sierra_driver); | 731 | retval = usb_register(&sierra_driver); |
@@ -725,18 +737,15 @@ static int __init sierra_init(void) | |||
725 | return 0; | 737 | return 0; |
726 | 738 | ||
727 | failed_driver_register: | 739 | failed_driver_register: |
728 | usb_serial_deregister(&sierra_3port_device); | 740 | usb_serial_deregister(&sierra_device); |
729 | failed_3port_device_register: | 741 | failed_device_register: |
730 | usb_serial_deregister(&sierra_1port_device); | ||
731 | failed_1port_device_register: | ||
732 | return retval; | 742 | return retval; |
733 | } | 743 | } |
734 | 744 | ||
735 | static void __exit sierra_exit(void) | 745 | static void __exit sierra_exit(void) |
736 | { | 746 | { |
737 | usb_deregister (&sierra_driver); | 747 | usb_deregister (&sierra_driver); |
738 | usb_serial_deregister(&sierra_1port_device); | 748 | usb_serial_deregister(&sierra_device); |
739 | usb_serial_deregister(&sierra_3port_device); | ||
740 | } | 749 | } |
741 | 750 | ||
742 | module_init(sierra_init); | 751 | module_init(sierra_init); |
@@ -747,6 +756,12 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
747 | MODULE_VERSION(DRIVER_VERSION); | 756 | MODULE_VERSION(DRIVER_VERSION); |
748 | MODULE_LICENSE("GPL"); | 757 | MODULE_LICENSE("GPL"); |
749 | 758 | ||
759 | module_param(truinstall, bool, 0); | ||
760 | MODULE_PARM_DESC(truinstall, "TRU-Install support"); | ||
761 | |||
762 | module_param(nmea, bool, 0); | ||
763 | MODULE_PARM_DESC(nmea, "NMEA streaming"); | ||
764 | |||
750 | #ifdef CONFIG_USB_DEBUG | 765 | #ifdef CONFIG_USB_DEBUG |
751 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 766 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
752 | MODULE_PARM_DESC(debug, "Debug messages"); | 767 | MODULE_PARM_DESC(debug, "Debug messages"); |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 1f0149495fb4..b517f93352ec 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -80,6 +80,7 @@ | |||
80 | #include <linux/ioctl.h> | 80 | #include <linux/ioctl.h> |
81 | #include <linux/serial.h> | 81 | #include <linux/serial.h> |
82 | #include <linux/circ_buf.h> | 82 | #include <linux/circ_buf.h> |
83 | #include <linux/mutex.h> | ||
83 | #include <asm/uaccess.h> | 84 | #include <asm/uaccess.h> |
84 | #include <asm/semaphore.h> | 85 | #include <asm/semaphore.h> |
85 | #include <linux/usb.h> | 86 | #include <linux/usb.h> |
@@ -139,7 +140,7 @@ struct ti_port { | |||
139 | }; | 140 | }; |
140 | 141 | ||
141 | struct ti_device { | 142 | struct ti_device { |
142 | struct semaphore td_open_close_sem; | 143 | struct mutex td_open_close_lock; |
143 | int td_open_port_count; | 144 | int td_open_port_count; |
144 | struct usb_serial *td_serial; | 145 | struct usb_serial *td_serial; |
145 | int td_is_3410; | 146 | int td_is_3410; |
@@ -424,7 +425,7 @@ static int ti_startup(struct usb_serial *serial) | |||
424 | dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); | 425 | dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); |
425 | return -ENOMEM; | 426 | return -ENOMEM; |
426 | } | 427 | } |
427 | sema_init(&tdev->td_open_close_sem, 1); | 428 | mutex_init(&tdev->td_open_close_lock); |
428 | tdev->td_serial = serial; | 429 | tdev->td_serial = serial; |
429 | usb_set_serial_data(serial, tdev); | 430 | usb_set_serial_data(serial, tdev); |
430 | 431 | ||
@@ -547,7 +548,7 @@ static int ti_open(struct usb_serial_port *port, struct file *file) | |||
547 | tdev = tport->tp_tdev; | 548 | tdev = tport->tp_tdev; |
548 | 549 | ||
549 | /* only one open on any port on a device at a time */ | 550 | /* only one open on any port on a device at a time */ |
550 | if (down_interruptible(&tdev->td_open_close_sem)) | 551 | if (mutex_lock_interruptible(&tdev->td_open_close_lock)) |
551 | return -ERESTARTSYS; | 552 | return -ERESTARTSYS; |
552 | 553 | ||
553 | if (port->tty) | 554 | if (port->tty) |
@@ -568,7 +569,7 @@ static int ti_open(struct usb_serial_port *port, struct file *file) | |||
568 | if (!urb) { | 569 | if (!urb) { |
569 | dev_err(&port->dev, "%s - no interrupt urb\n", __FUNCTION__); | 570 | dev_err(&port->dev, "%s - no interrupt urb\n", __FUNCTION__); |
570 | status = -EINVAL; | 571 | status = -EINVAL; |
571 | goto up_sem; | 572 | goto release_lock; |
572 | } | 573 | } |
573 | urb->complete = ti_interrupt_callback; | 574 | urb->complete = ti_interrupt_callback; |
574 | urb->context = tdev; | 575 | urb->context = tdev; |
@@ -576,11 +577,11 @@ static int ti_open(struct usb_serial_port *port, struct file *file) | |||
576 | status = usb_submit_urb(urb, GFP_KERNEL); | 577 | status = usb_submit_urb(urb, GFP_KERNEL); |
577 | if (status) { | 578 | if (status) { |
578 | dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __FUNCTION__, status); | 579 | dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __FUNCTION__, status); |
579 | goto up_sem; | 580 | goto release_lock; |
580 | } | 581 | } |
581 | } | 582 | } |
582 | 583 | ||
583 | ti_set_termios(port, NULL); | 584 | ti_set_termios(port, port->tty->termios); |
584 | 585 | ||
585 | dbg("%s - sending TI_OPEN_PORT", __FUNCTION__); | 586 | dbg("%s - sending TI_OPEN_PORT", __FUNCTION__); |
586 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 587 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
@@ -617,7 +618,7 @@ static int ti_open(struct usb_serial_port *port, struct file *file) | |||
617 | usb_clear_halt(dev, port->write_urb->pipe); | 618 | usb_clear_halt(dev, port->write_urb->pipe); |
618 | usb_clear_halt(dev, port->read_urb->pipe); | 619 | usb_clear_halt(dev, port->read_urb->pipe); |
619 | 620 | ||
620 | ti_set_termios(port, NULL); | 621 | ti_set_termios(port, port->tty->termios); |
621 | 622 | ||
622 | dbg("%s - sending TI_OPEN_PORT (2)", __FUNCTION__); | 623 | dbg("%s - sending TI_OPEN_PORT (2)", __FUNCTION__); |
623 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 624 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
@@ -656,13 +657,13 @@ static int ti_open(struct usb_serial_port *port, struct file *file) | |||
656 | tport->tp_is_open = 1; | 657 | tport->tp_is_open = 1; |
657 | ++tdev->td_open_port_count; | 658 | ++tdev->td_open_port_count; |
658 | 659 | ||
659 | goto up_sem; | 660 | goto release_lock; |
660 | 661 | ||
661 | unlink_int_urb: | 662 | unlink_int_urb: |
662 | if (tdev->td_open_port_count == 0) | 663 | if (tdev->td_open_port_count == 0) |
663 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); | 664 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); |
664 | up_sem: | 665 | release_lock: |
665 | up(&tdev->td_open_close_sem); | 666 | mutex_unlock(&tdev->td_open_close_lock); |
666 | dbg("%s - exit %d", __FUNCTION__, status); | 667 | dbg("%s - exit %d", __FUNCTION__, status); |
667 | return status; | 668 | return status; |
668 | } | 669 | } |
@@ -674,7 +675,7 @@ static void ti_close(struct usb_serial_port *port, struct file *file) | |||
674 | struct ti_port *tport; | 675 | struct ti_port *tport; |
675 | int port_number; | 676 | int port_number; |
676 | int status; | 677 | int status; |
677 | int do_up; | 678 | int do_unlock; |
678 | 679 | ||
679 | dbg("%s - port %d", __FUNCTION__, port->number); | 680 | dbg("%s - port %d", __FUNCTION__, port->number); |
680 | 681 | ||
@@ -699,16 +700,16 @@ static void ti_close(struct usb_serial_port *port, struct file *file) | |||
699 | if (status) | 700 | if (status) |
700 | dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __FUNCTION__, status); | 701 | dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __FUNCTION__, status); |
701 | 702 | ||
702 | /* if down is interrupted, continue anyway */ | 703 | /* if mutex_lock is interrupted, continue anyway */ |
703 | do_up = !down_interruptible(&tdev->td_open_close_sem); | 704 | do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock); |
704 | --tport->tp_tdev->td_open_port_count; | 705 | --tport->tp_tdev->td_open_port_count; |
705 | if (tport->tp_tdev->td_open_port_count <= 0) { | 706 | if (tport->tp_tdev->td_open_port_count <= 0) { |
706 | /* last port is closed, shut down interrupt urb */ | 707 | /* last port is closed, shut down interrupt urb */ |
707 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); | 708 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); |
708 | tport->tp_tdev->td_open_port_count = 0; | 709 | tport->tp_tdev->td_open_port_count = 0; |
709 | } | 710 | } |
710 | if (do_up) | 711 | if (do_unlock) |
711 | up(&tdev->td_open_close_sem); | 712 | mutex_unlock(&tdev->td_open_close_lock); |
712 | 713 | ||
713 | dbg("%s - exit", __FUNCTION__); | 714 | dbg("%s - exit", __FUNCTION__); |
714 | } | 715 | } |
@@ -896,24 +897,11 @@ static void ti_set_termios(struct usb_serial_port *port, | |||
896 | 897 | ||
897 | dbg("%s - port %d", __FUNCTION__, port->number); | 898 | dbg("%s - port %d", __FUNCTION__, port->number); |
898 | 899 | ||
899 | if (!tty || !tty->termios) { | ||
900 | dbg("%s - no tty or termios", __FUNCTION__); | ||
901 | return; | ||
902 | } | ||
903 | |||
904 | cflag = tty->termios->c_cflag; | 900 | cflag = tty->termios->c_cflag; |
905 | iflag = tty->termios->c_iflag; | 901 | iflag = tty->termios->c_iflag; |
906 | 902 | ||
907 | if (old_termios && cflag == old_termios->c_cflag | 903 | dbg("%s - cflag %08x, iflag %08x", __FUNCTION__, cflag, iflag); |
908 | && iflag == old_termios->c_iflag) { | 904 | dbg("%s - old clfag %08x, old iflag %08x", __FUNCTION__, old_termios->c_cflag, old_termios->c_iflag); |
909 | dbg("%s - nothing to change", __FUNCTION__); | ||
910 | return; | ||
911 | } | ||
912 | |||
913 | dbg("%s - clfag %08x, iflag %08x", __FUNCTION__, cflag, iflag); | ||
914 | |||
915 | if (old_termios) | ||
916 | dbg("%s - old clfag %08x, old iflag %08x", __FUNCTION__, old_termios->c_cflag, old_termios->c_iflag); | ||
917 | 905 | ||
918 | if (tport == NULL) | 906 | if (tport == NULL) |
919 | return; | 907 | return; |
@@ -947,6 +935,9 @@ static void ti_set_termios(struct usb_serial_port *port, | |||
947 | break; | 935 | break; |
948 | } | 936 | } |
949 | 937 | ||
938 | /* CMSPAR isn't supported by this driver */ | ||
939 | tty->termios->c_cflag &= ~CMSPAR; | ||
940 | |||
950 | if (cflag & PARENB) { | 941 | if (cflag & PARENB) { |
951 | if (cflag & PARODD) { | 942 | if (cflag & PARODD) { |
952 | config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING; | 943 | config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING; |
@@ -989,12 +980,17 @@ static void ti_set_termios(struct usb_serial_port *port, | |||
989 | } | 980 | } |
990 | 981 | ||
991 | baud = tty_get_baud_rate(tty); | 982 | baud = tty_get_baud_rate(tty); |
992 | if (!baud) baud = 9600; | 983 | if (!baud) |
984 | baud = 9600; | ||
993 | if (tport->tp_tdev->td_is_3410) | 985 | if (tport->tp_tdev->td_is_3410) |
994 | config->wBaudRate = (__u16)((923077 + baud/2) / baud); | 986 | config->wBaudRate = (__u16)((923077 + baud/2) / baud); |
995 | else | 987 | else |
996 | config->wBaudRate = (__u16)((461538 + baud/2) / baud); | 988 | config->wBaudRate = (__u16)((461538 + baud/2) / baud); |
997 | 989 | ||
990 | /* FIXME: Should calculate resulting baud here and report it back */ | ||
991 | if ((cflag & CBAUD) != B0) | ||
992 | tty_encode_baud_rate(tty, baud, baud); | ||
993 | |||
998 | dbg("%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d", | 994 | dbg("%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d", |
999 | __FUNCTION__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode); | 995 | __FUNCTION__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode); |
1000 | 996 | ||
@@ -1497,11 +1493,10 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1497 | struct ti_device *tdev = tport->tp_tdev; | 1493 | struct ti_device *tdev = tport->tp_tdev; |
1498 | struct usb_serial_port *port = tport->tp_port; | 1494 | struct usb_serial_port *port = tport->tp_port; |
1499 | wait_queue_t wait; | 1495 | wait_queue_t wait; |
1500 | unsigned long flags; | ||
1501 | 1496 | ||
1502 | dbg("%s - port %d", __FUNCTION__, port->number); | 1497 | dbg("%s - port %d", __FUNCTION__, port->number); |
1503 | 1498 | ||
1504 | spin_lock_irqsave(&tport->tp_lock, flags); | 1499 | spin_lock_irq(&tport->tp_lock); |
1505 | 1500 | ||
1506 | /* wait for data to drain from the buffer */ | 1501 | /* wait for data to drain from the buffer */ |
1507 | tdev->td_urb_error = 0; | 1502 | tdev->td_urb_error = 0; |
@@ -1512,11 +1507,11 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1512 | if (ti_buf_data_avail(tport->tp_write_buf) == 0 | 1507 | if (ti_buf_data_avail(tport->tp_write_buf) == 0 |
1513 | || timeout == 0 || signal_pending(current) | 1508 | || timeout == 0 || signal_pending(current) |
1514 | || tdev->td_urb_error | 1509 | || tdev->td_urb_error |
1515 | || !usb_get_intfdata(port->serial->interface)) /* disconnect */ | 1510 | || port->serial->disconnected) /* disconnect */ |
1516 | break; | 1511 | break; |
1517 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 1512 | spin_unlock_irq(&tport->tp_lock); |
1518 | timeout = schedule_timeout(timeout); | 1513 | timeout = schedule_timeout(timeout); |
1519 | spin_lock_irqsave(&tport->tp_lock, flags); | 1514 | spin_lock_irq(&tport->tp_lock); |
1520 | } | 1515 | } |
1521 | set_current_state(TASK_RUNNING); | 1516 | set_current_state(TASK_RUNNING); |
1522 | remove_wait_queue(&tport->tp_write_wait, &wait); | 1517 | remove_wait_queue(&tport->tp_write_wait, &wait); |
@@ -1525,19 +1520,23 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1525 | if (flush) | 1520 | if (flush) |
1526 | ti_buf_clear(tport->tp_write_buf); | 1521 | ti_buf_clear(tport->tp_write_buf); |
1527 | 1522 | ||
1528 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 1523 | spin_unlock_irq(&tport->tp_lock); |
1529 | 1524 | ||
1525 | mutex_lock(&port->serial->disc_mutex); | ||
1530 | /* wait for data to drain from the device */ | 1526 | /* wait for data to drain from the device */ |
1531 | /* wait for empty tx register, plus 20 ms */ | 1527 | /* wait for empty tx register, plus 20 ms */ |
1532 | timeout += jiffies; | 1528 | timeout += jiffies; |
1533 | tport->tp_lsr &= ~TI_LSR_TX_EMPTY; | 1529 | tport->tp_lsr &= ~TI_LSR_TX_EMPTY; |
1534 | while ((long)(jiffies - timeout) < 0 && !signal_pending(current) | 1530 | while ((long)(jiffies - timeout) < 0 && !signal_pending(current) |
1535 | && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error | 1531 | && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error |
1536 | && usb_get_intfdata(port->serial->interface)) { /* not disconnected */ | 1532 | && !port->serial->disconnected) { |
1537 | if (ti_get_lsr(tport)) | 1533 | if (ti_get_lsr(tport)) |
1538 | break; | 1534 | break; |
1535 | mutex_unlock(&port->serial->disc_mutex); | ||
1539 | msleep_interruptible(20); | 1536 | msleep_interruptible(20); |
1537 | mutex_lock(&port->serial->disc_mutex); | ||
1540 | } | 1538 | } |
1539 | mutex_unlock(&port->serial->disc_mutex); | ||
1541 | } | 1540 | } |
1542 | 1541 | ||
1543 | 1542 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 497e29a700ca..3ce98e8d7bce 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -225,16 +225,21 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
225 | goto bailout_mutex_unlock; | 225 | goto bailout_mutex_unlock; |
226 | } | 226 | } |
227 | 227 | ||
228 | retval = usb_autopm_get_interface(serial->interface); | ||
229 | if (retval) | ||
230 | goto bailout_module_put; | ||
228 | /* only call the device specific open if this | 231 | /* only call the device specific open if this |
229 | * is the first time the port is opened */ | 232 | * is the first time the port is opened */ |
230 | retval = serial->type->open(port, filp); | 233 | retval = serial->type->open(port, filp); |
231 | if (retval) | 234 | if (retval) |
232 | goto bailout_module_put; | 235 | goto bailout_interface_put; |
233 | } | 236 | } |
234 | 237 | ||
235 | mutex_unlock(&port->mutex); | 238 | mutex_unlock(&port->mutex); |
236 | return 0; | 239 | return 0; |
237 | 240 | ||
241 | bailout_interface_put: | ||
242 | usb_autopm_put_interface(serial->interface); | ||
238 | bailout_module_put: | 243 | bailout_module_put: |
239 | module_put(serial->type->driver.owner); | 244 | module_put(serial->type->driver.owner); |
240 | bailout_mutex_unlock: | 245 | bailout_mutex_unlock: |
@@ -264,17 +269,21 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
264 | } | 269 | } |
265 | 270 | ||
266 | --port->open_count; | 271 | --port->open_count; |
267 | if (port->open_count == 0) { | 272 | if (port->open_count == 0) |
268 | /* only call the device specific close if this | 273 | /* only call the device specific close if this |
269 | * port is being closed by the last owner */ | 274 | * port is being closed by the last owner */ |
270 | port->serial->type->close(port, filp); | 275 | port->serial->type->close(port, filp); |
271 | 276 | ||
277 | if (port->open_count == (port->console? 1 : 0)) { | ||
272 | if (port->tty) { | 278 | if (port->tty) { |
273 | if (port->tty->driver_data) | 279 | if (port->tty->driver_data) |
274 | port->tty->driver_data = NULL; | 280 | port->tty->driver_data = NULL; |
275 | port->tty = NULL; | 281 | port->tty = NULL; |
276 | } | 282 | } |
283 | } | ||
277 | 284 | ||
285 | if (port->open_count == 0) { | ||
286 | usb_autopm_put_interface(port->serial->interface); | ||
278 | module_put(port->serial->type->driver.owner); | 287 | module_put(port->serial->type->driver.owner); |
279 | } | 288 | } |
280 | 289 | ||
@@ -625,6 +634,7 @@ static struct usb_serial * create_serial (struct usb_device *dev, | |||
625 | serial->type = driver; | 634 | serial->type = driver; |
626 | serial->interface = interface; | 635 | serial->interface = interface; |
627 | kref_init(&serial->kref); | 636 | kref_init(&serial->kref); |
637 | mutex_init(&serial->disc_mutex); | ||
628 | 638 | ||
629 | return serial; | 639 | return serial; |
630 | } | 640 | } |
@@ -1080,20 +1090,22 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1080 | usb_serial_console_disconnect(serial); | 1090 | usb_serial_console_disconnect(serial); |
1081 | dbg ("%s", __FUNCTION__); | 1091 | dbg ("%s", __FUNCTION__); |
1082 | 1092 | ||
1093 | mutex_lock(&serial->disc_mutex); | ||
1083 | usb_set_intfdata (interface, NULL); | 1094 | usb_set_intfdata (interface, NULL); |
1084 | if (serial) { | 1095 | /* must set a flag, to signal subdrivers */ |
1085 | for (i = 0; i < serial->num_ports; ++i) { | 1096 | serial->disconnected = 1; |
1086 | port = serial->port[i]; | 1097 | for (i = 0; i < serial->num_ports; ++i) { |
1087 | if (port) { | 1098 | port = serial->port[i]; |
1088 | if (port->tty) | 1099 | if (port) { |
1089 | tty_hangup(port->tty); | 1100 | if (port->tty) |
1090 | kill_traffic(port); | 1101 | tty_hangup(port->tty); |
1091 | } | 1102 | kill_traffic(port); |
1092 | } | 1103 | } |
1093 | /* let the last holder of this object | ||
1094 | * cause it to be cleaned up */ | ||
1095 | usb_serial_put(serial); | ||
1096 | } | 1104 | } |
1105 | /* let the last holder of this object | ||
1106 | * cause it to be cleaned up */ | ||
1107 | mutex_unlock(&serial->disc_mutex); | ||
1108 | usb_serial_put(serial); | ||
1097 | dev_info(dev, "device disconnected\n"); | 1109 | dev_info(dev, "device disconnected\n"); |
1098 | } | 1110 | } |
1099 | 1111 | ||
@@ -1103,9 +1115,6 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) | |||
1103 | struct usb_serial_port *port; | 1115 | struct usb_serial_port *port; |
1104 | int i, r = 0; | 1116 | int i, r = 0; |
1105 | 1117 | ||
1106 | if (!serial) /* device has been disconnected */ | ||
1107 | return 0; | ||
1108 | |||
1109 | for (i = 0; i < serial->num_ports; ++i) { | 1118 | for (i = 0; i < serial->num_ports; ++i) { |
1110 | port = serial->port[i]; | 1119 | port = serial->port[i]; |
1111 | if (port) | 1120 | if (port) |
@@ -1253,6 +1262,7 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1253 | set_to_generic_if_null(device, read_bulk_callback); | 1262 | set_to_generic_if_null(device, read_bulk_callback); |
1254 | set_to_generic_if_null(device, write_bulk_callback); | 1263 | set_to_generic_if_null(device, write_bulk_callback); |
1255 | set_to_generic_if_null(device, shutdown); | 1264 | set_to_generic_if_null(device, shutdown); |
1265 | set_to_generic_if_null(device, resume); | ||
1256 | } | 1266 | } |
1257 | 1267 | ||
1258 | int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */ | 1268 | int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */ |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 7ee087fed913..22b3f78a388c 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -349,16 +349,20 @@ static void visor_close (struct usb_serial_port *port, struct file * filp) | |||
349 | usb_kill_urb(port->read_urb); | 349 | usb_kill_urb(port->read_urb); |
350 | usb_kill_urb(port->interrupt_in_urb); | 350 | usb_kill_urb(port->interrupt_in_urb); |
351 | 351 | ||
352 | /* Try to send shutdown message, if the device is gone, this will just fail. */ | 352 | mutex_lock(&port->serial->disc_mutex); |
353 | transfer_buffer = kmalloc (0x12, GFP_KERNEL); | 353 | if (!port->serial->disconnected) { |
354 | if (transfer_buffer) { | 354 | /* Try to send shutdown message, unless the device is gone */ |
355 | usb_control_msg (port->serial->dev, | 355 | transfer_buffer = kmalloc (0x12, GFP_KERNEL); |
356 | usb_rcvctrlpipe(port->serial->dev, 0), | 356 | if (transfer_buffer) { |
357 | VISOR_CLOSE_NOTIFICATION, 0xc2, | 357 | usb_control_msg (port->serial->dev, |
358 | 0x0000, 0x0000, | 358 | usb_rcvctrlpipe(port->serial->dev, 0), |
359 | transfer_buffer, 0x12, 300); | 359 | VISOR_CLOSE_NOTIFICATION, 0xc2, |
360 | kfree (transfer_buffer); | 360 | 0x0000, 0x0000, |
361 | transfer_buffer, 0x12, 300); | ||
362 | kfree (transfer_buffer); | ||
363 | } | ||
361 | } | 364 | } |
365 | mutex_unlock(&port->serial->disc_mutex); | ||
362 | 366 | ||
363 | if (stats) | 367 | if (stats) |
364 | dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n", | 368 | dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n", |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index ee5dd8b5a713..38726ef3132b 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -610,8 +610,7 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) | |||
610 | if (retval) | 610 | if (retval) |
611 | goto exit; | 611 | goto exit; |
612 | 612 | ||
613 | if (port->tty) | 613 | port->tty->low_latency = 1; |
614 | port->tty->low_latency = 1; | ||
615 | 614 | ||
616 | /* send an open port command */ | 615 | /* send an open port command */ |
617 | retval = firm_open(port); | 616 | retval = firm_open(port); |
@@ -659,11 +658,14 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp) | |||
659 | struct list_head *tmp2; | 658 | struct list_head *tmp2; |
660 | 659 | ||
661 | dbg("%s - port %d", __FUNCTION__, port->number); | 660 | dbg("%s - port %d", __FUNCTION__, port->number); |
662 | 661 | ||
662 | mutex_lock(&port->serial->disc_mutex); | ||
663 | /* filp is NULL when called from usb_serial_disconnect */ | 663 | /* filp is NULL when called from usb_serial_disconnect */ |
664 | if (filp && (tty_hung_up_p(filp))) { | 664 | if ((filp && (tty_hung_up_p(filp))) || port->serial->disconnected) { |
665 | mutex_unlock(&port->serial->disc_mutex); | ||
665 | return; | 666 | return; |
666 | } | 667 | } |
668 | mutex_unlock(&port->serial->disc_mutex); | ||
667 | 669 | ||
668 | port->tty->closing = 1; | 670 | port->tty->closing = 1; |
669 | 671 | ||
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index ee5b42aa5363..187dd1e01093 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c | |||
@@ -66,7 +66,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) | |||
66 | { | 66 | { |
67 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap*) us->iobuf; | 67 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap*) us->iobuf; |
68 | struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap*) us->iobuf; | 68 | struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap*) us->iobuf; |
69 | int res, partial; | 69 | int res; |
70 | unsigned int partial; | ||
70 | static char init_string[] = "\xec\x0a\x06\x00$PCCHIPS"; | 71 | static char init_string[] = "\xec\x0a\x06\x00$PCCHIPS"; |
71 | 72 | ||
72 | US_DEBUGP("Sending UCR-61S2B initialization packet...\n"); | 73 | US_DEBUGP("Sending UCR-61S2B initialization packet...\n"); |
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 0db488624ab1..2ae1e8673b19 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/errno.h> | 48 | #include <linux/errno.h> |
49 | #include <linux/slab.h> | 49 | #include <linux/slab.h> |
50 | #include <linux/hdreg.h> | 50 | #include <linux/hdreg.h> |
51 | #include <linux/ide.h> | ||
52 | #include <linux/scatterlist.h> | 51 | #include <linux/scatterlist.h> |
53 | 52 | ||
54 | #include <scsi/scsi.h> | 53 | #include <scsi/scsi.h> |
@@ -110,6 +109,12 @@ | |||
110 | #define REG_STATUS 0x80 | 109 | #define REG_STATUS 0x80 |
111 | #define REG_COMMAND 0x80 | 110 | #define REG_COMMAND 0x80 |
112 | 111 | ||
112 | /* ATA registers offset definitions */ | ||
113 | #define ATA_REG_ERROR_OFFSET 1 | ||
114 | #define ATA_REG_LCYL_OFFSET 4 | ||
115 | #define ATA_REG_HCYL_OFFSET 5 | ||
116 | #define ATA_REG_STATUS_OFFSET 7 | ||
117 | |||
113 | /* ATA error definitions not in <linux/hdreg.h> */ | 118 | /* ATA error definitions not in <linux/hdreg.h> */ |
114 | #define ATA_ERROR_MEDIA_CHANGE 0x20 | 119 | #define ATA_ERROR_MEDIA_CHANGE 0x20 |
115 | 120 | ||
@@ -360,7 +365,7 @@ static void isd200_build_sense(struct us_data *us, struct scsi_cmnd *srb) | |||
360 | { | 365 | { |
361 | struct isd200_info *info = (struct isd200_info *)us->extra; | 366 | struct isd200_info *info = (struct isd200_info *)us->extra; |
362 | struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0]; | 367 | struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0]; |
363 | unsigned char error = info->ATARegs[IDE_ERROR_OFFSET]; | 368 | unsigned char error = info->ATARegs[ATA_REG_ERROR_OFFSET]; |
364 | 369 | ||
365 | if(error & ATA_ERROR_MEDIA_CHANGE) { | 370 | if(error & ATA_ERROR_MEDIA_CHANGE) { |
366 | buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; | 371 | buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; |
@@ -549,8 +554,8 @@ static int isd200_read_regs( struct us_data *us ) | |||
549 | retStatus = ISD200_ERROR; | 554 | retStatus = ISD200_ERROR; |
550 | } else { | 555 | } else { |
551 | memcpy(info->ATARegs, info->RegsBuf, sizeof(info->ATARegs)); | 556 | memcpy(info->ATARegs, info->RegsBuf, sizeof(info->ATARegs)); |
552 | US_DEBUGP(" Got ATA Register[IDE_ERROR_OFFSET] = 0x%x\n", | 557 | US_DEBUGP(" Got ATA Register[ATA_REG_ERROR_OFFSET] = 0x%x\n", |
553 | info->ATARegs[IDE_ERROR_OFFSET]); | 558 | info->ATARegs[ATA_REG_ERROR_OFFSET]); |
554 | } | 559 | } |
555 | 560 | ||
556 | return retStatus; | 561 | return retStatus; |
@@ -892,7 +897,7 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, | |||
892 | break; | 897 | break; |
893 | 898 | ||
894 | if (!detect) { | 899 | if (!detect) { |
895 | if (regs[IDE_STATUS_OFFSET] & BUSY_STAT ) { | 900 | if (regs[ATA_REG_STATUS_OFFSET] & BUSY_STAT) { |
896 | US_DEBUGP(" %s status is still BSY, try again...\n",mstr); | 901 | US_DEBUGP(" %s status is still BSY, try again...\n",mstr); |
897 | } else { | 902 | } else { |
898 | US_DEBUGP(" %s status !BSY, continue with next operation\n",mstr); | 903 | US_DEBUGP(" %s status !BSY, continue with next operation\n",mstr); |
@@ -902,12 +907,12 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, | |||
902 | /* check for BUSY_STAT and */ | 907 | /* check for BUSY_STAT and */ |
903 | /* WRERR_STAT (workaround ATA Zip drive) and */ | 908 | /* WRERR_STAT (workaround ATA Zip drive) and */ |
904 | /* ERR_STAT (workaround for Archos CD-ROM) */ | 909 | /* ERR_STAT (workaround for Archos CD-ROM) */ |
905 | else if (regs[IDE_STATUS_OFFSET] & | 910 | else if (regs[ATA_REG_STATUS_OFFSET] & |
906 | (BUSY_STAT | WRERR_STAT | ERR_STAT )) { | 911 | (BUSY_STAT | WRERR_STAT | ERR_STAT )) { |
907 | US_DEBUGP(" Status indicates it is not ready, try again...\n"); | 912 | US_DEBUGP(" Status indicates it is not ready, try again...\n"); |
908 | } | 913 | } |
909 | /* check for DRDY, ATA devices set DRDY after SRST */ | 914 | /* check for DRDY, ATA devices set DRDY after SRST */ |
910 | else if (regs[IDE_STATUS_OFFSET] & READY_STAT) { | 915 | else if (regs[ATA_REG_STATUS_OFFSET] & READY_STAT) { |
911 | US_DEBUGP(" Identified ATA device\n"); | 916 | US_DEBUGP(" Identified ATA device\n"); |
912 | info->DeviceFlags |= DF_ATA_DEVICE; | 917 | info->DeviceFlags |= DF_ATA_DEVICE; |
913 | info->DeviceHead = master_slave; | 918 | info->DeviceHead = master_slave; |
@@ -916,8 +921,8 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, | |||
916 | /* check Cylinder High/Low to | 921 | /* check Cylinder High/Low to |
917 | determine if it is an ATAPI device | 922 | determine if it is an ATAPI device |
918 | */ | 923 | */ |
919 | else if ((regs[IDE_HCYL_OFFSET] == 0xEB) && | 924 | else if (regs[ATA_REG_HCYL_OFFSET] == 0xEB && |
920 | (regs[IDE_LCYL_OFFSET] == 0x14)) { | 925 | regs[ATA_REG_LCYL_OFFSET] == 0x14) { |
921 | /* It seems that the RICOH | 926 | /* It seems that the RICOH |
922 | MP6200A CD/RW drive will | 927 | MP6200A CD/RW drive will |
923 | report itself okay as a | 928 | report itself okay as a |
@@ -1001,12 +1006,6 @@ static int isd200_manual_enum(struct us_data *us) | |||
1001 | return(retStatus); | 1006 | return(retStatus); |
1002 | } | 1007 | } |
1003 | 1008 | ||
1004 | /* | ||
1005 | * We are the last non IDE user of the legacy IDE ident structures | ||
1006 | * and we thus want to keep a private copy of this function so the | ||
1007 | * driver can be used without the obsolete drivers/ide layer | ||
1008 | */ | ||
1009 | |||
1010 | static void isd200_fix_driveid (struct hd_driveid *id) | 1009 | static void isd200_fix_driveid (struct hd_driveid *id) |
1011 | { | 1010 | { |
1012 | #ifndef __LITTLE_ENDIAN | 1011 | #ifndef __LITTLE_ENDIAN |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6d6108b3993b..fe12737e0e2b 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -86,6 +86,14 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | |||
86 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | 86 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | /* Reported by Grant Grundler <grundler@parisc-linux.org> | ||
90 | * HP r707 camera in "Disk" mode with 2.00.23 or 2.00.24 firmware. | ||
91 | */ | ||
92 | UNUSUAL_DEV( 0x03f0, 0x4002, 0x0001, 0x0001, | ||
93 | "HP", | ||
94 | "PhotoSmart R707", | ||
95 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), | ||
96 | |||
89 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> | 97 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> |
90 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) | 98 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) |
91 | * for USB floppies that need the SINGLE_LUN enforcement. | 99 | * for USB floppies that need the SINGLE_LUN enforcement. |
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h index d53bf6945f0c..9b05da6268f7 100644 --- a/drivers/video/sis/sis.h +++ b/drivers/video/sis/sis.h | |||
@@ -39,12 +39,7 @@ | |||
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | 40 | ||
41 | #ifdef CONFIG_COMPAT | 41 | #ifdef CONFIG_COMPAT |
42 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) | ||
43 | #include <linux/ioctl32.h> | ||
44 | #define SIS_OLD_CONFIG_COMPAT | ||
45 | #else | ||
46 | #define SIS_NEW_CONFIG_COMPAT | 42 | #define SIS_NEW_CONFIG_COMPAT |
47 | #endif | ||
48 | #endif /* CONFIG_COMPAT */ | 43 | #endif /* CONFIG_COMPAT */ |
49 | 44 | ||
50 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) | 45 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) |
@@ -607,9 +602,6 @@ struct sis_video_info { | |||
607 | int haveXGIROM; | 602 | int haveXGIROM; |
608 | int registered; | 603 | int registered; |
609 | int warncount; | 604 | int warncount; |
610 | #ifdef SIS_OLD_CONFIG_COMPAT | ||
611 | int ioctl32registered; | ||
612 | #endif | ||
613 | 605 | ||
614 | int sisvga_engine; | 606 | int sisvga_engine; |
615 | int hwcursor_size; | 607 | int hwcursor_size; |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 37bd24b8d83b..93ae747440cb 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -5805,9 +5805,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5805 | ivideo->pcifunc = PCI_FUNC(pdev->devfn); | 5805 | ivideo->pcifunc = PCI_FUNC(pdev->devfn); |
5806 | ivideo->subsysvendor = pdev->subsystem_vendor; | 5806 | ivideo->subsysvendor = pdev->subsystem_vendor; |
5807 | ivideo->subsysdevice = pdev->subsystem_device; | 5807 | ivideo->subsysdevice = pdev->subsystem_device; |
5808 | #ifdef SIS_OLD_CONFIG_COMPAT | ||
5809 | ivideo->ioctl32registered = 0; | ||
5810 | #endif | ||
5811 | 5808 | ||
5812 | #ifndef MODULE | 5809 | #ifndef MODULE |
5813 | if(sisfb_mode_idx == -1) { | 5810 | if(sisfb_mode_idx == -1) { |
@@ -6420,30 +6417,6 @@ error_3: vfree(ivideo->bios_abase); | |||
6420 | ivideo->next = card_list; | 6417 | ivideo->next = card_list; |
6421 | card_list = ivideo; | 6418 | card_list = ivideo; |
6422 | 6419 | ||
6423 | #ifdef SIS_OLD_CONFIG_COMPAT | ||
6424 | { | ||
6425 | int ret; | ||
6426 | /* Our ioctls are all "32/64bit compatible" */ | ||
6427 | ret = register_ioctl32_conversion(FBIO_ALLOC, NULL); | ||
6428 | ret |= register_ioctl32_conversion(FBIO_FREE, NULL); | ||
6429 | ret |= register_ioctl32_conversion(FBIOGET_VBLANK, NULL); | ||
6430 | ret |= register_ioctl32_conversion(SISFB_GET_INFO_SIZE, NULL); | ||
6431 | ret |= register_ioctl32_conversion(SISFB_GET_INFO, NULL); | ||
6432 | ret |= register_ioctl32_conversion(SISFB_GET_TVPOSOFFSET, NULL); | ||
6433 | ret |= register_ioctl32_conversion(SISFB_SET_TVPOSOFFSET, NULL); | ||
6434 | ret |= register_ioctl32_conversion(SISFB_SET_LOCK, NULL); | ||
6435 | ret |= register_ioctl32_conversion(SISFB_GET_VBRSTATUS, NULL); | ||
6436 | ret |= register_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE, NULL); | ||
6437 | ret |= register_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE, NULL); | ||
6438 | ret |= register_ioctl32_conversion(SISFB_COMMAND, NULL); | ||
6439 | if(ret) | ||
6440 | printk(KERN_ERR | ||
6441 | "sisfb: Error registering ioctl32 translations\n"); | ||
6442 | else | ||
6443 | ivideo->ioctl32registered = 1; | ||
6444 | } | ||
6445 | #endif | ||
6446 | |||
6447 | printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n", | 6420 | printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n", |
6448 | ivideo->sisfb_accel ? "enabled" : "disabled", | 6421 | ivideo->sisfb_accel ? "enabled" : "disabled", |
6449 | ivideo->sisfb_ypan ? | 6422 | ivideo->sisfb_ypan ? |
@@ -6473,27 +6446,6 @@ static void __devexit sisfb_remove(struct pci_dev *pdev) | |||
6473 | int registered = ivideo->registered; | 6446 | int registered = ivideo->registered; |
6474 | int modechanged = ivideo->modechanged; | 6447 | int modechanged = ivideo->modechanged; |
6475 | 6448 | ||
6476 | #ifdef SIS_OLD_CONFIG_COMPAT | ||
6477 | if(ivideo->ioctl32registered) { | ||
6478 | int ret; | ||
6479 | ret = unregister_ioctl32_conversion(FBIO_ALLOC); | ||
6480 | ret |= unregister_ioctl32_conversion(FBIO_FREE); | ||
6481 | ret |= unregister_ioctl32_conversion(FBIOGET_VBLANK); | ||
6482 | ret |= unregister_ioctl32_conversion(SISFB_GET_INFO_SIZE); | ||
6483 | ret |= unregister_ioctl32_conversion(SISFB_GET_INFO); | ||
6484 | ret |= unregister_ioctl32_conversion(SISFB_GET_TVPOSOFFSET); | ||
6485 | ret |= unregister_ioctl32_conversion(SISFB_SET_TVPOSOFFSET); | ||
6486 | ret |= unregister_ioctl32_conversion(SISFB_SET_LOCK); | ||
6487 | ret |= unregister_ioctl32_conversion(SISFB_GET_VBRSTATUS); | ||
6488 | ret |= unregister_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE); | ||
6489 | ret |= unregister_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE); | ||
6490 | ret |= unregister_ioctl32_conversion(SISFB_COMMAND); | ||
6491 | if(ret) | ||
6492 | printk(KERN_ERR | ||
6493 | "sisfb: Error unregistering ioctl32 translations\n"); | ||
6494 | } | ||
6495 | #endif | ||
6496 | |||
6497 | /* Unmap */ | 6449 | /* Unmap */ |
6498 | iounmap(ivideo->mmio_vbase); | 6450 | iounmap(ivideo->mmio_vbase); |
6499 | iounmap(ivideo->video_vbase); | 6451 | iounmap(ivideo->video_vbase); |
diff --git a/fs/Kconfig b/fs/Kconfig index 219ec06a8c7e..987b5d7cb21a 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -1674,6 +1674,8 @@ config NFSD | |||
1674 | select CRYPTO_MD5 if NFSD_V4 | 1674 | select CRYPTO_MD5 if NFSD_V4 |
1675 | select CRYPTO if NFSD_V4 | 1675 | select CRYPTO if NFSD_V4 |
1676 | select FS_POSIX_ACL if NFSD_V4 | 1676 | select FS_POSIX_ACL if NFSD_V4 |
1677 | select PROC_FS if NFSD_V4 | ||
1678 | select PROC_FS if SUNRPC_GSS | ||
1677 | help | 1679 | help |
1678 | If you want your Linux box to act as an NFS *server*, so that other | 1680 | If you want your Linux box to act as an NFS *server*, so that other |
1679 | computers on your local network which support NFS can access certain | 1681 | computers on your local network which support NFS can access certain |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 572601e98dcd..ca6b16fc3101 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -34,10 +34,10 @@ static DEFINE_MUTEX(nlm_host_mutex); | |||
34 | 34 | ||
35 | static void nlm_gc_hosts(void); | 35 | static void nlm_gc_hosts(void); |
36 | static struct nsm_handle * __nsm_find(const struct sockaddr_in *, | 36 | static struct nsm_handle * __nsm_find(const struct sockaddr_in *, |
37 | const char *, int, int); | 37 | const char *, unsigned int, int); |
38 | static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, | 38 | static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, |
39 | const char *hostname, | 39 | const char *hostname, |
40 | int hostname_len); | 40 | unsigned int hostname_len); |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Common host lookup routine for server & client | 43 | * Common host lookup routine for server & client |
@@ -45,7 +45,8 @@ static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, | |||
45 | static struct nlm_host * | 45 | static struct nlm_host * |
46 | nlm_lookup_host(int server, const struct sockaddr_in *sin, | 46 | nlm_lookup_host(int server, const struct sockaddr_in *sin, |
47 | int proto, int version, const char *hostname, | 47 | int proto, int version, const char *hostname, |
48 | int hostname_len, const struct sockaddr_in *ssin) | 48 | unsigned int hostname_len, |
49 | const struct sockaddr_in *ssin) | ||
49 | { | 50 | { |
50 | struct hlist_head *chain; | 51 | struct hlist_head *chain; |
51 | struct hlist_node *pos; | 52 | struct hlist_node *pos; |
@@ -176,7 +177,7 @@ nlm_destroy_host(struct nlm_host *host) | |||
176 | */ | 177 | */ |
177 | struct nlm_host * | 178 | struct nlm_host * |
178 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | 179 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, |
179 | const char *hostname, int hostname_len) | 180 | const char *hostname, unsigned int hostname_len) |
180 | { | 181 | { |
181 | struct sockaddr_in ssin = {0}; | 182 | struct sockaddr_in ssin = {0}; |
182 | 183 | ||
@@ -189,7 +190,7 @@ nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | |||
189 | */ | 190 | */ |
190 | struct nlm_host * | 191 | struct nlm_host * |
191 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | 192 | nlmsvc_lookup_host(struct svc_rqst *rqstp, |
192 | const char *hostname, int hostname_len) | 193 | const char *hostname, unsigned int hostname_len) |
193 | { | 194 | { |
194 | struct sockaddr_in ssin = {0}; | 195 | struct sockaddr_in ssin = {0}; |
195 | 196 | ||
@@ -307,7 +308,8 @@ void nlm_release_host(struct nlm_host *host) | |||
307 | * Release all resources held by that peer. | 308 | * Release all resources held by that peer. |
308 | */ | 309 | */ |
309 | void nlm_host_rebooted(const struct sockaddr_in *sin, | 310 | void nlm_host_rebooted(const struct sockaddr_in *sin, |
310 | const char *hostname, int hostname_len, | 311 | const char *hostname, |
312 | unsigned int hostname_len, | ||
311 | u32 new_state) | 313 | u32 new_state) |
312 | { | 314 | { |
313 | struct hlist_head *chain; | 315 | struct hlist_head *chain; |
@@ -377,8 +379,13 @@ nlm_shutdown_hosts(void) | |||
377 | /* First, make all hosts eligible for gc */ | 379 | /* First, make all hosts eligible for gc */ |
378 | dprintk("lockd: nuking all hosts...\n"); | 380 | dprintk("lockd: nuking all hosts...\n"); |
379 | for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { | 381 | for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { |
380 | hlist_for_each_entry(host, pos, chain, h_hash) | 382 | hlist_for_each_entry(host, pos, chain, h_hash) { |
381 | host->h_expires = jiffies - 1; | 383 | host->h_expires = jiffies - 1; |
384 | if (host->h_rpcclnt) { | ||
385 | rpc_shutdown_client(host->h_rpcclnt); | ||
386 | host->h_rpcclnt = NULL; | ||
387 | } | ||
388 | } | ||
382 | } | 389 | } |
383 | 390 | ||
384 | /* Then, perform a garbage collection pass */ | 391 | /* Then, perform a garbage collection pass */ |
@@ -449,7 +456,7 @@ static DEFINE_MUTEX(nsm_mutex); | |||
449 | 456 | ||
450 | static struct nsm_handle * | 457 | static struct nsm_handle * |
451 | __nsm_find(const struct sockaddr_in *sin, | 458 | __nsm_find(const struct sockaddr_in *sin, |
452 | const char *hostname, int hostname_len, | 459 | const char *hostname, unsigned int hostname_len, |
453 | int create) | 460 | int create) |
454 | { | 461 | { |
455 | struct nsm_handle *nsm = NULL; | 462 | struct nsm_handle *nsm = NULL; |
@@ -503,7 +510,8 @@ out: | |||
503 | } | 510 | } |
504 | 511 | ||
505 | static struct nsm_handle * | 512 | static struct nsm_handle * |
506 | nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len) | 513 | nsm_find(const struct sockaddr_in *sin, const char *hostname, |
514 | unsigned int hostname_len) | ||
507 | { | 515 | { |
508 | return __nsm_find(sin, hostname, hostname_len, 1); | 516 | return __nsm_find(sin, hostname, hostname_len, 1); |
509 | } | 517 | } |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 82e2192a0d5c..08226464e563 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -219,19 +219,6 @@ lockd(struct svc_rqst *rqstp) | |||
219 | module_put_and_exit(0); | 219 | module_put_and_exit(0); |
220 | } | 220 | } |
221 | 221 | ||
222 | |||
223 | static int find_socket(struct svc_serv *serv, int proto) | ||
224 | { | ||
225 | struct svc_sock *svsk; | ||
226 | int found = 0; | ||
227 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) | ||
228 | if (svsk->sk_sk->sk_protocol == proto) { | ||
229 | found = 1; | ||
230 | break; | ||
231 | } | ||
232 | return found; | ||
233 | } | ||
234 | |||
235 | /* | 222 | /* |
236 | * Make any sockets that are needed but not present. | 223 | * Make any sockets that are needed but not present. |
237 | * If nlm_udpport or nlm_tcpport were set as module | 224 | * If nlm_udpport or nlm_tcpport were set as module |
@@ -240,17 +227,25 @@ static int find_socket(struct svc_serv *serv, int proto) | |||
240 | static int make_socks(struct svc_serv *serv, int proto) | 227 | static int make_socks(struct svc_serv *serv, int proto) |
241 | { | 228 | { |
242 | static int warned; | 229 | static int warned; |
230 | struct svc_xprt *xprt; | ||
243 | int err = 0; | 231 | int err = 0; |
244 | 232 | ||
245 | if (proto == IPPROTO_UDP || nlm_udpport) | 233 | if (proto == IPPROTO_UDP || nlm_udpport) { |
246 | if (!find_socket(serv, IPPROTO_UDP)) | 234 | xprt = svc_find_xprt(serv, "udp", 0, 0); |
247 | err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport, | 235 | if (!xprt) |
248 | SVC_SOCK_DEFAULTS); | 236 | err = svc_create_xprt(serv, "udp", nlm_udpport, |
249 | if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport)) | 237 | SVC_SOCK_DEFAULTS); |
250 | if (!find_socket(serv, IPPROTO_TCP)) | 238 | else |
251 | err = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport, | 239 | svc_xprt_put(xprt); |
252 | SVC_SOCK_DEFAULTS); | 240 | } |
253 | 241 | if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport)) { | |
242 | xprt = svc_find_xprt(serv, "tcp", 0, 0); | ||
243 | if (!xprt) | ||
244 | err = svc_create_xprt(serv, "tcp", nlm_tcpport, | ||
245 | SVC_SOCK_DEFAULTS); | ||
246 | else | ||
247 | svc_xprt_put(xprt); | ||
248 | } | ||
254 | if (err >= 0) { | 249 | if (err >= 0) { |
255 | warned = 0; | 250 | warned = 0; |
256 | err = 0; | 251 | err = 0; |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index bf27b6c6cb6b..385437e3387d 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -84,6 +84,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
84 | { | 84 | { |
85 | struct nlm_host *host; | 85 | struct nlm_host *host; |
86 | struct nlm_file *file; | 86 | struct nlm_file *file; |
87 | int rc = rpc_success; | ||
87 | 88 | ||
88 | dprintk("lockd: TEST4 called\n"); | 89 | dprintk("lockd: TEST4 called\n"); |
89 | resp->cookie = argp->cookie; | 90 | resp->cookie = argp->cookie; |
@@ -91,7 +92,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
91 | /* Don't accept test requests during grace period */ | 92 | /* Don't accept test requests during grace period */ |
92 | if (nlmsvc_grace_period) { | 93 | if (nlmsvc_grace_period) { |
93 | resp->status = nlm_lck_denied_grace_period; | 94 | resp->status = nlm_lck_denied_grace_period; |
94 | return rpc_success; | 95 | return rc; |
95 | } | 96 | } |
96 | 97 | ||
97 | /* Obtain client and file */ | 98 | /* Obtain client and file */ |
@@ -101,12 +102,13 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
101 | /* Now check for conflicting locks */ | 102 | /* Now check for conflicting locks */ |
102 | resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie); | 103 | resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie); |
103 | if (resp->status == nlm_drop_reply) | 104 | if (resp->status == nlm_drop_reply) |
104 | return rpc_drop_reply; | 105 | rc = rpc_drop_reply; |
106 | else | ||
107 | dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); | ||
105 | 108 | ||
106 | dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); | ||
107 | nlm_release_host(host); | 109 | nlm_release_host(host); |
108 | nlm_release_file(file); | 110 | nlm_release_file(file); |
109 | return rpc_success; | 111 | return rc; |
110 | } | 112 | } |
111 | 113 | ||
112 | static __be32 | 114 | static __be32 |
@@ -115,6 +117,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
115 | { | 117 | { |
116 | struct nlm_host *host; | 118 | struct nlm_host *host; |
117 | struct nlm_file *file; | 119 | struct nlm_file *file; |
120 | int rc = rpc_success; | ||
118 | 121 | ||
119 | dprintk("lockd: LOCK called\n"); | 122 | dprintk("lockd: LOCK called\n"); |
120 | 123 | ||
@@ -123,7 +126,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
123 | /* Don't accept new lock requests during grace period */ | 126 | /* Don't accept new lock requests during grace period */ |
124 | if (nlmsvc_grace_period && !argp->reclaim) { | 127 | if (nlmsvc_grace_period && !argp->reclaim) { |
125 | resp->status = nlm_lck_denied_grace_period; | 128 | resp->status = nlm_lck_denied_grace_period; |
126 | return rpc_success; | 129 | return rc; |
127 | } | 130 | } |
128 | 131 | ||
129 | /* Obtain client and file */ | 132 | /* Obtain client and file */ |
@@ -146,12 +149,13 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
146 | resp->status = nlmsvc_lock(rqstp, file, &argp->lock, | 149 | resp->status = nlmsvc_lock(rqstp, file, &argp->lock, |
147 | argp->block, &argp->cookie); | 150 | argp->block, &argp->cookie); |
148 | if (resp->status == nlm_drop_reply) | 151 | if (resp->status == nlm_drop_reply) |
149 | return rpc_drop_reply; | 152 | rc = rpc_drop_reply; |
153 | else | ||
154 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | ||
150 | 155 | ||
151 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | ||
152 | nlm_release_host(host); | 156 | nlm_release_host(host); |
153 | nlm_release_file(file); | 157 | nlm_release_file(file); |
154 | return rpc_success; | 158 | return rc; |
155 | } | 159 | } |
156 | 160 | ||
157 | static __be32 | 161 | static __be32 |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index d120ec39bcb0..2f4d8fa66689 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -501,25 +501,29 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
501 | block, block->b_flags, block->b_fl); | 501 | block, block->b_flags, block->b_fl); |
502 | if (block->b_flags & B_TIMED_OUT) { | 502 | if (block->b_flags & B_TIMED_OUT) { |
503 | nlmsvc_unlink_block(block); | 503 | nlmsvc_unlink_block(block); |
504 | return nlm_lck_denied; | 504 | ret = nlm_lck_denied; |
505 | goto out; | ||
505 | } | 506 | } |
506 | if (block->b_flags & B_GOT_CALLBACK) { | 507 | if (block->b_flags & B_GOT_CALLBACK) { |
508 | nlmsvc_unlink_block(block); | ||
507 | if (block->b_fl != NULL | 509 | if (block->b_fl != NULL |
508 | && block->b_fl->fl_type != F_UNLCK) { | 510 | && block->b_fl->fl_type != F_UNLCK) { |
509 | lock->fl = *block->b_fl; | 511 | lock->fl = *block->b_fl; |
510 | goto conf_lock; | 512 | goto conf_lock; |
511 | } | 513 | } else { |
512 | else { | 514 | ret = nlm_granted; |
513 | nlmsvc_unlink_block(block); | 515 | goto out; |
514 | return nlm_granted; | ||
515 | } | 516 | } |
516 | } | 517 | } |
517 | return nlm_drop_reply; | 518 | ret = nlm_drop_reply; |
519 | goto out; | ||
518 | } | 520 | } |
519 | 521 | ||
520 | error = vfs_test_lock(file->f_file, &lock->fl); | 522 | error = vfs_test_lock(file->f_file, &lock->fl); |
521 | if (error == -EINPROGRESS) | 523 | if (error == -EINPROGRESS) { |
522 | return nlmsvc_defer_lock_rqst(rqstp, block); | 524 | ret = nlmsvc_defer_lock_rqst(rqstp, block); |
525 | goto out; | ||
526 | } | ||
523 | if (error) { | 527 | if (error) { |
524 | ret = nlm_lck_denied_nolocks; | 528 | ret = nlm_lck_denied_nolocks; |
525 | goto out; | 529 | goto out; |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 9cd5c8b37593..88379cc6e0b1 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -113,6 +113,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
113 | { | 113 | { |
114 | struct nlm_host *host; | 114 | struct nlm_host *host; |
115 | struct nlm_file *file; | 115 | struct nlm_file *file; |
116 | int rc = rpc_success; | ||
116 | 117 | ||
117 | dprintk("lockd: TEST called\n"); | 118 | dprintk("lockd: TEST called\n"); |
118 | resp->cookie = argp->cookie; | 119 | resp->cookie = argp->cookie; |
@@ -120,7 +121,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
120 | /* Don't accept test requests during grace period */ | 121 | /* Don't accept test requests during grace period */ |
121 | if (nlmsvc_grace_period) { | 122 | if (nlmsvc_grace_period) { |
122 | resp->status = nlm_lck_denied_grace_period; | 123 | resp->status = nlm_lck_denied_grace_period; |
123 | return rpc_success; | 124 | return rc; |
124 | } | 125 | } |
125 | 126 | ||
126 | /* Obtain client and file */ | 127 | /* Obtain client and file */ |
@@ -130,13 +131,14 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
130 | /* Now check for conflicting locks */ | 131 | /* Now check for conflicting locks */ |
131 | resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie)); | 132 | resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie)); |
132 | if (resp->status == nlm_drop_reply) | 133 | if (resp->status == nlm_drop_reply) |
133 | return rpc_drop_reply; | 134 | rc = rpc_drop_reply; |
135 | else | ||
136 | dprintk("lockd: TEST status %d vers %d\n", | ||
137 | ntohl(resp->status), rqstp->rq_vers); | ||
134 | 138 | ||
135 | dprintk("lockd: TEST status %d vers %d\n", | ||
136 | ntohl(resp->status), rqstp->rq_vers); | ||
137 | nlm_release_host(host); | 139 | nlm_release_host(host); |
138 | nlm_release_file(file); | 140 | nlm_release_file(file); |
139 | return rpc_success; | 141 | return rc; |
140 | } | 142 | } |
141 | 143 | ||
142 | static __be32 | 144 | static __be32 |
@@ -145,6 +147,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
145 | { | 147 | { |
146 | struct nlm_host *host; | 148 | struct nlm_host *host; |
147 | struct nlm_file *file; | 149 | struct nlm_file *file; |
150 | int rc = rpc_success; | ||
148 | 151 | ||
149 | dprintk("lockd: LOCK called\n"); | 152 | dprintk("lockd: LOCK called\n"); |
150 | 153 | ||
@@ -153,7 +156,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
153 | /* Don't accept new lock requests during grace period */ | 156 | /* Don't accept new lock requests during grace period */ |
154 | if (nlmsvc_grace_period && !argp->reclaim) { | 157 | if (nlmsvc_grace_period && !argp->reclaim) { |
155 | resp->status = nlm_lck_denied_grace_period; | 158 | resp->status = nlm_lck_denied_grace_period; |
156 | return rpc_success; | 159 | return rc; |
157 | } | 160 | } |
158 | 161 | ||
159 | /* Obtain client and file */ | 162 | /* Obtain client and file */ |
@@ -176,12 +179,13 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
176 | resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock, | 179 | resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock, |
177 | argp->block, &argp->cookie)); | 180 | argp->block, &argp->cookie)); |
178 | if (resp->status == nlm_drop_reply) | 181 | if (resp->status == nlm_drop_reply) |
179 | return rpc_drop_reply; | 182 | rc = rpc_drop_reply; |
183 | else | ||
184 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | ||
180 | 185 | ||
181 | dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); | ||
182 | nlm_release_host(host); | 186 | nlm_release_host(host); |
183 | nlm_release_file(file); | 187 | nlm_release_file(file); |
184 | return rpc_success; | 188 | return rc; |
185 | } | 189 | } |
186 | 190 | ||
187 | static __be32 | 191 | static __be32 |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 84ebba33b98d..dbbefbcd6712 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -87,7 +87,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, | |||
87 | unsigned int hash; | 87 | unsigned int hash; |
88 | __be32 nfserr; | 88 | __be32 nfserr; |
89 | 89 | ||
90 | nlm_debug_print_fh("nlm_file_lookup", f); | 90 | nlm_debug_print_fh("nlm_lookup_file", f); |
91 | 91 | ||
92 | hash = file_hash(f); | 92 | hash = file_hash(f); |
93 | 93 | ||
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 9b6bbf1b9787..bd185a572a23 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -119,8 +119,8 @@ int nfs_callback_up(void) | |||
119 | if (!serv) | 119 | if (!serv) |
120 | goto out_err; | 120 | goto out_err; |
121 | 121 | ||
122 | ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport, | 122 | ret = svc_create_xprt(serv, "tcp", nfs_callback_set_tcpport, |
123 | SVC_SOCK_ANONYMOUS); | 123 | SVC_SOCK_ANONYMOUS); |
124 | if (ret <= 0) | 124 | if (ret <= 0) |
125 | goto out_destroy; | 125 | goto out_destroy; |
126 | nfs_callback_tcpport = ret; | 126 | nfs_callback_tcpport = ret; |
diff --git a/include/linux/nfsd/auth.h b/fs/nfsd/auth.h index 0fb9f7212195..78b3c0e93822 100644 --- a/include/linux/nfsd/auth.h +++ b/fs/nfsd/auth.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * include/linux/nfsd/auth.h | ||
3 | * | ||
4 | * nfsd-specific authentication stuff. | 2 | * nfsd-specific authentication stuff. |
5 | * uid/gid mapping not yet implemented. | 3 | * uid/gid mapping not yet implemented. |
6 | * | 4 | * |
@@ -10,8 +8,6 @@ | |||
10 | #ifndef LINUX_NFSD_AUTH_H | 8 | #ifndef LINUX_NFSD_AUTH_H |
11 | #define LINUX_NFSD_AUTH_H | 9 | #define LINUX_NFSD_AUTH_H |
12 | 10 | ||
13 | #ifdef __KERNEL__ | ||
14 | |||
15 | #define nfsd_luid(rq, uid) ((u32)(uid)) | 11 | #define nfsd_luid(rq, uid) ((u32)(uid)) |
16 | #define nfsd_lgid(rq, gid) ((u32)(gid)) | 12 | #define nfsd_lgid(rq, gid) ((u32)(gid)) |
17 | #define nfsd_ruid(rq, uid) ((u32)(uid)) | 13 | #define nfsd_ruid(rq, uid) ((u32)(uid)) |
@@ -23,5 +19,4 @@ | |||
23 | */ | 19 | */ |
24 | int nfsd_setuser(struct svc_rqst *, struct svc_export *); | 20 | int nfsd_setuser(struct svc_rqst *, struct svc_export *); |
25 | 21 | ||
26 | #endif /* __KERNEL__ */ | ||
27 | #endif /* LINUX_NFSD_AUTH_H */ | 22 | #endif /* LINUX_NFSD_AUTH_H */ |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 66d0aeb32a47..79b4bf812960 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -1357,8 +1357,6 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp) | |||
1357 | mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); | 1357 | mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); |
1358 | 1358 | ||
1359 | exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); | 1359 | exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); |
1360 | if (PTR_ERR(exp) == -ENOENT) | ||
1361 | return nfserr_perm; | ||
1362 | if (IS_ERR(exp)) | 1360 | if (IS_ERR(exp)) |
1363 | return nfserrno(PTR_ERR(exp)); | 1361 | return nfserrno(PTR_ERR(exp)); |
1364 | rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); | 1362 | rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); |
@@ -1637,13 +1635,19 @@ exp_verify_string(char *cp, int max) | |||
1637 | /* | 1635 | /* |
1638 | * Initialize the exports module. | 1636 | * Initialize the exports module. |
1639 | */ | 1637 | */ |
1640 | void | 1638 | int |
1641 | nfsd_export_init(void) | 1639 | nfsd_export_init(void) |
1642 | { | 1640 | { |
1641 | int rv; | ||
1643 | dprintk("nfsd: initializing export module.\n"); | 1642 | dprintk("nfsd: initializing export module.\n"); |
1644 | 1643 | ||
1645 | cache_register(&svc_export_cache); | 1644 | rv = cache_register(&svc_export_cache); |
1646 | cache_register(&svc_expkey_cache); | 1645 | if (rv) |
1646 | return rv; | ||
1647 | rv = cache_register(&svc_expkey_cache); | ||
1648 | if (rv) | ||
1649 | cache_unregister(&svc_export_cache); | ||
1650 | return rv; | ||
1647 | 1651 | ||
1648 | } | 1652 | } |
1649 | 1653 | ||
@@ -1670,10 +1674,8 @@ nfsd_export_shutdown(void) | |||
1670 | 1674 | ||
1671 | exp_writelock(); | 1675 | exp_writelock(); |
1672 | 1676 | ||
1673 | if (cache_unregister(&svc_expkey_cache)) | 1677 | cache_unregister(&svc_expkey_cache); |
1674 | printk(KERN_ERR "nfsd: failed to unregister expkey cache\n"); | 1678 | cache_unregister(&svc_export_cache); |
1675 | if (cache_unregister(&svc_export_cache)) | ||
1676 | printk(KERN_ERR "nfsd: failed to unregister export cache\n"); | ||
1677 | svcauth_unix_purge(); | 1679 | svcauth_unix_purge(); |
1678 | 1680 | ||
1679 | exp_writeunlock(); | 1681 | exp_writeunlock(); |
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 0e5fa11e6b44..1c3b7654e966 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c | |||
@@ -221,12 +221,17 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, | |||
221 | struct nfsd3_getaclres *resp) | 221 | struct nfsd3_getaclres *resp) |
222 | { | 222 | { |
223 | struct dentry *dentry = resp->fh.fh_dentry; | 223 | struct dentry *dentry = resp->fh.fh_dentry; |
224 | struct inode *inode = dentry->d_inode; | 224 | struct inode *inode; |
225 | struct kvec *head = rqstp->rq_res.head; | 225 | struct kvec *head = rqstp->rq_res.head; |
226 | unsigned int base; | 226 | unsigned int base; |
227 | int n; | 227 | int n; |
228 | int w; | 228 | int w; |
229 | 229 | ||
230 | /* | ||
231 | * Since this is version 2, the check for nfserr in | ||
232 | * nfsd_dispatch actually ensures the following cannot happen. | ||
233 | * However, it seems fragile to depend on that. | ||
234 | */ | ||
230 | if (dentry == NULL || dentry->d_inode == NULL) | 235 | if (dentry == NULL || dentry->d_inode == NULL) |
231 | return 0; | 236 | return 0; |
232 | inode = dentry->d_inode; | 237 | inode = dentry->d_inode; |
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index f917fd25858a..d7647f70e02b 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/sunrpc/svc.h> | 21 | #include <linux/sunrpc/svc.h> |
22 | #include <linux/nfsd/nfsd.h> | 22 | #include <linux/nfsd/nfsd.h> |
23 | #include <linux/nfsd/xdr3.h> | 23 | #include <linux/nfsd/xdr3.h> |
24 | #include "auth.h" | ||
24 | 25 | ||
25 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 26 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
26 | 27 | ||
@@ -88,10 +89,10 @@ encode_fh(__be32 *p, struct svc_fh *fhp) | |||
88 | * no slashes or null bytes. | 89 | * no slashes or null bytes. |
89 | */ | 90 | */ |
90 | static __be32 * | 91 | static __be32 * |
91 | decode_filename(__be32 *p, char **namp, int *lenp) | 92 | decode_filename(__be32 *p, char **namp, unsigned int *lenp) |
92 | { | 93 | { |
93 | char *name; | 94 | char *name; |
94 | int i; | 95 | unsigned int i; |
95 | 96 | ||
96 | if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) { | 97 | if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) { |
97 | for (i = 0, name = *namp; i < *lenp; i++, name++) { | 98 | for (i = 0, name = *namp; i < *lenp; i++, name++) { |
@@ -452,8 +453,7 @@ int | |||
452 | nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, | 453 | nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, |
453 | struct nfsd3_symlinkargs *args) | 454 | struct nfsd3_symlinkargs *args) |
454 | { | 455 | { |
455 | unsigned int len; | 456 | unsigned int len, avail; |
456 | int avail; | ||
457 | char *old, *new; | 457 | char *old, *new; |
458 | struct kvec *vec; | 458 | struct kvec *vec; |
459 | 459 | ||
@@ -486,7 +486,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, | |||
486 | /* now copy next page if there is one */ | 486 | /* now copy next page if there is one */ |
487 | if (len && !avail && rqstp->rq_arg.page_len) { | 487 | if (len && !avail && rqstp->rq_arg.page_len) { |
488 | avail = rqstp->rq_arg.page_len; | 488 | avail = rqstp->rq_arg.page_len; |
489 | if (avail > PAGE_SIZE) avail = PAGE_SIZE; | 489 | if (avail > PAGE_SIZE) |
490 | avail = PAGE_SIZE; | ||
490 | old = page_address(rqstp->rq_arg.pages[0]); | 491 | old = page_address(rqstp->rq_arg.pages[0]); |
491 | } | 492 | } |
492 | while (len && avail && *old) { | 493 | while (len && avail && *old) { |
@@ -816,11 +817,11 @@ static __be32 * | |||
816 | encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, | 817 | encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, |
817 | struct svc_fh *fhp) | 818 | struct svc_fh *fhp) |
818 | { | 819 | { |
819 | p = encode_post_op_attr(cd->rqstp, p, fhp); | 820 | p = encode_post_op_attr(cd->rqstp, p, fhp); |
820 | *p++ = xdr_one; /* yes, a file handle follows */ | 821 | *p++ = xdr_one; /* yes, a file handle follows */ |
821 | p = encode_fh(p, fhp); | 822 | p = encode_fh(p, fhp); |
822 | fh_put(fhp); | 823 | fh_put(fhp); |
823 | return p; | 824 | return p; |
824 | } | 825 | } |
825 | 826 | ||
826 | static int | 827 | static int |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 9d536a8cb379..aae2b29ae2c9 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -350,30 +350,6 @@ static struct rpc_version * nfs_cb_version[] = { | |||
350 | static int do_probe_callback(void *data) | 350 | static int do_probe_callback(void *data) |
351 | { | 351 | { |
352 | struct nfs4_client *clp = data; | 352 | struct nfs4_client *clp = data; |
353 | struct nfs4_callback *cb = &clp->cl_callback; | ||
354 | struct rpc_message msg = { | ||
355 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], | ||
356 | .rpc_argp = clp, | ||
357 | }; | ||
358 | int status; | ||
359 | |||
360 | status = rpc_call_sync(cb->cb_client, &msg, RPC_TASK_SOFT); | ||
361 | |||
362 | if (status) { | ||
363 | rpc_shutdown_client(cb->cb_client); | ||
364 | cb->cb_client = NULL; | ||
365 | } else | ||
366 | atomic_set(&cb->cb_set, 1); | ||
367 | put_nfs4_client(clp); | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * Set up the callback client and put a NFSPROC4_CB_NULL on the wire... | ||
373 | */ | ||
374 | void | ||
375 | nfsd4_probe_callback(struct nfs4_client *clp) | ||
376 | { | ||
377 | struct sockaddr_in addr; | 353 | struct sockaddr_in addr; |
378 | struct nfs4_callback *cb = &clp->cl_callback; | 354 | struct nfs4_callback *cb = &clp->cl_callback; |
379 | struct rpc_timeout timeparms = { | 355 | struct rpc_timeout timeparms = { |
@@ -390,13 +366,15 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
390 | .timeout = &timeparms, | 366 | .timeout = &timeparms, |
391 | .program = program, | 367 | .program = program, |
392 | .version = nfs_cb_version[1]->number, | 368 | .version = nfs_cb_version[1]->number, |
393 | .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ | 369 | .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ |
394 | .flags = (RPC_CLNT_CREATE_NOPING), | 370 | .flags = (RPC_CLNT_CREATE_NOPING), |
395 | }; | 371 | }; |
396 | struct task_struct *t; | 372 | struct rpc_message msg = { |
397 | 373 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], | |
398 | if (atomic_read(&cb->cb_set)) | 374 | .rpc_argp = clp, |
399 | return; | 375 | }; |
376 | struct rpc_clnt *client; | ||
377 | int status; | ||
400 | 378 | ||
401 | /* Initialize address */ | 379 | /* Initialize address */ |
402 | memset(&addr, 0, sizeof(addr)); | 380 | memset(&addr, 0, sizeof(addr)); |
@@ -416,29 +394,50 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
416 | program->stats->program = program; | 394 | program->stats->program = program; |
417 | 395 | ||
418 | /* Create RPC client */ | 396 | /* Create RPC client */ |
419 | cb->cb_client = rpc_create(&args); | 397 | client = rpc_create(&args); |
420 | if (IS_ERR(cb->cb_client)) { | 398 | if (IS_ERR(client)) { |
421 | dprintk("NFSD: couldn't create callback client\n"); | 399 | dprintk("NFSD: couldn't create callback client\n"); |
400 | status = PTR_ERR(client); | ||
422 | goto out_err; | 401 | goto out_err; |
423 | } | 402 | } |
424 | 403 | ||
404 | status = rpc_call_sync(client, &msg, RPC_TASK_SOFT); | ||
405 | |||
406 | if (status) | ||
407 | goto out_release_client; | ||
408 | |||
409 | cb->cb_client = client; | ||
410 | atomic_set(&cb->cb_set, 1); | ||
411 | put_nfs4_client(clp); | ||
412 | return 0; | ||
413 | out_release_client: | ||
414 | rpc_shutdown_client(client); | ||
415 | out_err: | ||
416 | put_nfs4_client(clp); | ||
417 | dprintk("NFSD: warning: no callback path to client %.*s\n", | ||
418 | (int)clp->cl_name.len, clp->cl_name.data); | ||
419 | return status; | ||
420 | } | ||
421 | |||
422 | /* | ||
423 | * Set up the callback client and put a NFSPROC4_CB_NULL on the wire... | ||
424 | */ | ||
425 | void | ||
426 | nfsd4_probe_callback(struct nfs4_client *clp) | ||
427 | { | ||
428 | struct task_struct *t; | ||
429 | |||
430 | BUG_ON(atomic_read(&clp->cl_callback.cb_set)); | ||
431 | |||
425 | /* the task holds a reference to the nfs4_client struct */ | 432 | /* the task holds a reference to the nfs4_client struct */ |
426 | atomic_inc(&clp->cl_count); | 433 | atomic_inc(&clp->cl_count); |
427 | 434 | ||
428 | t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe"); | 435 | t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe"); |
429 | 436 | ||
430 | if (IS_ERR(t)) | 437 | if (IS_ERR(t)) |
431 | goto out_release_clp; | 438 | atomic_dec(&clp->cl_count); |
432 | 439 | ||
433 | return; | 440 | return; |
434 | |||
435 | out_release_clp: | ||
436 | atomic_dec(&clp->cl_count); | ||
437 | rpc_shutdown_client(cb->cb_client); | ||
438 | out_err: | ||
439 | cb->cb_client = NULL; | ||
440 | dprintk("NFSD: warning: no callback path to client %.*s\n", | ||
441 | (int)clp->cl_name.len, clp->cl_name.data); | ||
442 | } | 441 | } |
443 | 442 | ||
444 | /* | 443 | /* |
@@ -458,9 +457,6 @@ nfsd4_cb_recall(struct nfs4_delegation *dp) | |||
458 | int retries = 1; | 457 | int retries = 1; |
459 | int status = 0; | 458 | int status = 0; |
460 | 459 | ||
461 | if ((!atomic_read(&clp->cl_callback.cb_set)) || !clnt) | ||
462 | return; | ||
463 | |||
464 | cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */ | 460 | cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */ |
465 | cbr->cbr_dp = dp; | 461 | cbr->cbr_dp = dp; |
466 | 462 | ||
@@ -469,6 +465,7 @@ nfsd4_cb_recall(struct nfs4_delegation *dp) | |||
469 | switch (status) { | 465 | switch (status) { |
470 | case -EIO: | 466 | case -EIO: |
471 | /* Network partition? */ | 467 | /* Network partition? */ |
468 | atomic_set(&clp->cl_callback.cb_set, 0); | ||
472 | case -EBADHANDLE: | 469 | case -EBADHANDLE: |
473 | case -NFS4ERR_BAD_STATEID: | 470 | case -NFS4ERR_BAD_STATEID: |
474 | /* Race: client probably got cb_recall | 471 | /* Race: client probably got cb_recall |
@@ -481,11 +478,10 @@ nfsd4_cb_recall(struct nfs4_delegation *dp) | |||
481 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); | 478 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); |
482 | } | 479 | } |
483 | out_put_cred: | 480 | out_put_cred: |
484 | if (status == -EIO) | 481 | /* |
485 | atomic_set(&clp->cl_callback.cb_set, 0); | 482 | * Success or failure, now we're either waiting for lease expiration |
486 | /* Success or failure, now we're either waiting for lease expiration | 483 | * or deleg_return. |
487 | * or deleg_return. */ | 484 | */ |
488 | dprintk("NFSD: nfs4_cb_recall: dp %p dl_flock %p dl_count %d\n",dp, dp->dl_flock, atomic_read(&dp->dl_count)); | ||
489 | put_nfs4_client(clp); | 485 | put_nfs4_client(clp); |
490 | nfs4_put_delegation(dp); | 486 | nfs4_put_delegation(dp); |
491 | return; | 487 | return; |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 4c0c683ce07a..996bd88b75ba 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -255,13 +255,10 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) | |||
255 | goto out; | 255 | goto out; |
256 | if (len == 0) | 256 | if (len == 0) |
257 | set_bit(CACHE_NEGATIVE, &ent.h.flags); | 257 | set_bit(CACHE_NEGATIVE, &ent.h.flags); |
258 | else { | 258 | else if (len >= IDMAP_NAMESZ) |
259 | if (error >= IDMAP_NAMESZ) { | 259 | goto out; |
260 | error = -EINVAL; | 260 | else |
261 | goto out; | ||
262 | } | ||
263 | memcpy(ent.name, buf1, sizeof(ent.name)); | 261 | memcpy(ent.name, buf1, sizeof(ent.name)); |
264 | } | ||
265 | error = -ENOMEM; | 262 | error = -ENOMEM; |
266 | res = idtoname_update(&ent, res); | 263 | res = idtoname_update(&ent, res); |
267 | if (res == NULL) | 264 | if (res == NULL) |
@@ -467,20 +464,25 @@ nametoid_update(struct ent *new, struct ent *old) | |||
467 | * Exported API | 464 | * Exported API |
468 | */ | 465 | */ |
469 | 466 | ||
470 | void | 467 | int |
471 | nfsd_idmap_init(void) | 468 | nfsd_idmap_init(void) |
472 | { | 469 | { |
473 | cache_register(&idtoname_cache); | 470 | int rv; |
474 | cache_register(&nametoid_cache); | 471 | |
472 | rv = cache_register(&idtoname_cache); | ||
473 | if (rv) | ||
474 | return rv; | ||
475 | rv = cache_register(&nametoid_cache); | ||
476 | if (rv) | ||
477 | cache_unregister(&idtoname_cache); | ||
478 | return rv; | ||
475 | } | 479 | } |
476 | 480 | ||
477 | void | 481 | void |
478 | nfsd_idmap_shutdown(void) | 482 | nfsd_idmap_shutdown(void) |
479 | { | 483 | { |
480 | if (cache_unregister(&idtoname_cache)) | 484 | cache_unregister(&idtoname_cache); |
481 | printk(KERN_ERR "nfsd: failed to unregister idtoname cache\n"); | 485 | cache_unregister(&nametoid_cache); |
482 | if (cache_unregister(&nametoid_cache)) | ||
483 | printk(KERN_ERR "nfsd: failed to unregister nametoid cache\n"); | ||
484 | } | 486 | } |
485 | 487 | ||
486 | /* | 488 | /* |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 18ead1790bb3..c593db047d8b 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -750,7 +750,7 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
750 | cstate->current_fh.fh_export, | 750 | cstate->current_fh.fh_export, |
751 | cstate->current_fh.fh_dentry, buf, | 751 | cstate->current_fh.fh_dentry, buf, |
752 | &count, verify->ve_bmval, | 752 | &count, verify->ve_bmval, |
753 | rqstp); | 753 | rqstp, 0); |
754 | 754 | ||
755 | /* this means that nfsd4_encode_fattr() ran out of space */ | 755 | /* this means that nfsd4_encode_fattr() ran out of space */ |
756 | if (status == nfserr_resource && count == 0) | 756 | if (status == nfserr_resource && count == 0) |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 31673cd251c3..f6744bc03dae 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -61,7 +61,6 @@ static time_t lease_time = 90; /* default lease time */ | |||
61 | static time_t user_lease_time = 90; | 61 | static time_t user_lease_time = 90; |
62 | static time_t boot_time; | 62 | static time_t boot_time; |
63 | static int in_grace = 1; | 63 | static int in_grace = 1; |
64 | static u32 current_clientid = 1; | ||
65 | static u32 current_ownerid = 1; | 64 | static u32 current_ownerid = 1; |
66 | static u32 current_fileid = 1; | 65 | static u32 current_fileid = 1; |
67 | static u32 current_delegid = 1; | 66 | static u32 current_delegid = 1; |
@@ -340,21 +339,20 @@ STALE_CLIENTID(clientid_t *clid) | |||
340 | * This type of memory management is somewhat inefficient, but we use it | 339 | * This type of memory management is somewhat inefficient, but we use it |
341 | * anyway since SETCLIENTID is not a common operation. | 340 | * anyway since SETCLIENTID is not a common operation. |
342 | */ | 341 | */ |
343 | static inline struct nfs4_client * | 342 | static struct nfs4_client *alloc_client(struct xdr_netobj name) |
344 | alloc_client(struct xdr_netobj name) | ||
345 | { | 343 | { |
346 | struct nfs4_client *clp; | 344 | struct nfs4_client *clp; |
347 | 345 | ||
348 | if ((clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) { | 346 | clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL); |
349 | if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) { | 347 | if (clp == NULL) |
350 | memcpy(clp->cl_name.data, name.data, name.len); | 348 | return NULL; |
351 | clp->cl_name.len = name.len; | 349 | clp->cl_name.data = kmalloc(name.len, GFP_KERNEL); |
352 | } | 350 | if (clp->cl_name.data == NULL) { |
353 | else { | 351 | kfree(clp); |
354 | kfree(clp); | 352 | return NULL; |
355 | clp = NULL; | ||
356 | } | ||
357 | } | 353 | } |
354 | memcpy(clp->cl_name.data, name.data, name.len); | ||
355 | clp->cl_name.len = name.len; | ||
358 | return clp; | 356 | return clp; |
359 | } | 357 | } |
360 | 358 | ||
@@ -363,8 +361,11 @@ shutdown_callback_client(struct nfs4_client *clp) | |||
363 | { | 361 | { |
364 | struct rpc_clnt *clnt = clp->cl_callback.cb_client; | 362 | struct rpc_clnt *clnt = clp->cl_callback.cb_client; |
365 | 363 | ||
366 | /* shutdown rpc client, ending any outstanding recall rpcs */ | ||
367 | if (clnt) { | 364 | if (clnt) { |
365 | /* | ||
366 | * Callback threads take a reference on the client, so there | ||
367 | * should be no outstanding callbacks at this point. | ||
368 | */ | ||
368 | clp->cl_callback.cb_client = NULL; | 369 | clp->cl_callback.cb_client = NULL; |
369 | rpc_shutdown_client(clnt); | 370 | rpc_shutdown_client(clnt); |
370 | } | 371 | } |
@@ -422,12 +423,13 @@ expire_client(struct nfs4_client *clp) | |||
422 | put_nfs4_client(clp); | 423 | put_nfs4_client(clp); |
423 | } | 424 | } |
424 | 425 | ||
425 | static struct nfs4_client * | 426 | static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir) |
426 | create_client(struct xdr_netobj name, char *recdir) { | 427 | { |
427 | struct nfs4_client *clp; | 428 | struct nfs4_client *clp; |
428 | 429 | ||
429 | if (!(clp = alloc_client(name))) | 430 | clp = alloc_client(name); |
430 | goto out; | 431 | if (clp == NULL) |
432 | return NULL; | ||
431 | memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); | 433 | memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); |
432 | atomic_set(&clp->cl_count, 1); | 434 | atomic_set(&clp->cl_count, 1); |
433 | atomic_set(&clp->cl_callback.cb_set, 0); | 435 | atomic_set(&clp->cl_callback.cb_set, 0); |
@@ -436,32 +438,30 @@ create_client(struct xdr_netobj name, char *recdir) { | |||
436 | INIT_LIST_HEAD(&clp->cl_openowners); | 438 | INIT_LIST_HEAD(&clp->cl_openowners); |
437 | INIT_LIST_HEAD(&clp->cl_delegations); | 439 | INIT_LIST_HEAD(&clp->cl_delegations); |
438 | INIT_LIST_HEAD(&clp->cl_lru); | 440 | INIT_LIST_HEAD(&clp->cl_lru); |
439 | out: | ||
440 | return clp; | 441 | return clp; |
441 | } | 442 | } |
442 | 443 | ||
443 | static void | 444 | static void copy_verf(struct nfs4_client *target, nfs4_verifier *source) |
444 | copy_verf(struct nfs4_client *target, nfs4_verifier *source) { | 445 | { |
445 | memcpy(target->cl_verifier.data, source->data, sizeof(target->cl_verifier.data)); | 446 | memcpy(target->cl_verifier.data, source->data, |
447 | sizeof(target->cl_verifier.data)); | ||
446 | } | 448 | } |
447 | 449 | ||
448 | static void | 450 | static void copy_clid(struct nfs4_client *target, struct nfs4_client *source) |
449 | copy_clid(struct nfs4_client *target, struct nfs4_client *source) { | 451 | { |
450 | target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; | 452 | target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; |
451 | target->cl_clientid.cl_id = source->cl_clientid.cl_id; | 453 | target->cl_clientid.cl_id = source->cl_clientid.cl_id; |
452 | } | 454 | } |
453 | 455 | ||
454 | static void | 456 | static void copy_cred(struct svc_cred *target, struct svc_cred *source) |
455 | copy_cred(struct svc_cred *target, struct svc_cred *source) { | 457 | { |
456 | |||
457 | target->cr_uid = source->cr_uid; | 458 | target->cr_uid = source->cr_uid; |
458 | target->cr_gid = source->cr_gid; | 459 | target->cr_gid = source->cr_gid; |
459 | target->cr_group_info = source->cr_group_info; | 460 | target->cr_group_info = source->cr_group_info; |
460 | get_group_info(target->cr_group_info); | 461 | get_group_info(target->cr_group_info); |
461 | } | 462 | } |
462 | 463 | ||
463 | static inline int | 464 | static int same_name(const char *n1, const char *n2) |
464 | same_name(const char *n1, const char *n2) | ||
465 | { | 465 | { |
466 | return 0 == memcmp(n1, n2, HEXDIR_LEN); | 466 | return 0 == memcmp(n1, n2, HEXDIR_LEN); |
467 | } | 467 | } |
@@ -485,26 +485,26 @@ same_creds(struct svc_cred *cr1, struct svc_cred *cr2) | |||
485 | return cr1->cr_uid == cr2->cr_uid; | 485 | return cr1->cr_uid == cr2->cr_uid; |
486 | } | 486 | } |
487 | 487 | ||
488 | static void | 488 | static void gen_clid(struct nfs4_client *clp) |
489 | gen_clid(struct nfs4_client *clp) { | 489 | { |
490 | static u32 current_clientid = 1; | ||
491 | |||
490 | clp->cl_clientid.cl_boot = boot_time; | 492 | clp->cl_clientid.cl_boot = boot_time; |
491 | clp->cl_clientid.cl_id = current_clientid++; | 493 | clp->cl_clientid.cl_id = current_clientid++; |
492 | } | 494 | } |
493 | 495 | ||
494 | static void | 496 | static void gen_confirm(struct nfs4_client *clp) |
495 | gen_confirm(struct nfs4_client *clp) { | 497 | { |
496 | struct timespec tv; | 498 | static u32 i; |
497 | u32 * p; | 499 | u32 *p; |
498 | 500 | ||
499 | tv = CURRENT_TIME; | ||
500 | p = (u32 *)clp->cl_confirm.data; | 501 | p = (u32 *)clp->cl_confirm.data; |
501 | *p++ = tv.tv_sec; | 502 | *p++ = get_seconds(); |
502 | *p++ = tv.tv_nsec; | 503 | *p++ = i++; |
503 | } | 504 | } |
504 | 505 | ||
505 | static int | 506 | static int check_name(struct xdr_netobj name) |
506 | check_name(struct xdr_netobj name) { | 507 | { |
507 | |||
508 | if (name.len == 0) | 508 | if (name.len == 0) |
509 | return 0; | 509 | return 0; |
510 | if (name.len > NFS4_OPAQUE_LIMIT) { | 510 | if (name.len > NFS4_OPAQUE_LIMIT) { |
@@ -683,39 +683,6 @@ out_err: | |||
683 | return; | 683 | return; |
684 | } | 684 | } |
685 | 685 | ||
686 | /* | ||
687 | * RFC 3010 has a complex implmentation description of processing a | ||
688 | * SETCLIENTID request consisting of 5 bullets, labeled as | ||
689 | * CASE0 - CASE4 below. | ||
690 | * | ||
691 | * NOTES: | ||
692 | * callback information will be processed in a future patch | ||
693 | * | ||
694 | * an unconfirmed record is added when: | ||
695 | * NORMAL (part of CASE 4): there is no confirmed nor unconfirmed record. | ||
696 | * CASE 1: confirmed record found with matching name, principal, | ||
697 | * verifier, and clientid. | ||
698 | * CASE 2: confirmed record found with matching name, principal, | ||
699 | * and there is no unconfirmed record with matching | ||
700 | * name and principal | ||
701 | * | ||
702 | * an unconfirmed record is replaced when: | ||
703 | * CASE 3: confirmed record found with matching name, principal, | ||
704 | * and an unconfirmed record is found with matching | ||
705 | * name, principal, and with clientid and | ||
706 | * confirm that does not match the confirmed record. | ||
707 | * CASE 4: there is no confirmed record with matching name and | ||
708 | * principal. there is an unconfirmed record with | ||
709 | * matching name, principal. | ||
710 | * | ||
711 | * an unconfirmed record is deleted when: | ||
712 | * CASE 1: an unconfirmed record that matches input name, verifier, | ||
713 | * and confirmed clientid. | ||
714 | * CASE 4: any unconfirmed records with matching name and principal | ||
715 | * that exist after an unconfirmed record has been replaced | ||
716 | * as described above. | ||
717 | * | ||
718 | */ | ||
719 | __be32 | 686 | __be32 |
720 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 687 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
721 | struct nfsd4_setclientid *setclid) | 688 | struct nfsd4_setclientid *setclid) |
@@ -748,11 +715,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
748 | nfs4_lock_state(); | 715 | nfs4_lock_state(); |
749 | conf = find_confirmed_client_by_str(dname, strhashval); | 716 | conf = find_confirmed_client_by_str(dname, strhashval); |
750 | if (conf) { | 717 | if (conf) { |
751 | /* | 718 | /* RFC 3530 14.2.33 CASE 0: */ |
752 | * CASE 0: | ||
753 | * clname match, confirmed, different principal | ||
754 | * or different ip_address | ||
755 | */ | ||
756 | status = nfserr_clid_inuse; | 719 | status = nfserr_clid_inuse; |
757 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred) | 720 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred) |
758 | || conf->cl_addr != sin->sin_addr.s_addr) { | 721 | || conf->cl_addr != sin->sin_addr.s_addr) { |
@@ -761,12 +724,17 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
761 | goto out; | 724 | goto out; |
762 | } | 725 | } |
763 | } | 726 | } |
727 | /* | ||
728 | * section 14.2.33 of RFC 3530 (under the heading "IMPLEMENTATION") | ||
729 | * has a description of SETCLIENTID request processing consisting | ||
730 | * of 5 bullet points, labeled as CASE0 - CASE4 below. | ||
731 | */ | ||
764 | unconf = find_unconfirmed_client_by_str(dname, strhashval); | 732 | unconf = find_unconfirmed_client_by_str(dname, strhashval); |
765 | status = nfserr_resource; | 733 | status = nfserr_resource; |
766 | if (!conf) { | 734 | if (!conf) { |
767 | /* | 735 | /* |
768 | * CASE 4: | 736 | * RFC 3530 14.2.33 CASE 4: |
769 | * placed first, because it is the normal case. | 737 | * placed first, because it is the normal case |
770 | */ | 738 | */ |
771 | if (unconf) | 739 | if (unconf) |
772 | expire_client(unconf); | 740 | expire_client(unconf); |
@@ -776,17 +744,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
776 | gen_clid(new); | 744 | gen_clid(new); |
777 | } else if (same_verf(&conf->cl_verifier, &clverifier)) { | 745 | } else if (same_verf(&conf->cl_verifier, &clverifier)) { |
778 | /* | 746 | /* |
779 | * CASE 1: | 747 | * RFC 3530 14.2.33 CASE 1: |
780 | * cl_name match, confirmed, principal match | 748 | * probable callback update |
781 | * verifier match: probable callback update | ||
782 | * | ||
783 | * remove any unconfirmed nfs4_client with | ||
784 | * matching cl_name, cl_verifier, and cl_clientid | ||
785 | * | ||
786 | * create and insert an unconfirmed nfs4_client with same | ||
787 | * cl_name, cl_verifier, and cl_clientid as existing | ||
788 | * nfs4_client, but with the new callback info and a | ||
789 | * new cl_confirm | ||
790 | */ | 749 | */ |
791 | if (unconf) { | 750 | if (unconf) { |
792 | /* Note this is removing unconfirmed {*x***}, | 751 | /* Note this is removing unconfirmed {*x***}, |
@@ -802,43 +761,25 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
802 | copy_clid(new, conf); | 761 | copy_clid(new, conf); |
803 | } else if (!unconf) { | 762 | } else if (!unconf) { |
804 | /* | 763 | /* |
805 | * CASE 2: | 764 | * RFC 3530 14.2.33 CASE 2: |
806 | * clname match, confirmed, principal match | 765 | * probable client reboot; state will be removed if |
807 | * verfier does not match | 766 | * confirmed. |
808 | * no unconfirmed. create a new unconfirmed nfs4_client | ||
809 | * using input clverifier, clname, and callback info | ||
810 | * and generate a new cl_clientid and cl_confirm. | ||
811 | */ | 767 | */ |
812 | new = create_client(clname, dname); | 768 | new = create_client(clname, dname); |
813 | if (new == NULL) | 769 | if (new == NULL) |
814 | goto out; | 770 | goto out; |
815 | gen_clid(new); | 771 | gen_clid(new); |
816 | } else if (!same_verf(&conf->cl_confirm, &unconf->cl_confirm)) { | 772 | } else { |
817 | /* | 773 | /* |
818 | * CASE3: | 774 | * RFC 3530 14.2.33 CASE 3: |
819 | * confirmed found (name, principal match) | 775 | * probable client reboot; state will be removed if |
820 | * confirmed verifier does not match input clverifier | 776 | * confirmed. |
821 | * | ||
822 | * unconfirmed found (name match) | ||
823 | * confirmed->cl_confirm != unconfirmed->cl_confirm | ||
824 | * | ||
825 | * remove unconfirmed. | ||
826 | * | ||
827 | * create an unconfirmed nfs4_client | ||
828 | * with same cl_name as existing confirmed nfs4_client, | ||
829 | * but with new callback info, new cl_clientid, | ||
830 | * new cl_verifier and a new cl_confirm | ||
831 | */ | 777 | */ |
832 | expire_client(unconf); | 778 | expire_client(unconf); |
833 | new = create_client(clname, dname); | 779 | new = create_client(clname, dname); |
834 | if (new == NULL) | 780 | if (new == NULL) |
835 | goto out; | 781 | goto out; |
836 | gen_clid(new); | 782 | gen_clid(new); |
837 | } else { | ||
838 | /* No cases hit !!! */ | ||
839 | status = nfserr_inval; | ||
840 | goto out; | ||
841 | |||
842 | } | 783 | } |
843 | copy_verf(new, &clverifier); | 784 | copy_verf(new, &clverifier); |
844 | new->cl_addr = sin->sin_addr.s_addr; | 785 | new->cl_addr = sin->sin_addr.s_addr; |
@@ -857,11 +798,9 @@ out: | |||
857 | 798 | ||
858 | 799 | ||
859 | /* | 800 | /* |
860 | * RFC 3010 has a complex implmentation description of processing a | 801 | * Section 14.2.34 of RFC 3530 (under the heading "IMPLEMENTATION") has |
861 | * SETCLIENTID_CONFIRM request consisting of 4 bullets describing | 802 | * a description of SETCLIENTID_CONFIRM request processing consisting of 4 |
862 | * processing on a DRC miss, labeled as CASE1 - CASE4 below. | 803 | * bullets, labeled as CASE1 - CASE4 below. |
863 | * | ||
864 | * NOTE: callback information will be processed here in a future patch | ||
865 | */ | 804 | */ |
866 | __be32 | 805 | __be32 |
867 | nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | 806 | nfsd4_setclientid_confirm(struct svc_rqst *rqstp, |
@@ -892,16 +831,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
892 | if (unconf && unconf->cl_addr != sin->sin_addr.s_addr) | 831 | if (unconf && unconf->cl_addr != sin->sin_addr.s_addr) |
893 | goto out; | 832 | goto out; |
894 | 833 | ||
895 | if ((conf && unconf) && | 834 | /* |
896 | (same_verf(&unconf->cl_confirm, &confirm)) && | 835 | * section 14.2.34 of RFC 3530 has a description of |
897 | (same_verf(&conf->cl_verifier, &unconf->cl_verifier)) && | 836 | * SETCLIENTID_CONFIRM request processing consisting |
898 | (same_name(conf->cl_recdir,unconf->cl_recdir)) && | 837 | * of 4 bullet points, labeled as CASE1 - CASE4 below. |
899 | (!same_verf(&conf->cl_confirm, &unconf->cl_confirm))) { | 838 | */ |
900 | /* CASE 1: | 839 | if (conf && unconf && same_verf(&confirm, &unconf->cl_confirm)) { |
901 | * unconf record that matches input clientid and input confirm. | 840 | /* |
902 | * conf record that matches input clientid. | 841 | * RFC 3530 14.2.34 CASE 1: |
903 | * conf and unconf records match names, verifiers | 842 | * callback update |
904 | */ | 843 | */ |
905 | if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) | 844 | if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) |
906 | status = nfserr_clid_inuse; | 845 | status = nfserr_clid_inuse; |
907 | else { | 846 | else { |
@@ -914,15 +853,11 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
914 | status = nfs_ok; | 853 | status = nfs_ok; |
915 | 854 | ||
916 | } | 855 | } |
917 | } else if ((conf && !unconf) || | 856 | } else if (conf && !unconf) { |
918 | ((conf && unconf) && | 857 | /* |
919 | (!same_verf(&conf->cl_verifier, &unconf->cl_verifier) || | 858 | * RFC 3530 14.2.34 CASE 2: |
920 | !same_name(conf->cl_recdir, unconf->cl_recdir)))) { | 859 | * probable retransmitted request; play it safe and |
921 | /* CASE 2: | 860 | * do nothing. |
922 | * conf record that matches input clientid. | ||
923 | * if unconf record matches input clientid, then | ||
924 | * unconf->cl_name or unconf->cl_verifier don't match the | ||
925 | * conf record. | ||
926 | */ | 861 | */ |
927 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) | 862 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) |
928 | status = nfserr_clid_inuse; | 863 | status = nfserr_clid_inuse; |
@@ -930,10 +865,9 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
930 | status = nfs_ok; | 865 | status = nfs_ok; |
931 | } else if (!conf && unconf | 866 | } else if (!conf && unconf |
932 | && same_verf(&unconf->cl_confirm, &confirm)) { | 867 | && same_verf(&unconf->cl_confirm, &confirm)) { |
933 | /* CASE 3: | 868 | /* |
934 | * conf record not found. | 869 | * RFC 3530 14.2.34 CASE 3: |
935 | * unconf record found. | 870 | * Normal case; new or rebooted client: |
936 | * unconf->cl_confirm matches input confirm | ||
937 | */ | 871 | */ |
938 | if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) { | 872 | if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) { |
939 | status = nfserr_clid_inuse; | 873 | status = nfserr_clid_inuse; |
@@ -948,16 +882,15 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
948 | } | 882 | } |
949 | move_to_confirmed(unconf); | 883 | move_to_confirmed(unconf); |
950 | conf = unconf; | 884 | conf = unconf; |
885 | nfsd4_probe_callback(conf); | ||
951 | status = nfs_ok; | 886 | status = nfs_ok; |
952 | } | 887 | } |
953 | } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm))) | 888 | } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm))) |
954 | && (!unconf || (unconf && !same_verf(&unconf->cl_confirm, | 889 | && (!unconf || (unconf && !same_verf(&unconf->cl_confirm, |
955 | &confirm)))) { | 890 | &confirm)))) { |
956 | /* CASE 4: | 891 | /* |
957 | * conf record not found, or if conf, conf->cl_confirm does not | 892 | * RFC 3530 14.2.34 CASE 4: |
958 | * match input confirm. | 893 | * Client probably hasn't noticed that we rebooted yet. |
959 | * unconf record not found, or if unconf, unconf->cl_confirm | ||
960 | * does not match input confirm. | ||
961 | */ | 894 | */ |
962 | status = nfserr_stale_clientid; | 895 | status = nfserr_stale_clientid; |
963 | } else { | 896 | } else { |
@@ -965,8 +898,6 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
965 | status = nfserr_clid_inuse; | 898 | status = nfserr_clid_inuse; |
966 | } | 899 | } |
967 | out: | 900 | out: |
968 | if (!status) | ||
969 | nfsd4_probe_callback(conf); | ||
970 | nfs4_unlock_state(); | 901 | nfs4_unlock_state(); |
971 | return status; | 902 | return status; |
972 | } | 903 | } |
@@ -1226,14 +1157,19 @@ find_file(struct inode *ino) | |||
1226 | return NULL; | 1157 | return NULL; |
1227 | } | 1158 | } |
1228 | 1159 | ||
1229 | static int access_valid(u32 x) | 1160 | static inline int access_valid(u32 x) |
1230 | { | 1161 | { |
1231 | return (x > 0 && x < 4); | 1162 | if (x < NFS4_SHARE_ACCESS_READ) |
1163 | return 0; | ||
1164 | if (x > NFS4_SHARE_ACCESS_BOTH) | ||
1165 | return 0; | ||
1166 | return 1; | ||
1232 | } | 1167 | } |
1233 | 1168 | ||
1234 | static int deny_valid(u32 x) | 1169 | static inline int deny_valid(u32 x) |
1235 | { | 1170 | { |
1236 | return (x >= 0 && x < 5); | 1171 | /* Note: unlike access bits, deny bits may be zero. */ |
1172 | return x <= NFS4_SHARE_DENY_BOTH; | ||
1237 | } | 1173 | } |
1238 | 1174 | ||
1239 | static void | 1175 | static void |
@@ -2162,8 +2098,10 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei | |||
2162 | goto check_replay; | 2098 | goto check_replay; |
2163 | } | 2099 | } |
2164 | 2100 | ||
2101 | *stpp = stp; | ||
2102 | *sopp = sop = stp->st_stateowner; | ||
2103 | |||
2165 | if (lock) { | 2104 | if (lock) { |
2166 | struct nfs4_stateowner *sop = stp->st_stateowner; | ||
2167 | clientid_t *lockclid = &lock->v.new.clientid; | 2105 | clientid_t *lockclid = &lock->v.new.clientid; |
2168 | struct nfs4_client *clp = sop->so_client; | 2106 | struct nfs4_client *clp = sop->so_client; |
2169 | int lkflg = 0; | 2107 | int lkflg = 0; |
@@ -2193,9 +2131,6 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei | |||
2193 | return nfserr_bad_stateid; | 2131 | return nfserr_bad_stateid; |
2194 | } | 2132 | } |
2195 | 2133 | ||
2196 | *stpp = stp; | ||
2197 | *sopp = sop = stp->st_stateowner; | ||
2198 | |||
2199 | /* | 2134 | /* |
2200 | * We now validate the seqid and stateid generation numbers. | 2135 | * We now validate the seqid and stateid generation numbers. |
2201 | * For the moment, we ignore the possibility of | 2136 | * For the moment, we ignore the possibility of |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 57333944af7f..b0592e7c378d 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -148,12 +148,12 @@ xdr_error: \ | |||
148 | } \ | 148 | } \ |
149 | } while (0) | 149 | } while (0) |
150 | 150 | ||
151 | static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) | 151 | static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) |
152 | { | 152 | { |
153 | /* We want more bytes than seem to be available. | 153 | /* We want more bytes than seem to be available. |
154 | * Maybe we need a new page, maybe we have just run out | 154 | * Maybe we need a new page, maybe we have just run out |
155 | */ | 155 | */ |
156 | int avail = (char*)argp->end - (char*)argp->p; | 156 | unsigned int avail = (char *)argp->end - (char *)argp->p; |
157 | __be32 *p; | 157 | __be32 *p; |
158 | if (avail + argp->pagelen < nbytes) | 158 | if (avail + argp->pagelen < nbytes) |
159 | return NULL; | 159 | return NULL; |
@@ -169,6 +169,11 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) | |||
169 | return NULL; | 169 | return NULL; |
170 | 170 | ||
171 | } | 171 | } |
172 | /* | ||
173 | * The following memcpy is safe because read_buf is always | ||
174 | * called with nbytes > avail, and the two cases above both | ||
175 | * guarantee p points to at least nbytes bytes. | ||
176 | */ | ||
172 | memcpy(p, argp->p, avail); | 177 | memcpy(p, argp->p, avail); |
173 | /* step to next page */ | 178 | /* step to next page */ |
174 | argp->p = page_address(argp->pagelist[0]); | 179 | argp->p = page_address(argp->pagelist[0]); |
@@ -1448,7 +1453,7 @@ static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) | |||
1448 | __be32 | 1453 | __be32 |
1449 | nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | 1454 | nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, |
1450 | struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, | 1455 | struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, |
1451 | struct svc_rqst *rqstp) | 1456 | struct svc_rqst *rqstp, int ignore_crossmnt) |
1452 | { | 1457 | { |
1453 | u32 bmval0 = bmval[0]; | 1458 | u32 bmval0 = bmval[0]; |
1454 | u32 bmval1 = bmval[1]; | 1459 | u32 bmval1 = bmval[1]; |
@@ -1828,7 +1833,12 @@ out_acl: | |||
1828 | if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { | 1833 | if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { |
1829 | if ((buflen -= 8) < 0) | 1834 | if ((buflen -= 8) < 0) |
1830 | goto out_resource; | 1835 | goto out_resource; |
1831 | if (exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) { | 1836 | /* |
1837 | * Get parent's attributes if not ignoring crossmount | ||
1838 | * and this is the root of a cross-mounted filesystem. | ||
1839 | */ | ||
1840 | if (ignore_crossmnt == 0 && | ||
1841 | exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) { | ||
1832 | err = vfs_getattr(exp->ex_mnt->mnt_parent, | 1842 | err = vfs_getattr(exp->ex_mnt->mnt_parent, |
1833 | exp->ex_mnt->mnt_mountpoint, &stat); | 1843 | exp->ex_mnt->mnt_mountpoint, &stat); |
1834 | if (err) | 1844 | if (err) |
@@ -1864,13 +1874,25 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | |||
1864 | struct svc_export *exp = cd->rd_fhp->fh_export; | 1874 | struct svc_export *exp = cd->rd_fhp->fh_export; |
1865 | struct dentry *dentry; | 1875 | struct dentry *dentry; |
1866 | __be32 nfserr; | 1876 | __be32 nfserr; |
1877 | int ignore_crossmnt = 0; | ||
1867 | 1878 | ||
1868 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); | 1879 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); |
1869 | if (IS_ERR(dentry)) | 1880 | if (IS_ERR(dentry)) |
1870 | return nfserrno(PTR_ERR(dentry)); | 1881 | return nfserrno(PTR_ERR(dentry)); |
1871 | 1882 | ||
1872 | exp_get(exp); | 1883 | exp_get(exp); |
1873 | if (d_mountpoint(dentry)) { | 1884 | /* |
1885 | * In the case of a mountpoint, the client may be asking for | ||
1886 | * attributes that are only properties of the underlying filesystem | ||
1887 | * as opposed to the cross-mounted file system. In such a case, | ||
1888 | * we will not follow the cross mount and will fill the attribtutes | ||
1889 | * directly from the mountpoint dentry. | ||
1890 | */ | ||
1891 | if (d_mountpoint(dentry) && | ||
1892 | (cd->rd_bmval[0] & ~FATTR4_WORD0_RDATTR_ERROR) == 0 && | ||
1893 | (cd->rd_bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID) == 0) | ||
1894 | ignore_crossmnt = 1; | ||
1895 | else if (d_mountpoint(dentry)) { | ||
1874 | int err; | 1896 | int err; |
1875 | 1897 | ||
1876 | /* | 1898 | /* |
@@ -1889,7 +1911,7 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | |||
1889 | 1911 | ||
1890 | } | 1912 | } |
1891 | nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, | 1913 | nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, |
1892 | cd->rd_rqstp); | 1914 | cd->rd_rqstp, ignore_crossmnt); |
1893 | out_put: | 1915 | out_put: |
1894 | dput(dentry); | 1916 | dput(dentry); |
1895 | exp_put(exp); | 1917 | exp_put(exp); |
@@ -2043,7 +2065,7 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 | |||
2043 | buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2); | 2065 | buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2); |
2044 | nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, | 2066 | nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, |
2045 | resp->p, &buflen, getattr->ga_bmval, | 2067 | resp->p, &buflen, getattr->ga_bmval, |
2046 | resp->rqstp); | 2068 | resp->rqstp, 0); |
2047 | if (!nfserr) | 2069 | if (!nfserr) |
2048 | resp->p += buflen; | 2070 | resp->p += buflen; |
2049 | return nfserr; | 2071 | return nfserr; |
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 578f2c9d56be..5bfc2ac60d54 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c | |||
@@ -44,17 +44,17 @@ static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec); | |||
44 | */ | 44 | */ |
45 | static DEFINE_SPINLOCK(cache_lock); | 45 | static DEFINE_SPINLOCK(cache_lock); |
46 | 46 | ||
47 | void | 47 | int nfsd_reply_cache_init(void) |
48 | nfsd_cache_init(void) | ||
49 | { | 48 | { |
50 | struct svc_cacherep *rp; | 49 | struct svc_cacherep *rp; |
51 | int i; | 50 | int i; |
52 | 51 | ||
53 | INIT_LIST_HEAD(&lru_head); | 52 | INIT_LIST_HEAD(&lru_head); |
54 | i = CACHESIZE; | 53 | i = CACHESIZE; |
55 | while(i) { | 54 | while (i) { |
56 | rp = kmalloc(sizeof(*rp), GFP_KERNEL); | 55 | rp = kmalloc(sizeof(*rp), GFP_KERNEL); |
57 | if (!rp) break; | 56 | if (!rp) |
57 | goto out_nomem; | ||
58 | list_add(&rp->c_lru, &lru_head); | 58 | list_add(&rp->c_lru, &lru_head); |
59 | rp->c_state = RC_UNUSED; | 59 | rp->c_state = RC_UNUSED; |
60 | rp->c_type = RC_NOCACHE; | 60 | rp->c_type = RC_NOCACHE; |
@@ -62,23 +62,19 @@ nfsd_cache_init(void) | |||
62 | i--; | 62 | i--; |
63 | } | 63 | } |
64 | 64 | ||
65 | if (i) | ||
66 | printk (KERN_ERR "nfsd: cannot allocate all %d cache entries, only got %d\n", | ||
67 | CACHESIZE, CACHESIZE-i); | ||
68 | |||
69 | hash_list = kcalloc (HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL); | 65 | hash_list = kcalloc (HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL); |
70 | if (!hash_list) { | 66 | if (!hash_list) |
71 | nfsd_cache_shutdown(); | 67 | goto out_nomem; |
72 | printk (KERN_ERR "nfsd: cannot allocate %Zd bytes for hash list\n", | ||
73 | HASHSIZE * sizeof(struct hlist_head)); | ||
74 | return; | ||
75 | } | ||
76 | 68 | ||
77 | cache_disabled = 0; | 69 | cache_disabled = 0; |
70 | return 0; | ||
71 | out_nomem: | ||
72 | printk(KERN_ERR "nfsd: failed to allocate reply cache\n"); | ||
73 | nfsd_reply_cache_shutdown(); | ||
74 | return -ENOMEM; | ||
78 | } | 75 | } |
79 | 76 | ||
80 | void | 77 | void nfsd_reply_cache_shutdown(void) |
81 | nfsd_cache_shutdown(void) | ||
82 | { | 78 | { |
83 | struct svc_cacherep *rp; | 79 | struct svc_cacherep *rp; |
84 | 80 | ||
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 77dc9893b7ba..8516137cdbb0 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -304,6 +304,9 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) | |||
304 | struct auth_domain *dom; | 304 | struct auth_domain *dom; |
305 | struct knfsd_fh fh; | 305 | struct knfsd_fh fh; |
306 | 306 | ||
307 | if (size == 0) | ||
308 | return -EINVAL; | ||
309 | |||
307 | if (buf[size-1] != '\n') | 310 | if (buf[size-1] != '\n') |
308 | return -EINVAL; | 311 | return -EINVAL; |
309 | buf[size-1] = 0; | 312 | buf[size-1] = 0; |
@@ -503,7 +506,7 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
503 | int len = 0; | 506 | int len = 0; |
504 | lock_kernel(); | 507 | lock_kernel(); |
505 | if (nfsd_serv) | 508 | if (nfsd_serv) |
506 | len = svc_sock_names(buf, nfsd_serv, NULL); | 509 | len = svc_xprt_names(nfsd_serv, buf, 0); |
507 | unlock_kernel(); | 510 | unlock_kernel(); |
508 | return len; | 511 | return len; |
509 | } | 512 | } |
@@ -540,7 +543,7 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
540 | } | 543 | } |
541 | return err < 0 ? err : 0; | 544 | return err < 0 ? err : 0; |
542 | } | 545 | } |
543 | if (buf[0] == '-') { | 546 | if (buf[0] == '-' && isdigit(buf[1])) { |
544 | char *toclose = kstrdup(buf+1, GFP_KERNEL); | 547 | char *toclose = kstrdup(buf+1, GFP_KERNEL); |
545 | int len = 0; | 548 | int len = 0; |
546 | if (!toclose) | 549 | if (!toclose) |
@@ -554,6 +557,53 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
554 | kfree(toclose); | 557 | kfree(toclose); |
555 | return len; | 558 | return len; |
556 | } | 559 | } |
560 | /* | ||
561 | * Add a transport listener by writing it's transport name | ||
562 | */ | ||
563 | if (isalpha(buf[0])) { | ||
564 | int err; | ||
565 | char transport[16]; | ||
566 | int port; | ||
567 | if (sscanf(buf, "%15s %4d", transport, &port) == 2) { | ||
568 | err = nfsd_create_serv(); | ||
569 | if (!err) { | ||
570 | err = svc_create_xprt(nfsd_serv, | ||
571 | transport, port, | ||
572 | SVC_SOCK_ANONYMOUS); | ||
573 | if (err == -ENOENT) | ||
574 | /* Give a reasonable perror msg for | ||
575 | * bad transport string */ | ||
576 | err = -EPROTONOSUPPORT; | ||
577 | } | ||
578 | return err < 0 ? err : 0; | ||
579 | } | ||
580 | } | ||
581 | /* | ||
582 | * Remove a transport by writing it's transport name and port number | ||
583 | */ | ||
584 | if (buf[0] == '-' && isalpha(buf[1])) { | ||
585 | struct svc_xprt *xprt; | ||
586 | int err = -EINVAL; | ||
587 | char transport[16]; | ||
588 | int port; | ||
589 | if (sscanf(&buf[1], "%15s %4d", transport, &port) == 2) { | ||
590 | if (port == 0) | ||
591 | return -EINVAL; | ||
592 | lock_kernel(); | ||
593 | if (nfsd_serv) { | ||
594 | xprt = svc_find_xprt(nfsd_serv, transport, | ||
595 | AF_UNSPEC, port); | ||
596 | if (xprt) { | ||
597 | svc_close_xprt(xprt); | ||
598 | svc_xprt_put(xprt); | ||
599 | err = 0; | ||
600 | } else | ||
601 | err = -ENOTCONN; | ||
602 | } | ||
603 | unlock_kernel(); | ||
604 | return err < 0 ? err : 0; | ||
605 | } | ||
606 | } | ||
557 | return -EINVAL; | 607 | return -EINVAL; |
558 | } | 608 | } |
559 | 609 | ||
@@ -616,7 +666,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) | |||
616 | char *recdir; | 666 | char *recdir; |
617 | int len, status; | 667 | int len, status; |
618 | 668 | ||
619 | if (size > PATH_MAX || buf[size-1] != '\n') | 669 | if (size == 0 || size > PATH_MAX || buf[size-1] != '\n') |
620 | return -EINVAL; | 670 | return -EINVAL; |
621 | buf[size-1] = 0; | 671 | buf[size-1] = 0; |
622 | 672 | ||
@@ -674,6 +724,27 @@ static struct file_system_type nfsd_fs_type = { | |||
674 | .kill_sb = kill_litter_super, | 724 | .kill_sb = kill_litter_super, |
675 | }; | 725 | }; |
676 | 726 | ||
727 | #ifdef CONFIG_PROC_FS | ||
728 | static int create_proc_exports_entry(void) | ||
729 | { | ||
730 | struct proc_dir_entry *entry; | ||
731 | |||
732 | entry = proc_mkdir("fs/nfs", NULL); | ||
733 | if (!entry) | ||
734 | return -ENOMEM; | ||
735 | entry = create_proc_entry("fs/nfs/exports", 0, NULL); | ||
736 | if (!entry) | ||
737 | return -ENOMEM; | ||
738 | entry->proc_fops = &exports_operations; | ||
739 | return 0; | ||
740 | } | ||
741 | #else /* CONFIG_PROC_FS */ | ||
742 | static int create_proc_exports_entry(void) | ||
743 | { | ||
744 | return 0; | ||
745 | } | ||
746 | #endif | ||
747 | |||
677 | static int __init init_nfsd(void) | 748 | static int __init init_nfsd(void) |
678 | { | 749 | { |
679 | int retval; | 750 | int retval; |
@@ -683,32 +754,43 @@ static int __init init_nfsd(void) | |||
683 | if (retval) | 754 | if (retval) |
684 | return retval; | 755 | return retval; |
685 | nfsd_stat_init(); /* Statistics */ | 756 | nfsd_stat_init(); /* Statistics */ |
686 | nfsd_cache_init(); /* RPC reply cache */ | 757 | retval = nfsd_reply_cache_init(); |
687 | nfsd_export_init(); /* Exports table */ | 758 | if (retval) |
759 | goto out_free_stat; | ||
760 | retval = nfsd_export_init(); | ||
761 | if (retval) | ||
762 | goto out_free_cache; | ||
688 | nfsd_lockd_init(); /* lockd->nfsd callbacks */ | 763 | nfsd_lockd_init(); /* lockd->nfsd callbacks */ |
689 | nfsd_idmap_init(); /* Name to ID mapping */ | 764 | retval = nfsd_idmap_init(); |
690 | if (proc_mkdir("fs/nfs", NULL)) { | 765 | if (retval) |
691 | struct proc_dir_entry *entry; | 766 | goto out_free_lockd; |
692 | entry = create_proc_entry("fs/nfs/exports", 0, NULL); | 767 | retval = create_proc_exports_entry(); |
693 | if (entry) | 768 | if (retval) |
694 | entry->proc_fops = &exports_operations; | 769 | goto out_free_idmap; |
695 | } | ||
696 | retval = register_filesystem(&nfsd_fs_type); | 770 | retval = register_filesystem(&nfsd_fs_type); |
697 | if (retval) { | 771 | if (retval) |
698 | nfsd_export_shutdown(); | 772 | goto out_free_all; |
699 | nfsd_cache_shutdown(); | 773 | return 0; |
700 | remove_proc_entry("fs/nfs/exports", NULL); | 774 | out_free_all: |
701 | remove_proc_entry("fs/nfs", NULL); | 775 | remove_proc_entry("fs/nfs/exports", NULL); |
702 | nfsd_stat_shutdown(); | 776 | remove_proc_entry("fs/nfs", NULL); |
703 | nfsd_lockd_shutdown(); | 777 | out_free_idmap: |
704 | } | 778 | nfsd_idmap_shutdown(); |
779 | out_free_lockd: | ||
780 | nfsd_lockd_shutdown(); | ||
781 | nfsd_export_shutdown(); | ||
782 | out_free_cache: | ||
783 | nfsd_reply_cache_shutdown(); | ||
784 | out_free_stat: | ||
785 | nfsd_stat_shutdown(); | ||
786 | nfsd4_free_slabs(); | ||
705 | return retval; | 787 | return retval; |
706 | } | 788 | } |
707 | 789 | ||
708 | static void __exit exit_nfsd(void) | 790 | static void __exit exit_nfsd(void) |
709 | { | 791 | { |
710 | nfsd_export_shutdown(); | 792 | nfsd_export_shutdown(); |
711 | nfsd_cache_shutdown(); | 793 | nfsd_reply_cache_shutdown(); |
712 | remove_proc_entry("fs/nfs/exports", NULL); | 794 | remove_proc_entry("fs/nfs/exports", NULL); |
713 | remove_proc_entry("fs/nfs", NULL); | 795 | remove_proc_entry("fs/nfs", NULL); |
714 | nfsd_stat_shutdown(); | 796 | nfsd_stat_shutdown(); |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 468f17a78441..8fbd2dc08a92 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/sunrpc/svc.h> | 22 | #include <linux/sunrpc/svc.h> |
23 | #include <linux/sunrpc/svcauth_gss.h> | 23 | #include <linux/sunrpc/svcauth_gss.h> |
24 | #include <linux/nfsd/nfsd.h> | 24 | #include <linux/nfsd/nfsd.h> |
25 | #include "auth.h" | ||
25 | 26 | ||
26 | #define NFSDDBG_FACILITY NFSDDBG_FH | 27 | #define NFSDDBG_FACILITY NFSDDBG_FH |
27 | 28 | ||
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 1190aeaa92be..9647b0f7bc0c 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -155,8 +155,8 @@ static int killsig; /* signal that was used to kill last nfsd */ | |||
155 | static void nfsd_last_thread(struct svc_serv *serv) | 155 | static void nfsd_last_thread(struct svc_serv *serv) |
156 | { | 156 | { |
157 | /* When last nfsd thread exits we need to do some clean-up */ | 157 | /* When last nfsd thread exits we need to do some clean-up */ |
158 | struct svc_sock *svsk; | 158 | struct svc_xprt *xprt; |
159 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) | 159 | list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) |
160 | lockd_down(); | 160 | lockd_down(); |
161 | nfsd_serv = NULL; | 161 | nfsd_serv = NULL; |
162 | nfsd_racache_shutdown(); | 162 | nfsd_racache_shutdown(); |
@@ -236,7 +236,7 @@ static int nfsd_init_socks(int port) | |||
236 | 236 | ||
237 | error = lockd_up(IPPROTO_UDP); | 237 | error = lockd_up(IPPROTO_UDP); |
238 | if (error >= 0) { | 238 | if (error >= 0) { |
239 | error = svc_makesock(nfsd_serv, IPPROTO_UDP, port, | 239 | error = svc_create_xprt(nfsd_serv, "udp", port, |
240 | SVC_SOCK_DEFAULTS); | 240 | SVC_SOCK_DEFAULTS); |
241 | if (error < 0) | 241 | if (error < 0) |
242 | lockd_down(); | 242 | lockd_down(); |
@@ -247,7 +247,7 @@ static int nfsd_init_socks(int port) | |||
247 | #ifdef CONFIG_NFSD_TCP | 247 | #ifdef CONFIG_NFSD_TCP |
248 | error = lockd_up(IPPROTO_TCP); | 248 | error = lockd_up(IPPROTO_TCP); |
249 | if (error >= 0) { | 249 | if (error >= 0) { |
250 | error = svc_makesock(nfsd_serv, IPPROTO_TCP, port, | 250 | error = svc_create_xprt(nfsd_serv, "tcp", port, |
251 | SVC_SOCK_DEFAULTS); | 251 | SVC_SOCK_DEFAULTS); |
252 | if (error < 0) | 252 | if (error < 0) |
253 | lockd_down(); | 253 | lockd_down(); |
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index b86e3658a0af..61ad61743d94 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/nfsd/nfsd.h> | 15 | #include <linux/nfsd/nfsd.h> |
16 | #include <linux/nfsd/xdr.h> | 16 | #include <linux/nfsd/xdr.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include "auth.h" | ||
18 | 19 | ||
19 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 20 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
20 | 21 | ||
@@ -62,10 +63,10 @@ encode_fh(__be32 *p, struct svc_fh *fhp) | |||
62 | * no slashes or null bytes. | 63 | * no slashes or null bytes. |
63 | */ | 64 | */ |
64 | static __be32 * | 65 | static __be32 * |
65 | decode_filename(__be32 *p, char **namp, int *lenp) | 66 | decode_filename(__be32 *p, char **namp, unsigned int *lenp) |
66 | { | 67 | { |
67 | char *name; | 68 | char *name; |
68 | int i; | 69 | unsigned int i; |
69 | 70 | ||
70 | if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXNAMLEN)) != NULL) { | 71 | if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXNAMLEN)) != NULL) { |
71 | for (i = 0, name = *namp; i < *lenp; i++, name++) { | 72 | for (i = 0, name = *namp; i < *lenp; i++, name++) { |
@@ -78,10 +79,10 @@ decode_filename(__be32 *p, char **namp, int *lenp) | |||
78 | } | 79 | } |
79 | 80 | ||
80 | static __be32 * | 81 | static __be32 * |
81 | decode_pathname(__be32 *p, char **namp, int *lenp) | 82 | decode_pathname(__be32 *p, char **namp, unsigned int *lenp) |
82 | { | 83 | { |
83 | char *name; | 84 | char *name; |
84 | int i; | 85 | unsigned int i; |
85 | 86 | ||
86 | if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXPATHLEN)) != NULL) { | 87 | if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXPATHLEN)) != NULL) { |
87 | for (i = 0, name = *namp; i < *lenp; i++, name++) { | 88 | for (i = 0, name = *namp; i < *lenp; i++, name++) { |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index d0199189924c..cc75e4fcd02b 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -132,7 +132,7 @@ out: | |||
132 | 132 | ||
133 | __be32 | 133 | __be32 |
134 | nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | 134 | nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, |
135 | const char *name, int len, | 135 | const char *name, unsigned int len, |
136 | struct svc_export **exp_ret, struct dentry **dentry_ret) | 136 | struct svc_export **exp_ret, struct dentry **dentry_ret) |
137 | { | 137 | { |
138 | struct svc_export *exp; | 138 | struct svc_export *exp; |
@@ -226,7 +226,7 @@ out_nfserr: | |||
226 | */ | 226 | */ |
227 | __be32 | 227 | __be32 |
228 | nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, | 228 | nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, |
229 | int len, struct svc_fh *resfh) | 229 | unsigned int len, struct svc_fh *resfh) |
230 | { | 230 | { |
231 | struct svc_export *exp; | 231 | struct svc_export *exp; |
232 | struct dentry *dentry; | 232 | struct dentry *dentry; |
@@ -1151,6 +1151,26 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1151 | } | 1151 | } |
1152 | #endif /* CONFIG_NFSD_V3 */ | 1152 | #endif /* CONFIG_NFSD_V3 */ |
1153 | 1153 | ||
1154 | __be32 | ||
1155 | nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, | ||
1156 | struct iattr *iap) | ||
1157 | { | ||
1158 | /* | ||
1159 | * Mode has already been set earlier in create: | ||
1160 | */ | ||
1161 | iap->ia_valid &= ~ATTR_MODE; | ||
1162 | /* | ||
1163 | * Setting uid/gid works only for root. Irix appears to | ||
1164 | * send along the gid on create when it tries to implement | ||
1165 | * setgid directories via NFS: | ||
1166 | */ | ||
1167 | if (current->fsuid != 0) | ||
1168 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); | ||
1169 | if (iap->ia_valid) | ||
1170 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | ||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1154 | /* | 1174 | /* |
1155 | * Create a file (regular, directory, device, fifo); UNIX sockets | 1175 | * Create a file (regular, directory, device, fifo); UNIX sockets |
1156 | * not yet implemented. | 1176 | * not yet implemented. |
@@ -1167,6 +1187,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1167 | struct dentry *dentry, *dchild = NULL; | 1187 | struct dentry *dentry, *dchild = NULL; |
1168 | struct inode *dirp; | 1188 | struct inode *dirp; |
1169 | __be32 err; | 1189 | __be32 err; |
1190 | __be32 err2; | ||
1170 | int host_err; | 1191 | int host_err; |
1171 | 1192 | ||
1172 | err = nfserr_perm; | 1193 | err = nfserr_perm; |
@@ -1257,16 +1278,9 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1257 | } | 1278 | } |
1258 | 1279 | ||
1259 | 1280 | ||
1260 | /* Set file attributes. Mode has already been set and | 1281 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); |
1261 | * setting uid/gid works only for root. Irix appears to | 1282 | if (err2) |
1262 | * send along the gid when it tries to implement setgid | 1283 | err = err2; |
1263 | * directories via NFS. | ||
1264 | */ | ||
1265 | if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { | ||
1266 | __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | ||
1267 | if (err2) | ||
1268 | err = err2; | ||
1269 | } | ||
1270 | /* | 1284 | /* |
1271 | * Update the file handle to get the new inode info. | 1285 | * Update the file handle to get the new inode info. |
1272 | */ | 1286 | */ |
@@ -1295,6 +1309,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1295 | struct dentry *dentry, *dchild = NULL; | 1309 | struct dentry *dentry, *dchild = NULL; |
1296 | struct inode *dirp; | 1310 | struct inode *dirp; |
1297 | __be32 err; | 1311 | __be32 err; |
1312 | __be32 err2; | ||
1298 | int host_err; | 1313 | int host_err; |
1299 | __u32 v_mtime=0, v_atime=0; | 1314 | __u32 v_mtime=0, v_atime=0; |
1300 | 1315 | ||
@@ -1399,16 +1414,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1399 | iap->ia_atime.tv_nsec = 0; | 1414 | iap->ia_atime.tv_nsec = 0; |
1400 | } | 1415 | } |
1401 | 1416 | ||
1402 | /* Set file attributes. | ||
1403 | * Irix appears to send along the gid when it tries to | ||
1404 | * implement setgid directories via NFS. Clear out all that cruft. | ||
1405 | */ | ||
1406 | set_attr: | 1417 | set_attr: |
1407 | if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { | 1418 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); |
1408 | __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | 1419 | if (err2) |
1409 | if (err2) | 1420 | err = err2; |
1410 | err = err2; | ||
1411 | } | ||
1412 | 1421 | ||
1413 | /* | 1422 | /* |
1414 | * Update the filehandle to get the new inode info. | 1423 | * Update the filehandle to get the new inode info. |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 9512f0456ad1..b729e64d0d4c 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -335,6 +335,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state); | |||
335 | 335 | ||
336 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void); | 336 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void); |
337 | 337 | ||
338 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); | ||
339 | |||
338 | acpi_status acpi_leave_sleep_state(u8 sleep_state); | 340 | acpi_status acpi_leave_sleep_state(u8 sleep_state); |
339 | 341 | ||
340 | #endif /* __ACXFACE_H__ */ | 342 | #endif /* __ACXFACE_H__ */ |
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h index 55b07bd5316c..dc189f01c5b3 100644 --- a/include/asm-arm/arch-at91/board.h +++ b/include/asm-arm/arch-at91/board.h | |||
@@ -40,7 +40,8 @@ | |||
40 | /* USB Device */ | 40 | /* USB Device */ |
41 | struct at91_udc_data { | 41 | struct at91_udc_data { |
42 | u8 vbus_pin; /* high == host powering us */ | 42 | u8 vbus_pin; /* high == host powering us */ |
43 | u8 pullup_pin; /* high == D+ pulled up */ | 43 | u8 pullup_pin; /* active == D+ pulled up */ |
44 | u8 pullup_active_low; /* true == pullup_pin is active low */ | ||
44 | }; | 45 | }; |
45 | extern void __init at91_add_device_udc(struct at91_udc_data *data); | 46 | extern void __init at91_add_device_udc(struct at91_udc_data *data); |
46 | 47 | ||
diff --git a/include/asm-arm/mach/udc_pxa2xx.h b/include/asm-arm/mach/udc_pxa2xx.h index ff0a95715a07..f191e147ea90 100644 --- a/include/asm-arm/mach/udc_pxa2xx.h +++ b/include/asm-arm/mach/udc_pxa2xx.h | |||
@@ -19,7 +19,9 @@ struct pxa2xx_udc_mach_info { | |||
19 | * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane | 19 | * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane |
20 | * VBUS IRQ and omit the methods above. Store the GPIO number | 20 | * VBUS IRQ and omit the methods above. Store the GPIO number |
21 | * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits. | 21 | * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits. |
22 | * Note that sometimes the signals go through inverters... | ||
22 | */ | 23 | */ |
24 | bool gpio_vbus_inverted; | ||
23 | u16 gpio_vbus; /* high == vbus present */ | 25 | u16 gpio_vbus; /* high == vbus present */ |
24 | u16 gpio_pullup; /* high == pullup activated */ | 26 | u16 gpio_pullup; /* high == pullup activated */ |
25 | }; | 27 | }; |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 85b2482cc736..c0f9bb78727d 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -143,6 +143,7 @@ header-y += snmp.h | |||
143 | header-y += sockios.h | 143 | header-y += sockios.h |
144 | header-y += som.h | 144 | header-y += som.h |
145 | header-y += sound.h | 145 | header-y += sound.h |
146 | header-y += suspend_ioctls.h | ||
146 | header-y += taskstats.h | 147 | header-y += taskstats.h |
147 | header-y += telephony.h | 148 | header-y += telephony.h |
148 | header-y += termios.h | 149 | header-y += termios.h |
diff --git a/include/linux/aspm.h b/include/linux/aspm.h new file mode 100644 index 000000000000..f41a69895485 --- /dev/null +++ b/include/linux/aspm.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * aspm.h | ||
3 | * | ||
4 | * PCI Express ASPM defines and function prototypes | ||
5 | * | ||
6 | * Copyright (C) 2007 Intel Corp. | ||
7 | * Zhang Yanmin (yanmin.zhang@intel.com) | ||
8 | * Shaohua Li (shaohua.li@intel.com) | ||
9 | * | ||
10 | * For more information, please consult the following manuals (look at | ||
11 | * http://www.pcisig.com/ for how to get them): | ||
12 | * | ||
13 | * PCI Express Specification | ||
14 | */ | ||
15 | |||
16 | #ifndef LINUX_ASPM_H | ||
17 | #define LINUX_ASPM_H | ||
18 | |||
19 | #include <linux/pci.h> | ||
20 | |||
21 | #define PCIE_LINK_STATE_L0S 1 | ||
22 | #define PCIE_LINK_STATE_L1 2 | ||
23 | #define PCIE_LINK_STATE_CLKPM 4 | ||
24 | |||
25 | #ifdef CONFIG_PCIEASPM | ||
26 | extern void pcie_aspm_init_link_state(struct pci_dev *pdev); | ||
27 | extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); | ||
28 | extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); | ||
29 | extern void pci_disable_link_state(struct pci_dev *pdev, int state); | ||
30 | #else | ||
31 | #define pcie_aspm_init_link_state(pdev) do {} while (0) | ||
32 | #define pcie_aspm_exit_link_state(pdev) do {} while (0) | ||
33 | #define pcie_aspm_pm_state_change(pdev) do {} while (0) | ||
34 | #define pci_disable_link_state(pdev, state) do {} while (0) | ||
35 | #endif | ||
36 | |||
37 | #ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */ | ||
38 | extern void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); | ||
39 | extern void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); | ||
40 | #else | ||
41 | #define pcie_aspm_create_sysfs_dev_files(pdev) do {} while (0) | ||
42 | #define pcie_aspm_remove_sysfs_dev_files(pdev) do {} while (0) | ||
43 | #endif | ||
44 | #endif /* LINUX_ASPM_H */ | ||
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index e2d1ce36b367..4babb2a129ac 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
@@ -173,14 +173,17 @@ void nlmclnt_next_cookie(struct nlm_cookie *); | |||
173 | /* | 173 | /* |
174 | * Host cache | 174 | * Host cache |
175 | */ | 175 | */ |
176 | struct nlm_host * nlmclnt_lookup_host(const struct sockaddr_in *, int, int, const char *, int); | 176 | struct nlm_host *nlmclnt_lookup_host(const struct sockaddr_in *, int, int, |
177 | struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *, const char *, int); | 177 | const char *, unsigned int); |
178 | struct nlm_host *nlmsvc_lookup_host(struct svc_rqst *, const char *, | ||
179 | unsigned int); | ||
178 | struct rpc_clnt * nlm_bind_host(struct nlm_host *); | 180 | struct rpc_clnt * nlm_bind_host(struct nlm_host *); |
179 | void nlm_rebind_host(struct nlm_host *); | 181 | void nlm_rebind_host(struct nlm_host *); |
180 | struct nlm_host * nlm_get_host(struct nlm_host *); | 182 | struct nlm_host * nlm_get_host(struct nlm_host *); |
181 | void nlm_release_host(struct nlm_host *); | 183 | void nlm_release_host(struct nlm_host *); |
182 | void nlm_shutdown_hosts(void); | 184 | void nlm_shutdown_hosts(void); |
183 | extern void nlm_host_rebooted(const struct sockaddr_in *, const char *, int, u32); | 185 | extern void nlm_host_rebooted(const struct sockaddr_in *, const char *, |
186 | unsigned int, u32); | ||
184 | void nsm_release(struct nsm_handle *); | 187 | void nsm_release(struct nsm_handle *); |
185 | 188 | ||
186 | 189 | ||
diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h index 83a1f9f6237b..df18fa053bcd 100644 --- a/include/linux/lockd/xdr.h +++ b/include/linux/lockd/xdr.h | |||
@@ -29,7 +29,7 @@ struct svc_rqst; | |||
29 | /* Lock info passed via NLM */ | 29 | /* Lock info passed via NLM */ |
30 | struct nlm_lock { | 30 | struct nlm_lock { |
31 | char * caller; | 31 | char * caller; |
32 | int len; /* length of "caller" */ | 32 | unsigned int len; /* length of "caller" */ |
33 | struct nfs_fh fh; | 33 | struct nfs_fh fh; |
34 | struct xdr_netobj oh; | 34 | struct xdr_netobj oh; |
35 | u32 svid; | 35 | u32 svid; |
@@ -78,7 +78,7 @@ struct nlm_res { | |||
78 | */ | 78 | */ |
79 | struct nlm_reboot { | 79 | struct nlm_reboot { |
80 | char * mon; | 80 | char * mon; |
81 | int len; | 81 | unsigned int len; |
82 | u32 state; | 82 | u32 state; |
83 | __be32 addr; | 83 | __be32 addr; |
84 | __be32 vers; | 84 | __be32 vers; |
diff --git a/include/linux/nfsd/Kbuild b/include/linux/nfsd/Kbuild index d9c5455808e5..e726fc3a4375 100644 --- a/include/linux/nfsd/Kbuild +++ b/include/linux/nfsd/Kbuild | |||
@@ -4,4 +4,3 @@ unifdef-y += stats.h | |||
4 | unifdef-y += syscall.h | 4 | unifdef-y += syscall.h |
5 | unifdef-y += nfsfh.h | 5 | unifdef-y += nfsfh.h |
6 | unifdef-y += debug.h | 6 | unifdef-y += debug.h |
7 | unifdef-y += auth.h | ||
diff --git a/include/linux/nfsd/cache.h b/include/linux/nfsd/cache.h index 007480cd6a60..7b5d784cc858 100644 --- a/include/linux/nfsd/cache.h +++ b/include/linux/nfsd/cache.h | |||
@@ -72,8 +72,8 @@ enum { | |||
72 | */ | 72 | */ |
73 | #define RC_DELAY (HZ/5) | 73 | #define RC_DELAY (HZ/5) |
74 | 74 | ||
75 | void nfsd_cache_init(void); | 75 | int nfsd_reply_cache_init(void); |
76 | void nfsd_cache_shutdown(void); | 76 | void nfsd_reply_cache_shutdown(void); |
77 | int nfsd_cache_lookup(struct svc_rqst *, int); | 77 | int nfsd_cache_lookup(struct svc_rqst *, int); |
78 | void nfsd_cache_update(struct svc_rqst *, int, __be32 *); | 78 | void nfsd_cache_update(struct svc_rqst *, int, __be32 *); |
79 | 79 | ||
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index bcb7abafbca9..3a1687251367 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h | |||
@@ -122,7 +122,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp); | |||
122 | /* | 122 | /* |
123 | * Function declarations | 123 | * Function declarations |
124 | */ | 124 | */ |
125 | void nfsd_export_init(void); | 125 | int nfsd_export_init(void); |
126 | void nfsd_export_shutdown(void); | 126 | void nfsd_export_shutdown(void); |
127 | void nfsd_export_flush(void); | 127 | void nfsd_export_flush(void); |
128 | void exp_readlock(void); | 128 | void exp_readlock(void); |
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 604a0d786bc6..8caf4c4f64e6 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/nfsd/debug.h> | 20 | #include <linux/nfsd/debug.h> |
21 | #include <linux/nfsd/nfsfh.h> | 21 | #include <linux/nfsd/nfsfh.h> |
22 | #include <linux/nfsd/export.h> | 22 | #include <linux/nfsd/export.h> |
23 | #include <linux/nfsd/auth.h> | ||
24 | #include <linux/nfsd/stats.h> | 23 | #include <linux/nfsd/stats.h> |
25 | /* | 24 | /* |
26 | * nfsd version | 25 | * nfsd version |
@@ -70,9 +69,9 @@ void nfsd_racache_shutdown(void); | |||
70 | int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, | 69 | int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, |
71 | struct svc_export **expp); | 70 | struct svc_export **expp); |
72 | __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, | 71 | __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, |
73 | const char *, int, struct svc_fh *); | 72 | const char *, unsigned int, struct svc_fh *); |
74 | __be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, | 73 | __be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, |
75 | const char *, int, | 74 | const char *, unsigned int, |
76 | struct svc_export **, struct dentry **); | 75 | struct svc_export **, struct dentry **); |
77 | __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, | 76 | __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, |
78 | struct iattr *, int, time_t); | 77 | struct iattr *, int, time_t); |
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h index 8bcddccb6c42..4e439765b705 100644 --- a/include/linux/nfsd/syscall.h +++ b/include/linux/nfsd/syscall.h | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/nfsd/const.h> | 18 | #include <linux/nfsd/const.h> |
19 | #include <linux/nfsd/export.h> | 19 | #include <linux/nfsd/export.h> |
20 | #include <linux/nfsd/nfsfh.h> | 20 | #include <linux/nfsd/nfsfh.h> |
21 | #include <linux/nfsd/auth.h> | ||
22 | 21 | ||
23 | /* | 22 | /* |
24 | * Version of the syscall interface | 23 | * Version of the syscall interface |
diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h index 67885d5e6e50..a0132ef58f21 100644 --- a/include/linux/nfsd/xdr.h +++ b/include/linux/nfsd/xdr.h | |||
@@ -23,7 +23,7 @@ struct nfsd_sattrargs { | |||
23 | struct nfsd_diropargs { | 23 | struct nfsd_diropargs { |
24 | struct svc_fh fh; | 24 | struct svc_fh fh; |
25 | char * name; | 25 | char * name; |
26 | int len; | 26 | unsigned int len; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | struct nfsd_readargs { | 29 | struct nfsd_readargs { |
@@ -43,17 +43,17 @@ struct nfsd_writeargs { | |||
43 | struct nfsd_createargs { | 43 | struct nfsd_createargs { |
44 | struct svc_fh fh; | 44 | struct svc_fh fh; |
45 | char * name; | 45 | char * name; |
46 | int len; | 46 | unsigned int len; |
47 | struct iattr attrs; | 47 | struct iattr attrs; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | struct nfsd_renameargs { | 50 | struct nfsd_renameargs { |
51 | struct svc_fh ffh; | 51 | struct svc_fh ffh; |
52 | char * fname; | 52 | char * fname; |
53 | int flen; | 53 | unsigned int flen; |
54 | struct svc_fh tfh; | 54 | struct svc_fh tfh; |
55 | char * tname; | 55 | char * tname; |
56 | int tlen; | 56 | unsigned int tlen; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | struct nfsd_readlinkargs { | 59 | struct nfsd_readlinkargs { |
@@ -65,15 +65,15 @@ struct nfsd_linkargs { | |||
65 | struct svc_fh ffh; | 65 | struct svc_fh ffh; |
66 | struct svc_fh tfh; | 66 | struct svc_fh tfh; |
67 | char * tname; | 67 | char * tname; |
68 | int tlen; | 68 | unsigned int tlen; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | struct nfsd_symlinkargs { | 71 | struct nfsd_symlinkargs { |
72 | struct svc_fh ffh; | 72 | struct svc_fh ffh; |
73 | char * fname; | 73 | char * fname; |
74 | int flen; | 74 | unsigned int flen; |
75 | char * tname; | 75 | char * tname; |
76 | int tlen; | 76 | unsigned int tlen; |
77 | struct iattr attrs; | 77 | struct iattr attrs; |
78 | }; | 78 | }; |
79 | 79 | ||
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h index 89d9d6061a62..421eddd65a25 100644 --- a/include/linux/nfsd/xdr3.h +++ b/include/linux/nfsd/xdr3.h | |||
@@ -21,7 +21,7 @@ struct nfsd3_sattrargs { | |||
21 | struct nfsd3_diropargs { | 21 | struct nfsd3_diropargs { |
22 | struct svc_fh fh; | 22 | struct svc_fh fh; |
23 | char * name; | 23 | char * name; |
24 | int len; | 24 | unsigned int len; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | struct nfsd3_accessargs { | 27 | struct nfsd3_accessargs { |
@@ -48,7 +48,7 @@ struct nfsd3_writeargs { | |||
48 | struct nfsd3_createargs { | 48 | struct nfsd3_createargs { |
49 | struct svc_fh fh; | 49 | struct svc_fh fh; |
50 | char * name; | 50 | char * name; |
51 | int len; | 51 | unsigned int len; |
52 | int createmode; | 52 | int createmode; |
53 | struct iattr attrs; | 53 | struct iattr attrs; |
54 | __be32 * verf; | 54 | __be32 * verf; |
@@ -57,7 +57,7 @@ struct nfsd3_createargs { | |||
57 | struct nfsd3_mknodargs { | 57 | struct nfsd3_mknodargs { |
58 | struct svc_fh fh; | 58 | struct svc_fh fh; |
59 | char * name; | 59 | char * name; |
60 | int len; | 60 | unsigned int len; |
61 | __u32 ftype; | 61 | __u32 ftype; |
62 | __u32 major, minor; | 62 | __u32 major, minor; |
63 | struct iattr attrs; | 63 | struct iattr attrs; |
@@ -66,10 +66,10 @@ struct nfsd3_mknodargs { | |||
66 | struct nfsd3_renameargs { | 66 | struct nfsd3_renameargs { |
67 | struct svc_fh ffh; | 67 | struct svc_fh ffh; |
68 | char * fname; | 68 | char * fname; |
69 | int flen; | 69 | unsigned int flen; |
70 | struct svc_fh tfh; | 70 | struct svc_fh tfh; |
71 | char * tname; | 71 | char * tname; |
72 | int tlen; | 72 | unsigned int tlen; |
73 | }; | 73 | }; |
74 | 74 | ||
75 | struct nfsd3_readlinkargs { | 75 | struct nfsd3_readlinkargs { |
@@ -81,15 +81,15 @@ struct nfsd3_linkargs { | |||
81 | struct svc_fh ffh; | 81 | struct svc_fh ffh; |
82 | struct svc_fh tfh; | 82 | struct svc_fh tfh; |
83 | char * tname; | 83 | char * tname; |
84 | int tlen; | 84 | unsigned int tlen; |
85 | }; | 85 | }; |
86 | 86 | ||
87 | struct nfsd3_symlinkargs { | 87 | struct nfsd3_symlinkargs { |
88 | struct svc_fh ffh; | 88 | struct svc_fh ffh; |
89 | char * fname; | 89 | char * fname; |
90 | int flen; | 90 | unsigned int flen; |
91 | char * tname; | 91 | char * tname; |
92 | int tlen; | 92 | unsigned int tlen; |
93 | struct iattr attrs; | 93 | struct iattr attrs; |
94 | }; | 94 | }; |
95 | 95 | ||
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index b0ddfb41c790..27bd3e38ec5a 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h | |||
@@ -441,7 +441,7 @@ void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); | |||
441 | void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); | 441 | void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); |
442 | __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | 442 | __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, |
443 | struct dentry *dentry, __be32 *buffer, int *countp, | 443 | struct dentry *dentry, __be32 *buffer, int *countp, |
444 | u32 *bmval, struct svc_rqst *); | 444 | u32 *bmval, struct svc_rqst *, int ignore_crossmnt); |
445 | extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, | 445 | extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, |
446 | struct nfsd4_compound_state *, | 446 | struct nfsd4_compound_state *, |
447 | struct nfsd4_setclientid *setclid); | 447 | struct nfsd4_setclientid *setclid); |
diff --git a/include/linux/nfsd_idmap.h b/include/linux/nfsd_idmap.h index e82746fcad14..d4a2ac18bd4c 100644 --- a/include/linux/nfsd_idmap.h +++ b/include/linux/nfsd_idmap.h | |||
@@ -44,11 +44,16 @@ | |||
44 | #define IDMAP_NAMESZ 128 | 44 | #define IDMAP_NAMESZ 128 |
45 | 45 | ||
46 | #ifdef CONFIG_NFSD_V4 | 46 | #ifdef CONFIG_NFSD_V4 |
47 | void nfsd_idmap_init(void); | 47 | int nfsd_idmap_init(void); |
48 | void nfsd_idmap_shutdown(void); | 48 | void nfsd_idmap_shutdown(void); |
49 | #else | 49 | #else |
50 | static inline void nfsd_idmap_init(void) {}; | 50 | static inline int nfsd_idmap_init(void) |
51 | static inline void nfsd_idmap_shutdown(void) {}; | 51 | { |
52 | return 0; | ||
53 | } | ||
54 | static inline void nfsd_idmap_shutdown(void) | ||
55 | { | ||
56 | } | ||
52 | #endif | 57 | #endif |
53 | 58 | ||
54 | int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); | 59 | int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 5dfbc684ce7d..f4df40038f0c 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
@@ -228,6 +228,8 @@ static inline int notifier_to_errno(int ret) | |||
228 | #define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */ | 228 | #define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */ |
229 | #define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */ | 229 | #define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */ |
230 | #define PM_POST_SUSPEND 0x0004 /* Suspend finished */ | 230 | #define PM_POST_SUSPEND 0x0004 /* Suspend finished */ |
231 | #define PM_RESTORE_PREPARE 0x0005 /* Going to restore a saved image */ | ||
232 | #define PM_POST_RESTORE 0x0006 /* Restore failed */ | ||
231 | 233 | ||
232 | /* Console keyboard events. | 234 | /* Console keyboard events. |
233 | * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and | 235 | * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and |
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 936ef82ed76a..3ba25065fa96 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h | |||
@@ -48,7 +48,15 @@ | |||
48 | 48 | ||
49 | #ifdef CONFIG_ACPI | 49 | #ifdef CONFIG_ACPI |
50 | extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags); | 50 | extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags); |
51 | extern acpi_status pci_osc_support_set(u32 flags); | 51 | extern acpi_status __pci_osc_support_set(u32 flags, const char *hid); |
52 | static inline acpi_status pci_osc_support_set(u32 flags) | ||
53 | { | ||
54 | return __pci_osc_support_set(flags, PCI_ROOT_HID_STRING); | ||
55 | } | ||
56 | static inline acpi_status pcie_osc_support_set(u32 flags) | ||
57 | { | ||
58 | return __pci_osc_support_set(flags, PCI_EXPRESS_ROOT_HID_STRING); | ||
59 | } | ||
52 | #else | 60 | #else |
53 | #if !defined(AE_ERROR) | 61 | #if !defined(AE_ERROR) |
54 | typedef u32 acpi_status; | 62 | typedef u32 acpi_status; |
@@ -57,6 +65,7 @@ typedef u32 acpi_status; | |||
57 | static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) | 65 | static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) |
58 | {return AE_ERROR;} | 66 | {return AE_ERROR;} |
59 | static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;} | 67 | static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;} |
68 | static inline acpi_status pcie_osc_support_set(u32 flags) {return AE_ERROR;} | ||
60 | #endif | 69 | #endif |
61 | 70 | ||
62 | #endif /* _PCI_ACPI_H_ */ | 71 | #endif /* _PCI_ACPI_H_ */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index ae1006322f80..4f96f1d94ac4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -28,7 +28,7 @@ | |||
28 | * 7:3 = slot | 28 | * 7:3 = slot |
29 | * 2:0 = function | 29 | * 2:0 = function |
30 | */ | 30 | */ |
31 | #define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) | 31 | #define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) |
32 | #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) | 32 | #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) |
33 | #define PCI_FUNC(devfn) ((devfn) & 0x07) | 33 | #define PCI_FUNC(devfn) ((devfn) & 0x07) |
34 | 34 | ||
@@ -66,7 +66,6 @@ enum pci_mmap_state { | |||
66 | #define PCI_DMA_FROMDEVICE 2 | 66 | #define PCI_DMA_FROMDEVICE 2 |
67 | #define PCI_DMA_NONE 3 | 67 | #define PCI_DMA_NONE 3 |
68 | 68 | ||
69 | #define DEVICE_COUNT_COMPATIBLE 4 | ||
70 | #define DEVICE_COUNT_RESOURCE 12 | 69 | #define DEVICE_COUNT_RESOURCE 12 |
71 | 70 | ||
72 | typedef int __bitwise pci_power_t; | 71 | typedef int __bitwise pci_power_t; |
@@ -129,6 +128,7 @@ struct pci_cap_saved_state { | |||
129 | u32 data[0]; | 128 | u32 data[0]; |
130 | }; | 129 | }; |
131 | 130 | ||
131 | struct pcie_link_state; | ||
132 | /* | 132 | /* |
133 | * The pci_dev structure is used to describe PCI devices. | 133 | * The pci_dev structure is used to describe PCI devices. |
134 | */ | 134 | */ |
@@ -164,13 +164,13 @@ struct pci_dev { | |||
164 | this is D0-D3, D0 being fully functional, | 164 | this is D0-D3, D0 being fully functional, |
165 | and D3 being off. */ | 165 | and D3 being off. */ |
166 | 166 | ||
167 | #ifdef CONFIG_PCIEASPM | ||
168 | struct pcie_link_state *link_state; /* ASPM link state. */ | ||
169 | #endif | ||
170 | |||
167 | pci_channel_state_t error_state; /* current connectivity state */ | 171 | pci_channel_state_t error_state; /* current connectivity state */ |
168 | struct device dev; /* Generic device interface */ | 172 | struct device dev; /* Generic device interface */ |
169 | 173 | ||
170 | /* device is compatible with these IDs */ | ||
171 | unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE]; | ||
172 | unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE]; | ||
173 | |||
174 | int cfg_size; /* Size of configuration space */ | 174 | int cfg_size; /* Size of configuration space */ |
175 | 175 | ||
176 | /* | 176 | /* |
@@ -219,7 +219,7 @@ static inline int pci_channel_offline(struct pci_dev *pdev) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | static inline struct pci_cap_saved_state *pci_find_saved_cap( | 221 | static inline struct pci_cap_saved_state *pci_find_saved_cap( |
222 | struct pci_dev *pci_dev,char cap) | 222 | struct pci_dev *pci_dev, char cap) |
223 | { | 223 | { |
224 | struct pci_cap_saved_state *tmp; | 224 | struct pci_cap_saved_state *tmp; |
225 | struct hlist_node *pos; | 225 | struct hlist_node *pos; |
@@ -278,13 +278,13 @@ struct pci_bus { | |||
278 | unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ | 278 | unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ |
279 | pci_bus_flags_t bus_flags; /* Inherited by child busses */ | 279 | pci_bus_flags_t bus_flags; /* Inherited by child busses */ |
280 | struct device *bridge; | 280 | struct device *bridge; |
281 | struct class_device class_dev; | 281 | struct device dev; |
282 | struct bin_attribute *legacy_io; /* legacy I/O for this bus */ | 282 | struct bin_attribute *legacy_io; /* legacy I/O for this bus */ |
283 | struct bin_attribute *legacy_mem; /* legacy mem */ | 283 | struct bin_attribute *legacy_mem; /* legacy mem */ |
284 | }; | 284 | }; |
285 | 285 | ||
286 | #define pci_bus_b(n) list_entry(n, struct pci_bus, node) | 286 | #define pci_bus_b(n) list_entry(n, struct pci_bus, node) |
287 | #define to_pci_bus(n) container_of(n, struct pci_bus, class_dev) | 287 | #define to_pci_bus(n) container_of(n, struct pci_bus, dev) |
288 | 288 | ||
289 | /* | 289 | /* |
290 | * Error values that may be returned by PCI functions. | 290 | * Error values that may be returned by PCI functions. |
@@ -314,8 +314,8 @@ struct pci_raw_ops { | |||
314 | extern struct pci_raw_ops *raw_pci_ops; | 314 | extern struct pci_raw_ops *raw_pci_ops; |
315 | 315 | ||
316 | struct pci_bus_region { | 316 | struct pci_bus_region { |
317 | unsigned long start; | 317 | resource_size_t start; |
318 | unsigned long end; | 318 | resource_size_t end; |
319 | }; | 319 | }; |
320 | 320 | ||
321 | struct pci_dynids { | 321 | struct pci_dynids { |
@@ -351,11 +351,10 @@ enum pci_ers_result { | |||
351 | }; | 351 | }; |
352 | 352 | ||
353 | /* PCI bus error event callbacks */ | 353 | /* PCI bus error event callbacks */ |
354 | struct pci_error_handlers | 354 | struct pci_error_handlers { |
355 | { | ||
356 | /* PCI bus error detected on this device */ | 355 | /* PCI bus error detected on this device */ |
357 | pci_ers_result_t (*error_detected)(struct pci_dev *dev, | 356 | pci_ers_result_t (*error_detected)(struct pci_dev *dev, |
358 | enum pci_channel_state error); | 357 | enum pci_channel_state error); |
359 | 358 | ||
360 | /* MMIO has been re-enabled, but not DMA */ | 359 | /* MMIO has been re-enabled, but not DMA */ |
361 | pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev); | 360 | pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev); |
@@ -390,7 +389,7 @@ struct pci_driver { | |||
390 | struct pci_dynids dynids; | 389 | struct pci_dynids dynids; |
391 | }; | 390 | }; |
392 | 391 | ||
393 | #define to_pci_driver(drv) container_of(drv,struct pci_driver, driver) | 392 | #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) |
394 | 393 | ||
395 | /** | 394 | /** |
396 | * PCI_DEVICE - macro used to describe a specific pci device | 395 | * PCI_DEVICE - macro used to describe a specific pci device |
@@ -448,7 +447,7 @@ extern int no_pci_devices(void); | |||
448 | 447 | ||
449 | void pcibios_fixup_bus(struct pci_bus *); | 448 | void pcibios_fixup_bus(struct pci_bus *); |
450 | int __must_check pcibios_enable_device(struct pci_dev *, int mask); | 449 | int __must_check pcibios_enable_device(struct pci_dev *, int mask); |
451 | char *pcibios_setup (char *str); | 450 | char *pcibios_setup(char *str); |
452 | 451 | ||
453 | /* Used only when drivers/pci/setup.c is used */ | 452 | /* Used only when drivers/pci/setup.c is used */ |
454 | void pcibios_align_resource(void *, struct resource *, resource_size_t, | 453 | void pcibios_align_resource(void *, struct resource *, resource_size_t, |
@@ -459,8 +458,10 @@ void pcibios_update_irq(struct pci_dev *, int irq); | |||
459 | 458 | ||
460 | extern struct pci_bus *pci_find_bus(int domain, int busnr); | 459 | extern struct pci_bus *pci_find_bus(int domain, int busnr); |
461 | void pci_bus_add_devices(struct pci_bus *bus); | 460 | void pci_bus_add_devices(struct pci_bus *bus); |
462 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); | 461 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, |
463 | static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) | 462 | struct pci_ops *ops, void *sysdata); |
463 | static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, | ||
464 | void *sysdata) | ||
464 | { | 465 | { |
465 | struct pci_bus *root_bus; | 466 | struct pci_bus *root_bus; |
466 | root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); | 467 | root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); |
@@ -468,15 +469,18 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s | |||
468 | pci_bus_add_devices(root_bus); | 469 | pci_bus_add_devices(root_bus); |
469 | return root_bus; | 470 | return root_bus; |
470 | } | 471 | } |
471 | struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); | 472 | struct pci_bus *pci_create_bus(struct device *parent, int bus, |
472 | struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); | 473 | struct pci_ops *ops, void *sysdata); |
474 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, | ||
475 | int busnr); | ||
473 | int pci_scan_slot(struct pci_bus *bus, int devfn); | 476 | int pci_scan_slot(struct pci_bus *bus, int devfn); |
474 | struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); | 477 | struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn); |
475 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); | 478 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); |
476 | unsigned int pci_scan_child_bus(struct pci_bus *bus); | 479 | unsigned int pci_scan_child_bus(struct pci_bus *bus); |
477 | int __must_check pci_bus_add_device(struct pci_dev *dev); | 480 | int __must_check pci_bus_add_device(struct pci_dev *dev); |
478 | void pci_read_bridge_bases(struct pci_bus *child); | 481 | void pci_read_bridge_bases(struct pci_bus *child); |
479 | struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res); | 482 | struct resource *pci_find_parent_resource(const struct pci_dev *dev, |
483 | struct resource *res); | ||
480 | int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); | 484 | int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); |
481 | extern struct pci_dev *pci_dev_get(struct pci_dev *dev); | 485 | extern struct pci_dev *pci_dev_get(struct pci_dev *dev); |
482 | extern void pci_dev_put(struct pci_dev *dev); | 486 | extern void pci_dev_put(struct pci_dev *dev); |
@@ -489,15 +493,19 @@ extern void pci_sort_breadthfirst(void); | |||
489 | /* Generic PCI functions exported to card drivers */ | 493 | /* Generic PCI functions exported to card drivers */ |
490 | 494 | ||
491 | #ifdef CONFIG_PCI_LEGACY | 495 | #ifdef CONFIG_PCI_LEGACY |
492 | struct pci_dev __deprecated *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); | 496 | struct pci_dev __deprecated *pci_find_device(unsigned int vendor, |
493 | struct pci_dev __deprecated *pci_find_slot (unsigned int bus, unsigned int devfn); | 497 | unsigned int device, |
498 | const struct pci_dev *from); | ||
499 | struct pci_dev __deprecated *pci_find_slot(unsigned int bus, | ||
500 | unsigned int devfn); | ||
494 | #endif /* CONFIG_PCI_LEGACY */ | 501 | #endif /* CONFIG_PCI_LEGACY */ |
495 | 502 | ||
496 | int pci_find_capability (struct pci_dev *dev, int cap); | 503 | int pci_find_capability(struct pci_dev *dev, int cap); |
497 | int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); | 504 | int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap); |
498 | int pci_find_ext_capability (struct pci_dev *dev, int cap); | 505 | int pci_find_ext_capability(struct pci_dev *dev, int cap); |
499 | int pci_find_ht_capability (struct pci_dev *dev, int ht_cap); | 506 | int pci_find_ht_capability(struct pci_dev *dev, int ht_cap); |
500 | int pci_find_next_ht_capability (struct pci_dev *dev, int pos, int ht_cap); | 507 | int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap); |
508 | void pcie_wait_pending_transaction(struct pci_dev *dev); | ||
501 | struct pci_bus *pci_find_next_bus(const struct pci_bus *from); | 509 | struct pci_bus *pci_find_next_bus(const struct pci_bus *from); |
502 | 510 | ||
503 | struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, | 511 | struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, |
@@ -505,49 +513,58 @@ struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, | |||
505 | struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device, | 513 | struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device, |
506 | struct pci_dev *from); | 514 | struct pci_dev *from); |
507 | 515 | ||
508 | struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, | 516 | struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, |
509 | unsigned int ss_vendor, unsigned int ss_device, | 517 | unsigned int ss_vendor, unsigned int ss_device, |
510 | struct pci_dev *from); | 518 | struct pci_dev *from); |
511 | struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); | 519 | struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn); |
512 | struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn); | 520 | struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn); |
513 | struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); | 521 | struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from); |
514 | int pci_dev_present(const struct pci_device_id *ids); | 522 | int pci_dev_present(const struct pci_device_id *ids); |
515 | const struct pci_device_id *pci_find_present(const struct pci_device_id *ids); | 523 | const struct pci_device_id *pci_find_present(const struct pci_device_id *ids); |
516 | 524 | ||
517 | int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val); | 525 | int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, |
518 | int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val); | 526 | int where, u8 *val); |
519 | int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val); | 527 | int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, |
520 | int pci_bus_write_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 val); | 528 | int where, u16 *val); |
521 | int pci_bus_write_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 val); | 529 | int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn, |
522 | int pci_bus_write_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 val); | 530 | int where, u32 *val); |
531 | int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, | ||
532 | int where, u8 val); | ||
533 | int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, | ||
534 | int where, u16 val); | ||
535 | int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, | ||
536 | int where, u32 val); | ||
523 | 537 | ||
524 | static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) | 538 | static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) |
525 | { | 539 | { |
526 | return pci_bus_read_config_byte (dev->bus, dev->devfn, where, val); | 540 | return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val); |
527 | } | 541 | } |
528 | static inline int pci_read_config_word(struct pci_dev *dev, int where, u16 *val) | 542 | static inline int pci_read_config_word(struct pci_dev *dev, int where, u16 *val) |
529 | { | 543 | { |
530 | return pci_bus_read_config_word (dev->bus, dev->devfn, where, val); | 544 | return pci_bus_read_config_word(dev->bus, dev->devfn, where, val); |
531 | } | 545 | } |
532 | static inline int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val) | 546 | static inline int pci_read_config_dword(struct pci_dev *dev, int where, |
547 | u32 *val) | ||
533 | { | 548 | { |
534 | return pci_bus_read_config_dword (dev->bus, dev->devfn, where, val); | 549 | return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val); |
535 | } | 550 | } |
536 | static inline int pci_write_config_byte(struct pci_dev *dev, int where, u8 val) | 551 | static inline int pci_write_config_byte(struct pci_dev *dev, int where, u8 val) |
537 | { | 552 | { |
538 | return pci_bus_write_config_byte (dev->bus, dev->devfn, where, val); | 553 | return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val); |
539 | } | 554 | } |
540 | static inline int pci_write_config_word(struct pci_dev *dev, int where, u16 val) | 555 | static inline int pci_write_config_word(struct pci_dev *dev, int where, u16 val) |
541 | { | 556 | { |
542 | return pci_bus_write_config_word (dev->bus, dev->devfn, where, val); | 557 | return pci_bus_write_config_word(dev->bus, dev->devfn, where, val); |
543 | } | 558 | } |
544 | static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val) | 559 | static inline int pci_write_config_dword(struct pci_dev *dev, int where, |
560 | u32 val) | ||
545 | { | 561 | { |
546 | return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val); | 562 | return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val); |
547 | } | 563 | } |
548 | 564 | ||
549 | int __must_check pci_enable_device(struct pci_dev *dev); | 565 | int __must_check pci_enable_device(struct pci_dev *dev); |
550 | int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); | 566 | int __must_check pci_enable_device_io(struct pci_dev *dev); |
567 | int __must_check pci_enable_device_mem(struct pci_dev *dev); | ||
551 | int __must_check pci_reenable_device(struct pci_dev *); | 568 | int __must_check pci_reenable_device(struct pci_dev *); |
552 | int __must_check pcim_enable_device(struct pci_dev *pdev); | 569 | int __must_check pcim_enable_device(struct pci_dev *pdev); |
553 | void pcim_pin_device(struct pci_dev *pdev); | 570 | void pcim_pin_device(struct pci_dev *pdev); |
@@ -576,14 +593,11 @@ int pcie_set_readrq(struct pci_dev *dev, int rq); | |||
576 | void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); | 593 | void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); |
577 | int __must_check pci_assign_resource(struct pci_dev *dev, int i); | 594 | int __must_check pci_assign_resource(struct pci_dev *dev, int i); |
578 | int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i); | 595 | int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i); |
579 | void pci_restore_bars(struct pci_dev *dev); | ||
580 | int pci_select_bars(struct pci_dev *dev, unsigned long flags); | 596 | int pci_select_bars(struct pci_dev *dev, unsigned long flags); |
581 | 597 | ||
582 | /* ROM control related routines */ | 598 | /* ROM control related routines */ |
583 | void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); | 599 | void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); |
584 | void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size); | ||
585 | void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); | 600 | void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); |
586 | void pci_remove_rom(struct pci_dev *pdev); | ||
587 | size_t pci_get_rom_size(void __iomem *rom, size_t size); | 601 | size_t pci_get_rom_size(void __iomem *rom, size_t size); |
588 | 602 | ||
589 | /* Power management related routines */ | 603 | /* Power management related routines */ |
@@ -594,7 +608,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); | |||
594 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); | 608 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); |
595 | 609 | ||
596 | /* Functions for PCI Hotplug drivers to use */ | 610 | /* Functions for PCI Hotplug drivers to use */ |
597 | int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); | 611 | int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); |
598 | 612 | ||
599 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ | 613 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ |
600 | void pci_bus_assign_resources(struct pci_bus *bus); | 614 | void pci_bus_assign_resources(struct pci_bus *bus); |
@@ -631,16 +645,18 @@ static inline int __must_check pci_register_driver(struct pci_driver *driver) | |||
631 | return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); | 645 | return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); |
632 | } | 646 | } |
633 | 647 | ||
634 | void pci_unregister_driver(struct pci_driver *); | 648 | void pci_unregister_driver(struct pci_driver *dev); |
635 | void pci_remove_behind_bridge(struct pci_dev *); | 649 | void pci_remove_behind_bridge(struct pci_dev *dev); |
636 | struct pci_driver *pci_dev_driver(const struct pci_dev *); | 650 | struct pci_driver *pci_dev_driver(const struct pci_dev *dev); |
637 | const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); | 651 | const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, |
638 | int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); | 652 | struct pci_dev *dev); |
653 | int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | ||
654 | int pass); | ||
639 | 655 | ||
640 | void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), | 656 | void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), |
641 | void *userdata); | 657 | void *userdata); |
642 | int pci_cfg_space_size(struct pci_dev *dev); | 658 | int pci_cfg_space_size(struct pci_dev *dev); |
643 | unsigned char pci_bus_max_busnr(struct pci_bus* bus); | 659 | unsigned char pci_bus_max_busnr(struct pci_bus *bus); |
644 | 660 | ||
645 | /* kmem_cache style wrapper around pci_alloc_consistent() */ | 661 | /* kmem_cache style wrapper around pci_alloc_consistent() */ |
646 | 662 | ||
@@ -669,19 +685,36 @@ struct msix_entry { | |||
669 | 685 | ||
670 | 686 | ||
671 | #ifndef CONFIG_PCI_MSI | 687 | #ifndef CONFIG_PCI_MSI |
672 | static inline int pci_enable_msi(struct pci_dev *dev) {return -1;} | 688 | static inline int pci_enable_msi(struct pci_dev *dev) |
673 | static inline void pci_disable_msi(struct pci_dev *dev) {} | 689 | { |
674 | static inline int pci_enable_msix(struct pci_dev* dev, | 690 | return -1; |
675 | struct msix_entry *entries, int nvec) {return -1;} | 691 | } |
676 | static inline void pci_disable_msix(struct pci_dev *dev) {} | 692 | |
677 | static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} | 693 | static inline void pci_disable_msi(struct pci_dev *dev) |
694 | { } | ||
695 | |||
696 | static inline int pci_enable_msix(struct pci_dev *dev, | ||
697 | struct msix_entry *entries, int nvec) | ||
698 | { | ||
699 | return -1; | ||
700 | } | ||
701 | |||
702 | static inline void pci_disable_msix(struct pci_dev *dev) | ||
703 | { } | ||
704 | |||
705 | static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) | ||
706 | { } | ||
707 | |||
708 | static inline void pci_restore_msi_state(struct pci_dev *dev) | ||
709 | { } | ||
678 | #else | 710 | #else |
679 | extern int pci_enable_msi(struct pci_dev *dev); | 711 | extern int pci_enable_msi(struct pci_dev *dev); |
680 | extern void pci_disable_msi(struct pci_dev *dev); | 712 | extern void pci_disable_msi(struct pci_dev *dev); |
681 | extern int pci_enable_msix(struct pci_dev* dev, | 713 | extern int pci_enable_msix(struct pci_dev *dev, |
682 | struct msix_entry *entries, int nvec); | 714 | struct msix_entry *entries, int nvec); |
683 | extern void pci_disable_msix(struct pci_dev *dev); | 715 | extern void pci_disable_msix(struct pci_dev *dev); |
684 | extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); | 716 | extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); |
717 | extern void pci_restore_msi_state(struct pci_dev *dev); | ||
685 | #endif | 718 | #endif |
686 | 719 | ||
687 | #ifdef CONFIG_HT_IRQ | 720 | #ifdef CONFIG_HT_IRQ |
@@ -702,7 +735,11 @@ extern void pci_unblock_user_cfg_access(struct pci_dev *dev); | |||
702 | extern int pci_domains_supported; | 735 | extern int pci_domains_supported; |
703 | #else | 736 | #else |
704 | enum { pci_domains_supported = 0 }; | 737 | enum { pci_domains_supported = 0 }; |
705 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } | 738 | static inline int pci_domain_nr(struct pci_bus *bus) |
739 | { | ||
740 | return 0; | ||
741 | } | ||
742 | |||
706 | static inline int pci_proc_domain(struct pci_bus *bus) | 743 | static inline int pci_proc_domain(struct pci_bus *bus) |
707 | { | 744 | { |
708 | return 0; | 745 | return 0; |
@@ -716,67 +753,161 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
716 | * these as simple inline functions to avoid hair in drivers. | 753 | * these as simple inline functions to avoid hair in drivers. |
717 | */ | 754 | */ |
718 | 755 | ||
719 | #define _PCI_NOP(o,s,t) \ | 756 | #define _PCI_NOP(o, s, t) \ |
720 | static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \ | 757 | static inline int pci_##o##_config_##s(struct pci_dev *dev, \ |
758 | int where, t val) \ | ||
721 | { return PCIBIOS_FUNC_NOT_SUPPORTED; } | 759 | { return PCIBIOS_FUNC_NOT_SUPPORTED; } |
722 | #define _PCI_NOP_ALL(o,x) _PCI_NOP(o,byte,u8 x) \ | 760 | |
723 | _PCI_NOP(o,word,u16 x) \ | 761 | #define _PCI_NOP_ALL(o, x) _PCI_NOP(o, byte, u8 x) \ |
724 | _PCI_NOP(o,dword,u32 x) | 762 | _PCI_NOP(o, word, u16 x) \ |
763 | _PCI_NOP(o, dword, u32 x) | ||
725 | _PCI_NOP_ALL(read, *) | 764 | _PCI_NOP_ALL(read, *) |
726 | _PCI_NOP_ALL(write,) | 765 | _PCI_NOP_ALL(write,) |
727 | 766 | ||
728 | static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from) | 767 | static inline struct pci_dev *pci_find_device(unsigned int vendor, |
729 | { return NULL; } | 768 | unsigned int device, |
769 | const struct pci_dev *from) | ||
770 | { | ||
771 | return NULL; | ||
772 | } | ||
730 | 773 | ||
731 | static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) | 774 | static inline struct pci_dev *pci_find_slot(unsigned int bus, |
732 | { return NULL; } | 775 | unsigned int devfn) |
776 | { | ||
777 | return NULL; | ||
778 | } | ||
733 | 779 | ||
734 | static inline struct pci_dev *pci_get_device(unsigned int vendor, | 780 | static inline struct pci_dev *pci_get_device(unsigned int vendor, |
735 | unsigned int device, struct pci_dev *from) | 781 | unsigned int device, |
736 | { return NULL; } | 782 | struct pci_dev *from) |
783 | { | ||
784 | return NULL; | ||
785 | } | ||
737 | 786 | ||
738 | static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor, | 787 | static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor, |
739 | unsigned int device, struct pci_dev *from) | 788 | unsigned int device, |
740 | { return NULL; } | 789 | struct pci_dev *from) |
790 | { | ||
791 | return NULL; | ||
792 | } | ||
741 | 793 | ||
742 | static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, | 794 | static inline struct pci_dev *pci_get_subsys(unsigned int vendor, |
743 | unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) | 795 | unsigned int device, |
744 | { return NULL; } | 796 | unsigned int ss_vendor, |
797 | unsigned int ss_device, | ||
798 | struct pci_dev *from) | ||
799 | { | ||
800 | return NULL; | ||
801 | } | ||
745 | 802 | ||
746 | static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) | 803 | static inline struct pci_dev *pci_get_class(unsigned int class, |
747 | { return NULL; } | 804 | struct pci_dev *from) |
805 | { | ||
806 | return NULL; | ||
807 | } | ||
748 | 808 | ||
749 | #define pci_dev_present(ids) (0) | 809 | #define pci_dev_present(ids) (0) |
750 | #define no_pci_devices() (1) | 810 | #define no_pci_devices() (1) |
751 | #define pci_find_present(ids) (NULL) | 811 | #define pci_find_present(ids) (NULL) |
752 | #define pci_dev_put(dev) do { } while (0) | 812 | #define pci_dev_put(dev) do { } while (0) |
753 | 813 | ||
754 | static inline void pci_set_master(struct pci_dev *dev) { } | 814 | static inline void pci_set_master(struct pci_dev *dev) |
755 | static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } | 815 | { } |
756 | static inline void pci_disable_device(struct pci_dev *dev) { } | 816 | |
757 | static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; } | 817 | static inline int pci_enable_device(struct pci_dev *dev) |
758 | static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;} | 818 | { |
759 | static inline int __pci_register_driver(struct pci_driver *drv, struct module *owner) { return 0;} | 819 | return -EIO; |
760 | static inline int pci_register_driver(struct pci_driver *drv) { return 0;} | 820 | } |
761 | static inline void pci_unregister_driver(struct pci_driver *drv) { } | 821 | |
762 | static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } | 822 | static inline void pci_disable_device(struct pci_dev *dev) |
763 | static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; } | 823 | { } |
764 | static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } | 824 | |
825 | static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) | ||
826 | { | ||
827 | return -EIO; | ||
828 | } | ||
829 | |||
830 | static inline int pci_assign_resource(struct pci_dev *dev, int i) | ||
831 | { | ||
832 | return -EBUSY; | ||
833 | } | ||
834 | |||
835 | static inline int __pci_register_driver(struct pci_driver *drv, | ||
836 | struct module *owner) | ||
837 | { | ||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static inline int pci_register_driver(struct pci_driver *drv) | ||
842 | { | ||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | static inline void pci_unregister_driver(struct pci_driver *drv) | ||
847 | { } | ||
848 | |||
849 | static inline int pci_find_capability(struct pci_dev *dev, int cap) | ||
850 | { | ||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static inline int pci_find_next_capability(struct pci_dev *dev, u8 post, | ||
855 | int cap) | ||
856 | { | ||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static inline int pci_find_ext_capability(struct pci_dev *dev, int cap) | ||
861 | { | ||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | static inline void pcie_wait_pending_transaction(struct pci_dev *dev) | ||
866 | { } | ||
765 | 867 | ||
766 | /* Power management related routines */ | 868 | /* Power management related routines */ |
767 | static inline int pci_save_state(struct pci_dev *dev) { return 0; } | 869 | static inline int pci_save_state(struct pci_dev *dev) |
768 | static inline int pci_restore_state(struct pci_dev *dev) { return 0; } | 870 | { |
769 | static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { return 0; } | 871 | return 0; |
770 | static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; } | 872 | } |
771 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; } | 873 | |
874 | static inline int pci_restore_state(struct pci_dev *dev) | ||
875 | { | ||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | ||
880 | { | ||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | static inline pci_power_t pci_choose_state(struct pci_dev *dev, | ||
885 | pm_message_t state) | ||
886 | { | ||
887 | return PCI_D0; | ||
888 | } | ||
889 | |||
890 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, | ||
891 | int enable) | ||
892 | { | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static inline int pci_request_regions(struct pci_dev *dev, const char *res_name) | ||
897 | { | ||
898 | return -EIO; | ||
899 | } | ||
772 | 900 | ||
773 | static inline int pci_request_regions(struct pci_dev *dev, const char *res_name) { return -EIO; } | 901 | static inline void pci_release_regions(struct pci_dev *dev) |
774 | static inline void pci_release_regions(struct pci_dev *dev) { } | 902 | { } |
775 | 903 | ||
776 | #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) | 904 | #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) |
777 | 905 | ||
778 | static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } | 906 | static inline void pci_block_user_cfg_access(struct pci_dev *dev) |
779 | static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { } | 907 | { } |
908 | |||
909 | static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) | ||
910 | { } | ||
780 | 911 | ||
781 | static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from) | 912 | static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from) |
782 | { return NULL; } | 913 | { return NULL; } |
@@ -797,27 +928,27 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, | |||
797 | 928 | ||
798 | /* these helpers provide future and backwards compatibility | 929 | /* these helpers provide future and backwards compatibility |
799 | * for accessing popular PCI BAR info */ | 930 | * for accessing popular PCI BAR info */ |
800 | #define pci_resource_start(dev,bar) ((dev)->resource[(bar)].start) | 931 | #define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) |
801 | #define pci_resource_end(dev,bar) ((dev)->resource[(bar)].end) | 932 | #define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end) |
802 | #define pci_resource_flags(dev,bar) ((dev)->resource[(bar)].flags) | 933 | #define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags) |
803 | #define pci_resource_len(dev,bar) \ | 934 | #define pci_resource_len(dev,bar) \ |
804 | ((pci_resource_start((dev),(bar)) == 0 && \ | 935 | ((pci_resource_start((dev), (bar)) == 0 && \ |
805 | pci_resource_end((dev),(bar)) == \ | 936 | pci_resource_end((dev), (bar)) == \ |
806 | pci_resource_start((dev),(bar))) ? 0 : \ | 937 | pci_resource_start((dev), (bar))) ? 0 : \ |
807 | \ | 938 | \ |
808 | (pci_resource_end((dev),(bar)) - \ | 939 | (pci_resource_end((dev), (bar)) - \ |
809 | pci_resource_start((dev),(bar)) + 1)) | 940 | pci_resource_start((dev), (bar)) + 1)) |
810 | 941 | ||
811 | /* Similar to the helpers above, these manipulate per-pci_dev | 942 | /* Similar to the helpers above, these manipulate per-pci_dev |
812 | * driver-specific data. They are really just a wrapper around | 943 | * driver-specific data. They are really just a wrapper around |
813 | * the generic device structure functions of these calls. | 944 | * the generic device structure functions of these calls. |
814 | */ | 945 | */ |
815 | static inline void *pci_get_drvdata (struct pci_dev *pdev) | 946 | static inline void *pci_get_drvdata(struct pci_dev *pdev) |
816 | { | 947 | { |
817 | return dev_get_drvdata(&pdev->dev); | 948 | return dev_get_drvdata(&pdev->dev); |
818 | } | 949 | } |
819 | 950 | ||
820 | static inline void pci_set_drvdata (struct pci_dev *pdev, void *data) | 951 | static inline void pci_set_drvdata(struct pci_dev *pdev, void *data) |
821 | { | 952 | { |
822 | dev_set_drvdata(&pdev->dev, data); | 953 | dev_set_drvdata(&pdev->dev, data); |
823 | } | 954 | } |
@@ -836,7 +967,7 @@ static inline char *pci_name(struct pci_dev *pdev) | |||
836 | */ | 967 | */ |
837 | #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER | 968 | #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER |
838 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | 969 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, |
839 | const struct resource *rsrc, resource_size_t *start, | 970 | const struct resource *rsrc, resource_size_t *start, |
840 | resource_size_t *end) | 971 | resource_size_t *end) |
841 | { | 972 | { |
842 | *start = rsrc->start; | 973 | *start = rsrc->start; |
@@ -888,9 +1019,9 @@ enum pci_fixup_pass { | |||
888 | 1019 | ||
889 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); | 1020 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); |
890 | 1021 | ||
891 | void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); | 1022 | void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); |
892 | void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr); | 1023 | void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr); |
893 | void __iomem * const * pcim_iomap_table(struct pci_dev *pdev); | 1024 | void __iomem * const *pcim_iomap_table(struct pci_dev *pdev); |
894 | int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name); | 1025 | int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name); |
895 | void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask); | 1026 | void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask); |
896 | 1027 | ||
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index c1914a8b94a9..c0c1223c9194 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h | |||
@@ -395,9 +395,17 @@ | |||
395 | #define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ | 395 | #define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ |
396 | #define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ | 396 | #define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ |
397 | #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ | 397 | #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ |
398 | #define PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */ | ||
399 | #define PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */ | ||
400 | #define PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */ | ||
401 | #define PCI_EXP_LNKCAP_CLKPM 0x40000 /* L1 Clock Power Management */ | ||
398 | #define PCI_EXP_LNKCTL 16 /* Link Control */ | 402 | #define PCI_EXP_LNKCTL 16 /* Link Control */ |
403 | #define PCI_EXP_LNKCTL_RL 0x20 /* Retrain Link */ | ||
404 | #define PCI_EXP_LNKCTL_CCC 0x40 /* Common Clock COnfiguration */ | ||
399 | #define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ | 405 | #define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ |
400 | #define PCI_EXP_LNKSTA 18 /* Link Status */ | 406 | #define PCI_EXP_LNKSTA 18 /* Link Status */ |
407 | #define PCI_EXP_LNKSTA_LT 0x800 /* Link Training */ | ||
408 | #define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */ | ||
401 | #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ | 409 | #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ |
402 | #define PCI_EXP_SLTCTL 24 /* Slot Control */ | 410 | #define PCI_EXP_SLTCTL 24 /* Slot Control */ |
403 | #define PCI_EXP_SLTSTA 26 /* Slot Status */ | 411 | #define PCI_EXP_SLTSTA 26 /* Slot Status */ |
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index bd7a6b0a87af..03547d6abee5 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h | |||
@@ -169,8 +169,8 @@ extern int cache_check(struct cache_detail *detail, | |||
169 | extern void cache_flush(void); | 169 | extern void cache_flush(void); |
170 | extern void cache_purge(struct cache_detail *detail); | 170 | extern void cache_purge(struct cache_detail *detail); |
171 | #define NEVER (0x7FFFFFFF) | 171 | #define NEVER (0x7FFFFFFF) |
172 | extern void cache_register(struct cache_detail *cd); | 172 | extern int cache_register(struct cache_detail *cd); |
173 | extern int cache_unregister(struct cache_detail *cd); | 173 | extern void cache_unregister(struct cache_detail *cd); |
174 | 174 | ||
175 | extern void qword_add(char **bpp, int *lp, char *str); | 175 | extern void qword_add(char **bpp, int *lp, char *str); |
176 | extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); | 176 | extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); |
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h index 3912cf16361e..10709cbe96fd 100644 --- a/include/linux/sunrpc/debug.h +++ b/include/linux/sunrpc/debug.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #define RPCDBG_BIND 0x0020 | 20 | #define RPCDBG_BIND 0x0020 |
21 | #define RPCDBG_SCHED 0x0040 | 21 | #define RPCDBG_SCHED 0x0040 |
22 | #define RPCDBG_TRANS 0x0080 | 22 | #define RPCDBG_TRANS 0x0080 |
23 | #define RPCDBG_SVCSOCK 0x0100 | 23 | #define RPCDBG_SVCXPRT 0x0100 |
24 | #define RPCDBG_SVCDSP 0x0200 | 24 | #define RPCDBG_SVCDSP 0x0200 |
25 | #define RPCDBG_MISC 0x0400 | 25 | #define RPCDBG_MISC 0x0400 |
26 | #define RPCDBG_CACHE 0x0800 | 26 | #define RPCDBG_CACHE 0x0800 |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 8531a70da73d..64c771056187 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -204,7 +204,7 @@ union svc_addr_u { | |||
204 | struct svc_rqst { | 204 | struct svc_rqst { |
205 | struct list_head rq_list; /* idle list */ | 205 | struct list_head rq_list; /* idle list */ |
206 | struct list_head rq_all; /* all threads list */ | 206 | struct list_head rq_all; /* all threads list */ |
207 | struct svc_sock * rq_sock; /* socket */ | 207 | struct svc_xprt * rq_xprt; /* transport ptr */ |
208 | struct sockaddr_storage rq_addr; /* peer address */ | 208 | struct sockaddr_storage rq_addr; /* peer address */ |
209 | size_t rq_addrlen; | 209 | size_t rq_addrlen; |
210 | 210 | ||
@@ -214,9 +214,10 @@ struct svc_rqst { | |||
214 | struct auth_ops * rq_authop; /* authentication flavour */ | 214 | struct auth_ops * rq_authop; /* authentication flavour */ |
215 | u32 rq_flavor; /* pseudoflavor */ | 215 | u32 rq_flavor; /* pseudoflavor */ |
216 | struct svc_cred rq_cred; /* auth info */ | 216 | struct svc_cred rq_cred; /* auth info */ |
217 | struct sk_buff * rq_skbuff; /* fast recv inet buffer */ | 217 | void * rq_xprt_ctxt; /* transport specific context ptr */ |
218 | struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ | 218 | struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ |
219 | 219 | ||
220 | size_t rq_xprt_hlen; /* xprt header len */ | ||
220 | struct xdr_buf rq_arg; | 221 | struct xdr_buf rq_arg; |
221 | struct xdr_buf rq_res; | 222 | struct xdr_buf rq_res; |
222 | struct page * rq_pages[RPCSVC_MAXPAGES]; | 223 | struct page * rq_pages[RPCSVC_MAXPAGES]; |
@@ -317,11 +318,12 @@ static inline void svc_free_res_pages(struct svc_rqst *rqstp) | |||
317 | 318 | ||
318 | struct svc_deferred_req { | 319 | struct svc_deferred_req { |
319 | u32 prot; /* protocol (UDP or TCP) */ | 320 | u32 prot; /* protocol (UDP or TCP) */ |
320 | struct svc_sock *svsk; | 321 | struct svc_xprt *xprt; |
321 | struct sockaddr_storage addr; /* where reply must go */ | 322 | struct sockaddr_storage addr; /* where reply must go */ |
322 | size_t addrlen; | 323 | size_t addrlen; |
323 | union svc_addr_u daddr; /* where reply must come from */ | 324 | union svc_addr_u daddr; /* where reply must come from */ |
324 | struct cache_deferred_req handle; | 325 | struct cache_deferred_req handle; |
326 | size_t xprt_hlen; | ||
325 | int argslen; | 327 | int argslen; |
326 | __be32 args[0]; | 328 | __be32 args[0]; |
327 | }; | 329 | }; |
@@ -382,6 +384,8 @@ struct svc_procedure { | |||
382 | */ | 384 | */ |
383 | struct svc_serv * svc_create(struct svc_program *, unsigned int, | 385 | struct svc_serv * svc_create(struct svc_program *, unsigned int, |
384 | void (*shutdown)(struct svc_serv*)); | 386 | void (*shutdown)(struct svc_serv*)); |
387 | struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, | ||
388 | struct svc_pool *pool); | ||
385 | int svc_create_thread(svc_thread_fn, struct svc_serv *); | 389 | int svc_create_thread(svc_thread_fn, struct svc_serv *); |
386 | void svc_exit_thread(struct svc_rqst *); | 390 | void svc_exit_thread(struct svc_rqst *); |
387 | struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, | 391 | struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, |
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h new file mode 100644 index 000000000000..c11bbcc081f9 --- /dev/null +++ b/include/linux/sunrpc/svc_rdma.h | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the BSD-type | ||
8 | * license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * | ||
17 | * Redistributions in binary form must reproduce the above | ||
18 | * copyright notice, this list of conditions and the following | ||
19 | * disclaimer in the documentation and/or other materials provided | ||
20 | * with the distribution. | ||
21 | * | ||
22 | * Neither the name of the Network Appliance, Inc. nor the names of | ||
23 | * its contributors may be used to endorse or promote products | ||
24 | * derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
30 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
31 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
32 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
33 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | * | ||
39 | * Author: Tom Tucker <tom@opengridcomputing.com> | ||
40 | */ | ||
41 | |||
42 | #ifndef SVC_RDMA_H | ||
43 | #define SVC_RDMA_H | ||
44 | #include <linux/sunrpc/xdr.h> | ||
45 | #include <linux/sunrpc/svcsock.h> | ||
46 | #include <linux/sunrpc/rpc_rdma.h> | ||
47 | #include <rdma/ib_verbs.h> | ||
48 | #include <rdma/rdma_cm.h> | ||
49 | #define SVCRDMA_DEBUG | ||
50 | |||
51 | /* RPC/RDMA parameters and stats */ | ||
52 | extern unsigned int svcrdma_ord; | ||
53 | extern unsigned int svcrdma_max_requests; | ||
54 | extern unsigned int svcrdma_max_req_size; | ||
55 | |||
56 | extern atomic_t rdma_stat_recv; | ||
57 | extern atomic_t rdma_stat_read; | ||
58 | extern atomic_t rdma_stat_write; | ||
59 | extern atomic_t rdma_stat_sq_starve; | ||
60 | extern atomic_t rdma_stat_rq_starve; | ||
61 | extern atomic_t rdma_stat_rq_poll; | ||
62 | extern atomic_t rdma_stat_rq_prod; | ||
63 | extern atomic_t rdma_stat_sq_poll; | ||
64 | extern atomic_t rdma_stat_sq_prod; | ||
65 | |||
66 | #define RPCRDMA_VERSION 1 | ||
67 | |||
68 | /* | ||
69 | * Contexts are built when an RDMA request is created and are a | ||
70 | * record of the resources that can be recovered when the request | ||
71 | * completes. | ||
72 | */ | ||
73 | struct svc_rdma_op_ctxt { | ||
74 | struct svc_rdma_op_ctxt *next; | ||
75 | struct xdr_buf arg; | ||
76 | struct list_head dto_q; | ||
77 | enum ib_wr_opcode wr_op; | ||
78 | enum ib_wc_status wc_status; | ||
79 | u32 byte_len; | ||
80 | struct svcxprt_rdma *xprt; | ||
81 | unsigned long flags; | ||
82 | enum dma_data_direction direction; | ||
83 | int count; | ||
84 | struct ib_sge sge[RPCSVC_MAXPAGES]; | ||
85 | struct page *pages[RPCSVC_MAXPAGES]; | ||
86 | }; | ||
87 | |||
88 | #define RDMACTXT_F_READ_DONE 1 | ||
89 | #define RDMACTXT_F_LAST_CTXT 2 | ||
90 | |||
91 | struct svcxprt_rdma { | ||
92 | struct svc_xprt sc_xprt; /* SVC transport structure */ | ||
93 | struct rdma_cm_id *sc_cm_id; /* RDMA connection id */ | ||
94 | struct list_head sc_accept_q; /* Conn. waiting accept */ | ||
95 | int sc_ord; /* RDMA read limit */ | ||
96 | wait_queue_head_t sc_read_wait; | ||
97 | int sc_max_sge; | ||
98 | |||
99 | int sc_sq_depth; /* Depth of SQ */ | ||
100 | atomic_t sc_sq_count; /* Number of SQ WR on queue */ | ||
101 | |||
102 | int sc_max_requests; /* Depth of RQ */ | ||
103 | int sc_max_req_size; /* Size of each RQ WR buf */ | ||
104 | |||
105 | struct ib_pd *sc_pd; | ||
106 | |||
107 | struct svc_rdma_op_ctxt *sc_ctxt_head; | ||
108 | int sc_ctxt_cnt; | ||
109 | int sc_ctxt_bump; | ||
110 | int sc_ctxt_max; | ||
111 | spinlock_t sc_ctxt_lock; | ||
112 | struct list_head sc_rq_dto_q; | ||
113 | spinlock_t sc_rq_dto_lock; | ||
114 | struct ib_qp *sc_qp; | ||
115 | struct ib_cq *sc_rq_cq; | ||
116 | struct ib_cq *sc_sq_cq; | ||
117 | struct ib_mr *sc_phys_mr; /* MR for server memory */ | ||
118 | |||
119 | spinlock_t sc_lock; /* transport lock */ | ||
120 | |||
121 | wait_queue_head_t sc_send_wait; /* SQ exhaustion waitlist */ | ||
122 | unsigned long sc_flags; | ||
123 | struct list_head sc_dto_q; /* DTO tasklet I/O pending Q */ | ||
124 | struct list_head sc_read_complete_q; | ||
125 | spinlock_t sc_read_complete_lock; | ||
126 | }; | ||
127 | /* sc_flags */ | ||
128 | #define RDMAXPRT_RQ_PENDING 1 | ||
129 | #define RDMAXPRT_SQ_PENDING 2 | ||
130 | #define RDMAXPRT_CONN_PENDING 3 | ||
131 | |||
132 | #define RPCRDMA_LISTEN_BACKLOG 10 | ||
133 | /* The default ORD value is based on two outstanding full-size writes with a | ||
134 | * page size of 4k, or 32k * 2 ops / 4k = 16 outstanding RDMA_READ. */ | ||
135 | #define RPCRDMA_ORD (64/4) | ||
136 | #define RPCRDMA_SQ_DEPTH_MULT 8 | ||
137 | #define RPCRDMA_MAX_THREADS 16 | ||
138 | #define RPCRDMA_MAX_REQUESTS 16 | ||
139 | #define RPCRDMA_MAX_REQ_SIZE 4096 | ||
140 | |||
141 | /* svc_rdma_marshal.c */ | ||
142 | extern void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *, | ||
143 | int *, int *); | ||
144 | extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg **, struct svc_rqst *); | ||
145 | extern int svc_rdma_xdr_decode_deferred_req(struct svc_rqst *); | ||
146 | extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *, | ||
147 | struct rpcrdma_msg *, | ||
148 | enum rpcrdma_errcode, u32 *); | ||
149 | extern void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *, int); | ||
150 | extern void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *, int); | ||
151 | extern void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *, int, | ||
152 | u32, u64, u32); | ||
153 | extern void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *, | ||
154 | struct rpcrdma_msg *, | ||
155 | struct rpcrdma_msg *, | ||
156 | enum rpcrdma_proc); | ||
157 | extern int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *); | ||
158 | |||
159 | /* svc_rdma_recvfrom.c */ | ||
160 | extern int svc_rdma_recvfrom(struct svc_rqst *); | ||
161 | |||
162 | /* svc_rdma_sendto.c */ | ||
163 | extern int svc_rdma_sendto(struct svc_rqst *); | ||
164 | |||
165 | /* svc_rdma_transport.c */ | ||
166 | extern int svc_rdma_send(struct svcxprt_rdma *, struct ib_send_wr *); | ||
167 | extern int svc_rdma_send_error(struct svcxprt_rdma *, struct rpcrdma_msg *, | ||
168 | enum rpcrdma_errcode); | ||
169 | struct page *svc_rdma_get_page(void); | ||
170 | extern int svc_rdma_post_recv(struct svcxprt_rdma *); | ||
171 | extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *); | ||
172 | extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *); | ||
173 | extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int); | ||
174 | extern void svc_sq_reap(struct svcxprt_rdma *); | ||
175 | extern void svc_rq_reap(struct svcxprt_rdma *); | ||
176 | extern struct svc_xprt_class svc_rdma_class; | ||
177 | extern void svc_rdma_prep_reply_hdr(struct svc_rqst *); | ||
178 | |||
179 | /* svc_rdma.c */ | ||
180 | extern int svc_rdma_init(void); | ||
181 | extern void svc_rdma_cleanup(void); | ||
182 | |||
183 | /* | ||
184 | * Returns the address of the first read chunk or <nul> if no read chunk is | ||
185 | * present | ||
186 | */ | ||
187 | static inline struct rpcrdma_read_chunk * | ||
188 | svc_rdma_get_read_chunk(struct rpcrdma_msg *rmsgp) | ||
189 | { | ||
190 | struct rpcrdma_read_chunk *ch = | ||
191 | (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; | ||
192 | |||
193 | if (ch->rc_discrim == 0) | ||
194 | return NULL; | ||
195 | |||
196 | return ch; | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * Returns the address of the first read write array element or <nul> if no | ||
201 | * write array list is present | ||
202 | */ | ||
203 | static inline struct rpcrdma_write_array * | ||
204 | svc_rdma_get_write_array(struct rpcrdma_msg *rmsgp) | ||
205 | { | ||
206 | if (rmsgp->rm_body.rm_chunks[0] != 0 | ||
207 | || rmsgp->rm_body.rm_chunks[1] == 0) | ||
208 | return NULL; | ||
209 | |||
210 | return (struct rpcrdma_write_array *)&rmsgp->rm_body.rm_chunks[1]; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Returns the address of the first reply array element or <nul> if no | ||
215 | * reply array is present | ||
216 | */ | ||
217 | static inline struct rpcrdma_write_array * | ||
218 | svc_rdma_get_reply_array(struct rpcrdma_msg *rmsgp) | ||
219 | { | ||
220 | struct rpcrdma_read_chunk *rch; | ||
221 | struct rpcrdma_write_array *wr_ary; | ||
222 | struct rpcrdma_write_array *rp_ary; | ||
223 | |||
224 | /* XXX: Need to fix when reply list may occur with read-list and/or | ||
225 | * write list */ | ||
226 | if (rmsgp->rm_body.rm_chunks[0] != 0 || | ||
227 | rmsgp->rm_body.rm_chunks[1] != 0) | ||
228 | return NULL; | ||
229 | |||
230 | rch = svc_rdma_get_read_chunk(rmsgp); | ||
231 | if (rch) { | ||
232 | while (rch->rc_discrim) | ||
233 | rch++; | ||
234 | |||
235 | /* The reply list follows an empty write array located | ||
236 | * at 'rc_position' here. The reply array is at rc_target. | ||
237 | */ | ||
238 | rp_ary = (struct rpcrdma_write_array *)&rch->rc_target; | ||
239 | |||
240 | goto found_it; | ||
241 | } | ||
242 | |||
243 | wr_ary = svc_rdma_get_write_array(rmsgp); | ||
244 | if (wr_ary) { | ||
245 | rp_ary = (struct rpcrdma_write_array *) | ||
246 | &wr_ary-> | ||
247 | wc_array[wr_ary->wc_nchunks].wc_target.rs_length; | ||
248 | |||
249 | goto found_it; | ||
250 | } | ||
251 | |||
252 | /* No read list, no write list */ | ||
253 | rp_ary = (struct rpcrdma_write_array *) | ||
254 | &rmsgp->rm_body.rm_chunks[2]; | ||
255 | |||
256 | found_it: | ||
257 | if (rp_ary->wc_discrim == 0) | ||
258 | return NULL; | ||
259 | |||
260 | return rp_ary; | ||
261 | } | ||
262 | #endif | ||
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h new file mode 100644 index 000000000000..6fd7b016517f --- /dev/null +++ b/include/linux/sunrpc/svc_xprt.h | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * linux/include/linux/sunrpc/svc_xprt.h | ||
3 | * | ||
4 | * RPC server transport I/O | ||
5 | */ | ||
6 | |||
7 | #ifndef SUNRPC_SVC_XPRT_H | ||
8 | #define SUNRPC_SVC_XPRT_H | ||
9 | |||
10 | #include <linux/sunrpc/svc.h> | ||
11 | #include <linux/module.h> | ||
12 | |||
13 | struct svc_xprt_ops { | ||
14 | struct svc_xprt *(*xpo_create)(struct svc_serv *, | ||
15 | struct sockaddr *, int, | ||
16 | int); | ||
17 | struct svc_xprt *(*xpo_accept)(struct svc_xprt *); | ||
18 | int (*xpo_has_wspace)(struct svc_xprt *); | ||
19 | int (*xpo_recvfrom)(struct svc_rqst *); | ||
20 | void (*xpo_prep_reply_hdr)(struct svc_rqst *); | ||
21 | int (*xpo_sendto)(struct svc_rqst *); | ||
22 | void (*xpo_release_rqst)(struct svc_rqst *); | ||
23 | void (*xpo_detach)(struct svc_xprt *); | ||
24 | void (*xpo_free)(struct svc_xprt *); | ||
25 | }; | ||
26 | |||
27 | struct svc_xprt_class { | ||
28 | const char *xcl_name; | ||
29 | struct module *xcl_owner; | ||
30 | struct svc_xprt_ops *xcl_ops; | ||
31 | struct list_head xcl_list; | ||
32 | u32 xcl_max_payload; | ||
33 | }; | ||
34 | |||
35 | struct svc_xprt { | ||
36 | struct svc_xprt_class *xpt_class; | ||
37 | struct svc_xprt_ops *xpt_ops; | ||
38 | struct kref xpt_ref; | ||
39 | struct list_head xpt_list; | ||
40 | struct list_head xpt_ready; | ||
41 | unsigned long xpt_flags; | ||
42 | #define XPT_BUSY 0 /* enqueued/receiving */ | ||
43 | #define XPT_CONN 1 /* conn pending */ | ||
44 | #define XPT_CLOSE 2 /* dead or dying */ | ||
45 | #define XPT_DATA 3 /* data pending */ | ||
46 | #define XPT_TEMP 4 /* connected transport */ | ||
47 | #define XPT_DEAD 6 /* transport closed */ | ||
48 | #define XPT_CHNGBUF 7 /* need to change snd/rcv buf sizes */ | ||
49 | #define XPT_DEFERRED 8 /* deferred request pending */ | ||
50 | #define XPT_OLD 9 /* used for xprt aging mark+sweep */ | ||
51 | #define XPT_DETACHED 10 /* detached from tempsocks list */ | ||
52 | #define XPT_LISTENER 11 /* listening endpoint */ | ||
53 | #define XPT_CACHE_AUTH 12 /* cache auth info */ | ||
54 | |||
55 | struct svc_pool *xpt_pool; /* current pool iff queued */ | ||
56 | struct svc_serv *xpt_server; /* service for transport */ | ||
57 | atomic_t xpt_reserved; /* space on outq that is rsvd */ | ||
58 | struct mutex xpt_mutex; /* to serialize sending data */ | ||
59 | spinlock_t xpt_lock; /* protects sk_deferred | ||
60 | * and xpt_auth_cache */ | ||
61 | void *xpt_auth_cache;/* auth cache */ | ||
62 | struct list_head xpt_deferred; /* deferred requests that need | ||
63 | * to be revisted */ | ||
64 | struct sockaddr_storage xpt_local; /* local address */ | ||
65 | size_t xpt_locallen; /* length of address */ | ||
66 | struct sockaddr_storage xpt_remote; /* remote peer's address */ | ||
67 | size_t xpt_remotelen; /* length of address */ | ||
68 | }; | ||
69 | |||
70 | int svc_reg_xprt_class(struct svc_xprt_class *); | ||
71 | void svc_unreg_xprt_class(struct svc_xprt_class *); | ||
72 | void svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *, | ||
73 | struct svc_serv *); | ||
74 | int svc_create_xprt(struct svc_serv *, char *, unsigned short, int); | ||
75 | void svc_xprt_enqueue(struct svc_xprt *xprt); | ||
76 | void svc_xprt_received(struct svc_xprt *); | ||
77 | void svc_xprt_put(struct svc_xprt *xprt); | ||
78 | void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt); | ||
79 | void svc_close_xprt(struct svc_xprt *xprt); | ||
80 | void svc_delete_xprt(struct svc_xprt *xprt); | ||
81 | int svc_port_is_privileged(struct sockaddr *sin); | ||
82 | int svc_print_xprts(char *buf, int maxlen); | ||
83 | struct svc_xprt *svc_find_xprt(struct svc_serv *, char *, int, int); | ||
84 | int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen); | ||
85 | |||
86 | static inline void svc_xprt_get(struct svc_xprt *xprt) | ||
87 | { | ||
88 | kref_get(&xprt->xpt_ref); | ||
89 | } | ||
90 | static inline void svc_xprt_set_local(struct svc_xprt *xprt, | ||
91 | struct sockaddr *sa, int salen) | ||
92 | { | ||
93 | memcpy(&xprt->xpt_local, sa, salen); | ||
94 | xprt->xpt_locallen = salen; | ||
95 | } | ||
96 | static inline void svc_xprt_set_remote(struct svc_xprt *xprt, | ||
97 | struct sockaddr *sa, int salen) | ||
98 | { | ||
99 | memcpy(&xprt->xpt_remote, sa, salen); | ||
100 | xprt->xpt_remotelen = salen; | ||
101 | } | ||
102 | static inline unsigned short svc_addr_port(struct sockaddr *sa) | ||
103 | { | ||
104 | unsigned short ret = 0; | ||
105 | switch (sa->sa_family) { | ||
106 | case AF_INET: | ||
107 | ret = ntohs(((struct sockaddr_in *)sa)->sin_port); | ||
108 | break; | ||
109 | case AF_INET6: | ||
110 | ret = ntohs(((struct sockaddr_in6 *)sa)->sin6_port); | ||
111 | break; | ||
112 | } | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | static inline size_t svc_addr_len(struct sockaddr *sa) | ||
117 | { | ||
118 | switch (sa->sa_family) { | ||
119 | case AF_INET: | ||
120 | return sizeof(struct sockaddr_in); | ||
121 | case AF_INET6: | ||
122 | return sizeof(struct sockaddr_in6); | ||
123 | } | ||
124 | return -EAFNOSUPPORT; | ||
125 | } | ||
126 | |||
127 | static inline unsigned short svc_xprt_local_port(struct svc_xprt *xprt) | ||
128 | { | ||
129 | return svc_addr_port((struct sockaddr *)&xprt->xpt_local); | ||
130 | } | ||
131 | |||
132 | static inline unsigned short svc_xprt_remote_port(struct svc_xprt *xprt) | ||
133 | { | ||
134 | return svc_addr_port((struct sockaddr *)&xprt->xpt_remote); | ||
135 | } | ||
136 | |||
137 | static inline char *__svc_print_addr(struct sockaddr *addr, | ||
138 | char *buf, size_t len) | ||
139 | { | ||
140 | switch (addr->sa_family) { | ||
141 | case AF_INET: | ||
142 | snprintf(buf, len, "%u.%u.%u.%u, port=%u", | ||
143 | NIPQUAD(((struct sockaddr_in *) addr)->sin_addr), | ||
144 | ntohs(((struct sockaddr_in *) addr)->sin_port)); | ||
145 | break; | ||
146 | |||
147 | case AF_INET6: | ||
148 | snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u", | ||
149 | NIP6(((struct sockaddr_in6 *) addr)->sin6_addr), | ||
150 | ntohs(((struct sockaddr_in6 *) addr)->sin6_port)); | ||
151 | break; | ||
152 | |||
153 | default: | ||
154 | snprintf(buf, len, "unknown address type: %d", addr->sa_family); | ||
155 | break; | ||
156 | } | ||
157 | return buf; | ||
158 | } | ||
159 | #endif /* SUNRPC_SVC_XPRT_H */ | ||
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index a53e0fa855d2..206f092ad4c7 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h | |||
@@ -10,42 +10,16 @@ | |||
10 | #define SUNRPC_SVCSOCK_H | 10 | #define SUNRPC_SVCSOCK_H |
11 | 11 | ||
12 | #include <linux/sunrpc/svc.h> | 12 | #include <linux/sunrpc/svc.h> |
13 | #include <linux/sunrpc/svc_xprt.h> | ||
13 | 14 | ||
14 | /* | 15 | /* |
15 | * RPC server socket. | 16 | * RPC server socket. |
16 | */ | 17 | */ |
17 | struct svc_sock { | 18 | struct svc_sock { |
18 | struct list_head sk_ready; /* list of ready sockets */ | 19 | struct svc_xprt sk_xprt; |
19 | struct list_head sk_list; /* list of all sockets */ | ||
20 | struct socket * sk_sock; /* berkeley socket layer */ | 20 | struct socket * sk_sock; /* berkeley socket layer */ |
21 | struct sock * sk_sk; /* INET layer */ | 21 | struct sock * sk_sk; /* INET layer */ |
22 | 22 | ||
23 | struct svc_pool * sk_pool; /* current pool iff queued */ | ||
24 | struct svc_serv * sk_server; /* service for this socket */ | ||
25 | atomic_t sk_inuse; /* use count */ | ||
26 | unsigned long sk_flags; | ||
27 | #define SK_BUSY 0 /* enqueued/receiving */ | ||
28 | #define SK_CONN 1 /* conn pending */ | ||
29 | #define SK_CLOSE 2 /* dead or dying */ | ||
30 | #define SK_DATA 3 /* data pending */ | ||
31 | #define SK_TEMP 4 /* temp (TCP) socket */ | ||
32 | #define SK_DEAD 6 /* socket closed */ | ||
33 | #define SK_CHNGBUF 7 /* need to change snd/rcv buffer sizes */ | ||
34 | #define SK_DEFERRED 8 /* request on sk_deferred */ | ||
35 | #define SK_OLD 9 /* used for temp socket aging mark+sweep */ | ||
36 | #define SK_DETACHED 10 /* detached from tempsocks list */ | ||
37 | |||
38 | atomic_t sk_reserved; /* space on outq that is reserved */ | ||
39 | |||
40 | spinlock_t sk_lock; /* protects sk_deferred and | ||
41 | * sk_info_authunix */ | ||
42 | struct list_head sk_deferred; /* deferred requests that need to | ||
43 | * be revisted */ | ||
44 | struct mutex sk_mutex; /* to serialize sending data */ | ||
45 | |||
46 | int (*sk_recvfrom)(struct svc_rqst *rqstp); | ||
47 | int (*sk_sendto)(struct svc_rqst *rqstp); | ||
48 | |||
49 | /* We keep the old state_change and data_ready CB's here */ | 23 | /* We keep the old state_change and data_ready CB's here */ |
50 | void (*sk_ostate)(struct sock *); | 24 | void (*sk_ostate)(struct sock *); |
51 | void (*sk_odata)(struct sock *, int bytes); | 25 | void (*sk_odata)(struct sock *, int bytes); |
@@ -54,21 +28,12 @@ struct svc_sock { | |||
54 | /* private TCP part */ | 28 | /* private TCP part */ |
55 | int sk_reclen; /* length of record */ | 29 | int sk_reclen; /* length of record */ |
56 | int sk_tcplen; /* current read length */ | 30 | int sk_tcplen; /* current read length */ |
57 | time_t sk_lastrecv; /* time of last received request */ | ||
58 | |||
59 | /* cache of various info for TCP sockets */ | ||
60 | void *sk_info_authunix; | ||
61 | |||
62 | struct sockaddr_storage sk_local; /* local address */ | ||
63 | struct sockaddr_storage sk_remote; /* remote peer's address */ | ||
64 | int sk_remotelen; /* length of address */ | ||
65 | }; | 31 | }; |
66 | 32 | ||
67 | /* | 33 | /* |
68 | * Function prototypes. | 34 | * Function prototypes. |
69 | */ | 35 | */ |
70 | int svc_makesock(struct svc_serv *, int, unsigned short, int flags); | 36 | void svc_close_all(struct list_head *); |
71 | void svc_force_close_socket(struct svc_sock *); | ||
72 | int svc_recv(struct svc_rqst *, long); | 37 | int svc_recv(struct svc_rqst *, long); |
73 | int svc_send(struct svc_rqst *); | 38 | int svc_send(struct svc_rqst *); |
74 | void svc_drop(struct svc_rqst *); | 39 | void svc_drop(struct svc_rqst *); |
@@ -78,6 +43,8 @@ int svc_addsock(struct svc_serv *serv, | |||
78 | int fd, | 43 | int fd, |
79 | char *name_return, | 44 | char *name_return, |
80 | int *proto); | 45 | int *proto); |
46 | void svc_init_xprt_sock(void); | ||
47 | void svc_cleanup_xprt_sock(void); | ||
81 | 48 | ||
82 | /* | 49 | /* |
83 | * svc_makesock socket characteristics | 50 | * svc_makesock socket characteristics |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 0751c9464d0f..e4057d729f03 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -112,7 +112,8 @@ struct xdr_buf { | |||
112 | __be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int len); | 112 | __be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int len); |
113 | __be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int len); | 113 | __be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int len); |
114 | __be32 *xdr_encode_string(__be32 *p, const char *s); | 114 | __be32 *xdr_encode_string(__be32 *p, const char *s); |
115 | __be32 *xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen); | 115 | __be32 *xdr_decode_string_inplace(__be32 *p, char **sp, unsigned int *lenp, |
116 | unsigned int maxlen); | ||
116 | __be32 *xdr_encode_netobj(__be32 *p, const struct xdr_netobj *); | 117 | __be32 *xdr_encode_netobj(__be32 *p, const struct xdr_netobj *); |
117 | __be32 *xdr_decode_netobj(__be32 *p, struct xdr_netobj *); | 118 | __be32 *xdr_decode_netobj(__be32 *p, struct xdr_netobj *); |
118 | 119 | ||
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 40280df2a3db..646ce2d068d4 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
@@ -38,18 +38,16 @@ typedef int __bitwise suspend_state_t; | |||
38 | * There is the %suspend_valid_only_mem function available that can be | 38 | * There is the %suspend_valid_only_mem function available that can be |
39 | * assigned to this if the platform only supports mem sleep. | 39 | * assigned to this if the platform only supports mem sleep. |
40 | * | 40 | * |
41 | * @set_target: Tell the platform which system sleep state is going to be | 41 | * @begin: Initialise a transition to given system sleep state. |
42 | * entered. | 42 | * @begin() is executed right prior to suspending devices. The information |
43 | * @set_target() is executed right prior to suspending devices. The | 43 | * conveyed to the platform code by @begin() should be disregarded by it as |
44 | * information conveyed to the platform code by @set_target() should be | 44 | * soon as @end() is executed. If @begin() fails (ie. returns nonzero), |
45 | * disregarded by the platform as soon as @finish() is executed and if | ||
46 | * @prepare() fails. If @set_target() fails (ie. returns nonzero), | ||
47 | * @prepare(), @enter() and @finish() will not be called by the PM core. | 45 | * @prepare(), @enter() and @finish() will not be called by the PM core. |
48 | * This callback is optional. However, if it is implemented, the argument | 46 | * This callback is optional. However, if it is implemented, the argument |
49 | * passed to @enter() is meaningless and should be ignored. | 47 | * passed to @enter() is redundant and should be ignored. |
50 | * | 48 | * |
51 | * @prepare: Prepare the platform for entering the system sleep state indicated | 49 | * @prepare: Prepare the platform for entering the system sleep state indicated |
52 | * by @set_target(). | 50 | * by @begin(). |
53 | * @prepare() is called right after devices have been suspended (ie. the | 51 | * @prepare() is called right after devices have been suspended (ie. the |
54 | * appropriate .suspend() method has been executed for each device) and | 52 | * appropriate .suspend() method has been executed for each device) and |
55 | * before the nonboot CPUs are disabled (it is executed with IRQs enabled). | 53 | * before the nonboot CPUs are disabled (it is executed with IRQs enabled). |
@@ -57,8 +55,8 @@ typedef int __bitwise suspend_state_t; | |||
57 | * error code otherwise, in which case the system cannot enter the desired | 55 | * error code otherwise, in which case the system cannot enter the desired |
58 | * sleep state (@enter() and @finish() will not be called in that case). | 56 | * sleep state (@enter() and @finish() will not be called in that case). |
59 | * | 57 | * |
60 | * @enter: Enter the system sleep state indicated by @set_target() or | 58 | * @enter: Enter the system sleep state indicated by @begin() or represented by |
61 | * represented by the argument if @set_target() is not implemented. | 59 | * the argument if @begin() is not implemented. |
62 | * This callback is mandatory. It returns 0 on success or a negative | 60 | * This callback is mandatory. It returns 0 on success or a negative |
63 | * error code otherwise, in which case the system cannot enter the desired | 61 | * error code otherwise, in which case the system cannot enter the desired |
64 | * sleep state. | 62 | * sleep state. |
@@ -69,13 +67,22 @@ typedef int __bitwise suspend_state_t; | |||
69 | * This callback is optional, but should be implemented by the platforms | 67 | * This callback is optional, but should be implemented by the platforms |
70 | * that implement @prepare(). If implemented, it is always called after | 68 | * that implement @prepare(). If implemented, it is always called after |
71 | * @enter() (even if @enter() fails). | 69 | * @enter() (even if @enter() fails). |
70 | * | ||
71 | * @end: Called by the PM core right after resuming devices, to indicate to | ||
72 | * the platform that the system has returned to the working state or | ||
73 | * the transition to the sleep state has been aborted. | ||
74 | * This callback is optional, but should be implemented by the platforms | ||
75 | * that implement @begin(), but platforms implementing @begin() should | ||
76 | * also provide a @end() which cleans up transitions aborted before | ||
77 | * @enter(). | ||
72 | */ | 78 | */ |
73 | struct platform_suspend_ops { | 79 | struct platform_suspend_ops { |
74 | int (*valid)(suspend_state_t state); | 80 | int (*valid)(suspend_state_t state); |
75 | int (*set_target)(suspend_state_t state); | 81 | int (*begin)(suspend_state_t state); |
76 | int (*prepare)(void); | 82 | int (*prepare)(void); |
77 | int (*enter)(suspend_state_t state); | 83 | int (*enter)(suspend_state_t state); |
78 | void (*finish)(void); | 84 | void (*finish)(void); |
85 | void (*end)(void); | ||
79 | }; | 86 | }; |
80 | 87 | ||
81 | #ifdef CONFIG_SUSPEND | 88 | #ifdef CONFIG_SUSPEND |
@@ -129,14 +136,17 @@ extern void mark_free_pages(struct zone *zone); | |||
129 | /** | 136 | /** |
130 | * struct platform_hibernation_ops - hibernation platform support | 137 | * struct platform_hibernation_ops - hibernation platform support |
131 | * | 138 | * |
132 | * The methods in this structure allow a platform to override the default | 139 | * The methods in this structure allow a platform to carry out special |
133 | * mechanism of shutting down the machine during a hibernation transition. | 140 | * operations required by it during a hibernation transition. |
134 | * | 141 | * |
135 | * All three methods must be assigned. | 142 | * All the methods below must be implemented. |
136 | * | 143 | * |
137 | * @start: Tell the platform driver that we're starting hibernation. | 144 | * @begin: Tell the platform driver that we're starting hibernation. |
138 | * Called right after shrinking memory and before freezing devices. | 145 | * Called right after shrinking memory and before freezing devices. |
139 | * | 146 | * |
147 | * @end: Called by the PM core right after resuming devices, to indicate to | ||
148 | * the platform that the system has returned to the working state. | ||
149 | * | ||
140 | * @pre_snapshot: Prepare the platform for creating the hibernation image. | 150 | * @pre_snapshot: Prepare the platform for creating the hibernation image. |
141 | * Called right after devices have been frozen and before the nonboot | 151 | * Called right after devices have been frozen and before the nonboot |
142 | * CPUs are disabled (runs with IRQs on). | 152 | * CPUs are disabled (runs with IRQs on). |
@@ -171,7 +181,8 @@ extern void mark_free_pages(struct zone *zone); | |||
171 | * thawing devices (runs with IRQs on). | 181 | * thawing devices (runs with IRQs on). |
172 | */ | 182 | */ |
173 | struct platform_hibernation_ops { | 183 | struct platform_hibernation_ops { |
174 | int (*start)(void); | 184 | int (*begin)(void); |
185 | void (*end)(void); | ||
175 | int (*pre_snapshot)(void); | 186 | int (*pre_snapshot)(void); |
176 | void (*finish)(void); | 187 | void (*finish)(void); |
177 | int (*prepare)(void); | 188 | int (*prepare)(void); |
@@ -213,17 +224,8 @@ void save_processor_state(void); | |||
213 | void restore_processor_state(void); | 224 | void restore_processor_state(void); |
214 | 225 | ||
215 | /* kernel/power/main.c */ | 226 | /* kernel/power/main.c */ |
216 | extern struct blocking_notifier_head pm_chain_head; | 227 | extern int register_pm_notifier(struct notifier_block *nb); |
217 | 228 | extern int unregister_pm_notifier(struct notifier_block *nb); | |
218 | static inline int register_pm_notifier(struct notifier_block *nb) | ||
219 | { | ||
220 | return blocking_notifier_chain_register(&pm_chain_head, nb); | ||
221 | } | ||
222 | |||
223 | static inline int unregister_pm_notifier(struct notifier_block *nb) | ||
224 | { | ||
225 | return blocking_notifier_chain_unregister(&pm_chain_head, nb); | ||
226 | } | ||
227 | 229 | ||
228 | #define pm_notifier(fn, pri) { \ | 230 | #define pm_notifier(fn, pri) { \ |
229 | static struct notifier_block fn##_nb = \ | 231 | static struct notifier_block fn##_nb = \ |
diff --git a/include/linux/suspend_ioctls.h b/include/linux/suspend_ioctls.h new file mode 100644 index 000000000000..2c6faec96bde --- /dev/null +++ b/include/linux/suspend_ioctls.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef _LINUX_SUSPEND_IOCTLS_H | ||
2 | #define _LINUX_SUSPEND_IOCTLS_H | ||
3 | |||
4 | /* | ||
5 | * This structure is used to pass the values needed for the identification | ||
6 | * of the resume swap area from a user space to the kernel via the | ||
7 | * SNAPSHOT_SET_SWAP_AREA ioctl | ||
8 | */ | ||
9 | struct resume_swap_area { | ||
10 | loff_t offset; | ||
11 | u_int32_t dev; | ||
12 | } __attribute__((packed)); | ||
13 | |||
14 | #define SNAPSHOT_IOC_MAGIC '3' | ||
15 | #define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1) | ||
16 | #define SNAPSHOT_UNFREEZE _IO(SNAPSHOT_IOC_MAGIC, 2) | ||
17 | #define SNAPSHOT_ATOMIC_RESTORE _IO(SNAPSHOT_IOC_MAGIC, 4) | ||
18 | #define SNAPSHOT_FREE _IO(SNAPSHOT_IOC_MAGIC, 5) | ||
19 | #define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9) | ||
20 | #define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11) | ||
21 | #define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \ | ||
22 | struct resume_swap_area) | ||
23 | #define SNAPSHOT_GET_IMAGE_SIZE _IOR(SNAPSHOT_IOC_MAGIC, 14, loff_t) | ||
24 | #define SNAPSHOT_PLATFORM_SUPPORT _IO(SNAPSHOT_IOC_MAGIC, 15) | ||
25 | #define SNAPSHOT_POWER_OFF _IO(SNAPSHOT_IOC_MAGIC, 16) | ||
26 | #define SNAPSHOT_CREATE_IMAGE _IOW(SNAPSHOT_IOC_MAGIC, 17, int) | ||
27 | #define SNAPSHOT_PREF_IMAGE_SIZE _IO(SNAPSHOT_IOC_MAGIC, 18) | ||
28 | #define SNAPSHOT_AVAIL_SWAP_SIZE _IOR(SNAPSHOT_IOC_MAGIC, 19, loff_t) | ||
29 | #define SNAPSHOT_ALLOC_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 20, loff_t) | ||
30 | #define SNAPSHOT_IOC_MAXNR 20 | ||
31 | |||
32 | #endif /* _LINUX_SUSPEND_IOCTLS_H */ | ||
diff --git a/include/linux/usb.h b/include/linux/usb.h index 5fc8ff73b7bb..2372e2e6b527 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -162,19 +162,19 @@ struct usb_interface { | |||
162 | unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ | 162 | unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ |
163 | 163 | ||
164 | struct device dev; /* interface specific device info */ | 164 | struct device dev; /* interface specific device info */ |
165 | struct device *usb_dev; /* pointer to the usb class's device, if any */ | 165 | struct device *usb_dev; |
166 | int pm_usage_cnt; /* usage counter for autosuspend */ | 166 | int pm_usage_cnt; /* usage counter for autosuspend */ |
167 | }; | 167 | }; |
168 | #define to_usb_interface(d) container_of(d, struct usb_interface, dev) | 168 | #define to_usb_interface(d) container_of(d, struct usb_interface, dev) |
169 | #define interface_to_usbdev(intf) \ | 169 | #define interface_to_usbdev(intf) \ |
170 | container_of(intf->dev.parent, struct usb_device, dev) | 170 | container_of(intf->dev.parent, struct usb_device, dev) |
171 | 171 | ||
172 | static inline void *usb_get_intfdata (struct usb_interface *intf) | 172 | static inline void *usb_get_intfdata(struct usb_interface *intf) |
173 | { | 173 | { |
174 | return dev_get_drvdata (&intf->dev); | 174 | return dev_get_drvdata(&intf->dev); |
175 | } | 175 | } |
176 | 176 | ||
177 | static inline void usb_set_intfdata (struct usb_interface *intf, void *data) | 177 | static inline void usb_set_intfdata(struct usb_interface *intf, void *data) |
178 | { | 178 | { |
179 | dev_set_drvdata(&intf->dev, data); | 179 | dev_set_drvdata(&intf->dev, data); |
180 | } | 180 | } |
@@ -275,9 +275,10 @@ struct usb_host_config { | |||
275 | 275 | ||
276 | int __usb_get_extra_descriptor(char *buffer, unsigned size, | 276 | int __usb_get_extra_descriptor(char *buffer, unsigned size, |
277 | unsigned char type, void **ptr); | 277 | unsigned char type, void **ptr); |
278 | #define usb_get_extra_descriptor(ifpoint,type,ptr)\ | 278 | #define usb_get_extra_descriptor(ifpoint, type, ptr) \ |
279 | __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\ | 279 | __usb_get_extra_descriptor((ifpoint)->extra, \ |
280 | type,(void**)ptr) | 280 | (ifpoint)->extralen, \ |
281 | type, (void **)ptr) | ||
281 | 282 | ||
282 | /* ----------------------------------------------------------------------- */ | 283 | /* ----------------------------------------------------------------------- */ |
283 | 284 | ||
@@ -318,7 +319,7 @@ struct usb_bus { | |||
318 | #ifdef CONFIG_USB_DEVICEFS | 319 | #ifdef CONFIG_USB_DEVICEFS |
319 | struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ | 320 | struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ |
320 | #endif | 321 | #endif |
321 | struct class_device *class_dev; /* class device for this bus */ | 322 | struct device *dev; /* device for this bus */ |
322 | 323 | ||
323 | #if defined(CONFIG_USB_MON) | 324 | #if defined(CONFIG_USB_MON) |
324 | struct mon_bus *mon_bus; /* non-null when associated */ | 325 | struct mon_bus *mon_bus; /* non-null when associated */ |
@@ -388,7 +389,7 @@ struct usb_device { | |||
388 | unsigned can_submit:1; /* URBs may be submitted */ | 389 | unsigned can_submit:1; /* URBs may be submitted */ |
389 | unsigned discon_suspended:1; /* Disconnected while suspended */ | 390 | unsigned discon_suspended:1; /* Disconnected while suspended */ |
390 | unsigned have_langid:1; /* whether string_langid is valid */ | 391 | unsigned have_langid:1; /* whether string_langid is valid */ |
391 | unsigned authorized:1; /* Policy has determined we can use it */ | 392 | unsigned authorized:1; /* Policy has said we can use it */ |
392 | unsigned wusb:1; /* Device is Wireless USB */ | 393 | unsigned wusb:1; /* Device is Wireless USB */ |
393 | int string_langid; /* language ID for strings */ | 394 | int string_langid; /* language ID for strings */ |
394 | 395 | ||
@@ -417,7 +418,10 @@ struct usb_device { | |||
417 | 418 | ||
418 | int pm_usage_cnt; /* usage counter for autosuspend */ | 419 | int pm_usage_cnt; /* usage counter for autosuspend */ |
419 | u32 quirks; /* quirks of the whole device */ | 420 | u32 quirks; /* quirks of the whole device */ |
420 | atomic_t urbnum; /* number of URBs submitted for the whole device */ | 421 | atomic_t urbnum; /* number of URBs submitted for |
422 | the whole device */ | ||
423 | |||
424 | unsigned long active_duration; /* total time device is not suspended */ | ||
421 | 425 | ||
422 | #ifdef CONFIG_PM | 426 | #ifdef CONFIG_PM |
423 | struct delayed_work autosuspend; /* for delayed autosuspends */ | 427 | struct delayed_work autosuspend; /* for delayed autosuspends */ |
@@ -425,6 +429,7 @@ struct usb_device { | |||
425 | 429 | ||
426 | unsigned long last_busy; /* time of last use */ | 430 | unsigned long last_busy; /* time of last use */ |
427 | int autosuspend_delay; /* in jiffies */ | 431 | int autosuspend_delay; /* in jiffies */ |
432 | unsigned long connect_time; /* time device was first connected */ | ||
428 | 433 | ||
429 | unsigned auto_pm:1; /* autosuspend/resume in progress */ | 434 | unsigned auto_pm:1; /* autosuspend/resume in progress */ |
430 | unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ | 435 | unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ |
@@ -498,11 +503,11 @@ static inline void usb_mark_last_busy(struct usb_device *udev) | |||
498 | /*-------------------------------------------------------------------------*/ | 503 | /*-------------------------------------------------------------------------*/ |
499 | 504 | ||
500 | /* for drivers using iso endpoints */ | 505 | /* for drivers using iso endpoints */ |
501 | extern int usb_get_current_frame_number (struct usb_device *usb_dev); | 506 | extern int usb_get_current_frame_number(struct usb_device *usb_dev); |
502 | 507 | ||
503 | /* used these for multi-interface device registration */ | 508 | /* used these for multi-interface device registration */ |
504 | extern int usb_driver_claim_interface(struct usb_driver *driver, | 509 | extern int usb_driver_claim_interface(struct usb_driver *driver, |
505 | struct usb_interface *iface, void* priv); | 510 | struct usb_interface *iface, void *priv); |
506 | 511 | ||
507 | /** | 512 | /** |
508 | * usb_interface_claimed - returns true iff an interface is claimed | 513 | * usb_interface_claimed - returns true iff an interface is claimed |
@@ -514,7 +519,8 @@ extern int usb_driver_claim_interface(struct usb_driver *driver, | |||
514 | * may need to explicitly claim that lock. | 519 | * may need to explicitly claim that lock. |
515 | * | 520 | * |
516 | */ | 521 | */ |
517 | static inline int usb_interface_claimed(struct usb_interface *iface) { | 522 | static inline int usb_interface_claimed(struct usb_interface *iface) |
523 | { | ||
518 | return (iface->dev.driver != NULL); | 524 | return (iface->dev.driver != NULL); |
519 | } | 525 | } |
520 | 526 | ||
@@ -557,12 +563,11 @@ extern struct usb_host_interface *usb_altnum_to_altsetting( | |||
557 | * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are | 563 | * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are |
558 | * high speed, and a different one if they are full or low speed. | 564 | * high speed, and a different one if they are full or low speed. |
559 | */ | 565 | */ |
560 | static inline int usb_make_path (struct usb_device *dev, char *buf, | 566 | static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size) |
561 | size_t size) | ||
562 | { | 567 | { |
563 | int actual; | 568 | int actual; |
564 | actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, | 569 | actual = snprintf(buf, size, "usb-%s-%s", dev->bus->bus_name, |
565 | dev->devpath); | 570 | dev->devpath); |
566 | return (actual >= (int)size) ? -1 : actual; | 571 | return (actual >= (int)size) ? -1 : actual; |
567 | } | 572 | } |
568 | 573 | ||
@@ -608,7 +613,8 @@ static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) | |||
608 | * | 613 | * |
609 | * Returns true if the endpoint is of type OUT, otherwise it returns false. | 614 | * Returns true if the endpoint is of type OUT, otherwise it returns false. |
610 | */ | 615 | */ |
611 | static inline int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) | 616 | static inline int usb_endpoint_dir_out( |
617 | const struct usb_endpoint_descriptor *epd) | ||
612 | { | 618 | { |
613 | return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); | 619 | return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); |
614 | } | 620 | } |
@@ -619,7 +625,8 @@ static inline int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd | |||
619 | * | 625 | * |
620 | * Returns true if the endpoint is of type bulk, otherwise it returns false. | 626 | * Returns true if the endpoint is of type bulk, otherwise it returns false. |
621 | */ | 627 | */ |
622 | static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) | 628 | static inline int usb_endpoint_xfer_bulk( |
629 | const struct usb_endpoint_descriptor *epd) | ||
623 | { | 630 | { |
624 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | 631 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
625 | USB_ENDPOINT_XFER_BULK); | 632 | USB_ENDPOINT_XFER_BULK); |
@@ -631,7 +638,8 @@ static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *e | |||
631 | * | 638 | * |
632 | * Returns true if the endpoint is of type control, otherwise it returns false. | 639 | * Returns true if the endpoint is of type control, otherwise it returns false. |
633 | */ | 640 | */ |
634 | static inline int usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd) | 641 | static inline int usb_endpoint_xfer_control( |
642 | const struct usb_endpoint_descriptor *epd) | ||
635 | { | 643 | { |
636 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | 644 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
637 | USB_ENDPOINT_XFER_CONTROL); | 645 | USB_ENDPOINT_XFER_CONTROL); |
@@ -644,7 +652,8 @@ static inline int usb_endpoint_xfer_control(const struct usb_endpoint_descriptor | |||
644 | * Returns true if the endpoint is of type interrupt, otherwise it returns | 652 | * Returns true if the endpoint is of type interrupt, otherwise it returns |
645 | * false. | 653 | * false. |
646 | */ | 654 | */ |
647 | static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) | 655 | static inline int usb_endpoint_xfer_int( |
656 | const struct usb_endpoint_descriptor *epd) | ||
648 | { | 657 | { |
649 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | 658 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
650 | USB_ENDPOINT_XFER_INT); | 659 | USB_ENDPOINT_XFER_INT); |
@@ -657,7 +666,8 @@ static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *ep | |||
657 | * Returns true if the endpoint is of type isochronous, otherwise it returns | 666 | * Returns true if the endpoint is of type isochronous, otherwise it returns |
658 | * false. | 667 | * false. |
659 | */ | 668 | */ |
660 | static inline int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd) | 669 | static inline int usb_endpoint_xfer_isoc( |
670 | const struct usb_endpoint_descriptor *epd) | ||
661 | { | 671 | { |
662 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | 672 | return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
663 | USB_ENDPOINT_XFER_ISOC); | 673 | USB_ENDPOINT_XFER_ISOC); |
@@ -670,7 +680,8 @@ static inline int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *e | |||
670 | * Returns true if the endpoint has bulk transfer type and IN direction, | 680 | * Returns true if the endpoint has bulk transfer type and IN direction, |
671 | * otherwise it returns false. | 681 | * otherwise it returns false. |
672 | */ | 682 | */ |
673 | static inline int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) | 683 | static inline int usb_endpoint_is_bulk_in( |
684 | const struct usb_endpoint_descriptor *epd) | ||
674 | { | 685 | { |
675 | return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd)); | 686 | return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd)); |
676 | } | 687 | } |
@@ -682,7 +693,8 @@ static inline int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor * | |||
682 | * Returns true if the endpoint has bulk transfer type and OUT direction, | 693 | * Returns true if the endpoint has bulk transfer type and OUT direction, |
683 | * otherwise it returns false. | 694 | * otherwise it returns false. |
684 | */ | 695 | */ |
685 | static inline int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) | 696 | static inline int usb_endpoint_is_bulk_out( |
697 | const struct usb_endpoint_descriptor *epd) | ||
686 | { | 698 | { |
687 | return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd)); | 699 | return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd)); |
688 | } | 700 | } |
@@ -694,7 +706,8 @@ static inline int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor | |||
694 | * Returns true if the endpoint has interrupt transfer type and IN direction, | 706 | * Returns true if the endpoint has interrupt transfer type and IN direction, |
695 | * otherwise it returns false. | 707 | * otherwise it returns false. |
696 | */ | 708 | */ |
697 | static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) | 709 | static inline int usb_endpoint_is_int_in( |
710 | const struct usb_endpoint_descriptor *epd) | ||
698 | { | 711 | { |
699 | return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd)); | 712 | return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd)); |
700 | } | 713 | } |
@@ -706,7 +719,8 @@ static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *e | |||
706 | * Returns true if the endpoint has interrupt transfer type and OUT direction, | 719 | * Returns true if the endpoint has interrupt transfer type and OUT direction, |
707 | * otherwise it returns false. | 720 | * otherwise it returns false. |
708 | */ | 721 | */ |
709 | static inline int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd) | 722 | static inline int usb_endpoint_is_int_out( |
723 | const struct usb_endpoint_descriptor *epd) | ||
710 | { | 724 | { |
711 | return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd)); | 725 | return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd)); |
712 | } | 726 | } |
@@ -718,7 +732,8 @@ static inline int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor * | |||
718 | * Returns true if the endpoint has isochronous transfer type and IN direction, | 732 | * Returns true if the endpoint has isochronous transfer type and IN direction, |
719 | * otherwise it returns false. | 733 | * otherwise it returns false. |
720 | */ | 734 | */ |
721 | static inline int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd) | 735 | static inline int usb_endpoint_is_isoc_in( |
736 | const struct usb_endpoint_descriptor *epd) | ||
722 | { | 737 | { |
723 | return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd)); | 738 | return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd)); |
724 | } | 739 | } |
@@ -730,7 +745,8 @@ static inline int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor * | |||
730 | * Returns true if the endpoint has isochronous transfer type and OUT direction, | 745 | * Returns true if the endpoint has isochronous transfer type and OUT direction, |
731 | * otherwise it returns false. | 746 | * otherwise it returns false. |
732 | */ | 747 | */ |
733 | static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd) | 748 | static inline int usb_endpoint_is_isoc_out( |
749 | const struct usb_endpoint_descriptor *epd) | ||
734 | { | 750 | { |
735 | return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd)); | 751 | return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd)); |
736 | } | 752 | } |
@@ -761,8 +777,9 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor | |||
761 | * specific device. | 777 | * specific device. |
762 | */ | 778 | */ |
763 | #define USB_DEVICE(vend,prod) \ | 779 | #define USB_DEVICE(vend,prod) \ |
764 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \ | 780 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ |
765 | .idProduct = (prod) | 781 | .idVendor = (vend), \ |
782 | .idProduct = (prod) | ||
766 | /** | 783 | /** |
767 | * USB_DEVICE_VER - macro used to describe a specific usb device with a | 784 | * USB_DEVICE_VER - macro used to describe a specific usb device with a |
768 | * version range | 785 | * version range |
@@ -774,10 +791,12 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor | |||
774 | * This macro is used to create a struct usb_device_id that matches a | 791 | * This macro is used to create a struct usb_device_id that matches a |
775 | * specific device, with a version range. | 792 | * specific device, with a version range. |
776 | */ | 793 | */ |
777 | #define USB_DEVICE_VER(vend,prod,lo,hi) \ | 794 | #define USB_DEVICE_VER(vend, prod, lo, hi) \ |
778 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \ | 795 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \ |
779 | .idVendor = (vend), .idProduct = (prod), \ | 796 | .idVendor = (vend), \ |
780 | .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) | 797 | .idProduct = (prod), \ |
798 | .bcdDevice_lo = (lo), \ | ||
799 | .bcdDevice_hi = (hi) | ||
781 | 800 | ||
782 | /** | 801 | /** |
783 | * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb | 802 | * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb |
@@ -789,8 +808,9 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor | |||
789 | * This macro is used to create a struct usb_device_id that matches a | 808 | * This macro is used to create a struct usb_device_id that matches a |
790 | * specific interface protocol of devices. | 809 | * specific interface protocol of devices. |
791 | */ | 810 | */ |
792 | #define USB_DEVICE_INTERFACE_PROTOCOL(vend,prod,pr) \ | 811 | #define USB_DEVICE_INTERFACE_PROTOCOL(vend, prod, pr) \ |
793 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ | 812 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ |
813 | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ | ||
794 | .idVendor = (vend), \ | 814 | .idVendor = (vend), \ |
795 | .idProduct = (prod), \ | 815 | .idProduct = (prod), \ |
796 | .bInterfaceProtocol = (pr) | 816 | .bInterfaceProtocol = (pr) |
@@ -804,12 +824,14 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor | |||
804 | * This macro is used to create a struct usb_device_id that matches a | 824 | * This macro is used to create a struct usb_device_id that matches a |
805 | * specific class of devices. | 825 | * specific class of devices. |
806 | */ | 826 | */ |
807 | #define USB_DEVICE_INFO(cl,sc,pr) \ | 827 | #define USB_DEVICE_INFO(cl, sc, pr) \ |
808 | .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), \ | 828 | .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, \ |
809 | .bDeviceSubClass = (sc), .bDeviceProtocol = (pr) | 829 | .bDeviceClass = (cl), \ |
830 | .bDeviceSubClass = (sc), \ | ||
831 | .bDeviceProtocol = (pr) | ||
810 | 832 | ||
811 | /** | 833 | /** |
812 | * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces | 834 | * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces |
813 | * @cl: bInterfaceClass value | 835 | * @cl: bInterfaceClass value |
814 | * @sc: bInterfaceSubClass value | 836 | * @sc: bInterfaceSubClass value |
815 | * @pr: bInterfaceProtocol value | 837 | * @pr: bInterfaceProtocol value |
@@ -817,9 +839,11 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor | |||
817 | * This macro is used to create a struct usb_device_id that matches a | 839 | * This macro is used to create a struct usb_device_id that matches a |
818 | * specific class of interfaces. | 840 | * specific class of interfaces. |
819 | */ | 841 | */ |
820 | #define USB_INTERFACE_INFO(cl,sc,pr) \ | 842 | #define USB_INTERFACE_INFO(cl, sc, pr) \ |
821 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \ | 843 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \ |
822 | .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr) | 844 | .bInterfaceClass = (cl), \ |
845 | .bInterfaceSubClass = (sc), \ | ||
846 | .bInterfaceProtocol = (pr) | ||
823 | 847 | ||
824 | /** | 848 | /** |
825 | * USB_DEVICE_AND_INTERFACE_INFO - macro used to describe a specific usb device | 849 | * USB_DEVICE_AND_INTERFACE_INFO - macro used to describe a specific usb device |
@@ -836,12 +860,14 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor | |||
836 | * This is especially useful when explicitly matching devices that have | 860 | * This is especially useful when explicitly matching devices that have |
837 | * vendor specific bDeviceClass values, but standards-compliant interfaces. | 861 | * vendor specific bDeviceClass values, but standards-compliant interfaces. |
838 | */ | 862 | */ |
839 | #define USB_DEVICE_AND_INTERFACE_INFO(vend,prod,cl,sc,pr) \ | 863 | #define USB_DEVICE_AND_INTERFACE_INFO(vend, prod, cl, sc, pr) \ |
840 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ | 864 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ |
841 | | USB_DEVICE_ID_MATCH_DEVICE, \ | 865 | | USB_DEVICE_ID_MATCH_DEVICE, \ |
842 | .idVendor = (vend), .idProduct = (prod), \ | 866 | .idVendor = (vend), \ |
867 | .idProduct = (prod), \ | ||
843 | .bInterfaceClass = (cl), \ | 868 | .bInterfaceClass = (cl), \ |
844 | .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr) | 869 | .bInterfaceSubClass = (sc), \ |
870 | .bInterfaceProtocol = (pr) | ||
845 | 871 | ||
846 | /* ----------------------------------------------------------------------- */ | 872 | /* ----------------------------------------------------------------------- */ |
847 | 873 | ||
@@ -1119,7 +1145,7 @@ typedef void (*usb_complete_t)(struct urb *); | |||
1119 | * transferred. It will normally be the same as requested, unless | 1145 | * transferred. It will normally be the same as requested, unless |
1120 | * either an error was reported or a short read was performed. | 1146 | * either an error was reported or a short read was performed. |
1121 | * The URB_SHORT_NOT_OK transfer flag may be used to make such | 1147 | * The URB_SHORT_NOT_OK transfer flag may be used to make such |
1122 | * short reads be reported as errors. | 1148 | * short reads be reported as errors. |
1123 | * @setup_packet: Only used for control transfers, this points to eight bytes | 1149 | * @setup_packet: Only used for control transfers, this points to eight bytes |
1124 | * of setup data. Control transfers always start by sending this data | 1150 | * of setup data. Control transfers always start by sending this data |
1125 | * to the device. Then transfer_buffer is read or written, if needed. | 1151 | * to the device. Then transfer_buffer is read or written, if needed. |
@@ -1138,7 +1164,7 @@ typedef void (*usb_complete_t)(struct urb *); | |||
1138 | * @complete: Completion handler. This URB is passed as the parameter to the | 1164 | * @complete: Completion handler. This URB is passed as the parameter to the |
1139 | * completion function. The completion function may then do what | 1165 | * completion function. The completion function may then do what |
1140 | * it likes with the URB, including resubmitting or freeing it. | 1166 | * it likes with the URB, including resubmitting or freeing it. |
1141 | * @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to | 1167 | * @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to |
1142 | * collect the transfer status for each buffer. | 1168 | * collect the transfer status for each buffer. |
1143 | * | 1169 | * |
1144 | * This structure identifies USB transfer requests. URBs must be allocated by | 1170 | * This structure identifies USB transfer requests. URBs must be allocated by |
@@ -1242,8 +1268,7 @@ typedef void (*usb_complete_t)(struct urb *); | |||
1242 | * when the urb is owned by the hcd, that is, since the call to | 1268 | * when the urb is owned by the hcd, that is, since the call to |
1243 | * usb_submit_urb() till the entry into the completion routine. | 1269 | * usb_submit_urb() till the entry into the completion routine. |
1244 | */ | 1270 | */ |
1245 | struct urb | 1271 | struct urb { |
1246 | { | ||
1247 | /* private: usb core and host controller only fields in the urb */ | 1272 | /* private: usb core and host controller only fields in the urb */ |
1248 | struct kref kref; /* reference count of the URB */ | 1273 | struct kref kref; /* reference count of the URB */ |
1249 | void *hcpriv; /* private data for host controller */ | 1274 | void *hcpriv; /* private data for host controller */ |
@@ -1254,10 +1279,10 @@ struct urb | |||
1254 | /* public: documented fields in the urb that can be used by drivers */ | 1279 | /* public: documented fields in the urb that can be used by drivers */ |
1255 | struct list_head urb_list; /* list head for use by the urb's | 1280 | struct list_head urb_list; /* list head for use by the urb's |
1256 | * current owner */ | 1281 | * current owner */ |
1257 | struct list_head anchor_list; /* the URB may be anchored by the driver */ | 1282 | struct list_head anchor_list; /* the URB may be anchored */ |
1258 | struct usb_anchor *anchor; | 1283 | struct usb_anchor *anchor; |
1259 | struct usb_device *dev; /* (in) pointer to associated device */ | 1284 | struct usb_device *dev; /* (in) pointer to associated device */ |
1260 | struct usb_host_endpoint *ep; /* (internal) pointer to endpoint struct */ | 1285 | struct usb_host_endpoint *ep; /* (internal) pointer to endpoint */ |
1261 | unsigned int pipe; /* (in) pipe information */ | 1286 | unsigned int pipe; /* (in) pipe information */ |
1262 | int status; /* (return) non-ISO status */ | 1287 | int status; /* (return) non-ISO status */ |
1263 | unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/ | 1288 | unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/ |
@@ -1294,14 +1319,14 @@ struct urb | |||
1294 | * Initializes a control urb with the proper information needed to submit | 1319 | * Initializes a control urb with the proper information needed to submit |
1295 | * it to a device. | 1320 | * it to a device. |
1296 | */ | 1321 | */ |
1297 | static inline void usb_fill_control_urb (struct urb *urb, | 1322 | static inline void usb_fill_control_urb(struct urb *urb, |
1298 | struct usb_device *dev, | 1323 | struct usb_device *dev, |
1299 | unsigned int pipe, | 1324 | unsigned int pipe, |
1300 | unsigned char *setup_packet, | 1325 | unsigned char *setup_packet, |
1301 | void *transfer_buffer, | 1326 | void *transfer_buffer, |
1302 | int buffer_length, | 1327 | int buffer_length, |
1303 | usb_complete_t complete_fn, | 1328 | usb_complete_t complete_fn, |
1304 | void *context) | 1329 | void *context) |
1305 | { | 1330 | { |
1306 | urb->dev = dev; | 1331 | urb->dev = dev; |
1307 | urb->pipe = pipe; | 1332 | urb->pipe = pipe; |
@@ -1325,13 +1350,13 @@ static inline void usb_fill_control_urb (struct urb *urb, | |||
1325 | * Initializes a bulk urb with the proper information needed to submit it | 1350 | * Initializes a bulk urb with the proper information needed to submit it |
1326 | * to a device. | 1351 | * to a device. |
1327 | */ | 1352 | */ |
1328 | static inline void usb_fill_bulk_urb (struct urb *urb, | 1353 | static inline void usb_fill_bulk_urb(struct urb *urb, |
1329 | struct usb_device *dev, | 1354 | struct usb_device *dev, |
1330 | unsigned int pipe, | 1355 | unsigned int pipe, |
1331 | void *transfer_buffer, | 1356 | void *transfer_buffer, |
1332 | int buffer_length, | 1357 | int buffer_length, |
1333 | usb_complete_t complete_fn, | 1358 | usb_complete_t complete_fn, |
1334 | void *context) | 1359 | void *context) |
1335 | { | 1360 | { |
1336 | urb->dev = dev; | 1361 | urb->dev = dev; |
1337 | urb->pipe = pipe; | 1362 | urb->pipe = pipe; |
@@ -1359,14 +1384,14 @@ static inline void usb_fill_bulk_urb (struct urb *urb, | |||
1359 | * the endpoint interval, and express polling intervals in microframes | 1384 | * the endpoint interval, and express polling intervals in microframes |
1360 | * (eight per millisecond) rather than in frames (one per millisecond). | 1385 | * (eight per millisecond) rather than in frames (one per millisecond). |
1361 | */ | 1386 | */ |
1362 | static inline void usb_fill_int_urb (struct urb *urb, | 1387 | static inline void usb_fill_int_urb(struct urb *urb, |
1363 | struct usb_device *dev, | 1388 | struct usb_device *dev, |
1364 | unsigned int pipe, | 1389 | unsigned int pipe, |
1365 | void *transfer_buffer, | 1390 | void *transfer_buffer, |
1366 | int buffer_length, | 1391 | int buffer_length, |
1367 | usb_complete_t complete_fn, | 1392 | usb_complete_t complete_fn, |
1368 | void *context, | 1393 | void *context, |
1369 | int interval) | 1394 | int interval) |
1370 | { | 1395 | { |
1371 | urb->dev = dev; | 1396 | urb->dev = dev; |
1372 | urb->pipe = pipe; | 1397 | urb->pipe = pipe; |
@@ -1419,15 +1444,15 @@ static inline int usb_urb_dir_out(struct urb *urb) | |||
1419 | return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT; | 1444 | return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT; |
1420 | } | 1445 | } |
1421 | 1446 | ||
1422 | void *usb_buffer_alloc (struct usb_device *dev, size_t size, | 1447 | void *usb_buffer_alloc(struct usb_device *dev, size_t size, |
1423 | gfp_t mem_flags, dma_addr_t *dma); | 1448 | gfp_t mem_flags, dma_addr_t *dma); |
1424 | void usb_buffer_free (struct usb_device *dev, size_t size, | 1449 | void usb_buffer_free(struct usb_device *dev, size_t size, |
1425 | void *addr, dma_addr_t dma); | 1450 | void *addr, dma_addr_t dma); |
1426 | 1451 | ||
1427 | #if 0 | 1452 | #if 0 |
1428 | struct urb *usb_buffer_map (struct urb *urb); | 1453 | struct urb *usb_buffer_map(struct urb *urb); |
1429 | void usb_buffer_dmasync (struct urb *urb); | 1454 | void usb_buffer_dmasync(struct urb *urb); |
1430 | void usb_buffer_unmap (struct urb *urb); | 1455 | void usb_buffer_unmap(struct urb *urb); |
1431 | #endif | 1456 | #endif |
1432 | 1457 | ||
1433 | struct scatterlist; | 1458 | struct scatterlist; |
@@ -1499,7 +1524,7 @@ struct usb_sg_request { | |||
1499 | int status; | 1524 | int status; |
1500 | size_t bytes; | 1525 | size_t bytes; |
1501 | 1526 | ||
1502 | /* | 1527 | /* |
1503 | * members below are private: to usbcore, | 1528 | * members below are private: to usbcore, |
1504 | * and are not provided for driver access! | 1529 | * and are not provided for driver access! |
1505 | */ | 1530 | */ |
@@ -1517,18 +1542,18 @@ struct usb_sg_request { | |||
1517 | struct completion complete; | 1542 | struct completion complete; |
1518 | }; | 1543 | }; |
1519 | 1544 | ||
1520 | int usb_sg_init ( | 1545 | int usb_sg_init( |
1521 | struct usb_sg_request *io, | 1546 | struct usb_sg_request *io, |
1522 | struct usb_device *dev, | 1547 | struct usb_device *dev, |
1523 | unsigned pipe, | 1548 | unsigned pipe, |
1524 | unsigned period, | 1549 | unsigned period, |
1525 | struct scatterlist *sg, | 1550 | struct scatterlist *sg, |
1526 | int nents, | 1551 | int nents, |
1527 | size_t length, | 1552 | size_t length, |
1528 | gfp_t mem_flags | 1553 | gfp_t mem_flags |
1529 | ); | 1554 | ); |
1530 | void usb_sg_cancel (struct usb_sg_request *io); | 1555 | void usb_sg_cancel(struct usb_sg_request *io); |
1531 | void usb_sg_wait (struct usb_sg_request *io); | 1556 | void usb_sg_wait(struct usb_sg_request *io); |
1532 | 1557 | ||
1533 | 1558 | ||
1534 | /* ----------------------------------------------------------------------- */ | 1559 | /* ----------------------------------------------------------------------- */ |
@@ -1585,21 +1610,21 @@ static inline unsigned int __create_pipe(struct usb_device *dev, | |||
1585 | 1610 | ||
1586 | /* Create various pipes... */ | 1611 | /* Create various pipes... */ |
1587 | #define usb_sndctrlpipe(dev,endpoint) \ | 1612 | #define usb_sndctrlpipe(dev,endpoint) \ |
1588 | ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint)) | 1613 | ((PIPE_CONTROL << 30) | __create_pipe(dev, endpoint)) |
1589 | #define usb_rcvctrlpipe(dev,endpoint) \ | 1614 | #define usb_rcvctrlpipe(dev,endpoint) \ |
1590 | ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) | 1615 | ((PIPE_CONTROL << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) |
1591 | #define usb_sndisocpipe(dev,endpoint) \ | 1616 | #define usb_sndisocpipe(dev,endpoint) \ |
1592 | ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint)) | 1617 | ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev, endpoint)) |
1593 | #define usb_rcvisocpipe(dev,endpoint) \ | 1618 | #define usb_rcvisocpipe(dev,endpoint) \ |
1594 | ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) | 1619 | ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) |
1595 | #define usb_sndbulkpipe(dev,endpoint) \ | 1620 | #define usb_sndbulkpipe(dev,endpoint) \ |
1596 | ((PIPE_BULK << 30) | __create_pipe(dev,endpoint)) | 1621 | ((PIPE_BULK << 30) | __create_pipe(dev, endpoint)) |
1597 | #define usb_rcvbulkpipe(dev,endpoint) \ | 1622 | #define usb_rcvbulkpipe(dev,endpoint) \ |
1598 | ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) | 1623 | ((PIPE_BULK << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) |
1599 | #define usb_sndintpipe(dev,endpoint) \ | 1624 | #define usb_sndintpipe(dev,endpoint) \ |
1600 | ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint)) | 1625 | ((PIPE_INTERRUPT << 30) | __create_pipe(dev, endpoint)) |
1601 | #define usb_rcvintpipe(dev,endpoint) \ | 1626 | #define usb_rcvintpipe(dev,endpoint) \ |
1602 | ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) | 1627 | ((PIPE_INTERRUPT << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) |
1603 | 1628 | ||
1604 | /*-------------------------------------------------------------------------*/ | 1629 | /*-------------------------------------------------------------------------*/ |
1605 | 1630 | ||
diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index 6ce42bf9f743..b8cba1dcb2c6 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild | |||
@@ -1,6 +1,7 @@ | |||
1 | unifdef-y += audio.h | 1 | header-y += audio.h |
2 | unifdef-y += cdc.h | 2 | header-y += cdc.h |
3 | unifdef-y += ch9.h | 3 | header-y += ch9.h |
4 | unifdef-y += gadgetfs.h | 4 | header-y += gadgetfs.h |
5 | unifdef-y += midi.h | 5 | header-y += midi.h |
6 | unifdef-y += g_printer.h | ||
6 | 7 | ||
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 6bd235994dc2..2dfeef16b221 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h | |||
@@ -27,13 +27,13 @@ | |||
27 | 27 | ||
28 | /* 4.3.2 Class-Specific AC Interface Descriptor */ | 28 | /* 4.3.2 Class-Specific AC Interface Descriptor */ |
29 | struct usb_ac_header_descriptor { | 29 | struct usb_ac_header_descriptor { |
30 | __u8 bLength; // 8+n | 30 | __u8 bLength; /* 8+n */ |
31 | __u8 bDescriptorType; // USB_DT_CS_INTERFACE | 31 | __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ |
32 | __u8 bDescriptorSubtype; // USB_MS_HEADER | 32 | __u8 bDescriptorSubtype; /* USB_MS_HEADER */ |
33 | __le16 bcdADC; // 0x0100 | 33 | __le16 bcdADC; /* 0x0100 */ |
34 | __le16 wTotalLength; // includes Unit and Terminal desc. | 34 | __le16 wTotalLength; /* includes Unit and Terminal desc. */ |
35 | __u8 bInCollection; // n | 35 | __u8 bInCollection; /* n */ |
36 | __u8 baInterfaceNr[]; // [n] | 36 | __u8 baInterfaceNr[]; /* [n] */ |
37 | } __attribute__ ((packed)); | 37 | } __attribute__ ((packed)); |
38 | 38 | ||
39 | #define USB_DT_AC_HEADER_SIZE(n) (8+(n)) | 39 | #define USB_DT_AC_HEADER_SIZE(n) (8+(n)) |
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h index 2204ae22c381..94ee4ecf0564 100644 --- a/include/linux/usb/cdc.h +++ b/include/linux/usb/cdc.h | |||
@@ -29,16 +29,16 @@ | |||
29 | * Class-Specific descriptors ... there are a couple dozen of them | 29 | * Class-Specific descriptors ... there are a couple dozen of them |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ | 32 | #define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ |
33 | #define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ | 33 | #define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ |
34 | #define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ | 34 | #define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ |
35 | #define USB_CDC_UNION_TYPE 0x06 /* union_desc */ | 35 | #define USB_CDC_UNION_TYPE 0x06 /* union_desc */ |
36 | #define USB_CDC_COUNTRY_TYPE 0x07 | 36 | #define USB_CDC_COUNTRY_TYPE 0x07 |
37 | #define USB_CDC_NETWORK_TERMINAL_TYPE 0x0a /* network_terminal_desc */ | 37 | #define USB_CDC_NETWORK_TERMINAL_TYPE 0x0a /* network_terminal_desc */ |
38 | #define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ | 38 | #define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ |
39 | #define USB_CDC_WHCM_TYPE 0x11 | 39 | #define USB_CDC_WHCM_TYPE 0x11 |
40 | #define USB_CDC_MDLM_TYPE 0x12 /* mdlm_desc */ | 40 | #define USB_CDC_MDLM_TYPE 0x12 /* mdlm_desc */ |
41 | #define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */ | 41 | #define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */ |
42 | #define USB_CDC_DMM_TYPE 0x14 | 42 | #define USB_CDC_DMM_TYPE 0x14 |
43 | #define USB_CDC_OBEX_TYPE 0x15 | 43 | #define USB_CDC_OBEX_TYPE 0x15 |
44 | 44 | ||
diff --git a/include/linux/usb/g_printer.h b/include/linux/usb/g_printer.h new file mode 100644 index 000000000000..0c5ea1e3eb98 --- /dev/null +++ b/include/linux/usb/g_printer.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * g_printer.h -- Header file for USB Printer gadget driver | ||
3 | * | ||
4 | * Copyright (C) 2007 Craig W. Nadler | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
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 | ||
19 | */ | ||
20 | |||
21 | |||
22 | #define PRINTER_NOT_ERROR 0x08 | ||
23 | #define PRINTER_SELECTED 0x10 | ||
24 | #define PRINTER_PAPER_EMPTY 0x20 | ||
25 | |||
26 | /* The 'g' code is also used by gadgetfs ioctl requests. | ||
27 | * Don't add any colliding codes to either driver, and keep | ||
28 | * them in unique ranges (size 0x20 for now). | ||
29 | */ | ||
30 | #define GADGET_GET_PRINTER_STATUS _IOR('g', 0x21, unsigned char) | ||
31 | #define GADGET_SET_PRINTER_STATUS _IOWR('g', 0x22, unsigned char) | ||
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index c1527c2ef3cb..aa3047ff00d1 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h | |||
@@ -70,9 +70,10 @@ struct usb_ep; | |||
70 | * | 70 | * |
71 | * Bulk endpoints can use any size buffers, and can also be used for interrupt | 71 | * Bulk endpoints can use any size buffers, and can also be used for interrupt |
72 | * transfers. interrupt-only endpoints can be much less functional. | 72 | * transfers. interrupt-only endpoints can be much less functional. |
73 | * | ||
74 | * NOTE: this is analagous to 'struct urb' on the host side, except that | ||
75 | * it's thinner and promotes more pre-allocation. | ||
73 | */ | 76 | */ |
74 | // NOTE this is analagous to 'struct urb' on the host side, | ||
75 | // except that it's thinner and promotes more pre-allocation. | ||
76 | 77 | ||
77 | struct usb_request { | 78 | struct usb_request { |
78 | void *buf; | 79 | void *buf; |
@@ -168,10 +169,10 @@ struct usb_ep { | |||
168 | * | 169 | * |
169 | * returns zero, or a negative error code. | 170 | * returns zero, or a negative error code. |
170 | */ | 171 | */ |
171 | static inline int | 172 | static inline int usb_ep_enable(struct usb_ep *ep, |
172 | usb_ep_enable (struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) | 173 | const struct usb_endpoint_descriptor *desc) |
173 | { | 174 | { |
174 | return ep->ops->enable (ep, desc); | 175 | return ep->ops->enable(ep, desc); |
175 | } | 176 | } |
176 | 177 | ||
177 | /** | 178 | /** |
@@ -186,10 +187,9 @@ usb_ep_enable (struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) | |||
186 | * | 187 | * |
187 | * returns zero, or a negative error code. | 188 | * returns zero, or a negative error code. |
188 | */ | 189 | */ |
189 | static inline int | 190 | static inline int usb_ep_disable(struct usb_ep *ep) |
190 | usb_ep_disable (struct usb_ep *ep) | ||
191 | { | 191 | { |
192 | return ep->ops->disable (ep); | 192 | return ep->ops->disable(ep); |
193 | } | 193 | } |
194 | 194 | ||
195 | /** | 195 | /** |
@@ -206,10 +206,10 @@ usb_ep_disable (struct usb_ep *ep) | |||
206 | * | 206 | * |
207 | * Returns the request, or null if one could not be allocated. | 207 | * Returns the request, or null if one could not be allocated. |
208 | */ | 208 | */ |
209 | static inline struct usb_request * | 209 | static inline struct usb_request *usb_ep_alloc_request(struct usb_ep *ep, |
210 | usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags) | 210 | gfp_t gfp_flags) |
211 | { | 211 | { |
212 | return ep->ops->alloc_request (ep, gfp_flags); | 212 | return ep->ops->alloc_request(ep, gfp_flags); |
213 | } | 213 | } |
214 | 214 | ||
215 | /** | 215 | /** |
@@ -221,10 +221,10 @@ usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags) | |||
221 | * Caller guarantees the request is not queued, and that it will | 221 | * Caller guarantees the request is not queued, and that it will |
222 | * no longer be requeued (or otherwise used). | 222 | * no longer be requeued (or otherwise used). |
223 | */ | 223 | */ |
224 | static inline void | 224 | static inline void usb_ep_free_request(struct usb_ep *ep, |
225 | usb_ep_free_request (struct usb_ep *ep, struct usb_request *req) | 225 | struct usb_request *req) |
226 | { | 226 | { |
227 | ep->ops->free_request (ep, req); | 227 | ep->ops->free_request(ep, req); |
228 | } | 228 | } |
229 | 229 | ||
230 | /** | 230 | /** |
@@ -281,10 +281,10 @@ usb_ep_free_request (struct usb_ep *ep, struct usb_request *req) | |||
281 | * report errors; errors will also be | 281 | * report errors; errors will also be |
282 | * reported when the usb peripheral is disconnected. | 282 | * reported when the usb peripheral is disconnected. |
283 | */ | 283 | */ |
284 | static inline int | 284 | static inline int usb_ep_queue(struct usb_ep *ep, |
285 | usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) | 285 | struct usb_request *req, gfp_t gfp_flags) |
286 | { | 286 | { |
287 | return ep->ops->queue (ep, req, gfp_flags); | 287 | return ep->ops->queue(ep, req, gfp_flags); |
288 | } | 288 | } |
289 | 289 | ||
290 | /** | 290 | /** |
@@ -301,9 +301,9 @@ usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) | |||
301 | * restrictions prevent drivers from supporting configuration changes, | 301 | * restrictions prevent drivers from supporting configuration changes, |
302 | * even to configuration zero (a "chapter 9" requirement). | 302 | * even to configuration zero (a "chapter 9" requirement). |
303 | */ | 303 | */ |
304 | static inline int usb_ep_dequeue (struct usb_ep *ep, struct usb_request *req) | 304 | static inline int usb_ep_dequeue(struct usb_ep *ep, struct usb_request *req) |
305 | { | 305 | { |
306 | return ep->ops->dequeue (ep, req); | 306 | return ep->ops->dequeue(ep, req); |
307 | } | 307 | } |
308 | 308 | ||
309 | /** | 309 | /** |
@@ -327,10 +327,9 @@ static inline int usb_ep_dequeue (struct usb_ep *ep, struct usb_request *req) | |||
327 | * transfer requests are still queued, or if the controller hardware | 327 | * transfer requests are still queued, or if the controller hardware |
328 | * (usually a FIFO) still holds bytes that the host hasn't collected. | 328 | * (usually a FIFO) still holds bytes that the host hasn't collected. |
329 | */ | 329 | */ |
330 | static inline int | 330 | static inline int usb_ep_set_halt(struct usb_ep *ep) |
331 | usb_ep_set_halt (struct usb_ep *ep) | ||
332 | { | 331 | { |
333 | return ep->ops->set_halt (ep, 1); | 332 | return ep->ops->set_halt(ep, 1); |
334 | } | 333 | } |
335 | 334 | ||
336 | /** | 335 | /** |
@@ -346,10 +345,9 @@ usb_ep_set_halt (struct usb_ep *ep) | |||
346 | * Note that some hardware can't support this request (like pxa2xx_udc), | 345 | * Note that some hardware can't support this request (like pxa2xx_udc), |
347 | * and accordingly can't correctly implement interface altsettings. | 346 | * and accordingly can't correctly implement interface altsettings. |
348 | */ | 347 | */ |
349 | static inline int | 348 | static inline int usb_ep_clear_halt(struct usb_ep *ep) |
350 | usb_ep_clear_halt (struct usb_ep *ep) | ||
351 | { | 349 | { |
352 | return ep->ops->set_halt (ep, 0); | 350 | return ep->ops->set_halt(ep, 0); |
353 | } | 351 | } |
354 | 352 | ||
355 | /** | 353 | /** |
@@ -367,11 +365,10 @@ usb_ep_clear_halt (struct usb_ep *ep) | |||
367 | * errno if the endpoint doesn't use a FIFO or doesn't support such | 365 | * errno if the endpoint doesn't use a FIFO or doesn't support such |
368 | * precise handling. | 366 | * precise handling. |
369 | */ | 367 | */ |
370 | static inline int | 368 | static inline int usb_ep_fifo_status(struct usb_ep *ep) |
371 | usb_ep_fifo_status (struct usb_ep *ep) | ||
372 | { | 369 | { |
373 | if (ep->ops->fifo_status) | 370 | if (ep->ops->fifo_status) |
374 | return ep->ops->fifo_status (ep); | 371 | return ep->ops->fifo_status(ep); |
375 | else | 372 | else |
376 | return -EOPNOTSUPP; | 373 | return -EOPNOTSUPP; |
377 | } | 374 | } |
@@ -385,11 +382,10 @@ usb_ep_fifo_status (struct usb_ep *ep) | |||
385 | * must never be used except when endpoint is not being used for any | 382 | * must never be used except when endpoint is not being used for any |
386 | * protocol translation. | 383 | * protocol translation. |
387 | */ | 384 | */ |
388 | static inline void | 385 | static inline void usb_ep_fifo_flush(struct usb_ep *ep) |
389 | usb_ep_fifo_flush (struct usb_ep *ep) | ||
390 | { | 386 | { |
391 | if (ep->ops->fifo_flush) | 387 | if (ep->ops->fifo_flush) |
392 | ep->ops->fifo_flush (ep); | 388 | ep->ops->fifo_flush(ep); |
393 | } | 389 | } |
394 | 390 | ||
395 | 391 | ||
@@ -469,10 +465,10 @@ struct usb_gadget { | |||
469 | struct device dev; | 465 | struct device dev; |
470 | }; | 466 | }; |
471 | 467 | ||
472 | static inline void set_gadget_data (struct usb_gadget *gadget, void *data) | 468 | static inline void set_gadget_data(struct usb_gadget *gadget, void *data) |
473 | { dev_set_drvdata (&gadget->dev, data); } | 469 | { dev_set_drvdata(&gadget->dev, data); } |
474 | static inline void *get_gadget_data (struct usb_gadget *gadget) | 470 | static inline void *get_gadget_data(struct usb_gadget *gadget) |
475 | { return dev_get_drvdata (&gadget->dev); } | 471 | { return dev_get_drvdata(&gadget->dev); } |
476 | 472 | ||
477 | /* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */ | 473 | /* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */ |
478 | #define gadget_for_each_ep(tmp,gadget) \ | 474 | #define gadget_for_each_ep(tmp,gadget) \ |
@@ -511,7 +507,6 @@ static inline int gadget_is_otg(struct usb_gadget *g) | |||
511 | #endif | 507 | #endif |
512 | } | 508 | } |
513 | 509 | ||
514 | |||
515 | /** | 510 | /** |
516 | * usb_gadget_frame_number - returns the current frame number | 511 | * usb_gadget_frame_number - returns the current frame number |
517 | * @gadget: controller that reports the frame number | 512 | * @gadget: controller that reports the frame number |
@@ -519,9 +514,9 @@ static inline int gadget_is_otg(struct usb_gadget *g) | |||
519 | * Returns the usb frame number, normally eleven bits from a SOF packet, | 514 | * Returns the usb frame number, normally eleven bits from a SOF packet, |
520 | * or negative errno if this device doesn't support this capability. | 515 | * or negative errno if this device doesn't support this capability. |
521 | */ | 516 | */ |
522 | static inline int usb_gadget_frame_number (struct usb_gadget *gadget) | 517 | static inline int usb_gadget_frame_number(struct usb_gadget *gadget) |
523 | { | 518 | { |
524 | return gadget->ops->get_frame (gadget); | 519 | return gadget->ops->get_frame(gadget); |
525 | } | 520 | } |
526 | 521 | ||
527 | /** | 522 | /** |
@@ -537,11 +532,11 @@ static inline int usb_gadget_frame_number (struct usb_gadget *gadget) | |||
537 | * even if OTG isn't otherwise in use. OTG devices may also start | 532 | * even if OTG isn't otherwise in use. OTG devices may also start |
538 | * remote wakeup even when hosts don't explicitly enable it. | 533 | * remote wakeup even when hosts don't explicitly enable it. |
539 | */ | 534 | */ |
540 | static inline int usb_gadget_wakeup (struct usb_gadget *gadget) | 535 | static inline int usb_gadget_wakeup(struct usb_gadget *gadget) |
541 | { | 536 | { |
542 | if (!gadget->ops->wakeup) | 537 | if (!gadget->ops->wakeup) |
543 | return -EOPNOTSUPP; | 538 | return -EOPNOTSUPP; |
544 | return gadget->ops->wakeup (gadget); | 539 | return gadget->ops->wakeup(gadget); |
545 | } | 540 | } |
546 | 541 | ||
547 | /** | 542 | /** |
@@ -553,12 +548,11 @@ static inline int usb_gadget_wakeup (struct usb_gadget *gadget) | |||
553 | * | 548 | * |
554 | * returns zero on success, else negative errno. | 549 | * returns zero on success, else negative errno. |
555 | */ | 550 | */ |
556 | static inline int | 551 | static inline int usb_gadget_set_selfpowered(struct usb_gadget *gadget) |
557 | usb_gadget_set_selfpowered (struct usb_gadget *gadget) | ||
558 | { | 552 | { |
559 | if (!gadget->ops->set_selfpowered) | 553 | if (!gadget->ops->set_selfpowered) |
560 | return -EOPNOTSUPP; | 554 | return -EOPNOTSUPP; |
561 | return gadget->ops->set_selfpowered (gadget, 1); | 555 | return gadget->ops->set_selfpowered(gadget, 1); |
562 | } | 556 | } |
563 | 557 | ||
564 | /** | 558 | /** |
@@ -571,12 +565,11 @@ usb_gadget_set_selfpowered (struct usb_gadget *gadget) | |||
571 | * | 565 | * |
572 | * returns zero on success, else negative errno. | 566 | * returns zero on success, else negative errno. |
573 | */ | 567 | */ |
574 | static inline int | 568 | static inline int usb_gadget_clear_selfpowered(struct usb_gadget *gadget) |
575 | usb_gadget_clear_selfpowered (struct usb_gadget *gadget) | ||
576 | { | 569 | { |
577 | if (!gadget->ops->set_selfpowered) | 570 | if (!gadget->ops->set_selfpowered) |
578 | return -EOPNOTSUPP; | 571 | return -EOPNOTSUPP; |
579 | return gadget->ops->set_selfpowered (gadget, 0); | 572 | return gadget->ops->set_selfpowered(gadget, 0); |
580 | } | 573 | } |
581 | 574 | ||
582 | /** | 575 | /** |
@@ -591,12 +584,11 @@ usb_gadget_clear_selfpowered (struct usb_gadget *gadget) | |||
591 | * | 584 | * |
592 | * Returns zero on success, else negative errno. | 585 | * Returns zero on success, else negative errno. |
593 | */ | 586 | */ |
594 | static inline int | 587 | static inline int usb_gadget_vbus_connect(struct usb_gadget *gadget) |
595 | usb_gadget_vbus_connect(struct usb_gadget *gadget) | ||
596 | { | 588 | { |
597 | if (!gadget->ops->vbus_session) | 589 | if (!gadget->ops->vbus_session) |
598 | return -EOPNOTSUPP; | 590 | return -EOPNOTSUPP; |
599 | return gadget->ops->vbus_session (gadget, 1); | 591 | return gadget->ops->vbus_session(gadget, 1); |
600 | } | 592 | } |
601 | 593 | ||
602 | /** | 594 | /** |
@@ -611,12 +603,11 @@ usb_gadget_vbus_connect(struct usb_gadget *gadget) | |||
611 | * | 603 | * |
612 | * Returns zero on success, else negative errno. | 604 | * Returns zero on success, else negative errno. |
613 | */ | 605 | */ |
614 | static inline int | 606 | static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) |
615 | usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) | ||
616 | { | 607 | { |
617 | if (!gadget->ops->vbus_draw) | 608 | if (!gadget->ops->vbus_draw) |
618 | return -EOPNOTSUPP; | 609 | return -EOPNOTSUPP; |
619 | return gadget->ops->vbus_draw (gadget, mA); | 610 | return gadget->ops->vbus_draw(gadget, mA); |
620 | } | 611 | } |
621 | 612 | ||
622 | /** | 613 | /** |
@@ -629,12 +620,11 @@ usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) | |||
629 | * | 620 | * |
630 | * Returns zero on success, else negative errno. | 621 | * Returns zero on success, else negative errno. |
631 | */ | 622 | */ |
632 | static inline int | 623 | static inline int usb_gadget_vbus_disconnect(struct usb_gadget *gadget) |
633 | usb_gadget_vbus_disconnect(struct usb_gadget *gadget) | ||
634 | { | 624 | { |
635 | if (!gadget->ops->vbus_session) | 625 | if (!gadget->ops->vbus_session) |
636 | return -EOPNOTSUPP; | 626 | return -EOPNOTSUPP; |
637 | return gadget->ops->vbus_session (gadget, 0); | 627 | return gadget->ops->vbus_session(gadget, 0); |
638 | } | 628 | } |
639 | 629 | ||
640 | /** | 630 | /** |
@@ -648,12 +638,11 @@ usb_gadget_vbus_disconnect(struct usb_gadget *gadget) | |||
648 | * | 638 | * |
649 | * Returns zero on success, else negative errno. | 639 | * Returns zero on success, else negative errno. |
650 | */ | 640 | */ |
651 | static inline int | 641 | static inline int usb_gadget_connect(struct usb_gadget *gadget) |
652 | usb_gadget_connect (struct usb_gadget *gadget) | ||
653 | { | 642 | { |
654 | if (!gadget->ops->pullup) | 643 | if (!gadget->ops->pullup) |
655 | return -EOPNOTSUPP; | 644 | return -EOPNOTSUPP; |
656 | return gadget->ops->pullup (gadget, 1); | 645 | return gadget->ops->pullup(gadget, 1); |
657 | } | 646 | } |
658 | 647 | ||
659 | /** | 648 | /** |
@@ -671,16 +660,14 @@ usb_gadget_connect (struct usb_gadget *gadget) | |||
671 | * | 660 | * |
672 | * Returns zero on success, else negative errno. | 661 | * Returns zero on success, else negative errno. |
673 | */ | 662 | */ |
674 | static inline int | 663 | static inline int usb_gadget_disconnect(struct usb_gadget *gadget) |
675 | usb_gadget_disconnect (struct usb_gadget *gadget) | ||
676 | { | 664 | { |
677 | if (!gadget->ops->pullup) | 665 | if (!gadget->ops->pullup) |
678 | return -EOPNOTSUPP; | 666 | return -EOPNOTSUPP; |
679 | return gadget->ops->pullup (gadget, 0); | 667 | return gadget->ops->pullup(gadget, 0); |
680 | } | 668 | } |
681 | 669 | ||
682 | 670 | ||
683 | |||
684 | /*-------------------------------------------------------------------------*/ | 671 | /*-------------------------------------------------------------------------*/ |
685 | 672 | ||
686 | /** | 673 | /** |
@@ -764,7 +751,7 @@ struct usb_gadget_driver { | |||
764 | void (*suspend)(struct usb_gadget *); | 751 | void (*suspend)(struct usb_gadget *); |
765 | void (*resume)(struct usb_gadget *); | 752 | void (*resume)(struct usb_gadget *); |
766 | 753 | ||
767 | // FIXME support safe rmmod | 754 | /* FIXME support safe rmmod */ |
768 | struct device_driver driver; | 755 | struct device_driver driver; |
769 | }; | 756 | }; |
770 | 757 | ||
@@ -790,7 +777,7 @@ struct usb_gadget_driver { | |||
790 | * the bind() functions will be in init sections. | 777 | * the bind() functions will be in init sections. |
791 | * This function must be called in a context that can sleep. | 778 | * This function must be called in a context that can sleep. |
792 | */ | 779 | */ |
793 | int usb_gadget_register_driver (struct usb_gadget_driver *driver); | 780 | int usb_gadget_register_driver(struct usb_gadget_driver *driver); |
794 | 781 | ||
795 | /** | 782 | /** |
796 | * usb_gadget_unregister_driver - unregister a gadget driver | 783 | * usb_gadget_unregister_driver - unregister a gadget driver |
@@ -805,7 +792,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver); | |||
805 | * will in in exit sections, so may not be linked in some kernels. | 792 | * will in in exit sections, so may not be linked in some kernels. |
806 | * This function must be called in a context that can sleep. | 793 | * This function must be called in a context that can sleep. |
807 | */ | 794 | */ |
808 | int usb_gadget_unregister_driver (struct usb_gadget_driver *driver); | 795 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver); |
809 | 796 | ||
810 | /*-------------------------------------------------------------------------*/ | 797 | /*-------------------------------------------------------------------------*/ |
811 | 798 | ||
@@ -838,7 +825,7 @@ struct usb_gadget_strings { | |||
838 | }; | 825 | }; |
839 | 826 | ||
840 | /* put descriptor for string with that id into buf (buflen >= 256) */ | 827 | /* put descriptor for string with that id into buf (buflen >= 256) */ |
841 | int usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf); | 828 | int usb_gadget_get_string(struct usb_gadget_strings *table, int id, u8 *buf); |
842 | 829 | ||
843 | /*-------------------------------------------------------------------------*/ | 830 | /*-------------------------------------------------------------------------*/ |
844 | 831 | ||
@@ -856,10 +843,10 @@ int usb_gadget_config_buf(const struct usb_config_descriptor *config, | |||
856 | 843 | ||
857 | /* utility wrapping a simple endpoint selection policy */ | 844 | /* utility wrapping a simple endpoint selection policy */ |
858 | 845 | ||
859 | extern struct usb_ep *usb_ep_autoconfig (struct usb_gadget *, | 846 | extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, |
860 | struct usb_endpoint_descriptor *) __devinit; | 847 | struct usb_endpoint_descriptor *) __devinit; |
861 | 848 | ||
862 | extern void usb_ep_autoconfig_reset (struct usb_gadget *) __devinit; | 849 | extern void usb_ep_autoconfig_reset(struct usb_gadget *) __devinit; |
863 | 850 | ||
864 | #endif /* __KERNEL__ */ | 851 | #endif /* __KERNEL__ */ |
865 | 852 | ||
diff --git a/include/linux/usb/gadgetfs.h b/include/linux/usb/gadgetfs.h index e8654c338729..c291ab1af747 100644 --- a/include/linux/usb/gadgetfs.h +++ b/include/linux/usb/gadgetfs.h | |||
@@ -36,7 +36,7 @@ enum usb_gadgetfs_event_type { | |||
36 | GADGETFS_DISCONNECT, | 36 | GADGETFS_DISCONNECT, |
37 | GADGETFS_SETUP, | 37 | GADGETFS_SETUP, |
38 | GADGETFS_SUSPEND, | 38 | GADGETFS_SUSPEND, |
39 | // and likely more ! | 39 | /* and likely more ! */ |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /* NOTE: this structure must stay the same size and layout on | 42 | /* NOTE: this structure must stay the same size and layout on |
@@ -44,21 +44,28 @@ enum usb_gadgetfs_event_type { | |||
44 | */ | 44 | */ |
45 | struct usb_gadgetfs_event { | 45 | struct usb_gadgetfs_event { |
46 | union { | 46 | union { |
47 | // NOP, DISCONNECT, SUSPEND: nothing | 47 | /* NOP, DISCONNECT, SUSPEND: nothing |
48 | // ... some hardware can't report disconnection | 48 | * ... some hardware can't report disconnection |
49 | */ | ||
49 | 50 | ||
50 | // CONNECT: just the speed | 51 | /* CONNECT: just the speed */ |
51 | enum usb_device_speed speed; | 52 | enum usb_device_speed speed; |
52 | 53 | ||
53 | // SETUP: packet; DATA phase i/o precedes next event | 54 | /* SETUP: packet; DATA phase i/o precedes next event |
54 | // (setup.bmRequestType & USB_DIR_IN) flags direction | 55 | *(setup.bmRequestType & USB_DIR_IN) flags direction |
55 | // ... includes SET_CONFIGURATION, SET_INTERFACE | 56 | * ... includes SET_CONFIGURATION, SET_INTERFACE |
57 | */ | ||
56 | struct usb_ctrlrequest setup; | 58 | struct usb_ctrlrequest setup; |
57 | } u; | 59 | } u; |
58 | enum usb_gadgetfs_event_type type; | 60 | enum usb_gadgetfs_event_type type; |
59 | }; | 61 | }; |
60 | 62 | ||
61 | 63 | ||
64 | /* The 'g' code is also used by printer gadget ioctl requests. | ||
65 | * Don't add any colliding codes to either driver, and keep | ||
66 | * them in unique ranges (size 0x20 for now). | ||
67 | */ | ||
68 | |||
62 | /* endpoint ioctls */ | 69 | /* endpoint ioctls */ |
63 | 70 | ||
64 | /* IN transfers may be reported to the gadget driver as complete | 71 | /* IN transfers may be reported to the gadget driver as complete |
@@ -68,14 +75,14 @@ struct usb_gadgetfs_event { | |||
68 | * THIS returns how many bytes are "unclaimed" in the endpoint fifo | 75 | * THIS returns how many bytes are "unclaimed" in the endpoint fifo |
69 | * (needed for precise fault handling, when the hardware allows it) | 76 | * (needed for precise fault handling, when the hardware allows it) |
70 | */ | 77 | */ |
71 | #define GADGETFS_FIFO_STATUS _IO('g',1) | 78 | #define GADGETFS_FIFO_STATUS _IO('g', 1) |
72 | 79 | ||
73 | /* discards any unclaimed data in the fifo. */ | 80 | /* discards any unclaimed data in the fifo. */ |
74 | #define GADGETFS_FIFO_FLUSH _IO('g',2) | 81 | #define GADGETFS_FIFO_FLUSH _IO('g', 2) |
75 | 82 | ||
76 | /* resets endpoint halt+toggle; used to implement set_interface. | 83 | /* resets endpoint halt+toggle; used to implement set_interface. |
77 | * some hardware (like pxa2xx) can't support this. | 84 | * some hardware (like pxa2xx) can't support this. |
78 | */ | 85 | */ |
79 | #define GADGETFS_CLEAR_HALT _IO('g',3) | 86 | #define GADGETFS_CLEAR_HALT _IO('g', 3) |
80 | 87 | ||
81 | #endif /* __LINUX_USB_GADGETFS_H */ | 88 | #endif /* __LINUX_USB_GADGETFS_H */ |
diff --git a/include/linux/usb/iowarrior.h b/include/linux/usb/iowarrior.h index cbbe020a4f5c..de6f380e17a2 100644 --- a/include/linux/usb/iowarrior.h +++ b/include/linux/usb/iowarrior.h | |||
@@ -14,14 +14,23 @@ | |||
14 | this information. | 14 | this information. |
15 | */ | 15 | */ |
16 | struct iowarrior_info { | 16 | struct iowarrior_info { |
17 | __u32 vendor; /* vendor id : supposed to be USB_VENDOR_ID_CODEMERCS in all cases */ | 17 | /* vendor id : supposed to be USB_VENDOR_ID_CODEMERCS in all cases */ |
18 | __u32 product; /* product id : depends on type of chip (USB_DEVICE_ID_CODEMERCS_XXXXX) */ | 18 | __u32 vendor; |
19 | __u8 serial[9]; /* the serial number of our chip (if a serial-number is not available this is empty string) */ | 19 | /* product id : depends on type of chip (USB_DEVICE_ID_CODEMERCS_X) */ |
20 | __u32 revision; /* revision number of the chip */ | 20 | __u32 product; |
21 | __u32 speed; /* USB-speed of the device (0=UNKNOWN, 1=LOW, 2=FULL 3=HIGH) */ | 21 | /* the serial number of our chip (if a serial-number is not available |
22 | __u32 power; /* power consumption of the device in mA */ | 22 | * this is empty string) */ |
23 | __u32 if_num; /* the number of the endpoint */ | 23 | __u8 serial[9]; |
24 | __u32 report_size; /* size of the data-packets on this interface */ | 24 | /* revision number of the chip */ |
25 | __u32 revision; | ||
26 | /* USB-speed of the device (0=UNKNOWN, 1=LOW, 2=FULL 3=HIGH) */ | ||
27 | __u32 speed; | ||
28 | /* power consumption of the device in mA */ | ||
29 | __u32 power; | ||
30 | /* the number of the endpoint */ | ||
31 | __u32 if_num; | ||
32 | /* size of the data-packets on this interface */ | ||
33 | __u32 report_size; | ||
25 | }; | 34 | }; |
26 | 35 | ||
27 | /* | 36 | /* |
diff --git a/include/linux/usb/isp116x.h b/include/linux/usb/isp116x.h index 436dd8a2b64a..67d2826f34fe 100644 --- a/include/linux/usb/isp116x.h +++ b/include/linux/usb/isp116x.h | |||
@@ -25,5 +25,5 @@ struct isp116x_platform_data { | |||
25 | 300ns delay between access to ADDR_REG and DATA_REG | 25 | 300ns delay between access to ADDR_REG and DATA_REG |
26 | OE, WE MUST NOT be changed during these intervals | 26 | OE, WE MUST NOT be changed during these intervals |
27 | */ | 27 | */ |
28 | void (*delay) (struct device * dev, int delay); | 28 | void (*delay) (struct device *dev, int delay); |
29 | }; | 29 | }; |
diff --git a/include/linux/usb/midi.h b/include/linux/usb/midi.h index 11a97d5ffd34..80624c562921 100644 --- a/include/linux/usb/midi.h +++ b/include/linux/usb/midi.h | |||
@@ -47,9 +47,9 @@ struct usb_ms_header_descriptor { | |||
47 | /* 6.1.2.2 MIDI IN Jack Descriptor */ | 47 | /* 6.1.2.2 MIDI IN Jack Descriptor */ |
48 | struct usb_midi_in_jack_descriptor { | 48 | struct usb_midi_in_jack_descriptor { |
49 | __u8 bLength; | 49 | __u8 bLength; |
50 | __u8 bDescriptorType; // USB_DT_CS_INTERFACE | 50 | __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ |
51 | __u8 bDescriptorSubtype; // USB_MS_MIDI_IN_JACK | 51 | __u8 bDescriptorSubtype; /* USB_MS_MIDI_IN_JACK */ |
52 | __u8 bJackType; // USB_MS_EMBEDDED/EXTERNAL | 52 | __u8 bJackType; /* USB_MS_EMBEDDED/EXTERNAL */ |
53 | __u8 bJackID; | 53 | __u8 bJackID; |
54 | __u8 iJack; | 54 | __u8 iJack; |
55 | } __attribute__ ((packed)); | 55 | } __attribute__ ((packed)); |
@@ -64,12 +64,12 @@ struct usb_midi_source_pin { | |||
64 | /* 6.1.2.3 MIDI OUT Jack Descriptor */ | 64 | /* 6.1.2.3 MIDI OUT Jack Descriptor */ |
65 | struct usb_midi_out_jack_descriptor { | 65 | struct usb_midi_out_jack_descriptor { |
66 | __u8 bLength; | 66 | __u8 bLength; |
67 | __u8 bDescriptorType; // USB_DT_CS_INTERFACE | 67 | __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */ |
68 | __u8 bDescriptorSubtype; // USB_MS_MIDI_OUT_JACK | 68 | __u8 bDescriptorSubtype; /* USB_MS_MIDI_OUT_JACK */ |
69 | __u8 bJackType; // USB_MS_EMBEDDED/EXTERNAL | 69 | __u8 bJackType; /* USB_MS_EMBEDDED/EXTERNAL */ |
70 | __u8 bJackID; | 70 | __u8 bJackID; |
71 | __u8 bNrInputPins; // p | 71 | __u8 bNrInputPins; /* p */ |
72 | struct usb_midi_source_pin pins[]; // [p] | 72 | struct usb_midi_source_pin pins[]; /* [p] */ |
73 | /*__u8 iJack; -- ommitted due to variable-sized pins[] */ | 73 | /*__u8 iJack; -- ommitted due to variable-sized pins[] */ |
74 | } __attribute__ ((packed)); | 74 | } __attribute__ ((packed)); |
75 | 75 | ||
@@ -90,11 +90,11 @@ struct usb_midi_out_jack_descriptor_##p { \ | |||
90 | 90 | ||
91 | /* 6.2.2 Class-Specific MS Bulk Data Endpoint Descriptor */ | 91 | /* 6.2.2 Class-Specific MS Bulk Data Endpoint Descriptor */ |
92 | struct usb_ms_endpoint_descriptor { | 92 | struct usb_ms_endpoint_descriptor { |
93 | __u8 bLength; // 4+n | 93 | __u8 bLength; /* 4+n */ |
94 | __u8 bDescriptorType; // USB_DT_CS_ENDPOINT | 94 | __u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */ |
95 | __u8 bDescriptorSubtype; // USB_MS_GENERAL | 95 | __u8 bDescriptorSubtype; /* USB_MS_GENERAL */ |
96 | __u8 bNumEmbMIDIJack; // n | 96 | __u8 bNumEmbMIDIJack; /* n */ |
97 | __u8 baAssocJackID[]; // [n] | 97 | __u8 baAssocJackID[]; /* [n] */ |
98 | } __attribute__ ((packed)); | 98 | } __attribute__ ((packed)); |
99 | 99 | ||
100 | #define USB_DT_MS_ENDPOINT_SIZE(n) (4 + (n)) | 100 | #define USB_DT_MS_ENDPOINT_SIZE(n) (4 + (n)) |
diff --git a/include/linux/usb/net2280.h b/include/linux/usb/net2280.h index c602f884f182..ec897cb844ab 100644 --- a/include/linux/usb/net2280.h +++ b/include/linux/usb/net2280.h | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | /* main registers, BAR0 + 0x0000 */ | 38 | /* main registers, BAR0 + 0x0000 */ |
39 | struct net2280_regs { | 39 | struct net2280_regs { |
40 | // offset 0x0000 | 40 | /* offset 0x0000 */ |
41 | u32 devinit; | 41 | u32 devinit; |
42 | #define LOCAL_CLOCK_FREQUENCY 8 | 42 | #define LOCAL_CLOCK_FREQUENCY 8 |
43 | #define FORCE_PCI_RESET 7 | 43 | #define FORCE_PCI_RESET 7 |
@@ -61,7 +61,7 @@ struct net2280_regs { | |||
61 | #define EEPROM_WRITE_DATA 0 | 61 | #define EEPROM_WRITE_DATA 0 |
62 | u32 eeclkfreq; | 62 | u32 eeclkfreq; |
63 | u32 _unused0; | 63 | u32 _unused0; |
64 | // offset 0x0010 | 64 | /* offset 0x0010 */ |
65 | 65 | ||
66 | u32 pciirqenb0; /* interrupt PCI master ... */ | 66 | u32 pciirqenb0; /* interrupt PCI master ... */ |
67 | #define SETUP_PACKET_INTERRUPT_ENABLE 7 | 67 | #define SETUP_PACKET_INTERRUPT_ENABLE 7 |
@@ -131,7 +131,7 @@ struct net2280_regs { | |||
131 | #define RESUME_INTERRUPT_ENABLE 1 | 131 | #define RESUME_INTERRUPT_ENABLE 1 |
132 | #define SOF_INTERRUPT_ENABLE 0 | 132 | #define SOF_INTERRUPT_ENABLE 0 |
133 | 133 | ||
134 | // offset 0x0020 | 134 | /* offset 0x0020 */ |
135 | u32 _unused1; | 135 | u32 _unused1; |
136 | u32 usbirqenb1; | 136 | u32 usbirqenb1; |
137 | #define USB_INTERRUPT_ENABLE 31 | 137 | #define USB_INTERRUPT_ENABLE 31 |
@@ -195,7 +195,7 @@ struct net2280_regs { | |||
195 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT 2 | 195 | #define SUSPEND_REQUEST_CHANGE_INTERRUPT 2 |
196 | #define RESUME_INTERRUPT 1 | 196 | #define RESUME_INTERRUPT 1 |
197 | #define SOF_INTERRUPT 0 | 197 | #define SOF_INTERRUPT 0 |
198 | // offset 0x0030 | 198 | /* offset 0x0030 */ |
199 | u32 idxaddr; | 199 | u32 idxaddr; |
200 | u32 idxdata; | 200 | u32 idxdata; |
201 | u32 fifoctl; | 201 | u32 fifoctl; |
@@ -204,7 +204,7 @@ struct net2280_regs { | |||
204 | #define PCI_BASE2_SELECT 2 | 204 | #define PCI_BASE2_SELECT 2 |
205 | #define FIFO_CONFIGURATION_SELECT 0 | 205 | #define FIFO_CONFIGURATION_SELECT 0 |
206 | u32 _unused2; | 206 | u32 _unused2; |
207 | // offset 0x0040 | 207 | /* offset 0x0040 */ |
208 | u32 memaddr; | 208 | u32 memaddr; |
209 | #define START 28 | 209 | #define START 28 |
210 | #define DIRECTION 27 | 210 | #define DIRECTION 27 |
@@ -213,7 +213,7 @@ struct net2280_regs { | |||
213 | u32 memdata0; | 213 | u32 memdata0; |
214 | u32 memdata1; | 214 | u32 memdata1; |
215 | u32 _unused3; | 215 | u32 _unused3; |
216 | // offset 0x0050 | 216 | /* offset 0x0050 */ |
217 | u32 gpioctl; | 217 | u32 gpioctl; |
218 | #define GPIO3_LED_SELECT 12 | 218 | #define GPIO3_LED_SELECT 12 |
219 | #define GPIO3_INTERRUPT_ENABLE 11 | 219 | #define GPIO3_INTERRUPT_ENABLE 11 |
@@ -237,7 +237,7 @@ struct net2280_regs { | |||
237 | 237 | ||
238 | /* usb control, BAR0 + 0x0080 */ | 238 | /* usb control, BAR0 + 0x0080 */ |
239 | struct net2280_usb_regs { | 239 | struct net2280_usb_regs { |
240 | // offset 0x0080 | 240 | /* offset 0x0080 */ |
241 | u32 stdrsp; | 241 | u32 stdrsp; |
242 | #define STALL_UNSUPPORTED_REQUESTS 31 | 242 | #define STALL_UNSUPPORTED_REQUESTS 31 |
243 | #define SET_TEST_MODE 16 | 243 | #define SET_TEST_MODE 16 |
@@ -275,7 +275,7 @@ struct net2280_usb_regs { | |||
275 | #define PME_WAKEUP_ENABLE 2 | 275 | #define PME_WAKEUP_ENABLE 2 |
276 | #define DEVICE_REMOTE_WAKEUP_ENABLE 1 | 276 | #define DEVICE_REMOTE_WAKEUP_ENABLE 1 |
277 | #define SELF_POWERED_STATUS 0 | 277 | #define SELF_POWERED_STATUS 0 |
278 | // offset 0x0090 | 278 | /* offset 0x0090 */ |
279 | u32 usbstat; | 279 | u32 usbstat; |
280 | #define HIGH_SPEED 7 | 280 | #define HIGH_SPEED 7 |
281 | #define FULL_SPEED 6 | 281 | #define FULL_SPEED 6 |
@@ -291,7 +291,7 @@ struct net2280_usb_regs { | |||
291 | #define TERMINATION_SELECT 0 | 291 | #define TERMINATION_SELECT 0 |
292 | u32 setup0123; | 292 | u32 setup0123; |
293 | u32 setup4567; | 293 | u32 setup4567; |
294 | // offset 0x0090 | 294 | /* offset 0x0090 */ |
295 | u32 _unused0; | 295 | u32 _unused0; |
296 | u32 ouraddr; | 296 | u32 ouraddr; |
297 | #define FORCE_IMMEDIATE 7 | 297 | #define FORCE_IMMEDIATE 7 |
@@ -301,7 +301,7 @@ struct net2280_usb_regs { | |||
301 | 301 | ||
302 | /* pci control, BAR0 + 0x0100 */ | 302 | /* pci control, BAR0 + 0x0100 */ |
303 | struct net2280_pci_regs { | 303 | struct net2280_pci_regs { |
304 | // offset 0x0100 | 304 | /* offset 0x0100 */ |
305 | u32 pcimstctl; | 305 | u32 pcimstctl; |
306 | #define PCI_ARBITER_PARK_SELECT 13 | 306 | #define PCI_ARBITER_PARK_SELECT 13 |
307 | #define PCI_MULTI LEVEL_ARBITER 12 | 307 | #define PCI_MULTI LEVEL_ARBITER 12 |
@@ -331,7 +331,7 @@ struct net2280_pci_regs { | |||
331 | * that can be loaded into some of these registers. | 331 | * that can be loaded into some of these registers. |
332 | */ | 332 | */ |
333 | struct net2280_dma_regs { /* [11.7] */ | 333 | struct net2280_dma_regs { /* [11.7] */ |
334 | // offset 0x0180, 0x01a0, 0x01c0, 0x01e0, | 334 | /* offset 0x0180, 0x01a0, 0x01c0, 0x01e0, */ |
335 | u32 dmactl; | 335 | u32 dmactl; |
336 | #define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25 | 336 | #define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25 |
337 | #define DMA_CLEAR_COUNT_ENABLE 21 | 337 | #define DMA_CLEAR_COUNT_ENABLE 21 |
@@ -355,7 +355,7 @@ struct net2280_dma_regs { /* [11.7] */ | |||
355 | #define DMA_ABORT 1 | 355 | #define DMA_ABORT 1 |
356 | #define DMA_START 0 | 356 | #define DMA_START 0 |
357 | u32 _unused0 [2]; | 357 | u32 _unused0 [2]; |
358 | // offset 0x0190, 0x01b0, 0x01d0, 0x01f0, | 358 | /* offset 0x0190, 0x01b0, 0x01d0, 0x01f0, */ |
359 | u32 dmacount; | 359 | u32 dmacount; |
360 | #define VALID_BIT 31 | 360 | #define VALID_BIT 31 |
361 | #define DMA_DIRECTION 30 | 361 | #define DMA_DIRECTION 30 |
@@ -371,9 +371,9 @@ struct net2280_dma_regs { /* [11.7] */ | |||
371 | /* dedicated endpoint registers, BAR0 + 0x0200 */ | 371 | /* dedicated endpoint registers, BAR0 + 0x0200 */ |
372 | 372 | ||
373 | struct net2280_dep_regs { /* [11.8] */ | 373 | struct net2280_dep_regs { /* [11.8] */ |
374 | // offset 0x0200, 0x0210, 0x220, 0x230, 0x240 | 374 | /* offset 0x0200, 0x0210, 0x220, 0x230, 0x240 */ |
375 | u32 dep_cfg; | 375 | u32 dep_cfg; |
376 | // offset 0x0204, 0x0214, 0x224, 0x234, 0x244 | 376 | /* offset 0x0204, 0x0214, 0x224, 0x234, 0x244 */ |
377 | u32 dep_rsp; | 377 | u32 dep_rsp; |
378 | u32 _unused [2]; | 378 | u32 _unused [2]; |
379 | } __attribute__ ((packed)); | 379 | } __attribute__ ((packed)); |
@@ -383,7 +383,7 @@ struct net2280_dep_regs { /* [11.8] */ | |||
383 | * ep0 reserved for control; E and F have only 64 bytes of fifo | 383 | * ep0 reserved for control; E and F have only 64 bytes of fifo |
384 | */ | 384 | */ |
385 | struct net2280_ep_regs { /* [11.9] */ | 385 | struct net2280_ep_regs { /* [11.9] */ |
386 | // offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 | 386 | /* offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 */ |
387 | u32 ep_cfg; | 387 | u32 ep_cfg; |
388 | #define ENDPOINT_BYTE_COUNT 16 | 388 | #define ENDPOINT_BYTE_COUNT 16 |
389 | #define ENDPOINT_ENABLE 10 | 389 | #define ENDPOINT_ENABLE 10 |
@@ -435,7 +435,7 @@ struct net2280_ep_regs { /* [11.9] */ | |||
435 | #define DATA_PACKET_TRANSMITTED_INTERRUPT 2 | 435 | #define DATA_PACKET_TRANSMITTED_INTERRUPT 2 |
436 | #define DATA_OUT_PING_TOKEN_INTERRUPT 1 | 436 | #define DATA_OUT_PING_TOKEN_INTERRUPT 1 |
437 | #define DATA_IN_TOKEN_INTERRUPT 0 | 437 | #define DATA_IN_TOKEN_INTERRUPT 0 |
438 | // offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 | 438 | /* offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 */ |
439 | u32 ep_avail; | 439 | u32 ep_avail; |
440 | u32 ep_data; | 440 | u32 ep_data; |
441 | u32 _unused0 [2]; | 441 | u32 _unused0 [2]; |
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 9897f7a818c5..e007074ebe41 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h | |||
@@ -1,4 +1,4 @@ | |||
1 | // include/linux/usb/otg.h | 1 | /* USB OTG (On The Go) defines */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * These APIs may be used between USB controllers. USB device drivers | 4 | * These APIs may be used between USB controllers. USB device drivers |
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 488ce128885c..21b4a1c6f585 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -20,7 +20,8 @@ | |||
20 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ | 20 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ |
21 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ | 21 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ |
22 | 22 | ||
23 | #define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */ | 23 | /* The maximum number of ports one device can grab at once */ |
24 | #define MAX_NUM_PORTS 8 | ||
24 | 25 | ||
25 | /* parity check flag */ | 26 | /* parity check flag */ |
26 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 27 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
@@ -61,29 +62,29 @@ | |||
61 | * ports of a device. | 62 | * ports of a device. |
62 | */ | 63 | */ |
63 | struct usb_serial_port { | 64 | struct usb_serial_port { |
64 | struct usb_serial * serial; | 65 | struct usb_serial *serial; |
65 | struct tty_struct * tty; | 66 | struct tty_struct *tty; |
66 | spinlock_t lock; | 67 | spinlock_t lock; |
67 | struct mutex mutex; | 68 | struct mutex mutex; |
68 | unsigned char number; | 69 | unsigned char number; |
69 | 70 | ||
70 | unsigned char * interrupt_in_buffer; | 71 | unsigned char *interrupt_in_buffer; |
71 | struct urb * interrupt_in_urb; | 72 | struct urb *interrupt_in_urb; |
72 | __u8 interrupt_in_endpointAddress; | 73 | __u8 interrupt_in_endpointAddress; |
73 | 74 | ||
74 | unsigned char * interrupt_out_buffer; | 75 | unsigned char *interrupt_out_buffer; |
75 | int interrupt_out_size; | 76 | int interrupt_out_size; |
76 | struct urb * interrupt_out_urb; | 77 | struct urb *interrupt_out_urb; |
77 | __u8 interrupt_out_endpointAddress; | 78 | __u8 interrupt_out_endpointAddress; |
78 | 79 | ||
79 | unsigned char * bulk_in_buffer; | 80 | unsigned char *bulk_in_buffer; |
80 | int bulk_in_size; | 81 | int bulk_in_size; |
81 | struct urb * read_urb; | 82 | struct urb *read_urb; |
82 | __u8 bulk_in_endpointAddress; | 83 | __u8 bulk_in_endpointAddress; |
83 | 84 | ||
84 | unsigned char * bulk_out_buffer; | 85 | unsigned char *bulk_out_buffer; |
85 | int bulk_out_size; | 86 | int bulk_out_size; |
86 | struct urb * write_urb; | 87 | struct urb *write_urb; |
87 | int write_urb_busy; | 88 | int write_urb_busy; |
88 | __u8 bulk_out_endpointAddress; | 89 | __u8 bulk_out_endpointAddress; |
89 | 90 | ||
@@ -92,17 +93,19 @@ struct usb_serial_port { | |||
92 | int open_count; | 93 | int open_count; |
93 | char throttled; | 94 | char throttled; |
94 | char throttle_req; | 95 | char throttle_req; |
96 | char console; | ||
95 | struct device dev; | 97 | struct device dev; |
96 | }; | 98 | }; |
97 | #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) | 99 | #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) |
98 | 100 | ||
99 | /* get and set the port private data pointer helper functions */ | 101 | /* get and set the port private data pointer helper functions */ |
100 | static inline void *usb_get_serial_port_data (struct usb_serial_port *port) | 102 | static inline void *usb_get_serial_port_data(struct usb_serial_port *port) |
101 | { | 103 | { |
102 | return dev_get_drvdata(&port->dev); | 104 | return dev_get_drvdata(&port->dev); |
103 | } | 105 | } |
104 | 106 | ||
105 | static inline void usb_set_serial_port_data (struct usb_serial_port *port, void *data) | 107 | static inline void usb_set_serial_port_data(struct usb_serial_port *port, |
108 | void *data) | ||
106 | { | 109 | { |
107 | dev_set_drvdata(&port->dev, data); | 110 | dev_set_drvdata(&port->dev, data); |
108 | } | 111 | } |
@@ -125,9 +128,10 @@ static inline void usb_set_serial_port_data (struct usb_serial_port *port, void | |||
125 | * usb_set_serial_data() to access this. | 128 | * usb_set_serial_data() to access this. |
126 | */ | 129 | */ |
127 | struct usb_serial { | 130 | struct usb_serial { |
128 | struct usb_device * dev; | 131 | struct usb_device *dev; |
129 | struct usb_serial_driver * type; | 132 | struct usb_serial_driver *type; |
130 | struct usb_interface * interface; | 133 | struct usb_interface *interface; |
134 | unsigned char disconnected; | ||
131 | unsigned char minor; | 135 | unsigned char minor; |
132 | unsigned char num_ports; | 136 | unsigned char num_ports; |
133 | unsigned char num_port_pointers; | 137 | unsigned char num_port_pointers; |
@@ -135,29 +139,30 @@ struct usb_serial { | |||
135 | char num_interrupt_out; | 139 | char num_interrupt_out; |
136 | char num_bulk_in; | 140 | char num_bulk_in; |
137 | char num_bulk_out; | 141 | char num_bulk_out; |
138 | struct usb_serial_port * port[MAX_NUM_PORTS]; | 142 | struct usb_serial_port *port[MAX_NUM_PORTS]; |
139 | struct kref kref; | 143 | struct kref kref; |
140 | void * private; | 144 | struct mutex disc_mutex; |
145 | void *private; | ||
141 | }; | 146 | }; |
142 | #define to_usb_serial(d) container_of(d, struct usb_serial, kref) | 147 | #define to_usb_serial(d) container_of(d, struct usb_serial, kref) |
143 | 148 | ||
144 | #define NUM_DONT_CARE 99 | 149 | #define NUM_DONT_CARE 99 |
145 | 150 | ||
146 | /* get and set the serial private data pointer helper functions */ | 151 | /* get and set the serial private data pointer helper functions */ |
147 | static inline void *usb_get_serial_data (struct usb_serial *serial) | 152 | static inline void *usb_get_serial_data(struct usb_serial *serial) |
148 | { | 153 | { |
149 | return serial->private; | 154 | return serial->private; |
150 | } | 155 | } |
151 | 156 | ||
152 | static inline void usb_set_serial_data (struct usb_serial *serial, void *data) | 157 | static inline void usb_set_serial_data(struct usb_serial *serial, void *data) |
153 | { | 158 | { |
154 | serial->private = data; | 159 | serial->private = data; |
155 | } | 160 | } |
156 | 161 | ||
157 | /** | 162 | /** |
158 | * usb_serial_driver - describes a usb serial driver | 163 | * usb_serial_driver - describes a usb serial driver |
159 | * @description: pointer to a string that describes this driver. This string used | 164 | * @description: pointer to a string that describes this driver. This string |
160 | * in the syslog messages when a device is inserted or removed. | 165 | * used in the syslog messages when a device is inserted or removed. |
161 | * @id_table: pointer to a list of usb_device_id structures that define all | 166 | * @id_table: pointer to a list of usb_device_id structures that define all |
162 | * of the devices this structure can support. | 167 | * of the devices this structure can support. |
163 | * @num_interrupt_in: If a device doesn't have this many interrupt-in | 168 | * @num_interrupt_in: If a device doesn't have this many interrupt-in |
@@ -218,82 +223,91 @@ struct usb_serial_driver { | |||
218 | struct usb_driver *usb_driver; | 223 | struct usb_driver *usb_driver; |
219 | struct usb_dynids dynids; | 224 | struct usb_dynids dynids; |
220 | 225 | ||
221 | int (*probe) (struct usb_serial *serial, const struct usb_device_id *id); | 226 | int (*probe)(struct usb_serial *serial, const struct usb_device_id *id); |
222 | int (*attach) (struct usb_serial *serial); | 227 | int (*attach)(struct usb_serial *serial); |
223 | int (*calc_num_ports) (struct usb_serial *serial); | 228 | int (*calc_num_ports) (struct usb_serial *serial); |
224 | 229 | ||
225 | void (*shutdown) (struct usb_serial *serial); | 230 | void (*shutdown)(struct usb_serial *serial); |
226 | 231 | ||
227 | int (*port_probe) (struct usb_serial_port *port); | 232 | int (*port_probe)(struct usb_serial_port *port); |
228 | int (*port_remove) (struct usb_serial_port *port); | 233 | int (*port_remove)(struct usb_serial_port *port); |
229 | 234 | ||
230 | int (*suspend) (struct usb_serial *serial, pm_message_t message); | 235 | int (*suspend)(struct usb_serial *serial, pm_message_t message); |
231 | int (*resume) (struct usb_serial *serial); | 236 | int (*resume)(struct usb_serial *serial); |
232 | 237 | ||
233 | /* serial function calls */ | 238 | /* serial function calls */ |
234 | int (*open) (struct usb_serial_port *port, struct file * filp); | 239 | int (*open)(struct usb_serial_port *port, struct file *filp); |
235 | void (*close) (struct usb_serial_port *port, struct file * filp); | 240 | void (*close)(struct usb_serial_port *port, struct file *filp); |
236 | int (*write) (struct usb_serial_port *port, const unsigned char *buf, int count); | 241 | int (*write)(struct usb_serial_port *port, const unsigned char *buf, |
237 | int (*write_room) (struct usb_serial_port *port); | 242 | int count); |
238 | int (*ioctl) (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 243 | int (*write_room)(struct usb_serial_port *port); |
239 | void (*set_termios) (struct usb_serial_port *port, struct ktermios * old); | 244 | int (*ioctl)(struct usb_serial_port *port, struct file *file, |
240 | void (*break_ctl) (struct usb_serial_port *port, int break_state); | 245 | unsigned int cmd, unsigned long arg); |
241 | int (*chars_in_buffer) (struct usb_serial_port *port); | 246 | void (*set_termios)(struct usb_serial_port *port, struct ktermios *old); |
242 | void (*throttle) (struct usb_serial_port *port); | 247 | void (*break_ctl)(struct usb_serial_port *port, int break_state); |
243 | void (*unthrottle) (struct usb_serial_port *port); | 248 | int (*chars_in_buffer)(struct usb_serial_port *port); |
244 | int (*tiocmget) (struct usb_serial_port *port, struct file *file); | 249 | void (*throttle)(struct usb_serial_port *port); |
245 | int (*tiocmset) (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); | 250 | void (*unthrottle)(struct usb_serial_port *port); |
251 | int (*tiocmget)(struct usb_serial_port *port, struct file *file); | ||
252 | int (*tiocmset)(struct usb_serial_port *port, struct file *file, | ||
253 | unsigned int set, unsigned int clear); | ||
246 | 254 | ||
247 | void (*read_int_callback)(struct urb *urb); | 255 | void (*read_int_callback)(struct urb *urb); |
248 | void (*write_int_callback)(struct urb *urb); | 256 | void (*write_int_callback)(struct urb *urb); |
249 | void (*read_bulk_callback)(struct urb *urb); | 257 | void (*read_bulk_callback)(struct urb *urb); |
250 | void (*write_bulk_callback)(struct urb *urb); | 258 | void (*write_bulk_callback)(struct urb *urb); |
251 | }; | 259 | }; |
252 | #define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver) | 260 | #define to_usb_serial_driver(d) \ |
261 | container_of(d, struct usb_serial_driver, driver) | ||
253 | 262 | ||
254 | extern int usb_serial_register(struct usb_serial_driver *driver); | 263 | extern int usb_serial_register(struct usb_serial_driver *driver); |
255 | extern void usb_serial_deregister(struct usb_serial_driver *driver); | 264 | extern void usb_serial_deregister(struct usb_serial_driver *driver); |
256 | extern void usb_serial_port_softint(struct usb_serial_port *port); | 265 | extern void usb_serial_port_softint(struct usb_serial_port *port); |
257 | 266 | ||
258 | extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); | 267 | extern int usb_serial_probe(struct usb_interface *iface, |
268 | const struct usb_device_id *id); | ||
259 | extern void usb_serial_disconnect(struct usb_interface *iface); | 269 | extern void usb_serial_disconnect(struct usb_interface *iface); |
260 | 270 | ||
261 | extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message); | 271 | extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message); |
262 | extern int usb_serial_resume(struct usb_interface *intf); | 272 | extern int usb_serial_resume(struct usb_interface *intf); |
263 | 273 | ||
264 | extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest); | 274 | extern int ezusb_writememory(struct usb_serial *serial, int address, |
265 | extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit); | 275 | unsigned char *data, int length, __u8 bRequest); |
276 | extern int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit); | ||
266 | 277 | ||
267 | /* USB Serial console functions */ | 278 | /* USB Serial console functions */ |
268 | #ifdef CONFIG_USB_SERIAL_CONSOLE | 279 | #ifdef CONFIG_USB_SERIAL_CONSOLE |
269 | extern void usb_serial_console_init (int debug, int minor); | 280 | extern void usb_serial_console_init(int debug, int minor); |
270 | extern void usb_serial_console_exit (void); | 281 | extern void usb_serial_console_exit(void); |
271 | extern void usb_serial_console_disconnect(struct usb_serial *serial); | 282 | extern void usb_serial_console_disconnect(struct usb_serial *serial); |
272 | #else | 283 | #else |
273 | static inline void usb_serial_console_init (int debug, int minor) { } | 284 | static inline void usb_serial_console_init(int debug, int minor) { } |
274 | static inline void usb_serial_console_exit (void) { } | 285 | static inline void usb_serial_console_exit(void) { } |
275 | static inline void usb_serial_console_disconnect(struct usb_serial *serial) {} | 286 | static inline void usb_serial_console_disconnect(struct usb_serial *serial) {} |
276 | #endif | 287 | #endif |
277 | 288 | ||
278 | /* Functions needed by other parts of the usbserial core */ | 289 | /* Functions needed by other parts of the usbserial core */ |
279 | extern struct usb_serial *usb_serial_get_by_index (unsigned int minor); | 290 | extern struct usb_serial *usb_serial_get_by_index(unsigned int minor); |
280 | extern void usb_serial_put(struct usb_serial *serial); | 291 | extern void usb_serial_put(struct usb_serial *serial); |
281 | extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); | 292 | extern int usb_serial_generic_open(struct usb_serial_port *port, |
282 | extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count); | 293 | struct file *filp); |
283 | extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); | 294 | extern int usb_serial_generic_write(struct usb_serial_port *port, |
284 | extern int usb_serial_generic_resume (struct usb_serial *serial); | 295 | const unsigned char *buf, int count); |
285 | extern int usb_serial_generic_write_room (struct usb_serial_port *port); | 296 | extern void usb_serial_generic_close(struct usb_serial_port *port, |
286 | extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port); | 297 | struct file *filp); |
287 | extern void usb_serial_generic_read_bulk_callback (struct urb *urb); | 298 | extern int usb_serial_generic_resume(struct usb_serial *serial); |
288 | extern void usb_serial_generic_write_bulk_callback (struct urb *urb); | 299 | extern int usb_serial_generic_write_room(struct usb_serial_port *port); |
289 | extern void usb_serial_generic_throttle (struct usb_serial_port *port); | 300 | extern int usb_serial_generic_chars_in_buffer(struct usb_serial_port *port); |
290 | extern void usb_serial_generic_unthrottle (struct usb_serial_port *port); | 301 | extern void usb_serial_generic_read_bulk_callback(struct urb *urb); |
291 | extern void usb_serial_generic_shutdown (struct usb_serial *serial); | 302 | extern void usb_serial_generic_write_bulk_callback(struct urb *urb); |
292 | extern int usb_serial_generic_register (int debug); | 303 | extern void usb_serial_generic_throttle(struct usb_serial_port *port); |
293 | extern void usb_serial_generic_deregister (void); | 304 | extern void usb_serial_generic_unthrottle(struct usb_serial_port *port); |
294 | 305 | extern void usb_serial_generic_shutdown(struct usb_serial *serial); | |
295 | extern int usb_serial_bus_register (struct usb_serial_driver *device); | 306 | extern int usb_serial_generic_register(int debug); |
296 | extern void usb_serial_bus_deregister (struct usb_serial_driver *device); | 307 | extern void usb_serial_generic_deregister(void); |
308 | |||
309 | extern int usb_serial_bus_register(struct usb_serial_driver *device); | ||
310 | extern void usb_serial_bus_deregister(struct usb_serial_driver *device); | ||
297 | 311 | ||
298 | extern struct usb_serial_driver usb_serial_generic_device; | 312 | extern struct usb_serial_driver usb_serial_generic_device; |
299 | extern struct bus_type usb_serial_bus_type; | 313 | extern struct bus_type usb_serial_bus_type; |
@@ -307,16 +321,22 @@ static inline void usb_serial_debug_data(int debug, | |||
307 | int i; | 321 | int i; |
308 | 322 | ||
309 | if (debug) { | 323 | if (debug) { |
310 | dev_printk(KERN_DEBUG, dev, "%s - length = %d, data = ", function, size); | 324 | dev_printk(KERN_DEBUG, dev, "%s - length = %d, data = ", |
325 | function, size); | ||
311 | for (i = 0; i < size; ++i) | 326 | for (i = 0; i < size; ++i) |
312 | printk ("%.2x ", data[i]); | 327 | printk("%.2x ", data[i]); |
313 | printk ("\n"); | 328 | printk("\n"); |
314 | } | 329 | } |
315 | } | 330 | } |
316 | 331 | ||
317 | /* Use our own dbg macro */ | 332 | /* Use our own dbg macro */ |
318 | #undef dbg | 333 | #undef dbg |
319 | #define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg); } while (0) | 334 | #define dbg(format, arg...) \ |
335 | do { \ | ||
336 | if (debug) \ | ||
337 | printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , \ | ||
338 | ## arg); \ | ||
339 | } while (0) | ||
320 | 340 | ||
321 | 341 | ||
322 | 342 | ||
diff --git a/include/linux/usb/sl811.h b/include/linux/usb/sl811.h index 397ee3b3d7f3..877373da410d 100644 --- a/include/linux/usb/sl811.h +++ b/include/linux/usb/sl811.h | |||
@@ -19,8 +19,8 @@ struct sl811_platform_data { | |||
19 | /* pulse sl811 nRST (probably with a GPIO) */ | 19 | /* pulse sl811 nRST (probably with a GPIO) */ |
20 | void (*reset)(struct device *dev); | 20 | void (*reset)(struct device *dev); |
21 | 21 | ||
22 | // some boards need something like these: | 22 | /* some boards need something like these: */ |
23 | // int (*check_overcurrent)(struct device *dev); | 23 | /* int (*check_overcurrent)(struct device *dev); */ |
24 | // void (*clock_enable)(struct device *dev, int is_on); | 24 | /* void (*clock_enable)(struct device *dev, int is_on); */ |
25 | }; | 25 | }; |
26 | 26 | ||
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index a417b09b8b3d..cee0623b3c7b 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h | |||
@@ -80,10 +80,9 @@ enum { US_DO_ALL_FLAGS }; | |||
80 | #define US_SC_UFI 0x04 /* Floppy */ | 80 | #define US_SC_UFI 0x04 /* Floppy */ |
81 | #define US_SC_8070 0x05 /* Removable media */ | 81 | #define US_SC_8070 0x05 /* Removable media */ |
82 | #define US_SC_SCSI 0x06 /* Transparent */ | 82 | #define US_SC_SCSI 0x06 /* Transparent */ |
83 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | 83 | #define US_SC_LOCKABLE 0x07 /* Password-protected */ |
84 | #define US_SC_MIN US_SC_RBC | ||
85 | #define US_SC_MAX US_SC_ISD200 | ||
86 | 84 | ||
85 | #define US_SC_ISD200 0xf0 /* ISD200 ATA */ | ||
87 | #define US_SC_DEVICE 0xff /* Use device's value */ | 86 | #define US_SC_DEVICE 0xff /* Use device's value */ |
88 | 87 | ||
89 | /* Protocols */ | 88 | /* Protocols */ |
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h index 8ca5a7fbc9ec..17cb108b7db0 100644 --- a/include/linux/usbdevice_fs.h +++ b/include/linux/usbdevice_fs.h | |||
@@ -104,7 +104,7 @@ struct usbdevfs_urb { | |||
104 | int error_count; | 104 | int error_count; |
105 | unsigned int signr; /* signal to be sent on completion, | 105 | unsigned int signr; /* signal to be sent on completion, |
106 | or 0 if none should be sent. */ | 106 | or 0 if none should be sent. */ |
107 | void *usercontext; | 107 | void __user *usercontext; |
108 | struct usbdevfs_iso_packet_desc iso_frame_desc[0]; | 108 | struct usbdevfs_iso_packet_desc iso_frame_desc[0]; |
109 | }; | 109 | }; |
110 | 110 | ||
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 8e186c678149..ef9b802738a5 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -44,9 +44,30 @@ config PM_VERBOSE | |||
44 | ---help--- | 44 | ---help--- |
45 | This option enables verbose messages from the Power Management code. | 45 | This option enables verbose messages from the Power Management code. |
46 | 46 | ||
47 | config CAN_PM_TRACE | ||
48 | def_bool y | ||
49 | depends on PM_DEBUG && PM_SLEEP && EXPERIMENTAL | ||
50 | |||
47 | config PM_TRACE | 51 | config PM_TRACE |
52 | bool | ||
53 | help | ||
54 | This enables code to save the last PM event point across | ||
55 | reboot. The architecture needs to support this, x86 for | ||
56 | example does by saving things in the RTC, see below. | ||
57 | |||
58 | The architecture specific code must provide the extern | ||
59 | functions from <linux/resume-trace.h> as well as the | ||
60 | <asm/resume-trace.h> header with a TRACE_RESUME() macro. | ||
61 | |||
62 | The way the information is presented is architecture- | ||
63 | dependent, x86 will print the information during a | ||
64 | late_initcall. | ||
65 | |||
66 | config PM_TRACE_RTC | ||
48 | bool "Suspend/resume event tracing" | 67 | bool "Suspend/resume event tracing" |
49 | depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL | 68 | depends on CAN_PM_TRACE |
69 | depends on X86 | ||
70 | select PM_TRACE | ||
50 | default n | 71 | default n |
51 | ---help--- | 72 | ---help--- |
52 | This enables some cheesy code to save the last PM event point in the | 73 | This enables some cheesy code to save the last PM event point in the |
@@ -63,7 +84,8 @@ config PM_TRACE | |||
63 | 84 | ||
64 | config PM_SLEEP_SMP | 85 | config PM_SLEEP_SMP |
65 | bool | 86 | bool |
66 | depends on SUSPEND_SMP_POSSIBLE || HIBERNATION_SMP_POSSIBLE | 87 | depends on SMP |
88 | depends on ARCH_SUSPEND_POSSIBLE || ARCH_HIBERNATION_POSSIBLE | ||
67 | depends on PM_SLEEP | 89 | depends on PM_SLEEP |
68 | select HOTPLUG_CPU | 90 | select HOTPLUG_CPU |
69 | default y | 91 | default y |
@@ -73,46 +95,29 @@ config PM_SLEEP | |||
73 | depends on SUSPEND || HIBERNATION | 95 | depends on SUSPEND || HIBERNATION |
74 | default y | 96 | default y |
75 | 97 | ||
76 | config SUSPEND_UP_POSSIBLE | ||
77 | bool | ||
78 | depends on (X86 && !X86_VOYAGER) || PPC || ARM || BLACKFIN || MIPS \ | ||
79 | || SUPERH || FRV | ||
80 | depends on !SMP | ||
81 | default y | ||
82 | |||
83 | config SUSPEND_SMP_POSSIBLE | ||
84 | bool | ||
85 | depends on (X86 && !X86_VOYAGER) \ | ||
86 | || (PPC && (PPC_PSERIES || PPC_PMAC)) || ARM | ||
87 | depends on SMP | ||
88 | default y | ||
89 | |||
90 | config SUSPEND | 98 | config SUSPEND |
91 | bool "Suspend to RAM and standby" | 99 | bool "Suspend to RAM and standby" |
92 | depends on PM | 100 | depends on PM && ARCH_SUSPEND_POSSIBLE |
93 | depends on SUSPEND_UP_POSSIBLE || SUSPEND_SMP_POSSIBLE | ||
94 | default y | 101 | default y |
95 | ---help--- | 102 | ---help--- |
96 | Allow the system to enter sleep states in which main memory is | 103 | Allow the system to enter sleep states in which main memory is |
97 | powered and thus its contents are preserved, such as the | 104 | powered and thus its contents are preserved, such as the |
98 | suspend-to-RAM state (i.e. the ACPI S3 state). | 105 | suspend-to-RAM state (e.g. the ACPI S3 state). |
99 | 106 | ||
100 | config HIBERNATION_UP_POSSIBLE | 107 | config SUSPEND_FREEZER |
101 | bool | 108 | bool "Enable freezer for suspend to RAM/standby" \ |
102 | depends on X86 || PPC64_SWSUSP || PPC32 | 109 | if ARCH_WANTS_FREEZER_CONTROL || BROKEN |
103 | depends on !SMP | 110 | depends on SUSPEND |
104 | default y | 111 | default y |
112 | help | ||
113 | This allows you to turn off the freezer for suspend. If this is | ||
114 | done, no tasks are frozen for suspend to RAM/standby. | ||
105 | 115 | ||
106 | config HIBERNATION_SMP_POSSIBLE | 116 | Turning OFF this setting is NOT recommended! If in doubt, say Y. |
107 | bool | ||
108 | depends on (X86 && !X86_VOYAGER) || PPC64_SWSUSP | ||
109 | depends on SMP | ||
110 | default y | ||
111 | 117 | ||
112 | config HIBERNATION | 118 | config HIBERNATION |
113 | bool "Hibernation (aka 'suspend to disk')" | 119 | bool "Hibernation (aka 'suspend to disk')" |
114 | depends on PM && SWAP | 120 | depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE |
115 | depends on HIBERNATION_UP_POSSIBLE || HIBERNATION_SMP_POSSIBLE | ||
116 | ---help--- | 121 | ---help--- |
117 | Enable the suspend to disk (STD) functionality, which is usually | 122 | Enable the suspend to disk (STD) functionality, which is usually |
118 | called "hibernation" in user interfaces. STD checkpoints the | 123 | called "hibernation" in user interfaces. STD checkpoints the |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index b138b431e271..d09da0895174 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -54,8 +54,8 @@ static struct platform_hibernation_ops *hibernation_ops; | |||
54 | 54 | ||
55 | void hibernation_set_ops(struct platform_hibernation_ops *ops) | 55 | void hibernation_set_ops(struct platform_hibernation_ops *ops) |
56 | { | 56 | { |
57 | if (ops && !(ops->start && ops->pre_snapshot && ops->finish | 57 | if (ops && !(ops->begin && ops->end && ops->pre_snapshot |
58 | && ops->prepare && ops->enter && ops->pre_restore | 58 | && ops->prepare && ops->finish && ops->enter && ops->pre_restore |
59 | && ops->restore_cleanup)) { | 59 | && ops->restore_cleanup)) { |
60 | WARN_ON(1); | 60 | WARN_ON(1); |
61 | return; | 61 | return; |
@@ -70,15 +70,55 @@ void hibernation_set_ops(struct platform_hibernation_ops *ops) | |||
70 | mutex_unlock(&pm_mutex); | 70 | mutex_unlock(&pm_mutex); |
71 | } | 71 | } |
72 | 72 | ||
73 | #ifdef CONFIG_PM_DEBUG | ||
74 | static void hibernation_debug_sleep(void) | ||
75 | { | ||
76 | printk(KERN_INFO "hibernation debug: Waiting for 5 seconds.\n"); | ||
77 | mdelay(5000); | ||
78 | } | ||
79 | |||
80 | static int hibernation_testmode(int mode) | ||
81 | { | ||
82 | if (hibernation_mode == mode) { | ||
83 | hibernation_debug_sleep(); | ||
84 | return 1; | ||
85 | } | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int hibernation_test(int level) | ||
90 | { | ||
91 | if (pm_test_level == level) { | ||
92 | hibernation_debug_sleep(); | ||
93 | return 1; | ||
94 | } | ||
95 | return 0; | ||
96 | } | ||
97 | #else /* !CONFIG_PM_DEBUG */ | ||
98 | static int hibernation_testmode(int mode) { return 0; } | ||
99 | static int hibernation_test(int level) { return 0; } | ||
100 | #endif /* !CONFIG_PM_DEBUG */ | ||
101 | |||
73 | /** | 102 | /** |
74 | * platform_start - tell the platform driver that we're starting | 103 | * platform_begin - tell the platform driver that we're starting |
75 | * hibernation | 104 | * hibernation |
76 | */ | 105 | */ |
77 | 106 | ||
78 | static int platform_start(int platform_mode) | 107 | static int platform_begin(int platform_mode) |
79 | { | 108 | { |
80 | return (platform_mode && hibernation_ops) ? | 109 | return (platform_mode && hibernation_ops) ? |
81 | hibernation_ops->start() : 0; | 110 | hibernation_ops->begin() : 0; |
111 | } | ||
112 | |||
113 | /** | ||
114 | * platform_end - tell the platform driver that we've entered the | ||
115 | * working state | ||
116 | */ | ||
117 | |||
118 | static void platform_end(int platform_mode) | ||
119 | { | ||
120 | if (platform_mode && hibernation_ops) | ||
121 | hibernation_ops->end(); | ||
82 | } | 122 | } |
83 | 123 | ||
84 | /** | 124 | /** |
@@ -162,19 +202,25 @@ int create_image(int platform_mode) | |||
162 | */ | 202 | */ |
163 | error = device_power_down(PMSG_FREEZE); | 203 | error = device_power_down(PMSG_FREEZE); |
164 | if (error) { | 204 | if (error) { |
165 | printk(KERN_ERR "Some devices failed to power down, " | 205 | printk(KERN_ERR "PM: Some devices failed to power down, " |
166 | KERN_ERR "aborting suspend\n"); | 206 | "aborting hibernation\n"); |
167 | goto Enable_irqs; | 207 | goto Enable_irqs; |
168 | } | 208 | } |
169 | 209 | ||
210 | if (hibernation_test(TEST_CORE)) | ||
211 | goto Power_up; | ||
212 | |||
213 | in_suspend = 1; | ||
170 | save_processor_state(); | 214 | save_processor_state(); |
171 | error = swsusp_arch_suspend(); | 215 | error = swsusp_arch_suspend(); |
172 | if (error) | 216 | if (error) |
173 | printk(KERN_ERR "Error %d while creating the image\n", error); | 217 | printk(KERN_ERR "PM: Error %d creating hibernation image\n", |
218 | error); | ||
174 | /* Restore control flow magically appears here */ | 219 | /* Restore control flow magically appears here */ |
175 | restore_processor_state(); | 220 | restore_processor_state(); |
176 | if (!in_suspend) | 221 | if (!in_suspend) |
177 | platform_leave(platform_mode); | 222 | platform_leave(platform_mode); |
223 | Power_up: | ||
178 | /* NOTE: device_power_up() is just a resume() for devices | 224 | /* NOTE: device_power_up() is just a resume() for devices |
179 | * that suspended with irqs off ... no overall powerup. | 225 | * that suspended with irqs off ... no overall powerup. |
180 | */ | 226 | */ |
@@ -202,36 +248,90 @@ int hibernation_snapshot(int platform_mode) | |||
202 | if (error) | 248 | if (error) |
203 | return error; | 249 | return error; |
204 | 250 | ||
205 | error = platform_start(platform_mode); | 251 | error = platform_begin(platform_mode); |
206 | if (error) | 252 | if (error) |
207 | return error; | 253 | goto Close; |
208 | 254 | ||
209 | suspend_console(); | 255 | suspend_console(); |
210 | error = device_suspend(PMSG_FREEZE); | 256 | error = device_suspend(PMSG_FREEZE); |
211 | if (error) | 257 | if (error) |
212 | goto Resume_console; | 258 | goto Resume_console; |
213 | 259 | ||
214 | error = platform_pre_snapshot(platform_mode); | 260 | if (hibernation_test(TEST_DEVICES)) |
215 | if (error) | ||
216 | goto Resume_devices; | 261 | goto Resume_devices; |
217 | 262 | ||
263 | error = platform_pre_snapshot(platform_mode); | ||
264 | if (error || hibernation_test(TEST_PLATFORM)) | ||
265 | goto Finish; | ||
266 | |||
218 | error = disable_nonboot_cpus(); | 267 | error = disable_nonboot_cpus(); |
219 | if (!error) { | 268 | if (!error) { |
220 | if (hibernation_mode != HIBERNATION_TEST) { | 269 | if (hibernation_test(TEST_CPUS)) |
221 | in_suspend = 1; | 270 | goto Enable_cpus; |
222 | error = create_image(platform_mode); | 271 | |
223 | /* Control returns here after successful restore */ | 272 | if (hibernation_testmode(HIBERNATION_TEST)) |
224 | } else { | 273 | goto Enable_cpus; |
225 | printk("swsusp debug: Waiting for 5 seconds.\n"); | 274 | |
226 | mdelay(5000); | 275 | error = create_image(platform_mode); |
227 | } | 276 | /* Control returns here after successful restore */ |
228 | } | 277 | } |
278 | Enable_cpus: | ||
229 | enable_nonboot_cpus(); | 279 | enable_nonboot_cpus(); |
230 | Resume_devices: | 280 | Finish: |
231 | platform_finish(platform_mode); | 281 | platform_finish(platform_mode); |
282 | Resume_devices: | ||
232 | device_resume(); | 283 | device_resume(); |
233 | Resume_console: | 284 | Resume_console: |
234 | resume_console(); | 285 | resume_console(); |
286 | Close: | ||
287 | platform_end(platform_mode); | ||
288 | return error; | ||
289 | } | ||
290 | |||
291 | /** | ||
292 | * resume_target_kernel - prepare devices that need to be suspended with | ||
293 | * interrupts off, restore the contents of highmem that have not been | ||
294 | * restored yet from the image and run the low level code that will restore | ||
295 | * the remaining contents of memory and switch to the just restored target | ||
296 | * kernel. | ||
297 | */ | ||
298 | |||
299 | static int resume_target_kernel(void) | ||
300 | { | ||
301 | int error; | ||
302 | |||
303 | local_irq_disable(); | ||
304 | error = device_power_down(PMSG_PRETHAW); | ||
305 | if (error) { | ||
306 | printk(KERN_ERR "PM: Some devices failed to power down, " | ||
307 | "aborting resume\n"); | ||
308 | goto Enable_irqs; | ||
309 | } | ||
310 | /* We'll ignore saved state, but this gets preempt count (etc) right */ | ||
311 | save_processor_state(); | ||
312 | error = restore_highmem(); | ||
313 | if (!error) { | ||
314 | error = swsusp_arch_resume(); | ||
315 | /* | ||
316 | * The code below is only ever reached in case of a failure. | ||
317 | * Otherwise execution continues at place where | ||
318 | * swsusp_arch_suspend() was called | ||
319 | */ | ||
320 | BUG_ON(!error); | ||
321 | /* This call to restore_highmem() undos the previous one */ | ||
322 | restore_highmem(); | ||
323 | } | ||
324 | /* | ||
325 | * The only reason why swsusp_arch_resume() can fail is memory being | ||
326 | * very tight, so we have to free it as soon as we can to avoid | ||
327 | * subsequent failures | ||
328 | */ | ||
329 | swsusp_free(); | ||
330 | restore_processor_state(); | ||
331 | touch_softlockup_watchdog(); | ||
332 | device_power_up(); | ||
333 | Enable_irqs: | ||
334 | local_irq_enable(); | ||
235 | return error; | 335 | return error; |
236 | } | 336 | } |
237 | 337 | ||
@@ -258,7 +358,7 @@ int hibernation_restore(int platform_mode) | |||
258 | if (!error) { | 358 | if (!error) { |
259 | error = disable_nonboot_cpus(); | 359 | error = disable_nonboot_cpus(); |
260 | if (!error) | 360 | if (!error) |
261 | error = swsusp_resume(); | 361 | error = resume_target_kernel(); |
262 | enable_nonboot_cpus(); | 362 | enable_nonboot_cpus(); |
263 | } | 363 | } |
264 | platform_restore_cleanup(platform_mode); | 364 | platform_restore_cleanup(platform_mode); |
@@ -286,9 +386,9 @@ int hibernation_platform_enter(void) | |||
286 | * hibernation_ops->finish() before saving the image, so we should let | 386 | * hibernation_ops->finish() before saving the image, so we should let |
287 | * the firmware know that we're going to enter the sleep state after all | 387 | * the firmware know that we're going to enter the sleep state after all |
288 | */ | 388 | */ |
289 | error = hibernation_ops->start(); | 389 | error = hibernation_ops->begin(); |
290 | if (error) | 390 | if (error) |
291 | return error; | 391 | goto Close; |
292 | 392 | ||
293 | suspend_console(); | 393 | suspend_console(); |
294 | error = device_suspend(PMSG_SUSPEND); | 394 | error = device_suspend(PMSG_SUSPEND); |
@@ -322,6 +422,8 @@ int hibernation_platform_enter(void) | |||
322 | device_resume(); | 422 | device_resume(); |
323 | Resume_console: | 423 | Resume_console: |
324 | resume_console(); | 424 | resume_console(); |
425 | Close: | ||
426 | hibernation_ops->end(); | ||
325 | return error; | 427 | return error; |
326 | } | 428 | } |
327 | 429 | ||
@@ -352,24 +454,17 @@ static void power_down(void) | |||
352 | * Valid image is on the disk, if we continue we risk serious data | 454 | * Valid image is on the disk, if we continue we risk serious data |
353 | * corruption after resume. | 455 | * corruption after resume. |
354 | */ | 456 | */ |
355 | printk(KERN_CRIT "Please power me down manually\n"); | 457 | printk(KERN_CRIT "PM: Please power down manually\n"); |
356 | while(1); | 458 | while(1); |
357 | } | 459 | } |
358 | 460 | ||
359 | static void unprepare_processes(void) | ||
360 | { | ||
361 | thaw_processes(); | ||
362 | pm_restore_console(); | ||
363 | } | ||
364 | |||
365 | static int prepare_processes(void) | 461 | static int prepare_processes(void) |
366 | { | 462 | { |
367 | int error = 0; | 463 | int error = 0; |
368 | 464 | ||
369 | pm_prepare_console(); | ||
370 | if (freeze_processes()) { | 465 | if (freeze_processes()) { |
371 | error = -EBUSY; | 466 | error = -EBUSY; |
372 | unprepare_processes(); | 467 | thaw_processes(); |
373 | } | 468 | } |
374 | return error; | 469 | return error; |
375 | } | 470 | } |
@@ -389,6 +484,7 @@ int hibernate(void) | |||
389 | goto Unlock; | 484 | goto Unlock; |
390 | } | 485 | } |
391 | 486 | ||
487 | pm_prepare_console(); | ||
392 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); | 488 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); |
393 | if (error) | 489 | if (error) |
394 | goto Exit; | 490 | goto Exit; |
@@ -398,7 +494,7 @@ int hibernate(void) | |||
398 | if (error) | 494 | if (error) |
399 | goto Exit; | 495 | goto Exit; |
400 | 496 | ||
401 | printk("Syncing filesystems ... "); | 497 | printk(KERN_INFO "PM: Syncing filesystems ... "); |
402 | sys_sync(); | 498 | sys_sync(); |
403 | printk("done.\n"); | 499 | printk("done.\n"); |
404 | 500 | ||
@@ -406,11 +502,12 @@ int hibernate(void) | |||
406 | if (error) | 502 | if (error) |
407 | goto Finish; | 503 | goto Finish; |
408 | 504 | ||
409 | if (hibernation_mode == HIBERNATION_TESTPROC) { | 505 | if (hibernation_test(TEST_FREEZER)) |
410 | printk("swsusp debug: Waiting for 5 seconds.\n"); | ||
411 | mdelay(5000); | ||
412 | goto Thaw; | 506 | goto Thaw; |
413 | } | 507 | |
508 | if (hibernation_testmode(HIBERNATION_TESTPROC)) | ||
509 | goto Thaw; | ||
510 | |||
414 | error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); | 511 | error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); |
415 | if (in_suspend && !error) { | 512 | if (in_suspend && !error) { |
416 | unsigned int flags = 0; | 513 | unsigned int flags = 0; |
@@ -427,11 +524,12 @@ int hibernate(void) | |||
427 | swsusp_free(); | 524 | swsusp_free(); |
428 | } | 525 | } |
429 | Thaw: | 526 | Thaw: |
430 | unprepare_processes(); | 527 | thaw_processes(); |
431 | Finish: | 528 | Finish: |
432 | free_basic_memory_bitmaps(); | 529 | free_basic_memory_bitmaps(); |
433 | Exit: | 530 | Exit: |
434 | pm_notifier_call_chain(PM_POST_HIBERNATION); | 531 | pm_notifier_call_chain(PM_POST_HIBERNATION); |
532 | pm_restore_console(); | ||
435 | atomic_inc(&snapshot_device_available); | 533 | atomic_inc(&snapshot_device_available); |
436 | Unlock: | 534 | Unlock: |
437 | mutex_unlock(&pm_mutex); | 535 | mutex_unlock(&pm_mutex); |
@@ -473,22 +571,23 @@ static int software_resume(void) | |||
473 | return -ENOENT; | 571 | return -ENOENT; |
474 | } | 572 | } |
475 | swsusp_resume_device = name_to_dev_t(resume_file); | 573 | swsusp_resume_device = name_to_dev_t(resume_file); |
476 | pr_debug("swsusp: Resume From Partition %s\n", resume_file); | 574 | pr_debug("PM: Resume from partition %s\n", resume_file); |
477 | } else { | 575 | } else { |
478 | pr_debug("swsusp: Resume From Partition %d:%d\n", | 576 | pr_debug("PM: Resume from partition %d:%d\n", |
479 | MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); | 577 | MAJOR(swsusp_resume_device), |
578 | MINOR(swsusp_resume_device)); | ||
480 | } | 579 | } |
481 | 580 | ||
482 | if (noresume) { | 581 | if (noresume) { |
483 | /** | 582 | /** |
484 | * FIXME: If noresume is specified, we need to find the partition | 583 | * FIXME: If noresume is specified, we need to find the |
485 | * and reset it back to normal swap space. | 584 | * partition and reset it back to normal swap space. |
486 | */ | 585 | */ |
487 | mutex_unlock(&pm_mutex); | 586 | mutex_unlock(&pm_mutex); |
488 | return 0; | 587 | return 0; |
489 | } | 588 | } |
490 | 589 | ||
491 | pr_debug("PM: Checking swsusp image.\n"); | 590 | pr_debug("PM: Checking hibernation image.\n"); |
492 | error = swsusp_check(); | 591 | error = swsusp_check(); |
493 | if (error) | 592 | if (error) |
494 | goto Unlock; | 593 | goto Unlock; |
@@ -499,6 +598,11 @@ static int software_resume(void) | |||
499 | goto Unlock; | 598 | goto Unlock; |
500 | } | 599 | } |
501 | 600 | ||
601 | pm_prepare_console(); | ||
602 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); | ||
603 | if (error) | ||
604 | goto Finish; | ||
605 | |||
502 | error = create_basic_memory_bitmaps(); | 606 | error = create_basic_memory_bitmaps(); |
503 | if (error) | 607 | if (error) |
504 | goto Finish; | 608 | goto Finish; |
@@ -510,7 +614,7 @@ static int software_resume(void) | |||
510 | goto Done; | 614 | goto Done; |
511 | } | 615 | } |
512 | 616 | ||
513 | pr_debug("PM: Reading swsusp image.\n"); | 617 | pr_debug("PM: Reading hibernation image.\n"); |
514 | 618 | ||
515 | error = swsusp_read(&flags); | 619 | error = swsusp_read(&flags); |
516 | if (!error) | 620 | if (!error) |
@@ -518,10 +622,12 @@ static int software_resume(void) | |||
518 | 622 | ||
519 | printk(KERN_ERR "PM: Restore failed, recovering.\n"); | 623 | printk(KERN_ERR "PM: Restore failed, recovering.\n"); |
520 | swsusp_free(); | 624 | swsusp_free(); |
521 | unprepare_processes(); | 625 | thaw_processes(); |
522 | Done: | 626 | Done: |
523 | free_basic_memory_bitmaps(); | 627 | free_basic_memory_bitmaps(); |
524 | Finish: | 628 | Finish: |
629 | pm_notifier_call_chain(PM_POST_RESTORE); | ||
630 | pm_restore_console(); | ||
525 | atomic_inc(&snapshot_device_available); | 631 | atomic_inc(&snapshot_device_available); |
526 | /* For success case, the suspend path will release the lock */ | 632 | /* For success case, the suspend path will release the lock */ |
527 | Unlock: | 633 | Unlock: |
@@ -636,7 +742,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, | |||
636 | error = -EINVAL; | 742 | error = -EINVAL; |
637 | 743 | ||
638 | if (!error) | 744 | if (!error) |
639 | pr_debug("PM: suspend-to-disk mode set to '%s'\n", | 745 | pr_debug("PM: Hibernation mode set to '%s'\n", |
640 | hibernation_modes[mode]); | 746 | hibernation_modes[mode]); |
641 | mutex_unlock(&pm_mutex); | 747 | mutex_unlock(&pm_mutex); |
642 | return error ? error : n; | 748 | return error ? error : n; |
@@ -668,7 +774,7 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, | |||
668 | mutex_lock(&pm_mutex); | 774 | mutex_lock(&pm_mutex); |
669 | swsusp_resume_device = res; | 775 | swsusp_resume_device = res; |
670 | mutex_unlock(&pm_mutex); | 776 | mutex_unlock(&pm_mutex); |
671 | printk("Attempting manual resume\n"); | 777 | printk(KERN_INFO "PM: Starting manual resume from disk\n"); |
672 | noresume = 0; | 778 | noresume = 0; |
673 | software_resume(); | 779 | software_resume(); |
674 | ret = n; | 780 | ret = n; |
diff --git a/kernel/power/main.c b/kernel/power/main.c index efc08360e627..6a6d5eb3524e 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -24,13 +24,112 @@ | |||
24 | 24 | ||
25 | #include "power.h" | 25 | #include "power.h" |
26 | 26 | ||
27 | BLOCKING_NOTIFIER_HEAD(pm_chain_head); | ||
28 | |||
29 | DEFINE_MUTEX(pm_mutex); | 27 | DEFINE_MUTEX(pm_mutex); |
30 | 28 | ||
31 | unsigned int pm_flags; | 29 | unsigned int pm_flags; |
32 | EXPORT_SYMBOL(pm_flags); | 30 | EXPORT_SYMBOL(pm_flags); |
33 | 31 | ||
32 | #ifdef CONFIG_PM_SLEEP | ||
33 | |||
34 | /* Routines for PM-transition notifications */ | ||
35 | |||
36 | static BLOCKING_NOTIFIER_HEAD(pm_chain_head); | ||
37 | |||
38 | int register_pm_notifier(struct notifier_block *nb) | ||
39 | { | ||
40 | return blocking_notifier_chain_register(&pm_chain_head, nb); | ||
41 | } | ||
42 | EXPORT_SYMBOL_GPL(register_pm_notifier); | ||
43 | |||
44 | int unregister_pm_notifier(struct notifier_block *nb) | ||
45 | { | ||
46 | return blocking_notifier_chain_unregister(&pm_chain_head, nb); | ||
47 | } | ||
48 | EXPORT_SYMBOL_GPL(unregister_pm_notifier); | ||
49 | |||
50 | int pm_notifier_call_chain(unsigned long val) | ||
51 | { | ||
52 | return (blocking_notifier_call_chain(&pm_chain_head, val, NULL) | ||
53 | == NOTIFY_BAD) ? -EINVAL : 0; | ||
54 | } | ||
55 | |||
56 | #ifdef CONFIG_PM_DEBUG | ||
57 | int pm_test_level = TEST_NONE; | ||
58 | |||
59 | static int suspend_test(int level) | ||
60 | { | ||
61 | if (pm_test_level == level) { | ||
62 | printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); | ||
63 | mdelay(5000); | ||
64 | return 1; | ||
65 | } | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static const char * const pm_tests[__TEST_AFTER_LAST] = { | ||
70 | [TEST_NONE] = "none", | ||
71 | [TEST_CORE] = "core", | ||
72 | [TEST_CPUS] = "processors", | ||
73 | [TEST_PLATFORM] = "platform", | ||
74 | [TEST_DEVICES] = "devices", | ||
75 | [TEST_FREEZER] = "freezer", | ||
76 | }; | ||
77 | |||
78 | static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr, | ||
79 | char *buf) | ||
80 | { | ||
81 | char *s = buf; | ||
82 | int level; | ||
83 | |||
84 | for (level = TEST_FIRST; level <= TEST_MAX; level++) | ||
85 | if (pm_tests[level]) { | ||
86 | if (level == pm_test_level) | ||
87 | s += sprintf(s, "[%s] ", pm_tests[level]); | ||
88 | else | ||
89 | s += sprintf(s, "%s ", pm_tests[level]); | ||
90 | } | ||
91 | |||
92 | if (s != buf) | ||
93 | /* convert the last space to a newline */ | ||
94 | *(s-1) = '\n'; | ||
95 | |||
96 | return (s - buf); | ||
97 | } | ||
98 | |||
99 | static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, | ||
100 | const char *buf, size_t n) | ||
101 | { | ||
102 | const char * const *s; | ||
103 | int level; | ||
104 | char *p; | ||
105 | int len; | ||
106 | int error = -EINVAL; | ||
107 | |||
108 | p = memchr(buf, '\n', n); | ||
109 | len = p ? p - buf : n; | ||
110 | |||
111 | mutex_lock(&pm_mutex); | ||
112 | |||
113 | level = TEST_FIRST; | ||
114 | for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++) | ||
115 | if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) { | ||
116 | pm_test_level = level; | ||
117 | error = 0; | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | mutex_unlock(&pm_mutex); | ||
122 | |||
123 | return error ? error : n; | ||
124 | } | ||
125 | |||
126 | power_attr(pm_test); | ||
127 | #else /* !CONFIG_PM_DEBUG */ | ||
128 | static inline int suspend_test(int level) { return 0; } | ||
129 | #endif /* !CONFIG_PM_DEBUG */ | ||
130 | |||
131 | #endif /* CONFIG_PM_SLEEP */ | ||
132 | |||
34 | #ifdef CONFIG_SUSPEND | 133 | #ifdef CONFIG_SUSPEND |
35 | 134 | ||
36 | /* This is just an arbitrary number */ | 135 | /* This is just an arbitrary number */ |
@@ -76,13 +175,13 @@ static int suspend_prepare(void) | |||
76 | if (!suspend_ops || !suspend_ops->enter) | 175 | if (!suspend_ops || !suspend_ops->enter) |
77 | return -EPERM; | 176 | return -EPERM; |
78 | 177 | ||
178 | pm_prepare_console(); | ||
179 | |||
79 | error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); | 180 | error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); |
80 | if (error) | 181 | if (error) |
81 | goto Finish; | 182 | goto Finish; |
82 | 183 | ||
83 | pm_prepare_console(); | 184 | if (suspend_freeze_processes()) { |
84 | |||
85 | if (freeze_processes()) { | ||
86 | error = -EAGAIN; | 185 | error = -EAGAIN; |
87 | goto Thaw; | 186 | goto Thaw; |
88 | } | 187 | } |
@@ -100,10 +199,10 @@ static int suspend_prepare(void) | |||
100 | return 0; | 199 | return 0; |
101 | 200 | ||
102 | Thaw: | 201 | Thaw: |
103 | thaw_processes(); | 202 | suspend_thaw_processes(); |
104 | pm_restore_console(); | ||
105 | Finish: | 203 | Finish: |
106 | pm_notifier_call_chain(PM_POST_SUSPEND); | 204 | pm_notifier_call_chain(PM_POST_SUSPEND); |
205 | pm_restore_console(); | ||
107 | return error; | 206 | return error; |
108 | } | 207 | } |
109 | 208 | ||
@@ -133,10 +232,13 @@ static int suspend_enter(suspend_state_t state) | |||
133 | BUG_ON(!irqs_disabled()); | 232 | BUG_ON(!irqs_disabled()); |
134 | 233 | ||
135 | if ((error = device_power_down(PMSG_SUSPEND))) { | 234 | if ((error = device_power_down(PMSG_SUSPEND))) { |
136 | printk(KERN_ERR "Some devices failed to power down\n"); | 235 | printk(KERN_ERR "PM: Some devices failed to power down\n"); |
137 | goto Done; | 236 | goto Done; |
138 | } | 237 | } |
139 | error = suspend_ops->enter(state); | 238 | |
239 | if (!suspend_test(TEST_CORE)) | ||
240 | error = suspend_ops->enter(state); | ||
241 | |||
140 | device_power_up(); | 242 | device_power_up(); |
141 | Done: | 243 | Done: |
142 | arch_suspend_enable_irqs(); | 244 | arch_suspend_enable_irqs(); |
@@ -145,8 +247,8 @@ static int suspend_enter(suspend_state_t state) | |||
145 | } | 247 | } |
146 | 248 | ||
147 | /** | 249 | /** |
148 | * suspend_devices_and_enter - suspend devices and enter the desired system sleep | 250 | * suspend_devices_and_enter - suspend devices and enter the desired system |
149 | * state. | 251 | * sleep state. |
150 | * @state: state to enter | 252 | * @state: state to enter |
151 | */ | 253 | */ |
152 | int suspend_devices_and_enter(suspend_state_t state) | 254 | int suspend_devices_and_enter(suspend_state_t state) |
@@ -156,33 +258,45 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
156 | if (!suspend_ops) | 258 | if (!suspend_ops) |
157 | return -ENOSYS; | 259 | return -ENOSYS; |
158 | 260 | ||
159 | if (suspend_ops->set_target) { | 261 | if (suspend_ops->begin) { |
160 | error = suspend_ops->set_target(state); | 262 | error = suspend_ops->begin(state); |
161 | if (error) | 263 | if (error) |
162 | return error; | 264 | goto Close; |
163 | } | 265 | } |
164 | suspend_console(); | 266 | suspend_console(); |
165 | error = device_suspend(PMSG_SUSPEND); | 267 | error = device_suspend(PMSG_SUSPEND); |
166 | if (error) { | 268 | if (error) { |
167 | printk(KERN_ERR "Some devices failed to suspend\n"); | 269 | printk(KERN_ERR "PM: Some devices failed to suspend\n"); |
168 | goto Resume_console; | 270 | goto Resume_console; |
169 | } | 271 | } |
272 | |||
273 | if (suspend_test(TEST_DEVICES)) | ||
274 | goto Resume_devices; | ||
275 | |||
170 | if (suspend_ops->prepare) { | 276 | if (suspend_ops->prepare) { |
171 | error = suspend_ops->prepare(); | 277 | error = suspend_ops->prepare(); |
172 | if (error) | 278 | if (error) |
173 | goto Resume_devices; | 279 | goto Resume_devices; |
174 | } | 280 | } |
281 | |||
282 | if (suspend_test(TEST_PLATFORM)) | ||
283 | goto Finish; | ||
284 | |||
175 | error = disable_nonboot_cpus(); | 285 | error = disable_nonboot_cpus(); |
176 | if (!error) | 286 | if (!error && !suspend_test(TEST_CPUS)) |
177 | suspend_enter(state); | 287 | suspend_enter(state); |
178 | 288 | ||
179 | enable_nonboot_cpus(); | 289 | enable_nonboot_cpus(); |
290 | Finish: | ||
180 | if (suspend_ops->finish) | 291 | if (suspend_ops->finish) |
181 | suspend_ops->finish(); | 292 | suspend_ops->finish(); |
182 | Resume_devices: | 293 | Resume_devices: |
183 | device_resume(); | 294 | device_resume(); |
184 | Resume_console: | 295 | Resume_console: |
185 | resume_console(); | 296 | resume_console(); |
297 | Close: | ||
298 | if (suspend_ops->end) | ||
299 | suspend_ops->end(); | ||
186 | return error; | 300 | return error; |
187 | } | 301 | } |
188 | 302 | ||
@@ -194,9 +308,9 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
194 | */ | 308 | */ |
195 | static void suspend_finish(void) | 309 | static void suspend_finish(void) |
196 | { | 310 | { |
197 | thaw_processes(); | 311 | suspend_thaw_processes(); |
198 | pm_restore_console(); | ||
199 | pm_notifier_call_chain(PM_POST_SUSPEND); | 312 | pm_notifier_call_chain(PM_POST_SUSPEND); |
313 | pm_restore_console(); | ||
200 | } | 314 | } |
201 | 315 | ||
202 | 316 | ||
@@ -238,17 +352,22 @@ static int enter_state(suspend_state_t state) | |||
238 | if (!mutex_trylock(&pm_mutex)) | 352 | if (!mutex_trylock(&pm_mutex)) |
239 | return -EBUSY; | 353 | return -EBUSY; |
240 | 354 | ||
241 | printk("Syncing filesystems ... "); | 355 | printk(KERN_INFO "PM: Syncing filesystems ... "); |
242 | sys_sync(); | 356 | sys_sync(); |
243 | printk("done.\n"); | 357 | printk("done.\n"); |
244 | 358 | ||
245 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); | 359 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); |
246 | if ((error = suspend_prepare())) | 360 | error = suspend_prepare(); |
361 | if (error) | ||
247 | goto Unlock; | 362 | goto Unlock; |
248 | 363 | ||
364 | if (suspend_test(TEST_FREEZER)) | ||
365 | goto Finish; | ||
366 | |||
249 | pr_debug("PM: Entering %s sleep\n", pm_states[state]); | 367 | pr_debug("PM: Entering %s sleep\n", pm_states[state]); |
250 | error = suspend_devices_and_enter(state); | 368 | error = suspend_devices_and_enter(state); |
251 | 369 | ||
370 | Finish: | ||
252 | pr_debug("PM: Finishing wakeup.\n"); | 371 | pr_debug("PM: Finishing wakeup.\n"); |
253 | suspend_finish(); | 372 | suspend_finish(); |
254 | Unlock: | 373 | Unlock: |
@@ -369,18 +488,18 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr, | |||
369 | } | 488 | } |
370 | 489 | ||
371 | power_attr(pm_trace); | 490 | power_attr(pm_trace); |
491 | #endif /* CONFIG_PM_TRACE */ | ||
372 | 492 | ||
373 | static struct attribute * g[] = { | 493 | static struct attribute * g[] = { |
374 | &state_attr.attr, | 494 | &state_attr.attr, |
495 | #ifdef CONFIG_PM_TRACE | ||
375 | &pm_trace_attr.attr, | 496 | &pm_trace_attr.attr, |
497 | #endif | ||
498 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG) | ||
499 | &pm_test_attr.attr, | ||
500 | #endif | ||
376 | NULL, | 501 | NULL, |
377 | }; | 502 | }; |
378 | #else | ||
379 | static struct attribute * g[] = { | ||
380 | &state_attr.attr, | ||
381 | NULL, | ||
382 | }; | ||
383 | #endif /* CONFIG_PM_TRACE */ | ||
384 | 503 | ||
385 | static struct attribute_group attr_group = { | 504 | static struct attribute_group attr_group = { |
386 | .attrs = g, | 505 | .attrs = g, |
diff --git a/kernel/power/power.h b/kernel/power/power.h index 2093c3a9a994..700f44ec8406 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #include <linux/suspend.h> | 1 | #include <linux/suspend.h> |
2 | #include <linux/suspend_ioctls.h> | ||
2 | #include <linux/utsname.h> | 3 | #include <linux/utsname.h> |
4 | #include <linux/freezer.h> | ||
3 | 5 | ||
4 | struct swsusp_info { | 6 | struct swsusp_info { |
5 | struct new_utsname uts; | 7 | struct new_utsname uts; |
@@ -128,42 +130,12 @@ struct snapshot_handle { | |||
128 | #define data_of(handle) ((handle).buffer + (handle).buf_offset) | 130 | #define data_of(handle) ((handle).buffer + (handle).buf_offset) |
129 | 131 | ||
130 | extern unsigned int snapshot_additional_pages(struct zone *zone); | 132 | extern unsigned int snapshot_additional_pages(struct zone *zone); |
133 | extern unsigned long snapshot_get_image_size(void); | ||
131 | extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); | 134 | extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); |
132 | extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); | 135 | extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); |
133 | extern void snapshot_write_finalize(struct snapshot_handle *handle); | 136 | extern void snapshot_write_finalize(struct snapshot_handle *handle); |
134 | extern int snapshot_image_loaded(struct snapshot_handle *handle); | 137 | extern int snapshot_image_loaded(struct snapshot_handle *handle); |
135 | 138 | ||
136 | /* | ||
137 | * This structure is used to pass the values needed for the identification | ||
138 | * of the resume swap area from a user space to the kernel via the | ||
139 | * SNAPSHOT_SET_SWAP_AREA ioctl | ||
140 | */ | ||
141 | struct resume_swap_area { | ||
142 | loff_t offset; | ||
143 | u_int32_t dev; | ||
144 | } __attribute__((packed)); | ||
145 | |||
146 | #define SNAPSHOT_IOC_MAGIC '3' | ||
147 | #define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1) | ||
148 | #define SNAPSHOT_UNFREEZE _IO(SNAPSHOT_IOC_MAGIC, 2) | ||
149 | #define SNAPSHOT_ATOMIC_SNAPSHOT _IOW(SNAPSHOT_IOC_MAGIC, 3, void *) | ||
150 | #define SNAPSHOT_ATOMIC_RESTORE _IO(SNAPSHOT_IOC_MAGIC, 4) | ||
151 | #define SNAPSHOT_FREE _IO(SNAPSHOT_IOC_MAGIC, 5) | ||
152 | #define SNAPSHOT_SET_IMAGE_SIZE _IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long) | ||
153 | #define SNAPSHOT_AVAIL_SWAP _IOR(SNAPSHOT_IOC_MAGIC, 7, void *) | ||
154 | #define SNAPSHOT_GET_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 8, void *) | ||
155 | #define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9) | ||
156 | #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) | ||
157 | #define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11) | ||
158 | #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) | ||
159 | #define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \ | ||
160 | struct resume_swap_area) | ||
161 | #define SNAPSHOT_IOC_MAXNR 13 | ||
162 | |||
163 | #define PMOPS_PREPARE 1 | ||
164 | #define PMOPS_ENTER 2 | ||
165 | #define PMOPS_FINISH 3 | ||
166 | |||
167 | /* If unset, the snapshot device cannot be open. */ | 139 | /* If unset, the snapshot device cannot be open. */ |
168 | extern atomic_t snapshot_device_available; | 140 | extern atomic_t snapshot_device_available; |
169 | 141 | ||
@@ -181,7 +153,6 @@ extern int swsusp_swap_in_use(void); | |||
181 | extern int swsusp_check(void); | 153 | extern int swsusp_check(void); |
182 | extern int swsusp_shrink_memory(void); | 154 | extern int swsusp_shrink_memory(void); |
183 | extern void swsusp_free(void); | 155 | extern void swsusp_free(void); |
184 | extern int swsusp_resume(void); | ||
185 | extern int swsusp_read(unsigned int *flags_p); | 156 | extern int swsusp_read(unsigned int *flags_p); |
186 | extern int swsusp_write(unsigned int flags); | 157 | extern int swsusp_write(unsigned int flags); |
187 | extern void swsusp_close(void); | 158 | extern void swsusp_close(void); |
@@ -201,11 +172,56 @@ static inline int suspend_devices_and_enter(suspend_state_t state) | |||
201 | } | 172 | } |
202 | #endif /* !CONFIG_SUSPEND */ | 173 | #endif /* !CONFIG_SUSPEND */ |
203 | 174 | ||
204 | /* kernel/power/common.c */ | 175 | #ifdef CONFIG_PM_SLEEP |
205 | extern struct blocking_notifier_head pm_chain_head; | 176 | /* kernel/power/main.c */ |
177 | extern int pm_notifier_call_chain(unsigned long val); | ||
178 | #endif | ||
179 | |||
180 | #ifdef CONFIG_HIGHMEM | ||
181 | unsigned int count_highmem_pages(void); | ||
182 | int restore_highmem(void); | ||
183 | #else | ||
184 | static inline unsigned int count_highmem_pages(void) { return 0; } | ||
185 | static inline int restore_highmem(void) { return 0; } | ||
186 | #endif | ||
187 | |||
188 | /* | ||
189 | * Suspend test levels | ||
190 | */ | ||
191 | enum { | ||
192 | /* keep first */ | ||
193 | TEST_NONE, | ||
194 | TEST_CORE, | ||
195 | TEST_CPUS, | ||
196 | TEST_PLATFORM, | ||
197 | TEST_DEVICES, | ||
198 | TEST_FREEZER, | ||
199 | /* keep last */ | ||
200 | __TEST_AFTER_LAST | ||
201 | }; | ||
202 | |||
203 | #define TEST_FIRST TEST_NONE | ||
204 | #define TEST_MAX (__TEST_AFTER_LAST - 1) | ||
205 | |||
206 | extern int pm_test_level; | ||
207 | |||
208 | #ifdef CONFIG_SUSPEND_FREEZER | ||
209 | static inline int suspend_freeze_processes(void) | ||
210 | { | ||
211 | return freeze_processes(); | ||
212 | } | ||
206 | 213 | ||
207 | static inline int pm_notifier_call_chain(unsigned long val) | 214 | static inline void suspend_thaw_processes(void) |
208 | { | 215 | { |
209 | return (blocking_notifier_call_chain(&pm_chain_head, val, NULL) | 216 | thaw_processes(); |
210 | == NOTIFY_BAD) ? -EINVAL : 0; | ||
211 | } | 217 | } |
218 | #else | ||
219 | static inline int suspend_freeze_processes(void) | ||
220 | { | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static inline void suspend_thaw_processes(void) | ||
225 | { | ||
226 | } | ||
227 | #endif | ||
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 78039b477d2b..f6a5df934f8d 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -635,7 +635,7 @@ __register_nosave_region(unsigned long start_pfn, unsigned long end_pfn, | |||
635 | region->end_pfn = end_pfn; | 635 | region->end_pfn = end_pfn; |
636 | list_add_tail(®ion->list, &nosave_regions); | 636 | list_add_tail(®ion->list, &nosave_regions); |
637 | Report: | 637 | Report: |
638 | printk("swsusp: Registered nosave memory region: %016lx - %016lx\n", | 638 | printk(KERN_INFO "PM: Registered nosave memory: %016lx - %016lx\n", |
639 | start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); | 639 | start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); |
640 | } | 640 | } |
641 | 641 | ||
@@ -704,7 +704,7 @@ static void mark_nosave_pages(struct memory_bitmap *bm) | |||
704 | list_for_each_entry(region, &nosave_regions, list) { | 704 | list_for_each_entry(region, &nosave_regions, list) { |
705 | unsigned long pfn; | 705 | unsigned long pfn; |
706 | 706 | ||
707 | printk("swsusp: Marking nosave pages: %016lx - %016lx\n", | 707 | pr_debug("PM: Marking nosave pages: %016lx - %016lx\n", |
708 | region->start_pfn << PAGE_SHIFT, | 708 | region->start_pfn << PAGE_SHIFT, |
709 | region->end_pfn << PAGE_SHIFT); | 709 | region->end_pfn << PAGE_SHIFT); |
710 | 710 | ||
@@ -749,7 +749,7 @@ int create_basic_memory_bitmaps(void) | |||
749 | free_pages_map = bm2; | 749 | free_pages_map = bm2; |
750 | mark_nosave_pages(forbidden_pages_map); | 750 | mark_nosave_pages(forbidden_pages_map); |
751 | 751 | ||
752 | printk("swsusp: Basic memory bitmaps created\n"); | 752 | pr_debug("PM: Basic memory bitmaps created\n"); |
753 | 753 | ||
754 | return 0; | 754 | return 0; |
755 | 755 | ||
@@ -784,7 +784,7 @@ void free_basic_memory_bitmaps(void) | |||
784 | memory_bm_free(bm2, PG_UNSAFE_CLEAR); | 784 | memory_bm_free(bm2, PG_UNSAFE_CLEAR); |
785 | kfree(bm2); | 785 | kfree(bm2); |
786 | 786 | ||
787 | printk("swsusp: Basic memory bitmaps freed\n"); | 787 | pr_debug("PM: Basic memory bitmaps freed\n"); |
788 | } | 788 | } |
789 | 789 | ||
790 | /** | 790 | /** |
@@ -872,7 +872,6 @@ unsigned int count_highmem_pages(void) | |||
872 | } | 872 | } |
873 | #else | 873 | #else |
874 | static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } | 874 | static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } |
875 | static inline unsigned int count_highmem_pages(void) { return 0; } | ||
876 | #endif /* CONFIG_HIGHMEM */ | 875 | #endif /* CONFIG_HIGHMEM */ |
877 | 876 | ||
878 | /** | 877 | /** |
@@ -1089,7 +1088,7 @@ static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem) | |||
1089 | } | 1088 | } |
1090 | 1089 | ||
1091 | nr_pages += count_pages_for_highmem(nr_highmem); | 1090 | nr_pages += count_pages_for_highmem(nr_highmem); |
1092 | pr_debug("swsusp: Normal pages needed: %u + %u + %u, available pages: %u\n", | 1091 | pr_debug("PM: Normal pages needed: %u + %u + %u, available pages: %u\n", |
1093 | nr_pages, PAGES_FOR_IO, meta, free); | 1092 | nr_pages, PAGES_FOR_IO, meta, free); |
1094 | 1093 | ||
1095 | return free > nr_pages + PAGES_FOR_IO + meta; | 1094 | return free > nr_pages + PAGES_FOR_IO + meta; |
@@ -1202,20 +1201,20 @@ asmlinkage int swsusp_save(void) | |||
1202 | { | 1201 | { |
1203 | unsigned int nr_pages, nr_highmem; | 1202 | unsigned int nr_pages, nr_highmem; |
1204 | 1203 | ||
1205 | printk("swsusp: critical section: \n"); | 1204 | printk(KERN_INFO "PM: Creating hibernation image: \n"); |
1206 | 1205 | ||
1207 | drain_local_pages(); | 1206 | drain_local_pages(); |
1208 | nr_pages = count_data_pages(); | 1207 | nr_pages = count_data_pages(); |
1209 | nr_highmem = count_highmem_pages(); | 1208 | nr_highmem = count_highmem_pages(); |
1210 | printk("swsusp: Need to copy %u pages\n", nr_pages + nr_highmem); | 1209 | printk(KERN_INFO "PM: Need to copy %u pages\n", nr_pages + nr_highmem); |
1211 | 1210 | ||
1212 | if (!enough_free_mem(nr_pages, nr_highmem)) { | 1211 | if (!enough_free_mem(nr_pages, nr_highmem)) { |
1213 | printk(KERN_ERR "swsusp: Not enough free memory\n"); | 1212 | printk(KERN_ERR "PM: Not enough free memory\n"); |
1214 | return -ENOMEM; | 1213 | return -ENOMEM; |
1215 | } | 1214 | } |
1216 | 1215 | ||
1217 | if (swsusp_alloc(&orig_bm, ©_bm, nr_pages, nr_highmem)) { | 1216 | if (swsusp_alloc(&orig_bm, ©_bm, nr_pages, nr_highmem)) { |
1218 | printk(KERN_ERR "swsusp: Memory allocation failed\n"); | 1217 | printk(KERN_ERR "PM: Memory allocation failed\n"); |
1219 | return -ENOMEM; | 1218 | return -ENOMEM; |
1220 | } | 1219 | } |
1221 | 1220 | ||
@@ -1235,7 +1234,8 @@ asmlinkage int swsusp_save(void) | |||
1235 | nr_copy_pages = nr_pages; | 1234 | nr_copy_pages = nr_pages; |
1236 | nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE); | 1235 | nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE); |
1237 | 1236 | ||
1238 | printk("swsusp: critical section: done (%d pages copied)\n", nr_pages); | 1237 | printk(KERN_INFO "PM: Hibernation image created (%d pages copied)\n", |
1238 | nr_pages); | ||
1239 | 1239 | ||
1240 | return 0; | 1240 | return 0; |
1241 | } | 1241 | } |
@@ -1264,12 +1264,17 @@ static char *check_image_kernel(struct swsusp_info *info) | |||
1264 | } | 1264 | } |
1265 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ | 1265 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ |
1266 | 1266 | ||
1267 | unsigned long snapshot_get_image_size(void) | ||
1268 | { | ||
1269 | return nr_copy_pages + nr_meta_pages + 1; | ||
1270 | } | ||
1271 | |||
1267 | static int init_header(struct swsusp_info *info) | 1272 | static int init_header(struct swsusp_info *info) |
1268 | { | 1273 | { |
1269 | memset(info, 0, sizeof(struct swsusp_info)); | 1274 | memset(info, 0, sizeof(struct swsusp_info)); |
1270 | info->num_physpages = num_physpages; | 1275 | info->num_physpages = num_physpages; |
1271 | info->image_pages = nr_copy_pages; | 1276 | info->image_pages = nr_copy_pages; |
1272 | info->pages = nr_copy_pages + nr_meta_pages + 1; | 1277 | info->pages = snapshot_get_image_size(); |
1273 | info->size = info->pages; | 1278 | info->size = info->pages; |
1274 | info->size <<= PAGE_SHIFT; | 1279 | info->size <<= PAGE_SHIFT; |
1275 | return init_header_complete(info); | 1280 | return init_header_complete(info); |
@@ -1429,7 +1434,7 @@ static int check_header(struct swsusp_info *info) | |||
1429 | if (!reason && info->num_physpages != num_physpages) | 1434 | if (!reason && info->num_physpages != num_physpages) |
1430 | reason = "memory size"; | 1435 | reason = "memory size"; |
1431 | if (reason) { | 1436 | if (reason) { |
1432 | printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason); | 1437 | printk(KERN_ERR "PM: Image mismatch: %s\n", reason); |
1433 | return -EPERM; | 1438 | return -EPERM; |
1434 | } | 1439 | } |
1435 | return 0; | 1440 | return 0; |
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 917aba100575..a0abf9a463f9 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -28,8 +28,6 @@ | |||
28 | 28 | ||
29 | #include "power.h" | 29 | #include "power.h" |
30 | 30 | ||
31 | extern char resume_file[]; | ||
32 | |||
33 | #define SWSUSP_SIG "S1SUSPEND" | 31 | #define SWSUSP_SIG "S1SUSPEND" |
34 | 32 | ||
35 | struct swsusp_header { | 33 | struct swsusp_header { |
@@ -73,7 +71,8 @@ static int submit(int rw, pgoff_t page_off, struct page *page, | |||
73 | bio->bi_end_io = end_swap_bio_read; | 71 | bio->bi_end_io = end_swap_bio_read; |
74 | 72 | ||
75 | if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { | 73 | if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { |
76 | printk("swsusp: ERROR: adding page to bio at %ld\n", page_off); | 74 | printk(KERN_ERR "PM: Adding page to bio failed at %ld\n", |
75 | page_off); | ||
77 | bio_put(bio); | 76 | bio_put(bio); |
78 | return -EFAULT; | 77 | return -EFAULT; |
79 | } | 78 | } |
@@ -153,7 +152,7 @@ static int mark_swapfiles(sector_t start, unsigned int flags) | |||
153 | error = bio_write_page(swsusp_resume_block, | 152 | error = bio_write_page(swsusp_resume_block, |
154 | swsusp_header, NULL); | 153 | swsusp_header, NULL); |
155 | } else { | 154 | } else { |
156 | printk(KERN_ERR "swsusp: Swap header not found!\n"); | 155 | printk(KERN_ERR "PM: Swap header not found!\n"); |
157 | error = -ENODEV; | 156 | error = -ENODEV; |
158 | } | 157 | } |
159 | return error; | 158 | return error; |
@@ -325,7 +324,8 @@ static int save_image(struct swap_map_handle *handle, | |||
325 | struct timeval start; | 324 | struct timeval start; |
326 | struct timeval stop; | 325 | struct timeval stop; |
327 | 326 | ||
328 | printk("Saving image data pages (%u pages) ... ", nr_to_write); | 327 | printk(KERN_INFO "PM: Saving image data pages (%u pages) ... ", |
328 | nr_to_write); | ||
329 | m = nr_to_write / 100; | 329 | m = nr_to_write / 100; |
330 | if (!m) | 330 | if (!m) |
331 | m = 1; | 331 | m = 1; |
@@ -365,7 +365,7 @@ static int enough_swap(unsigned int nr_pages) | |||
365 | { | 365 | { |
366 | unsigned int free_swap = count_swap_pages(root_swap, 1); | 366 | unsigned int free_swap = count_swap_pages(root_swap, 1); |
367 | 367 | ||
368 | pr_debug("swsusp: free swap pages: %u\n", free_swap); | 368 | pr_debug("PM: Free swap pages: %u\n", free_swap); |
369 | return free_swap > nr_pages + PAGES_FOR_IO; | 369 | return free_swap > nr_pages + PAGES_FOR_IO; |
370 | } | 370 | } |
371 | 371 | ||
@@ -388,7 +388,7 @@ int swsusp_write(unsigned int flags) | |||
388 | 388 | ||
389 | error = swsusp_swap_check(); | 389 | error = swsusp_swap_check(); |
390 | if (error) { | 390 | if (error) { |
391 | printk(KERN_ERR "swsusp: Cannot find swap device, try " | 391 | printk(KERN_ERR "PM: Cannot find swap device, try " |
392 | "swapon -a.\n"); | 392 | "swapon -a.\n"); |
393 | return error; | 393 | return error; |
394 | } | 394 | } |
@@ -402,7 +402,7 @@ int swsusp_write(unsigned int flags) | |||
402 | } | 402 | } |
403 | header = (struct swsusp_info *)data_of(snapshot); | 403 | header = (struct swsusp_info *)data_of(snapshot); |
404 | if (!enough_swap(header->pages)) { | 404 | if (!enough_swap(header->pages)) { |
405 | printk(KERN_ERR "swsusp: Not enough free swap\n"); | 405 | printk(KERN_ERR "PM: Not enough free swap\n"); |
406 | error = -ENOSPC; | 406 | error = -ENOSPC; |
407 | goto out; | 407 | goto out; |
408 | } | 408 | } |
@@ -417,7 +417,7 @@ int swsusp_write(unsigned int flags) | |||
417 | 417 | ||
418 | if (!error) { | 418 | if (!error) { |
419 | flush_swap_writer(&handle); | 419 | flush_swap_writer(&handle); |
420 | printk("S"); | 420 | printk(KERN_INFO "PM: S"); |
421 | error = mark_swapfiles(start, flags); | 421 | error = mark_swapfiles(start, flags); |
422 | printk("|\n"); | 422 | printk("|\n"); |
423 | } | 423 | } |
@@ -507,7 +507,8 @@ static int load_image(struct swap_map_handle *handle, | |||
507 | int err2; | 507 | int err2; |
508 | unsigned nr_pages; | 508 | unsigned nr_pages; |
509 | 509 | ||
510 | printk("Loading image data pages (%u pages) ... ", nr_to_read); | 510 | printk(KERN_INFO "PM: Loading image data pages (%u pages) ... ", |
511 | nr_to_read); | ||
511 | m = nr_to_read / 100; | 512 | m = nr_to_read / 100; |
512 | if (!m) | 513 | if (!m) |
513 | m = 1; | 514 | m = 1; |
@@ -558,7 +559,7 @@ int swsusp_read(unsigned int *flags_p) | |||
558 | 559 | ||
559 | *flags_p = swsusp_header->flags; | 560 | *flags_p = swsusp_header->flags; |
560 | if (IS_ERR(resume_bdev)) { | 561 | if (IS_ERR(resume_bdev)) { |
561 | pr_debug("swsusp: block device not initialised\n"); | 562 | pr_debug("PM: Image device not initialised\n"); |
562 | return PTR_ERR(resume_bdev); | 563 | return PTR_ERR(resume_bdev); |
563 | } | 564 | } |
564 | 565 | ||
@@ -577,9 +578,9 @@ int swsusp_read(unsigned int *flags_p) | |||
577 | blkdev_put(resume_bdev); | 578 | blkdev_put(resume_bdev); |
578 | 579 | ||
579 | if (!error) | 580 | if (!error) |
580 | pr_debug("swsusp: Reading resume file was successful\n"); | 581 | pr_debug("PM: Image successfully loaded\n"); |
581 | else | 582 | else |
582 | pr_debug("swsusp: Error %d resuming\n", error); | 583 | pr_debug("PM: Error %d resuming\n", error); |
583 | return error; | 584 | return error; |
584 | } | 585 | } |
585 | 586 | ||
@@ -611,13 +612,13 @@ int swsusp_check(void) | |||
611 | if (error) | 612 | if (error) |
612 | blkdev_put(resume_bdev); | 613 | blkdev_put(resume_bdev); |
613 | else | 614 | else |
614 | pr_debug("swsusp: Signature found, resuming\n"); | 615 | pr_debug("PM: Signature found, resuming\n"); |
615 | } else { | 616 | } else { |
616 | error = PTR_ERR(resume_bdev); | 617 | error = PTR_ERR(resume_bdev); |
617 | } | 618 | } |
618 | 619 | ||
619 | if (error) | 620 | if (error) |
620 | pr_debug("swsusp: Error %d check for resume file\n", error); | 621 | pr_debug("PM: Error %d checking image file\n", error); |
621 | 622 | ||
622 | return error; | 623 | return error; |
623 | } | 624 | } |
@@ -629,7 +630,7 @@ int swsusp_check(void) | |||
629 | void swsusp_close(void) | 630 | void swsusp_close(void) |
630 | { | 631 | { |
631 | if (IS_ERR(resume_bdev)) { | 632 | if (IS_ERR(resume_bdev)) { |
632 | pr_debug("swsusp: block device not initialised\n"); | 633 | pr_debug("PM: Image device not initialised\n"); |
633 | return; | 634 | return; |
634 | } | 635 | } |
635 | 636 | ||
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index e1722d3155f1..023ff2a31d89 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
@@ -64,14 +64,6 @@ unsigned long image_size = 500 * 1024 * 1024; | |||
64 | 64 | ||
65 | int in_suspend __nosavedata = 0; | 65 | int in_suspend __nosavedata = 0; |
66 | 66 | ||
67 | #ifdef CONFIG_HIGHMEM | ||
68 | unsigned int count_highmem_pages(void); | ||
69 | int restore_highmem(void); | ||
70 | #else | ||
71 | static inline int restore_highmem(void) { return 0; } | ||
72 | static inline unsigned int count_highmem_pages(void) { return 0; } | ||
73 | #endif | ||
74 | |||
75 | /** | 67 | /** |
76 | * The following functions are used for tracing the allocated | 68 | * The following functions are used for tracing the allocated |
77 | * swap pages, so that they can be freed in case of an error. | 69 | * swap pages, so that they can be freed in case of an error. |
@@ -196,7 +188,8 @@ void swsusp_show_speed(struct timeval *start, struct timeval *stop, | |||
196 | centisecs = 1; /* avoid div-by-zero */ | 188 | centisecs = 1; /* avoid div-by-zero */ |
197 | k = nr_pages * (PAGE_SIZE / 1024); | 189 | k = nr_pages * (PAGE_SIZE / 1024); |
198 | kps = (k * 100) / centisecs; | 190 | kps = (k * 100) / centisecs; |
199 | printk("%s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", msg, k, | 191 | printk(KERN_INFO "PM: %s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", |
192 | msg, k, | ||
200 | centisecs / 100, centisecs % 100, | 193 | centisecs / 100, centisecs % 100, |
201 | kps / 1000, (kps % 1000) / 10); | 194 | kps / 1000, (kps % 1000) / 10); |
202 | } | 195 | } |
@@ -227,7 +220,7 @@ int swsusp_shrink_memory(void) | |||
227 | char *p = "-\\|/"; | 220 | char *p = "-\\|/"; |
228 | struct timeval start, stop; | 221 | struct timeval start, stop; |
229 | 222 | ||
230 | printk("Shrinking memory... "); | 223 | printk(KERN_INFO "PM: Shrinking memory... "); |
231 | do_gettimeofday(&start); | 224 | do_gettimeofday(&start); |
232 | do { | 225 | do { |
233 | long size, highmem_size; | 226 | long size, highmem_size; |
@@ -269,38 +262,3 @@ int swsusp_shrink_memory(void) | |||
269 | 262 | ||
270 | return 0; | 263 | return 0; |
271 | } | 264 | } |
272 | |||
273 | int swsusp_resume(void) | ||
274 | { | ||
275 | int error; | ||
276 | |||
277 | local_irq_disable(); | ||
278 | /* NOTE: device_power_down() is just a suspend() with irqs off; | ||
279 | * it has no special "power things down" semantics | ||
280 | */ | ||
281 | if (device_power_down(PMSG_PRETHAW)) | ||
282 | printk(KERN_ERR "Some devices failed to power down, very bad\n"); | ||
283 | /* We'll ignore saved state, but this gets preempt count (etc) right */ | ||
284 | save_processor_state(); | ||
285 | error = restore_highmem(); | ||
286 | if (!error) { | ||
287 | error = swsusp_arch_resume(); | ||
288 | /* The code below is only ever reached in case of a failure. | ||
289 | * Otherwise execution continues at place where | ||
290 | * swsusp_arch_suspend() was called | ||
291 | */ | ||
292 | BUG_ON(!error); | ||
293 | /* This call to restore_highmem() undos the previous one */ | ||
294 | restore_highmem(); | ||
295 | } | ||
296 | /* The only reason why swsusp_arch_resume() can fail is memory being | ||
297 | * very tight, so we have to free it as soon as we can to avoid | ||
298 | * subsequent failures | ||
299 | */ | ||
300 | swsusp_free(); | ||
301 | restore_processor_state(); | ||
302 | touch_softlockup_watchdog(); | ||
303 | device_power_up(); | ||
304 | local_irq_enable(); | ||
305 | return error; | ||
306 | } | ||
diff --git a/kernel/power/user.c b/kernel/power/user.c index 5bd321bcbb75..f5512cb3aa86 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -28,6 +28,29 @@ | |||
28 | 28 | ||
29 | #include "power.h" | 29 | #include "power.h" |
30 | 30 | ||
31 | /* | ||
32 | * NOTE: The SNAPSHOT_SET_SWAP_FILE and SNAPSHOT_PMOPS ioctls are obsolete and | ||
33 | * will be removed in the future. They are only preserved here for | ||
34 | * compatibility with existing userland utilities. | ||
35 | */ | ||
36 | #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) | ||
37 | #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) | ||
38 | |||
39 | #define PMOPS_PREPARE 1 | ||
40 | #define PMOPS_ENTER 2 | ||
41 | #define PMOPS_FINISH 3 | ||
42 | |||
43 | /* | ||
44 | * NOTE: The following ioctl definitions are wrong and have been replaced with | ||
45 | * correct ones. They are only preserved here for compatibility with existing | ||
46 | * userland utilities and will be removed in the future. | ||
47 | */ | ||
48 | #define SNAPSHOT_ATOMIC_SNAPSHOT _IOW(SNAPSHOT_IOC_MAGIC, 3, void *) | ||
49 | #define SNAPSHOT_SET_IMAGE_SIZE _IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long) | ||
50 | #define SNAPSHOT_AVAIL_SWAP _IOR(SNAPSHOT_IOC_MAGIC, 7, void *) | ||
51 | #define SNAPSHOT_GET_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 8, void *) | ||
52 | |||
53 | |||
31 | #define SNAPSHOT_MINOR 231 | 54 | #define SNAPSHOT_MINOR 231 |
32 | 55 | ||
33 | static struct snapshot_data { | 56 | static struct snapshot_data { |
@@ -36,7 +59,7 @@ static struct snapshot_data { | |||
36 | int mode; | 59 | int mode; |
37 | char frozen; | 60 | char frozen; |
38 | char ready; | 61 | char ready; |
39 | char platform_suspend; | 62 | char platform_support; |
40 | } snapshot_state; | 63 | } snapshot_state; |
41 | 64 | ||
42 | atomic_t snapshot_device_available = ATOMIC_INIT(1); | 65 | atomic_t snapshot_device_available = ATOMIC_INIT(1); |
@@ -44,6 +67,7 @@ atomic_t snapshot_device_available = ATOMIC_INIT(1); | |||
44 | static int snapshot_open(struct inode *inode, struct file *filp) | 67 | static int snapshot_open(struct inode *inode, struct file *filp) |
45 | { | 68 | { |
46 | struct snapshot_data *data; | 69 | struct snapshot_data *data; |
70 | int error; | ||
47 | 71 | ||
48 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) | 72 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) |
49 | return -EBUSY; | 73 | return -EBUSY; |
@@ -64,13 +88,23 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
64 | data->swap = swsusp_resume_device ? | 88 | data->swap = swsusp_resume_device ? |
65 | swap_type_of(swsusp_resume_device, 0, NULL) : -1; | 89 | swap_type_of(swsusp_resume_device, 0, NULL) : -1; |
66 | data->mode = O_RDONLY; | 90 | data->mode = O_RDONLY; |
91 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); | ||
92 | if (error) | ||
93 | pm_notifier_call_chain(PM_POST_RESTORE); | ||
67 | } else { | 94 | } else { |
68 | data->swap = -1; | 95 | data->swap = -1; |
69 | data->mode = O_WRONLY; | 96 | data->mode = O_WRONLY; |
97 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); | ||
98 | if (error) | ||
99 | pm_notifier_call_chain(PM_POST_HIBERNATION); | ||
100 | } | ||
101 | if (error) { | ||
102 | atomic_inc(&snapshot_device_available); | ||
103 | return error; | ||
70 | } | 104 | } |
71 | data->frozen = 0; | 105 | data->frozen = 0; |
72 | data->ready = 0; | 106 | data->ready = 0; |
73 | data->platform_suspend = 0; | 107 | data->platform_support = 0; |
74 | 108 | ||
75 | return 0; | 109 | return 0; |
76 | } | 110 | } |
@@ -88,6 +122,8 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
88 | thaw_processes(); | 122 | thaw_processes(); |
89 | mutex_unlock(&pm_mutex); | 123 | mutex_unlock(&pm_mutex); |
90 | } | 124 | } |
125 | pm_notifier_call_chain(data->mode == O_WRONLY ? | ||
126 | PM_POST_HIBERNATION : PM_POST_RESTORE); | ||
91 | atomic_inc(&snapshot_device_available); | 127 | atomic_inc(&snapshot_device_available); |
92 | return 0; | 128 | return 0; |
93 | } | 129 | } |
@@ -133,7 +169,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
133 | { | 169 | { |
134 | int error = 0; | 170 | int error = 0; |
135 | struct snapshot_data *data; | 171 | struct snapshot_data *data; |
136 | loff_t avail; | 172 | loff_t size; |
137 | sector_t offset; | 173 | sector_t offset; |
138 | 174 | ||
139 | if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) | 175 | if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) |
@@ -151,18 +187,13 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
151 | if (data->frozen) | 187 | if (data->frozen) |
152 | break; | 188 | break; |
153 | mutex_lock(&pm_mutex); | 189 | mutex_lock(&pm_mutex); |
154 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); | 190 | printk("Syncing filesystems ... "); |
155 | if (!error) { | 191 | sys_sync(); |
156 | printk("Syncing filesystems ... "); | 192 | printk("done.\n"); |
157 | sys_sync(); | 193 | |
158 | printk("done.\n"); | 194 | error = freeze_processes(); |
159 | |||
160 | error = freeze_processes(); | ||
161 | if (error) | ||
162 | thaw_processes(); | ||
163 | } | ||
164 | if (error) | 195 | if (error) |
165 | pm_notifier_call_chain(PM_POST_HIBERNATION); | 196 | thaw_processes(); |
166 | mutex_unlock(&pm_mutex); | 197 | mutex_unlock(&pm_mutex); |
167 | if (!error) | 198 | if (!error) |
168 | data->frozen = 1; | 199 | data->frozen = 1; |
@@ -173,19 +204,19 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
173 | break; | 204 | break; |
174 | mutex_lock(&pm_mutex); | 205 | mutex_lock(&pm_mutex); |
175 | thaw_processes(); | 206 | thaw_processes(); |
176 | pm_notifier_call_chain(PM_POST_HIBERNATION); | ||
177 | mutex_unlock(&pm_mutex); | 207 | mutex_unlock(&pm_mutex); |
178 | data->frozen = 0; | 208 | data->frozen = 0; |
179 | break; | 209 | break; |
180 | 210 | ||
211 | case SNAPSHOT_CREATE_IMAGE: | ||
181 | case SNAPSHOT_ATOMIC_SNAPSHOT: | 212 | case SNAPSHOT_ATOMIC_SNAPSHOT: |
182 | if (data->mode != O_RDONLY || !data->frozen || data->ready) { | 213 | if (data->mode != O_RDONLY || !data->frozen || data->ready) { |
183 | error = -EPERM; | 214 | error = -EPERM; |
184 | break; | 215 | break; |
185 | } | 216 | } |
186 | error = hibernation_snapshot(data->platform_suspend); | 217 | error = hibernation_snapshot(data->platform_support); |
187 | if (!error) | 218 | if (!error) |
188 | error = put_user(in_suspend, (unsigned int __user *)arg); | 219 | error = put_user(in_suspend, (int __user *)arg); |
189 | if (!error) | 220 | if (!error) |
190 | data->ready = 1; | 221 | data->ready = 1; |
191 | break; | 222 | break; |
@@ -197,7 +228,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
197 | error = -EPERM; | 228 | error = -EPERM; |
198 | break; | 229 | break; |
199 | } | 230 | } |
200 | error = hibernation_restore(data->platform_suspend); | 231 | error = hibernation_restore(data->platform_support); |
201 | break; | 232 | break; |
202 | 233 | ||
203 | case SNAPSHOT_FREE: | 234 | case SNAPSHOT_FREE: |
@@ -206,16 +237,29 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
206 | data->ready = 0; | 237 | data->ready = 0; |
207 | break; | 238 | break; |
208 | 239 | ||
240 | case SNAPSHOT_PREF_IMAGE_SIZE: | ||
209 | case SNAPSHOT_SET_IMAGE_SIZE: | 241 | case SNAPSHOT_SET_IMAGE_SIZE: |
210 | image_size = arg; | 242 | image_size = arg; |
211 | break; | 243 | break; |
212 | 244 | ||
245 | case SNAPSHOT_GET_IMAGE_SIZE: | ||
246 | if (!data->ready) { | ||
247 | error = -ENODATA; | ||
248 | break; | ||
249 | } | ||
250 | size = snapshot_get_image_size(); | ||
251 | size <<= PAGE_SHIFT; | ||
252 | error = put_user(size, (loff_t __user *)arg); | ||
253 | break; | ||
254 | |||
255 | case SNAPSHOT_AVAIL_SWAP_SIZE: | ||
213 | case SNAPSHOT_AVAIL_SWAP: | 256 | case SNAPSHOT_AVAIL_SWAP: |
214 | avail = count_swap_pages(data->swap, 1); | 257 | size = count_swap_pages(data->swap, 1); |
215 | avail <<= PAGE_SHIFT; | 258 | size <<= PAGE_SHIFT; |
216 | error = put_user(avail, (loff_t __user *)arg); | 259 | error = put_user(size, (loff_t __user *)arg); |
217 | break; | 260 | break; |
218 | 261 | ||
262 | case SNAPSHOT_ALLOC_SWAP_PAGE: | ||
219 | case SNAPSHOT_GET_SWAP_PAGE: | 263 | case SNAPSHOT_GET_SWAP_PAGE: |
220 | if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { | 264 | if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { |
221 | error = -ENODEV; | 265 | error = -ENODEV; |
@@ -224,7 +268,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
224 | offset = alloc_swapdev_block(data->swap); | 268 | offset = alloc_swapdev_block(data->swap); |
225 | if (offset) { | 269 | if (offset) { |
226 | offset <<= PAGE_SHIFT; | 270 | offset <<= PAGE_SHIFT; |
227 | error = put_user(offset, (sector_t __user *)arg); | 271 | error = put_user(offset, (loff_t __user *)arg); |
228 | } else { | 272 | } else { |
229 | error = -ENOSPC; | 273 | error = -ENOSPC; |
230 | } | 274 | } |
@@ -238,7 +282,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
238 | free_all_swap_pages(data->swap); | 282 | free_all_swap_pages(data->swap); |
239 | break; | 283 | break; |
240 | 284 | ||
241 | case SNAPSHOT_SET_SWAP_FILE: | 285 | case SNAPSHOT_SET_SWAP_FILE: /* This ioctl is deprecated */ |
242 | if (!swsusp_swap_in_use()) { | 286 | if (!swsusp_swap_in_use()) { |
243 | /* | 287 | /* |
244 | * User space encodes device types as two-byte values, | 288 | * User space encodes device types as two-byte values, |
@@ -275,26 +319,33 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
275 | mutex_unlock(&pm_mutex); | 319 | mutex_unlock(&pm_mutex); |
276 | break; | 320 | break; |
277 | 321 | ||
278 | case SNAPSHOT_PMOPS: | 322 | case SNAPSHOT_PLATFORM_SUPPORT: |
323 | data->platform_support = !!arg; | ||
324 | break; | ||
325 | |||
326 | case SNAPSHOT_POWER_OFF: | ||
327 | if (data->platform_support) | ||
328 | error = hibernation_platform_enter(); | ||
329 | break; | ||
330 | |||
331 | case SNAPSHOT_PMOPS: /* This ioctl is deprecated */ | ||
279 | error = -EINVAL; | 332 | error = -EINVAL; |
280 | 333 | ||
281 | switch (arg) { | 334 | switch (arg) { |
282 | 335 | ||
283 | case PMOPS_PREPARE: | 336 | case PMOPS_PREPARE: |
284 | data->platform_suspend = 1; | 337 | data->platform_support = 1; |
285 | error = 0; | 338 | error = 0; |
286 | break; | 339 | break; |
287 | 340 | ||
288 | case PMOPS_ENTER: | 341 | case PMOPS_ENTER: |
289 | if (data->platform_suspend) | 342 | if (data->platform_support) |
290 | error = hibernation_platform_enter(); | 343 | error = hibernation_platform_enter(); |
291 | |||
292 | break; | 344 | break; |
293 | 345 | ||
294 | case PMOPS_FINISH: | 346 | case PMOPS_FINISH: |
295 | if (data->platform_suspend) | 347 | if (data->platform_support) |
296 | error = 0; | 348 | error = 0; |
297 | |||
298 | break; | 349 | break; |
299 | 350 | ||
300 | default: | 351 | default: |
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index c1d76552446e..7c2da88db4ed 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
@@ -101,6 +101,10 @@ void softlockup_tick(void) | |||
101 | 101 | ||
102 | now = get_timestamp(this_cpu); | 102 | now = get_timestamp(this_cpu); |
103 | 103 | ||
104 | /* Wake up the high-prio watchdog task every second: */ | ||
105 | if (now > (touch_timestamp + 1)) | ||
106 | wake_up_process(per_cpu(watchdog_task, this_cpu)); | ||
107 | |||
104 | /* Warn about unreasonable delays: */ | 108 | /* Warn about unreasonable delays: */ |
105 | if (now <= (touch_timestamp + softlockup_thresh)) | 109 | if (now <= (touch_timestamp + softlockup_thresh)) |
106 | return; | 110 | return; |
@@ -191,11 +195,11 @@ static void check_hung_uninterruptible_tasks(int this_cpu) | |||
191 | read_lock(&tasklist_lock); | 195 | read_lock(&tasklist_lock); |
192 | do_each_thread(g, t) { | 196 | do_each_thread(g, t) { |
193 | if (!--max_count) | 197 | if (!--max_count) |
194 | break; | 198 | goto unlock; |
195 | if (t->state & TASK_UNINTERRUPTIBLE) | 199 | if (t->state & TASK_UNINTERRUPTIBLE) |
196 | check_hung_task(t, now); | 200 | check_hung_task(t, now); |
197 | } while_each_thread(g, t); | 201 | } while_each_thread(g, t); |
198 | 202 | unlock: | |
199 | read_unlock(&tasklist_lock); | 203 | read_unlock(&tasklist_lock); |
200 | } | 204 | } |
201 | 205 | ||
@@ -218,14 +222,19 @@ static int watchdog(void *__bind_cpu) | |||
218 | * debug-printout triggers in softlockup_tick(). | 222 | * debug-printout triggers in softlockup_tick(). |
219 | */ | 223 | */ |
220 | while (!kthread_should_stop()) { | 224 | while (!kthread_should_stop()) { |
225 | set_current_state(TASK_INTERRUPTIBLE); | ||
221 | touch_softlockup_watchdog(); | 226 | touch_softlockup_watchdog(); |
222 | msleep_interruptible(10000); | 227 | schedule(); |
228 | |||
229 | if (kthread_should_stop()) | ||
230 | break; | ||
223 | 231 | ||
224 | if (this_cpu != check_cpu) | 232 | if (this_cpu != check_cpu) |
225 | continue; | 233 | continue; |
226 | 234 | ||
227 | if (sysctl_hung_task_timeout_secs) | 235 | if (sysctl_hung_task_timeout_secs) |
228 | check_hung_uninterruptible_tasks(this_cpu); | 236 | check_hung_uninterruptible_tasks(this_cpu); |
237 | |||
229 | } | 238 | } |
230 | 239 | ||
231 | return 0; | 240 | return 0; |
@@ -259,13 +268,6 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
259 | wake_up_process(per_cpu(watchdog_task, hotcpu)); | 268 | wake_up_process(per_cpu(watchdog_task, hotcpu)); |
260 | break; | 269 | break; |
261 | #ifdef CONFIG_HOTPLUG_CPU | 270 | #ifdef CONFIG_HOTPLUG_CPU |
262 | case CPU_UP_CANCELED: | ||
263 | case CPU_UP_CANCELED_FROZEN: | ||
264 | if (!per_cpu(watchdog_task, hotcpu)) | ||
265 | break; | ||
266 | /* Unbind so it can run. Fall thru. */ | ||
267 | kthread_bind(per_cpu(watchdog_task, hotcpu), | ||
268 | any_online_cpu(cpu_online_map)); | ||
269 | case CPU_DOWN_PREPARE: | 271 | case CPU_DOWN_PREPARE: |
270 | case CPU_DOWN_PREPARE_FROZEN: | 272 | case CPU_DOWN_PREPARE_FROZEN: |
271 | if (hotcpu == check_cpu) { | 273 | if (hotcpu == check_cpu) { |
@@ -275,6 +277,14 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
275 | check_cpu = any_online_cpu(temp_cpu_online_map); | 277 | check_cpu = any_online_cpu(temp_cpu_online_map); |
276 | } | 278 | } |
277 | break; | 279 | break; |
280 | |||
281 | case CPU_UP_CANCELED: | ||
282 | case CPU_UP_CANCELED_FROZEN: | ||
283 | if (!per_cpu(watchdog_task, hotcpu)) | ||
284 | break; | ||
285 | /* Unbind so it can run. Fall thru. */ | ||
286 | kthread_bind(per_cpu(watchdog_task, hotcpu), | ||
287 | any_online_cpu(cpu_online_map)); | ||
278 | case CPU_DEAD: | 288 | case CPU_DEAD: |
279 | case CPU_DEAD_FROZEN: | 289 | case CPU_DEAD_FROZEN: |
280 | p = per_cpu(watchdog_task, hotcpu); | 290 | p = per_cpu(watchdog_task, hotcpu); |
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile index 5c69a725e530..92e1dbe50947 100644 --- a/net/sunrpc/Makefile +++ b/net/sunrpc/Makefile | |||
@@ -11,6 +11,7 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \ | |||
11 | auth.o auth_null.o auth_unix.o \ | 11 | auth.o auth_null.o auth_unix.o \ |
12 | svc.o svcsock.o svcauth.o svcauth_unix.o \ | 12 | svc.o svcsock.o svcauth.o svcauth_unix.o \ |
13 | rpcb_clnt.o timer.o xdr.o \ | 13 | rpcb_clnt.o timer.o xdr.o \ |
14 | sunrpc_syms.o cache.o rpc_pipe.o | 14 | sunrpc_syms.o cache.o rpc_pipe.o \ |
15 | svc_xprt.o | ||
15 | sunrpc-$(CONFIG_PROC_FS) += stats.o | 16 | sunrpc-$(CONFIG_PROC_FS) += stats.o |
16 | sunrpc-$(CONFIG_SYSCTL) += sysctl.o | 17 | sunrpc-$(CONFIG_SYSCTL) += sysctl.o |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 73940df6c460..481f984e9a22 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -224,38 +224,34 @@ static int rsi_parse(struct cache_detail *cd, | |||
224 | 224 | ||
225 | /* major/minor */ | 225 | /* major/minor */ |
226 | len = qword_get(&mesg, buf, mlen); | 226 | len = qword_get(&mesg, buf, mlen); |
227 | if (len < 0) | 227 | if (len <= 0) |
228 | goto out; | 228 | goto out; |
229 | if (len == 0) { | 229 | rsii.major_status = simple_strtoul(buf, &ep, 10); |
230 | if (*ep) | ||
231 | goto out; | ||
232 | len = qword_get(&mesg, buf, mlen); | ||
233 | if (len <= 0) | ||
234 | goto out; | ||
235 | rsii.minor_status = simple_strtoul(buf, &ep, 10); | ||
236 | if (*ep) | ||
230 | goto out; | 237 | goto out; |
231 | } else { | ||
232 | rsii.major_status = simple_strtoul(buf, &ep, 10); | ||
233 | if (*ep) | ||
234 | goto out; | ||
235 | len = qword_get(&mesg, buf, mlen); | ||
236 | if (len <= 0) | ||
237 | goto out; | ||
238 | rsii.minor_status = simple_strtoul(buf, &ep, 10); | ||
239 | if (*ep) | ||
240 | goto out; | ||
241 | 238 | ||
242 | /* out_handle */ | 239 | /* out_handle */ |
243 | len = qword_get(&mesg, buf, mlen); | 240 | len = qword_get(&mesg, buf, mlen); |
244 | if (len < 0) | 241 | if (len < 0) |
245 | goto out; | 242 | goto out; |
246 | status = -ENOMEM; | 243 | status = -ENOMEM; |
247 | if (dup_to_netobj(&rsii.out_handle, buf, len)) | 244 | if (dup_to_netobj(&rsii.out_handle, buf, len)) |
248 | goto out; | 245 | goto out; |
249 | 246 | ||
250 | /* out_token */ | 247 | /* out_token */ |
251 | len = qword_get(&mesg, buf, mlen); | 248 | len = qword_get(&mesg, buf, mlen); |
252 | status = -EINVAL; | 249 | status = -EINVAL; |
253 | if (len < 0) | 250 | if (len < 0) |
254 | goto out; | 251 | goto out; |
255 | status = -ENOMEM; | 252 | status = -ENOMEM; |
256 | if (dup_to_netobj(&rsii.out_token, buf, len)) | 253 | if (dup_to_netobj(&rsii.out_token, buf, len)) |
257 | goto out; | 254 | goto out; |
258 | } | ||
259 | rsii.h.expiry_time = expiry; | 255 | rsii.h.expiry_time = expiry; |
260 | rsip = rsi_update(&rsii, rsip); | 256 | rsip = rsi_update(&rsii, rsip); |
261 | status = 0; | 257 | status = 0; |
@@ -975,6 +971,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
975 | struct kvec *resv = &rqstp->rq_res.head[0]; | 971 | struct kvec *resv = &rqstp->rq_res.head[0]; |
976 | struct xdr_netobj tmpobj; | 972 | struct xdr_netobj tmpobj; |
977 | struct rsi *rsip, rsikey; | 973 | struct rsi *rsip, rsikey; |
974 | int ret; | ||
978 | 975 | ||
979 | /* Read the verifier; should be NULL: */ | 976 | /* Read the verifier; should be NULL: */ |
980 | *authp = rpc_autherr_badverf; | 977 | *authp = rpc_autherr_badverf; |
@@ -1014,23 +1011,27 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1014 | /* No upcall result: */ | 1011 | /* No upcall result: */ |
1015 | return SVC_DROP; | 1012 | return SVC_DROP; |
1016 | case 0: | 1013 | case 0: |
1014 | ret = SVC_DROP; | ||
1017 | /* Got an answer to the upcall; use it: */ | 1015 | /* Got an answer to the upcall; use it: */ |
1018 | if (gss_write_init_verf(rqstp, rsip)) | 1016 | if (gss_write_init_verf(rqstp, rsip)) |
1019 | return SVC_DROP; | 1017 | goto out; |
1020 | if (resv->iov_len + 4 > PAGE_SIZE) | 1018 | if (resv->iov_len + 4 > PAGE_SIZE) |
1021 | return SVC_DROP; | 1019 | goto out; |
1022 | svc_putnl(resv, RPC_SUCCESS); | 1020 | svc_putnl(resv, RPC_SUCCESS); |
1023 | if (svc_safe_putnetobj(resv, &rsip->out_handle)) | 1021 | if (svc_safe_putnetobj(resv, &rsip->out_handle)) |
1024 | return SVC_DROP; | 1022 | goto out; |
1025 | if (resv->iov_len + 3 * 4 > PAGE_SIZE) | 1023 | if (resv->iov_len + 3 * 4 > PAGE_SIZE) |
1026 | return SVC_DROP; | 1024 | goto out; |
1027 | svc_putnl(resv, rsip->major_status); | 1025 | svc_putnl(resv, rsip->major_status); |
1028 | svc_putnl(resv, rsip->minor_status); | 1026 | svc_putnl(resv, rsip->minor_status); |
1029 | svc_putnl(resv, GSS_SEQ_WIN); | 1027 | svc_putnl(resv, GSS_SEQ_WIN); |
1030 | if (svc_safe_putnetobj(resv, &rsip->out_token)) | 1028 | if (svc_safe_putnetobj(resv, &rsip->out_token)) |
1031 | return SVC_DROP; | 1029 | goto out; |
1032 | } | 1030 | } |
1033 | return SVC_COMPLETE; | 1031 | ret = SVC_COMPLETE; |
1032 | out: | ||
1033 | cache_put(&rsip->h, &rsi_cache); | ||
1034 | return ret; | ||
1034 | } | 1035 | } |
1035 | 1036 | ||
1036 | /* | 1037 | /* |
@@ -1125,6 +1126,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
1125 | case RPC_GSS_PROC_DESTROY: | 1126 | case RPC_GSS_PROC_DESTROY: |
1126 | if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) | 1127 | if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) |
1127 | goto auth_err; | 1128 | goto auth_err; |
1129 | rsci->h.expiry_time = get_seconds(); | ||
1128 | set_bit(CACHE_NEGATIVE, &rsci->h.flags); | 1130 | set_bit(CACHE_NEGATIVE, &rsci->h.flags); |
1129 | if (resv->iov_len + 4 > PAGE_SIZE) | 1131 | if (resv->iov_len + 4 > PAGE_SIZE) |
1130 | goto drop; | 1132 | goto drop; |
@@ -1386,19 +1388,26 @@ int | |||
1386 | gss_svc_init(void) | 1388 | gss_svc_init(void) |
1387 | { | 1389 | { |
1388 | int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); | 1390 | int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); |
1389 | if (rv == 0) { | 1391 | if (rv) |
1390 | cache_register(&rsc_cache); | 1392 | return rv; |
1391 | cache_register(&rsi_cache); | 1393 | rv = cache_register(&rsc_cache); |
1392 | } | 1394 | if (rv) |
1395 | goto out1; | ||
1396 | rv = cache_register(&rsi_cache); | ||
1397 | if (rv) | ||
1398 | goto out2; | ||
1399 | return 0; | ||
1400 | out2: | ||
1401 | cache_unregister(&rsc_cache); | ||
1402 | out1: | ||
1403 | svc_auth_unregister(RPC_AUTH_GSS); | ||
1393 | return rv; | 1404 | return rv; |
1394 | } | 1405 | } |
1395 | 1406 | ||
1396 | void | 1407 | void |
1397 | gss_svc_shutdown(void) | 1408 | gss_svc_shutdown(void) |
1398 | { | 1409 | { |
1399 | if (cache_unregister(&rsc_cache)) | 1410 | cache_unregister(&rsc_cache); |
1400 | printk(KERN_ERR "auth_rpcgss: failed to unregister rsc cache\n"); | 1411 | cache_unregister(&rsi_cache); |
1401 | if (cache_unregister(&rsi_cache)) | ||
1402 | printk(KERN_ERR "auth_rpcgss: failed to unregister rsi cache\n"); | ||
1403 | svc_auth_unregister(RPC_AUTH_GSS); | 1412 | svc_auth_unregister(RPC_AUTH_GSS); |
1404 | } | 1413 | } |
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 73f053d0cc7a..636c8e04e0be 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -245,6 +245,7 @@ int cache_check(struct cache_detail *detail, | |||
245 | cache_put(h, detail); | 245 | cache_put(h, detail); |
246 | return rv; | 246 | return rv; |
247 | } | 247 | } |
248 | EXPORT_SYMBOL(cache_check); | ||
248 | 249 | ||
249 | /* | 250 | /* |
250 | * caches need to be periodically cleaned. | 251 | * caches need to be periodically cleaned. |
@@ -290,44 +291,78 @@ static const struct file_operations cache_flush_operations; | |||
290 | static void do_cache_clean(struct work_struct *work); | 291 | static void do_cache_clean(struct work_struct *work); |
291 | static DECLARE_DELAYED_WORK(cache_cleaner, do_cache_clean); | 292 | static DECLARE_DELAYED_WORK(cache_cleaner, do_cache_clean); |
292 | 293 | ||
293 | void cache_register(struct cache_detail *cd) | 294 | static void remove_cache_proc_entries(struct cache_detail *cd) |
294 | { | 295 | { |
295 | cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc); | 296 | if (cd->proc_ent == NULL) |
296 | if (cd->proc_ent) { | 297 | return; |
297 | struct proc_dir_entry *p; | 298 | if (cd->flush_ent) |
298 | cd->proc_ent->owner = cd->owner; | 299 | remove_proc_entry("flush", cd->proc_ent); |
299 | cd->channel_ent = cd->content_ent = NULL; | 300 | if (cd->channel_ent) |
301 | remove_proc_entry("channel", cd->proc_ent); | ||
302 | if (cd->content_ent) | ||
303 | remove_proc_entry("content", cd->proc_ent); | ||
304 | cd->proc_ent = NULL; | ||
305 | remove_proc_entry(cd->name, proc_net_rpc); | ||
306 | } | ||
300 | 307 | ||
301 | p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, | 308 | #ifdef CONFIG_PROC_FS |
302 | cd->proc_ent); | 309 | static int create_cache_proc_entries(struct cache_detail *cd) |
303 | cd->flush_ent = p; | 310 | { |
304 | if (p) { | 311 | struct proc_dir_entry *p; |
305 | p->proc_fops = &cache_flush_operations; | ||
306 | p->owner = cd->owner; | ||
307 | p->data = cd; | ||
308 | } | ||
309 | 312 | ||
310 | if (cd->cache_request || cd->cache_parse) { | 313 | cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc); |
311 | p = create_proc_entry("channel", S_IFREG|S_IRUSR|S_IWUSR, | 314 | if (cd->proc_ent == NULL) |
312 | cd->proc_ent); | 315 | goto out_nomem; |
313 | cd->channel_ent = p; | 316 | cd->proc_ent->owner = cd->owner; |
314 | if (p) { | 317 | cd->channel_ent = cd->content_ent = NULL; |
315 | p->proc_fops = &cache_file_operations; | 318 | |
316 | p->owner = cd->owner; | 319 | p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); |
317 | p->data = cd; | 320 | cd->flush_ent = p; |
318 | } | 321 | if (p == NULL) |
319 | } | 322 | goto out_nomem; |
320 | if (cd->cache_show) { | 323 | p->proc_fops = &cache_flush_operations; |
321 | p = create_proc_entry("content", S_IFREG|S_IRUSR|S_IWUSR, | 324 | p->owner = cd->owner; |
322 | cd->proc_ent); | 325 | p->data = cd; |
323 | cd->content_ent = p; | 326 | |
324 | if (p) { | 327 | if (cd->cache_request || cd->cache_parse) { |
325 | p->proc_fops = &content_file_operations; | 328 | p = create_proc_entry("channel", S_IFREG|S_IRUSR|S_IWUSR, |
326 | p->owner = cd->owner; | 329 | cd->proc_ent); |
327 | p->data = cd; | 330 | cd->channel_ent = p; |
328 | } | 331 | if (p == NULL) |
329 | } | 332 | goto out_nomem; |
333 | p->proc_fops = &cache_file_operations; | ||
334 | p->owner = cd->owner; | ||
335 | p->data = cd; | ||
330 | } | 336 | } |
337 | if (cd->cache_show) { | ||
338 | p = create_proc_entry("content", S_IFREG|S_IRUSR|S_IWUSR, | ||
339 | cd->proc_ent); | ||
340 | cd->content_ent = p; | ||
341 | if (p == NULL) | ||
342 | goto out_nomem; | ||
343 | p->proc_fops = &content_file_operations; | ||
344 | p->owner = cd->owner; | ||
345 | p->data = cd; | ||
346 | } | ||
347 | return 0; | ||
348 | out_nomem: | ||
349 | remove_cache_proc_entries(cd); | ||
350 | return -ENOMEM; | ||
351 | } | ||
352 | #else /* CONFIG_PROC_FS */ | ||
353 | static int create_cache_proc_entries(struct cache_detail *cd) | ||
354 | { | ||
355 | return 0; | ||
356 | } | ||
357 | #endif | ||
358 | |||
359 | int cache_register(struct cache_detail *cd) | ||
360 | { | ||
361 | int ret; | ||
362 | |||
363 | ret = create_cache_proc_entries(cd); | ||
364 | if (ret) | ||
365 | return ret; | ||
331 | rwlock_init(&cd->hash_lock); | 366 | rwlock_init(&cd->hash_lock); |
332 | INIT_LIST_HEAD(&cd->queue); | 367 | INIT_LIST_HEAD(&cd->queue); |
333 | spin_lock(&cache_list_lock); | 368 | spin_lock(&cache_list_lock); |
@@ -341,9 +376,11 @@ void cache_register(struct cache_detail *cd) | |||
341 | 376 | ||
342 | /* start the cleaning process */ | 377 | /* start the cleaning process */ |
343 | schedule_delayed_work(&cache_cleaner, 0); | 378 | schedule_delayed_work(&cache_cleaner, 0); |
379 | return 0; | ||
344 | } | 380 | } |
381 | EXPORT_SYMBOL(cache_register); | ||
345 | 382 | ||
346 | int cache_unregister(struct cache_detail *cd) | 383 | void cache_unregister(struct cache_detail *cd) |
347 | { | 384 | { |
348 | cache_purge(cd); | 385 | cache_purge(cd); |
349 | spin_lock(&cache_list_lock); | 386 | spin_lock(&cache_list_lock); |
@@ -351,30 +388,23 @@ int cache_unregister(struct cache_detail *cd) | |||
351 | if (cd->entries || atomic_read(&cd->inuse)) { | 388 | if (cd->entries || atomic_read(&cd->inuse)) { |
352 | write_unlock(&cd->hash_lock); | 389 | write_unlock(&cd->hash_lock); |
353 | spin_unlock(&cache_list_lock); | 390 | spin_unlock(&cache_list_lock); |
354 | return -EBUSY; | 391 | goto out; |
355 | } | 392 | } |
356 | if (current_detail == cd) | 393 | if (current_detail == cd) |
357 | current_detail = NULL; | 394 | current_detail = NULL; |
358 | list_del_init(&cd->others); | 395 | list_del_init(&cd->others); |
359 | write_unlock(&cd->hash_lock); | 396 | write_unlock(&cd->hash_lock); |
360 | spin_unlock(&cache_list_lock); | 397 | spin_unlock(&cache_list_lock); |
361 | if (cd->proc_ent) { | 398 | remove_cache_proc_entries(cd); |
362 | if (cd->flush_ent) | ||
363 | remove_proc_entry("flush", cd->proc_ent); | ||
364 | if (cd->channel_ent) | ||
365 | remove_proc_entry("channel", cd->proc_ent); | ||
366 | if (cd->content_ent) | ||
367 | remove_proc_entry("content", cd->proc_ent); | ||
368 | |||
369 | cd->proc_ent = NULL; | ||
370 | remove_proc_entry(cd->name, proc_net_rpc); | ||
371 | } | ||
372 | if (list_empty(&cache_list)) { | 399 | if (list_empty(&cache_list)) { |
373 | /* module must be being unloaded so its safe to kill the worker */ | 400 | /* module must be being unloaded so its safe to kill the worker */ |
374 | cancel_delayed_work_sync(&cache_cleaner); | 401 | cancel_delayed_work_sync(&cache_cleaner); |
375 | } | 402 | } |
376 | return 0; | 403 | return; |
404 | out: | ||
405 | printk(KERN_ERR "nfsd: failed to unregister %s cache\n", cd->name); | ||
377 | } | 406 | } |
407 | EXPORT_SYMBOL(cache_unregister); | ||
378 | 408 | ||
379 | /* clean cache tries to find something to clean | 409 | /* clean cache tries to find something to clean |
380 | * and cleans it. | 410 | * and cleans it. |
@@ -489,6 +519,7 @@ void cache_flush(void) | |||
489 | while (cache_clean() != -1) | 519 | while (cache_clean() != -1) |
490 | cond_resched(); | 520 | cond_resched(); |
491 | } | 521 | } |
522 | EXPORT_SYMBOL(cache_flush); | ||
492 | 523 | ||
493 | void cache_purge(struct cache_detail *detail) | 524 | void cache_purge(struct cache_detail *detail) |
494 | { | 525 | { |
@@ -497,7 +528,7 @@ void cache_purge(struct cache_detail *detail) | |||
497 | cache_flush(); | 528 | cache_flush(); |
498 | detail->flush_time = 1; | 529 | detail->flush_time = 1; |
499 | } | 530 | } |
500 | 531 | EXPORT_SYMBOL(cache_purge); | |
501 | 532 | ||
502 | 533 | ||
503 | /* | 534 | /* |
@@ -634,13 +665,13 @@ void cache_clean_deferred(void *owner) | |||
634 | /* | 665 | /* |
635 | * communicate with user-space | 666 | * communicate with user-space |
636 | * | 667 | * |
637 | * We have a magic /proc file - /proc/sunrpc/cache | 668 | * We have a magic /proc file - /proc/sunrpc/<cachename>/channel. |
638 | * On read, you get a full request, or block | 669 | * On read, you get a full request, or block. |
639 | * On write, an update request is processed | 670 | * On write, an update request is processed. |
640 | * Poll works if anything to read, and always allows write | 671 | * Poll works if anything to read, and always allows write. |
641 | * | 672 | * |
642 | * Implemented by linked list of requests. Each open file has | 673 | * Implemented by linked list of requests. Each open file has |
643 | * a ->private that also exists in this list. New request are added | 674 | * a ->private that also exists in this list. New requests are added |
644 | * to the end and may wakeup and preceding readers. | 675 | * to the end and may wakeup and preceding readers. |
645 | * New readers are added to the head. If, on read, an item is found with | 676 | * New readers are added to the head. If, on read, an item is found with |
646 | * CACHE_UPCALLING clear, we free it from the list. | 677 | * CACHE_UPCALLING clear, we free it from the list. |
@@ -963,6 +994,7 @@ void qword_add(char **bpp, int *lp, char *str) | |||
963 | *bpp = bp; | 994 | *bpp = bp; |
964 | *lp = len; | 995 | *lp = len; |
965 | } | 996 | } |
997 | EXPORT_SYMBOL(qword_add); | ||
966 | 998 | ||
967 | void qword_addhex(char **bpp, int *lp, char *buf, int blen) | 999 | void qword_addhex(char **bpp, int *lp, char *buf, int blen) |
968 | { | 1000 | { |
@@ -991,6 +1023,7 @@ void qword_addhex(char **bpp, int *lp, char *buf, int blen) | |||
991 | *bpp = bp; | 1023 | *bpp = bp; |
992 | *lp = len; | 1024 | *lp = len; |
993 | } | 1025 | } |
1026 | EXPORT_SYMBOL(qword_addhex); | ||
994 | 1027 | ||
995 | static void warn_no_listener(struct cache_detail *detail) | 1028 | static void warn_no_listener(struct cache_detail *detail) |
996 | { | 1029 | { |
@@ -1113,6 +1146,7 @@ int qword_get(char **bpp, char *dest, int bufsize) | |||
1113 | *dest = '\0'; | 1146 | *dest = '\0'; |
1114 | return len; | 1147 | return len; |
1115 | } | 1148 | } |
1149 | EXPORT_SYMBOL(qword_get); | ||
1116 | 1150 | ||
1117 | 1151 | ||
1118 | /* | 1152 | /* |
@@ -1244,18 +1278,18 @@ static ssize_t read_flush(struct file *file, char __user *buf, | |||
1244 | struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data; | 1278 | struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data; |
1245 | char tbuf[20]; | 1279 | char tbuf[20]; |
1246 | unsigned long p = *ppos; | 1280 | unsigned long p = *ppos; |
1247 | int len; | 1281 | size_t len; |
1248 | 1282 | ||
1249 | sprintf(tbuf, "%lu\n", cd->flush_time); | 1283 | sprintf(tbuf, "%lu\n", cd->flush_time); |
1250 | len = strlen(tbuf); | 1284 | len = strlen(tbuf); |
1251 | if (p >= len) | 1285 | if (p >= len) |
1252 | return 0; | 1286 | return 0; |
1253 | len -= p; | 1287 | len -= p; |
1254 | if (len > count) len = count; | 1288 | if (len > count) |
1289 | len = count; | ||
1255 | if (copy_to_user(buf, (void*)(tbuf+p), len)) | 1290 | if (copy_to_user(buf, (void*)(tbuf+p), len)) |
1256 | len = -EFAULT; | 1291 | return -EFAULT; |
1257 | else | 1292 | *ppos += len; |
1258 | *ppos += len; | ||
1259 | return len; | 1293 | return len; |
1260 | } | 1294 | } |
1261 | 1295 | ||
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 74df2d358e61..5a16875f5ac8 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c | |||
@@ -33,7 +33,7 @@ struct proc_dir_entry *proc_net_rpc = NULL; | |||
33 | static int rpc_proc_show(struct seq_file *seq, void *v) { | 33 | static int rpc_proc_show(struct seq_file *seq, void *v) { |
34 | const struct rpc_stat *statp = seq->private; | 34 | const struct rpc_stat *statp = seq->private; |
35 | const struct rpc_program *prog = statp->program; | 35 | const struct rpc_program *prog = statp->program; |
36 | int i, j; | 36 | unsigned int i, j; |
37 | 37 | ||
38 | seq_printf(seq, | 38 | seq_printf(seq, |
39 | "net %u %u %u %u\n", | 39 | "net %u %u %u %u\n", |
@@ -81,7 +81,7 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) { | |||
81 | const struct svc_program *prog = statp->program; | 81 | const struct svc_program *prog = statp->program; |
82 | const struct svc_procedure *proc; | 82 | const struct svc_procedure *proc; |
83 | const struct svc_version *vers; | 83 | const struct svc_version *vers; |
84 | int i, j; | 84 | unsigned int i, j; |
85 | 85 | ||
86 | seq_printf(seq, | 86 | seq_printf(seq, |
87 | "net %u %u %u %u\n", | 87 | "net %u %u %u %u\n", |
@@ -106,6 +106,7 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) { | |||
106 | seq_putc(seq, '\n'); | 106 | seq_putc(seq, '\n'); |
107 | } | 107 | } |
108 | } | 108 | } |
109 | EXPORT_SYMBOL(svc_seq_show); | ||
109 | 110 | ||
110 | /** | 111 | /** |
111 | * rpc_alloc_iostats - allocate an rpc_iostats structure | 112 | * rpc_alloc_iostats - allocate an rpc_iostats structure |
@@ -255,12 +256,14 @@ svc_proc_register(struct svc_stat *statp, const struct file_operations *fops) | |||
255 | { | 256 | { |
256 | return do_register(statp->program->pg_name, statp, fops); | 257 | return do_register(statp->program->pg_name, statp, fops); |
257 | } | 258 | } |
259 | EXPORT_SYMBOL(svc_proc_register); | ||
258 | 260 | ||
259 | void | 261 | void |
260 | svc_proc_unregister(const char *name) | 262 | svc_proc_unregister(const char *name) |
261 | { | 263 | { |
262 | remove_proc_entry(name, proc_net_rpc); | 264 | remove_proc_entry(name, proc_net_rpc); |
263 | } | 265 | } |
266 | EXPORT_SYMBOL(svc_proc_unregister); | ||
264 | 267 | ||
265 | void | 268 | void |
266 | rpc_proc_init(void) | 269 | rpc_proc_init(void) |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 1a7e309d008b..843629f55763 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -22,48 +22,6 @@ | |||
22 | #include <linux/sunrpc/rpc_pipe_fs.h> | 22 | #include <linux/sunrpc/rpc_pipe_fs.h> |
23 | #include <linux/sunrpc/xprtsock.h> | 23 | #include <linux/sunrpc/xprtsock.h> |
24 | 24 | ||
25 | /* RPC server stuff */ | ||
26 | EXPORT_SYMBOL(svc_create); | ||
27 | EXPORT_SYMBOL(svc_create_thread); | ||
28 | EXPORT_SYMBOL(svc_create_pooled); | ||
29 | EXPORT_SYMBOL(svc_set_num_threads); | ||
30 | EXPORT_SYMBOL(svc_exit_thread); | ||
31 | EXPORT_SYMBOL(svc_destroy); | ||
32 | EXPORT_SYMBOL(svc_drop); | ||
33 | EXPORT_SYMBOL(svc_process); | ||
34 | EXPORT_SYMBOL(svc_recv); | ||
35 | EXPORT_SYMBOL(svc_wake_up); | ||
36 | EXPORT_SYMBOL(svc_makesock); | ||
37 | EXPORT_SYMBOL(svc_reserve); | ||
38 | EXPORT_SYMBOL(svc_auth_register); | ||
39 | EXPORT_SYMBOL(auth_domain_lookup); | ||
40 | EXPORT_SYMBOL(svc_authenticate); | ||
41 | EXPORT_SYMBOL(svc_set_client); | ||
42 | |||
43 | /* RPC statistics */ | ||
44 | #ifdef CONFIG_PROC_FS | ||
45 | EXPORT_SYMBOL(svc_proc_register); | ||
46 | EXPORT_SYMBOL(svc_proc_unregister); | ||
47 | EXPORT_SYMBOL(svc_seq_show); | ||
48 | #endif | ||
49 | |||
50 | /* caching... */ | ||
51 | EXPORT_SYMBOL(auth_domain_find); | ||
52 | EXPORT_SYMBOL(auth_domain_put); | ||
53 | EXPORT_SYMBOL(auth_unix_add_addr); | ||
54 | EXPORT_SYMBOL(auth_unix_forget_old); | ||
55 | EXPORT_SYMBOL(auth_unix_lookup); | ||
56 | EXPORT_SYMBOL(cache_check); | ||
57 | EXPORT_SYMBOL(cache_flush); | ||
58 | EXPORT_SYMBOL(cache_purge); | ||
59 | EXPORT_SYMBOL(cache_register); | ||
60 | EXPORT_SYMBOL(cache_unregister); | ||
61 | EXPORT_SYMBOL(qword_add); | ||
62 | EXPORT_SYMBOL(qword_addhex); | ||
63 | EXPORT_SYMBOL(qword_get); | ||
64 | EXPORT_SYMBOL(svcauth_unix_purge); | ||
65 | EXPORT_SYMBOL(unix_domain_find); | ||
66 | |||
67 | extern struct cache_detail ip_map_cache, unix_gid_cache; | 25 | extern struct cache_detail ip_map_cache, unix_gid_cache; |
68 | 26 | ||
69 | static int __init | 27 | static int __init |
@@ -85,7 +43,8 @@ init_sunrpc(void) | |||
85 | #endif | 43 | #endif |
86 | cache_register(&ip_map_cache); | 44 | cache_register(&ip_map_cache); |
87 | cache_register(&unix_gid_cache); | 45 | cache_register(&unix_gid_cache); |
88 | init_socket_xprt(); | 46 | svc_init_xprt_sock(); /* svc sock transport */ |
47 | init_socket_xprt(); /* clnt sock transport */ | ||
89 | rpcauth_init_module(); | 48 | rpcauth_init_module(); |
90 | out: | 49 | out: |
91 | return err; | 50 | return err; |
@@ -96,12 +55,11 @@ cleanup_sunrpc(void) | |||
96 | { | 55 | { |
97 | rpcauth_remove_module(); | 56 | rpcauth_remove_module(); |
98 | cleanup_socket_xprt(); | 57 | cleanup_socket_xprt(); |
58 | svc_cleanup_xprt_sock(); | ||
99 | unregister_rpc_pipefs(); | 59 | unregister_rpc_pipefs(); |
100 | rpc_destroy_mempool(); | 60 | rpc_destroy_mempool(); |
101 | if (cache_unregister(&ip_map_cache)) | 61 | cache_unregister(&ip_map_cache); |
102 | printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n"); | 62 | cache_unregister(&unix_gid_cache); |
103 | if (cache_unregister(&unix_gid_cache)) | ||
104 | printk(KERN_ERR "sunrpc: failed to unregister unix_gid cache\n"); | ||
105 | #ifdef RPC_DEBUG | 63 | #ifdef RPC_DEBUG |
106 | rpc_unregister_sysctl(); | 64 | rpc_unregister_sysctl(); |
107 | #endif | 65 | #endif |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 4ad5fbbb18b4..a290e1523297 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -364,7 +364,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, | |||
364 | void (*shutdown)(struct svc_serv *serv)) | 364 | void (*shutdown)(struct svc_serv *serv)) |
365 | { | 365 | { |
366 | struct svc_serv *serv; | 366 | struct svc_serv *serv; |
367 | int vers; | 367 | unsigned int vers; |
368 | unsigned int xdrsize; | 368 | unsigned int xdrsize; |
369 | unsigned int i; | 369 | unsigned int i; |
370 | 370 | ||
@@ -433,6 +433,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize, | |||
433 | { | 433 | { |
434 | return __svc_create(prog, bufsize, /*npools*/1, shutdown); | 434 | return __svc_create(prog, bufsize, /*npools*/1, shutdown); |
435 | } | 435 | } |
436 | EXPORT_SYMBOL(svc_create); | ||
436 | 437 | ||
437 | struct svc_serv * | 438 | struct svc_serv * |
438 | svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | 439 | svc_create_pooled(struct svc_program *prog, unsigned int bufsize, |
@@ -452,6 +453,7 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | |||
452 | 453 | ||
453 | return serv; | 454 | return serv; |
454 | } | 455 | } |
456 | EXPORT_SYMBOL(svc_create_pooled); | ||
455 | 457 | ||
456 | /* | 458 | /* |
457 | * Destroy an RPC service. Should be called with the BKL held | 459 | * Destroy an RPC service. Should be called with the BKL held |
@@ -459,9 +461,6 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | |||
459 | void | 461 | void |
460 | svc_destroy(struct svc_serv *serv) | 462 | svc_destroy(struct svc_serv *serv) |
461 | { | 463 | { |
462 | struct svc_sock *svsk; | ||
463 | struct svc_sock *tmp; | ||
464 | |||
465 | dprintk("svc: svc_destroy(%s, %d)\n", | 464 | dprintk("svc: svc_destroy(%s, %d)\n", |
466 | serv->sv_program->pg_name, | 465 | serv->sv_program->pg_name, |
467 | serv->sv_nrthreads); | 466 | serv->sv_nrthreads); |
@@ -476,14 +475,12 @@ svc_destroy(struct svc_serv *serv) | |||
476 | 475 | ||
477 | del_timer_sync(&serv->sv_temptimer); | 476 | del_timer_sync(&serv->sv_temptimer); |
478 | 477 | ||
479 | list_for_each_entry_safe(svsk, tmp, &serv->sv_tempsocks, sk_list) | 478 | svc_close_all(&serv->sv_tempsocks); |
480 | svc_force_close_socket(svsk); | ||
481 | 479 | ||
482 | if (serv->sv_shutdown) | 480 | if (serv->sv_shutdown) |
483 | serv->sv_shutdown(serv); | 481 | serv->sv_shutdown(serv); |
484 | 482 | ||
485 | list_for_each_entry_safe(svsk, tmp, &serv->sv_permsocks, sk_list) | 483 | svc_close_all(&serv->sv_permsocks); |
486 | svc_force_close_socket(svsk); | ||
487 | 484 | ||
488 | BUG_ON(!list_empty(&serv->sv_permsocks)); | 485 | BUG_ON(!list_empty(&serv->sv_permsocks)); |
489 | BUG_ON(!list_empty(&serv->sv_tempsocks)); | 486 | BUG_ON(!list_empty(&serv->sv_tempsocks)); |
@@ -498,6 +495,7 @@ svc_destroy(struct svc_serv *serv) | |||
498 | kfree(serv->sv_pools); | 495 | kfree(serv->sv_pools); |
499 | kfree(serv); | 496 | kfree(serv); |
500 | } | 497 | } |
498 | EXPORT_SYMBOL(svc_destroy); | ||
501 | 499 | ||
502 | /* | 500 | /* |
503 | * Allocate an RPC server's buffer space. | 501 | * Allocate an RPC server's buffer space. |
@@ -536,31 +534,17 @@ svc_release_buffer(struct svc_rqst *rqstp) | |||
536 | put_page(rqstp->rq_pages[i]); | 534 | put_page(rqstp->rq_pages[i]); |
537 | } | 535 | } |
538 | 536 | ||
539 | /* | 537 | struct svc_rqst * |
540 | * Create a thread in the given pool. Caller must hold BKL. | 538 | svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool) |
541 | * On a NUMA or SMP machine, with a multi-pool serv, the thread | ||
542 | * will be restricted to run on the cpus belonging to the pool. | ||
543 | */ | ||
544 | static int | ||
545 | __svc_create_thread(svc_thread_fn func, struct svc_serv *serv, | ||
546 | struct svc_pool *pool) | ||
547 | { | 539 | { |
548 | struct svc_rqst *rqstp; | 540 | struct svc_rqst *rqstp; |
549 | int error = -ENOMEM; | ||
550 | int have_oldmask = 0; | ||
551 | cpumask_t oldmask; | ||
552 | 541 | ||
553 | rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL); | 542 | rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL); |
554 | if (!rqstp) | 543 | if (!rqstp) |
555 | goto out; | 544 | goto out_enomem; |
556 | 545 | ||
557 | init_waitqueue_head(&rqstp->rq_wait); | 546 | init_waitqueue_head(&rqstp->rq_wait); |
558 | 547 | ||
559 | if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) | ||
560 | || !(rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) | ||
561 | || !svc_init_buffer(rqstp, serv->sv_max_mesg)) | ||
562 | goto out_thread; | ||
563 | |||
564 | serv->sv_nrthreads++; | 548 | serv->sv_nrthreads++; |
565 | spin_lock_bh(&pool->sp_lock); | 549 | spin_lock_bh(&pool->sp_lock); |
566 | pool->sp_nrthreads++; | 550 | pool->sp_nrthreads++; |
@@ -569,6 +553,45 @@ __svc_create_thread(svc_thread_fn func, struct svc_serv *serv, | |||
569 | rqstp->rq_server = serv; | 553 | rqstp->rq_server = serv; |
570 | rqstp->rq_pool = pool; | 554 | rqstp->rq_pool = pool; |
571 | 555 | ||
556 | rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL); | ||
557 | if (!rqstp->rq_argp) | ||
558 | goto out_thread; | ||
559 | |||
560 | rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL); | ||
561 | if (!rqstp->rq_resp) | ||
562 | goto out_thread; | ||
563 | |||
564 | if (!svc_init_buffer(rqstp, serv->sv_max_mesg)) | ||
565 | goto out_thread; | ||
566 | |||
567 | return rqstp; | ||
568 | out_thread: | ||
569 | svc_exit_thread(rqstp); | ||
570 | out_enomem: | ||
571 | return ERR_PTR(-ENOMEM); | ||
572 | } | ||
573 | EXPORT_SYMBOL(svc_prepare_thread); | ||
574 | |||
575 | /* | ||
576 | * Create a thread in the given pool. Caller must hold BKL. | ||
577 | * On a NUMA or SMP machine, with a multi-pool serv, the thread | ||
578 | * will be restricted to run on the cpus belonging to the pool. | ||
579 | */ | ||
580 | static int | ||
581 | __svc_create_thread(svc_thread_fn func, struct svc_serv *serv, | ||
582 | struct svc_pool *pool) | ||
583 | { | ||
584 | struct svc_rqst *rqstp; | ||
585 | int error = -ENOMEM; | ||
586 | int have_oldmask = 0; | ||
587 | cpumask_t oldmask; | ||
588 | |||
589 | rqstp = svc_prepare_thread(serv, pool); | ||
590 | if (IS_ERR(rqstp)) { | ||
591 | error = PTR_ERR(rqstp); | ||
592 | goto out; | ||
593 | } | ||
594 | |||
572 | if (serv->sv_nrpools > 1) | 595 | if (serv->sv_nrpools > 1) |
573 | have_oldmask = svc_pool_map_set_cpumask(pool->sp_id, &oldmask); | 596 | have_oldmask = svc_pool_map_set_cpumask(pool->sp_id, &oldmask); |
574 | 597 | ||
@@ -597,6 +620,7 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv) | |||
597 | { | 620 | { |
598 | return __svc_create_thread(func, serv, &serv->sv_pools[0]); | 621 | return __svc_create_thread(func, serv, &serv->sv_pools[0]); |
599 | } | 622 | } |
623 | EXPORT_SYMBOL(svc_create_thread); | ||
600 | 624 | ||
601 | /* | 625 | /* |
602 | * Choose a pool in which to create a new thread, for svc_set_num_threads | 626 | * Choose a pool in which to create a new thread, for svc_set_num_threads |
@@ -700,6 +724,7 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) | |||
700 | 724 | ||
701 | return error; | 725 | return error; |
702 | } | 726 | } |
727 | EXPORT_SYMBOL(svc_set_num_threads); | ||
703 | 728 | ||
704 | /* | 729 | /* |
705 | * Called from a server thread as it's exiting. Caller must hold BKL. | 730 | * Called from a server thread as it's exiting. Caller must hold BKL. |
@@ -726,6 +751,7 @@ svc_exit_thread(struct svc_rqst *rqstp) | |||
726 | if (serv) | 751 | if (serv) |
727 | svc_destroy(serv); | 752 | svc_destroy(serv); |
728 | } | 753 | } |
754 | EXPORT_SYMBOL(svc_exit_thread); | ||
729 | 755 | ||
730 | /* | 756 | /* |
731 | * Register an RPC service with the local portmapper. | 757 | * Register an RPC service with the local portmapper. |
@@ -737,7 +763,8 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port) | |||
737 | { | 763 | { |
738 | struct svc_program *progp; | 764 | struct svc_program *progp; |
739 | unsigned long flags; | 765 | unsigned long flags; |
740 | int i, error = 0, dummy; | 766 | unsigned int i; |
767 | int error = 0, dummy; | ||
741 | 768 | ||
742 | if (!port) | 769 | if (!port) |
743 | clear_thread_flag(TIF_SIGPENDING); | 770 | clear_thread_flag(TIF_SIGPENDING); |
@@ -840,9 +867,9 @@ svc_process(struct svc_rqst *rqstp) | |||
840 | rqstp->rq_res.tail[0].iov_len = 0; | 867 | rqstp->rq_res.tail[0].iov_len = 0; |
841 | /* Will be turned off only in gss privacy case: */ | 868 | /* Will be turned off only in gss privacy case: */ |
842 | rqstp->rq_splice_ok = 1; | 869 | rqstp->rq_splice_ok = 1; |
843 | /* tcp needs a space for the record length... */ | 870 | |
844 | if (rqstp->rq_prot == IPPROTO_TCP) | 871 | /* Setup reply header */ |
845 | svc_putnl(resv, 0); | 872 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); |
846 | 873 | ||
847 | rqstp->rq_xid = svc_getu32(argv); | 874 | rqstp->rq_xid = svc_getu32(argv); |
848 | svc_putu32(resv, rqstp->rq_xid); | 875 | svc_putu32(resv, rqstp->rq_xid); |
@@ -1049,16 +1076,15 @@ err_bad: | |||
1049 | svc_putnl(resv, ntohl(rpc_stat)); | 1076 | svc_putnl(resv, ntohl(rpc_stat)); |
1050 | goto sendit; | 1077 | goto sendit; |
1051 | } | 1078 | } |
1079 | EXPORT_SYMBOL(svc_process); | ||
1052 | 1080 | ||
1053 | /* | 1081 | /* |
1054 | * Return (transport-specific) limit on the rpc payload. | 1082 | * Return (transport-specific) limit on the rpc payload. |
1055 | */ | 1083 | */ |
1056 | u32 svc_max_payload(const struct svc_rqst *rqstp) | 1084 | u32 svc_max_payload(const struct svc_rqst *rqstp) |
1057 | { | 1085 | { |
1058 | int max = RPCSVC_MAXPAYLOAD_TCP; | 1086 | u32 max = rqstp->rq_xprt->xpt_class->xcl_max_payload; |
1059 | 1087 | ||
1060 | if (rqstp->rq_sock->sk_sock->type == SOCK_DGRAM) | ||
1061 | max = RPCSVC_MAXPAYLOAD_UDP; | ||
1062 | if (rqstp->rq_server->sv_max_payload < max) | 1088 | if (rqstp->rq_server->sv_max_payload < max) |
1063 | max = rqstp->rq_server->sv_max_payload; | 1089 | max = rqstp->rq_server->sv_max_payload; |
1064 | return max; | 1090 | return max; |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c new file mode 100644 index 000000000000..ea377e06afae --- /dev/null +++ b/net/sunrpc/svc_xprt.c | |||
@@ -0,0 +1,1055 @@ | |||
1 | /* | ||
2 | * linux/net/sunrpc/svc_xprt.c | ||
3 | * | ||
4 | * Author: Tom Tucker <tom@opengridcomputing.com> | ||
5 | */ | ||
6 | |||
7 | #include <linux/sched.h> | ||
8 | #include <linux/errno.h> | ||
9 | #include <linux/fcntl.h> | ||
10 | #include <linux/net.h> | ||
11 | #include <linux/in.h> | ||
12 | #include <linux/inet.h> | ||
13 | #include <linux/udp.h> | ||
14 | #include <linux/tcp.h> | ||
15 | #include <linux/unistd.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/netdevice.h> | ||
18 | #include <linux/skbuff.h> | ||
19 | #include <linux/file.h> | ||
20 | #include <linux/freezer.h> | ||
21 | #include <net/sock.h> | ||
22 | #include <net/checksum.h> | ||
23 | #include <net/ip.h> | ||
24 | #include <net/ipv6.h> | ||
25 | #include <net/tcp_states.h> | ||
26 | #include <linux/uaccess.h> | ||
27 | #include <asm/ioctls.h> | ||
28 | |||
29 | #include <linux/sunrpc/types.h> | ||
30 | #include <linux/sunrpc/clnt.h> | ||
31 | #include <linux/sunrpc/xdr.h> | ||
32 | #include <linux/sunrpc/stats.h> | ||
33 | #include <linux/sunrpc/svc_xprt.h> | ||
34 | |||
35 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | ||
36 | |||
37 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); | ||
38 | static int svc_deferred_recv(struct svc_rqst *rqstp); | ||
39 | static struct cache_deferred_req *svc_defer(struct cache_req *req); | ||
40 | static void svc_age_temp_xprts(unsigned long closure); | ||
41 | |||
42 | /* apparently the "standard" is that clients close | ||
43 | * idle connections after 5 minutes, servers after | ||
44 | * 6 minutes | ||
45 | * http://www.connectathon.org/talks96/nfstcp.pdf | ||
46 | */ | ||
47 | static int svc_conn_age_period = 6*60; | ||
48 | |||
49 | /* List of registered transport classes */ | ||
50 | static DEFINE_SPINLOCK(svc_xprt_class_lock); | ||
51 | static LIST_HEAD(svc_xprt_class_list); | ||
52 | |||
53 | /* SMP locking strategy: | ||
54 | * | ||
55 | * svc_pool->sp_lock protects most of the fields of that pool. | ||
56 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. | ||
57 | * when both need to be taken (rare), svc_serv->sv_lock is first. | ||
58 | * BKL protects svc_serv->sv_nrthread. | ||
59 | * svc_sock->sk_lock protects the svc_sock->sk_deferred list | ||
60 | * and the ->sk_info_authunix cache. | ||
61 | * | ||
62 | * The XPT_BUSY bit in xprt->xpt_flags prevents a transport being | ||
63 | * enqueued multiply. During normal transport processing this bit | ||
64 | * is set by svc_xprt_enqueue and cleared by svc_xprt_received. | ||
65 | * Providers should not manipulate this bit directly. | ||
66 | * | ||
67 | * Some flags can be set to certain values at any time | ||
68 | * providing that certain rules are followed: | ||
69 | * | ||
70 | * XPT_CONN, XPT_DATA: | ||
71 | * - Can be set or cleared at any time. | ||
72 | * - After a set, svc_xprt_enqueue must be called to enqueue | ||
73 | * the transport for processing. | ||
74 | * - After a clear, the transport must be read/accepted. | ||
75 | * If this succeeds, it must be set again. | ||
76 | * XPT_CLOSE: | ||
77 | * - Can set at any time. It is never cleared. | ||
78 | * XPT_DEAD: | ||
79 | * - Can only be set while XPT_BUSY is held which ensures | ||
80 | * that no other thread will be using the transport or will | ||
81 | * try to set XPT_DEAD. | ||
82 | */ | ||
83 | |||
84 | int svc_reg_xprt_class(struct svc_xprt_class *xcl) | ||
85 | { | ||
86 | struct svc_xprt_class *cl; | ||
87 | int res = -EEXIST; | ||
88 | |||
89 | dprintk("svc: Adding svc transport class '%s'\n", xcl->xcl_name); | ||
90 | |||
91 | INIT_LIST_HEAD(&xcl->xcl_list); | ||
92 | spin_lock(&svc_xprt_class_lock); | ||
93 | /* Make sure there isn't already a class with the same name */ | ||
94 | list_for_each_entry(cl, &svc_xprt_class_list, xcl_list) { | ||
95 | if (strcmp(xcl->xcl_name, cl->xcl_name) == 0) | ||
96 | goto out; | ||
97 | } | ||
98 | list_add_tail(&xcl->xcl_list, &svc_xprt_class_list); | ||
99 | res = 0; | ||
100 | out: | ||
101 | spin_unlock(&svc_xprt_class_lock); | ||
102 | return res; | ||
103 | } | ||
104 | EXPORT_SYMBOL_GPL(svc_reg_xprt_class); | ||
105 | |||
106 | void svc_unreg_xprt_class(struct svc_xprt_class *xcl) | ||
107 | { | ||
108 | dprintk("svc: Removing svc transport class '%s'\n", xcl->xcl_name); | ||
109 | spin_lock(&svc_xprt_class_lock); | ||
110 | list_del_init(&xcl->xcl_list); | ||
111 | spin_unlock(&svc_xprt_class_lock); | ||
112 | } | ||
113 | EXPORT_SYMBOL_GPL(svc_unreg_xprt_class); | ||
114 | |||
115 | /* | ||
116 | * Format the transport list for printing | ||
117 | */ | ||
118 | int svc_print_xprts(char *buf, int maxlen) | ||
119 | { | ||
120 | struct list_head *le; | ||
121 | char tmpstr[80]; | ||
122 | int len = 0; | ||
123 | buf[0] = '\0'; | ||
124 | |||
125 | spin_lock(&svc_xprt_class_lock); | ||
126 | list_for_each(le, &svc_xprt_class_list) { | ||
127 | int slen; | ||
128 | struct svc_xprt_class *xcl = | ||
129 | list_entry(le, struct svc_xprt_class, xcl_list); | ||
130 | |||
131 | sprintf(tmpstr, "%s %d\n", xcl->xcl_name, xcl->xcl_max_payload); | ||
132 | slen = strlen(tmpstr); | ||
133 | if (len + slen > maxlen) | ||
134 | break; | ||
135 | len += slen; | ||
136 | strcat(buf, tmpstr); | ||
137 | } | ||
138 | spin_unlock(&svc_xprt_class_lock); | ||
139 | |||
140 | return len; | ||
141 | } | ||
142 | |||
143 | static void svc_xprt_free(struct kref *kref) | ||
144 | { | ||
145 | struct svc_xprt *xprt = | ||
146 | container_of(kref, struct svc_xprt, xpt_ref); | ||
147 | struct module *owner = xprt->xpt_class->xcl_owner; | ||
148 | if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags) | ||
149 | && xprt->xpt_auth_cache != NULL) | ||
150 | svcauth_unix_info_release(xprt->xpt_auth_cache); | ||
151 | xprt->xpt_ops->xpo_free(xprt); | ||
152 | module_put(owner); | ||
153 | } | ||
154 | |||
155 | void svc_xprt_put(struct svc_xprt *xprt) | ||
156 | { | ||
157 | kref_put(&xprt->xpt_ref, svc_xprt_free); | ||
158 | } | ||
159 | EXPORT_SYMBOL_GPL(svc_xprt_put); | ||
160 | |||
161 | /* | ||
162 | * Called by transport drivers to initialize the transport independent | ||
163 | * portion of the transport instance. | ||
164 | */ | ||
165 | void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt, | ||
166 | struct svc_serv *serv) | ||
167 | { | ||
168 | memset(xprt, 0, sizeof(*xprt)); | ||
169 | xprt->xpt_class = xcl; | ||
170 | xprt->xpt_ops = xcl->xcl_ops; | ||
171 | kref_init(&xprt->xpt_ref); | ||
172 | xprt->xpt_server = serv; | ||
173 | INIT_LIST_HEAD(&xprt->xpt_list); | ||
174 | INIT_LIST_HEAD(&xprt->xpt_ready); | ||
175 | INIT_LIST_HEAD(&xprt->xpt_deferred); | ||
176 | mutex_init(&xprt->xpt_mutex); | ||
177 | spin_lock_init(&xprt->xpt_lock); | ||
178 | set_bit(XPT_BUSY, &xprt->xpt_flags); | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(svc_xprt_init); | ||
181 | |||
182 | int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port, | ||
183 | int flags) | ||
184 | { | ||
185 | struct svc_xprt_class *xcl; | ||
186 | struct sockaddr_in sin = { | ||
187 | .sin_family = AF_INET, | ||
188 | .sin_addr.s_addr = INADDR_ANY, | ||
189 | .sin_port = htons(port), | ||
190 | }; | ||
191 | dprintk("svc: creating transport %s[%d]\n", xprt_name, port); | ||
192 | spin_lock(&svc_xprt_class_lock); | ||
193 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { | ||
194 | struct svc_xprt *newxprt; | ||
195 | |||
196 | if (strcmp(xprt_name, xcl->xcl_name)) | ||
197 | continue; | ||
198 | |||
199 | if (!try_module_get(xcl->xcl_owner)) | ||
200 | goto err; | ||
201 | |||
202 | spin_unlock(&svc_xprt_class_lock); | ||
203 | newxprt = xcl->xcl_ops-> | ||
204 | xpo_create(serv, (struct sockaddr *)&sin, sizeof(sin), | ||
205 | flags); | ||
206 | if (IS_ERR(newxprt)) { | ||
207 | module_put(xcl->xcl_owner); | ||
208 | return PTR_ERR(newxprt); | ||
209 | } | ||
210 | |||
211 | clear_bit(XPT_TEMP, &newxprt->xpt_flags); | ||
212 | spin_lock_bh(&serv->sv_lock); | ||
213 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); | ||
214 | spin_unlock_bh(&serv->sv_lock); | ||
215 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); | ||
216 | return svc_xprt_local_port(newxprt); | ||
217 | } | ||
218 | err: | ||
219 | spin_unlock(&svc_xprt_class_lock); | ||
220 | dprintk("svc: transport %s not found\n", xprt_name); | ||
221 | return -ENOENT; | ||
222 | } | ||
223 | EXPORT_SYMBOL_GPL(svc_create_xprt); | ||
224 | |||
225 | /* | ||
226 | * Copy the local and remote xprt addresses to the rqstp structure | ||
227 | */ | ||
228 | void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt) | ||
229 | { | ||
230 | struct sockaddr *sin; | ||
231 | |||
232 | memcpy(&rqstp->rq_addr, &xprt->xpt_remote, xprt->xpt_remotelen); | ||
233 | rqstp->rq_addrlen = xprt->xpt_remotelen; | ||
234 | |||
235 | /* | ||
236 | * Destination address in request is needed for binding the | ||
237 | * source address in RPC replies/callbacks later. | ||
238 | */ | ||
239 | sin = (struct sockaddr *)&xprt->xpt_local; | ||
240 | switch (sin->sa_family) { | ||
241 | case AF_INET: | ||
242 | rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr; | ||
243 | break; | ||
244 | case AF_INET6: | ||
245 | rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr; | ||
246 | break; | ||
247 | } | ||
248 | } | ||
249 | EXPORT_SYMBOL_GPL(svc_xprt_copy_addrs); | ||
250 | |||
251 | /** | ||
252 | * svc_print_addr - Format rq_addr field for printing | ||
253 | * @rqstp: svc_rqst struct containing address to print | ||
254 | * @buf: target buffer for formatted address | ||
255 | * @len: length of target buffer | ||
256 | * | ||
257 | */ | ||
258 | char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len) | ||
259 | { | ||
260 | return __svc_print_addr(svc_addr(rqstp), buf, len); | ||
261 | } | ||
262 | EXPORT_SYMBOL_GPL(svc_print_addr); | ||
263 | |||
264 | /* | ||
265 | * Queue up an idle server thread. Must have pool->sp_lock held. | ||
266 | * Note: this is really a stack rather than a queue, so that we only | ||
267 | * use as many different threads as we need, and the rest don't pollute | ||
268 | * the cache. | ||
269 | */ | ||
270 | static void svc_thread_enqueue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
271 | { | ||
272 | list_add(&rqstp->rq_list, &pool->sp_threads); | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * Dequeue an nfsd thread. Must have pool->sp_lock held. | ||
277 | */ | ||
278 | static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
279 | { | ||
280 | list_del(&rqstp->rq_list); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Queue up a transport with data pending. If there are idle nfsd | ||
285 | * processes, wake 'em up. | ||
286 | * | ||
287 | */ | ||
288 | void svc_xprt_enqueue(struct svc_xprt *xprt) | ||
289 | { | ||
290 | struct svc_serv *serv = xprt->xpt_server; | ||
291 | struct svc_pool *pool; | ||
292 | struct svc_rqst *rqstp; | ||
293 | int cpu; | ||
294 | |||
295 | if (!(xprt->xpt_flags & | ||
296 | ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) | ||
297 | return; | ||
298 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | ||
299 | return; | ||
300 | |||
301 | cpu = get_cpu(); | ||
302 | pool = svc_pool_for_cpu(xprt->xpt_server, cpu); | ||
303 | put_cpu(); | ||
304 | |||
305 | spin_lock_bh(&pool->sp_lock); | ||
306 | |||
307 | if (!list_empty(&pool->sp_threads) && | ||
308 | !list_empty(&pool->sp_sockets)) | ||
309 | printk(KERN_ERR | ||
310 | "svc_xprt_enqueue: " | ||
311 | "threads and transports both waiting??\n"); | ||
312 | |||
313 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { | ||
314 | /* Don't enqueue dead transports */ | ||
315 | dprintk("svc: transport %p is dead, not enqueued\n", xprt); | ||
316 | goto out_unlock; | ||
317 | } | ||
318 | |||
319 | /* Mark transport as busy. It will remain in this state until | ||
320 | * the provider calls svc_xprt_received. We update XPT_BUSY | ||
321 | * atomically because it also guards against trying to enqueue | ||
322 | * the transport twice. | ||
323 | */ | ||
324 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) { | ||
325 | /* Don't enqueue transport while already enqueued */ | ||
326 | dprintk("svc: transport %p busy, not enqueued\n", xprt); | ||
327 | goto out_unlock; | ||
328 | } | ||
329 | BUG_ON(xprt->xpt_pool != NULL); | ||
330 | xprt->xpt_pool = pool; | ||
331 | |||
332 | /* Handle pending connection */ | ||
333 | if (test_bit(XPT_CONN, &xprt->xpt_flags)) | ||
334 | goto process; | ||
335 | |||
336 | /* Handle close in-progress */ | ||
337 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) | ||
338 | goto process; | ||
339 | |||
340 | /* Check if we have space to reply to a request */ | ||
341 | if (!xprt->xpt_ops->xpo_has_wspace(xprt)) { | ||
342 | /* Don't enqueue while not enough space for reply */ | ||
343 | dprintk("svc: no write space, transport %p not enqueued\n", | ||
344 | xprt); | ||
345 | xprt->xpt_pool = NULL; | ||
346 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
347 | goto out_unlock; | ||
348 | } | ||
349 | |||
350 | process: | ||
351 | if (!list_empty(&pool->sp_threads)) { | ||
352 | rqstp = list_entry(pool->sp_threads.next, | ||
353 | struct svc_rqst, | ||
354 | rq_list); | ||
355 | dprintk("svc: transport %p served by daemon %p\n", | ||
356 | xprt, rqstp); | ||
357 | svc_thread_dequeue(pool, rqstp); | ||
358 | if (rqstp->rq_xprt) | ||
359 | printk(KERN_ERR | ||
360 | "svc_xprt_enqueue: server %p, rq_xprt=%p!\n", | ||
361 | rqstp, rqstp->rq_xprt); | ||
362 | rqstp->rq_xprt = xprt; | ||
363 | svc_xprt_get(xprt); | ||
364 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
365 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
366 | BUG_ON(xprt->xpt_pool != pool); | ||
367 | wake_up(&rqstp->rq_wait); | ||
368 | } else { | ||
369 | dprintk("svc: transport %p put into queue\n", xprt); | ||
370 | list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); | ||
371 | BUG_ON(xprt->xpt_pool != pool); | ||
372 | } | ||
373 | |||
374 | out_unlock: | ||
375 | spin_unlock_bh(&pool->sp_lock); | ||
376 | } | ||
377 | EXPORT_SYMBOL_GPL(svc_xprt_enqueue); | ||
378 | |||
379 | /* | ||
380 | * Dequeue the first transport. Must be called with the pool->sp_lock held. | ||
381 | */ | ||
382 | static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) | ||
383 | { | ||
384 | struct svc_xprt *xprt; | ||
385 | |||
386 | if (list_empty(&pool->sp_sockets)) | ||
387 | return NULL; | ||
388 | |||
389 | xprt = list_entry(pool->sp_sockets.next, | ||
390 | struct svc_xprt, xpt_ready); | ||
391 | list_del_init(&xprt->xpt_ready); | ||
392 | |||
393 | dprintk("svc: transport %p dequeued, inuse=%d\n", | ||
394 | xprt, atomic_read(&xprt->xpt_ref.refcount)); | ||
395 | |||
396 | return xprt; | ||
397 | } | ||
398 | |||
399 | /* | ||
400 | * svc_xprt_received conditionally queues the transport for processing | ||
401 | * by another thread. The caller must hold the XPT_BUSY bit and must | ||
402 | * not thereafter touch transport data. | ||
403 | * | ||
404 | * Note: XPT_DATA only gets cleared when a read-attempt finds no (or | ||
405 | * insufficient) data. | ||
406 | */ | ||
407 | void svc_xprt_received(struct svc_xprt *xprt) | ||
408 | { | ||
409 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | ||
410 | xprt->xpt_pool = NULL; | ||
411 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
412 | svc_xprt_enqueue(xprt); | ||
413 | } | ||
414 | EXPORT_SYMBOL_GPL(svc_xprt_received); | ||
415 | |||
416 | /** | ||
417 | * svc_reserve - change the space reserved for the reply to a request. | ||
418 | * @rqstp: The request in question | ||
419 | * @space: new max space to reserve | ||
420 | * | ||
421 | * Each request reserves some space on the output queue of the transport | ||
422 | * to make sure the reply fits. This function reduces that reserved | ||
423 | * space to be the amount of space used already, plus @space. | ||
424 | * | ||
425 | */ | ||
426 | void svc_reserve(struct svc_rqst *rqstp, int space) | ||
427 | { | ||
428 | space += rqstp->rq_res.head[0].iov_len; | ||
429 | |||
430 | if (space < rqstp->rq_reserved) { | ||
431 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
432 | atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved); | ||
433 | rqstp->rq_reserved = space; | ||
434 | |||
435 | svc_xprt_enqueue(xprt); | ||
436 | } | ||
437 | } | ||
438 | EXPORT_SYMBOL(svc_reserve); | ||
439 | |||
440 | static void svc_xprt_release(struct svc_rqst *rqstp) | ||
441 | { | ||
442 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
443 | |||
444 | rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); | ||
445 | |||
446 | svc_free_res_pages(rqstp); | ||
447 | rqstp->rq_res.page_len = 0; | ||
448 | rqstp->rq_res.page_base = 0; | ||
449 | |||
450 | /* Reset response buffer and release | ||
451 | * the reservation. | ||
452 | * But first, check that enough space was reserved | ||
453 | * for the reply, otherwise we have a bug! | ||
454 | */ | ||
455 | if ((rqstp->rq_res.len) > rqstp->rq_reserved) | ||
456 | printk(KERN_ERR "RPC request reserved %d but used %d\n", | ||
457 | rqstp->rq_reserved, | ||
458 | rqstp->rq_res.len); | ||
459 | |||
460 | rqstp->rq_res.head[0].iov_len = 0; | ||
461 | svc_reserve(rqstp, 0); | ||
462 | rqstp->rq_xprt = NULL; | ||
463 | |||
464 | svc_xprt_put(xprt); | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * External function to wake up a server waiting for data | ||
469 | * This really only makes sense for services like lockd | ||
470 | * which have exactly one thread anyway. | ||
471 | */ | ||
472 | void svc_wake_up(struct svc_serv *serv) | ||
473 | { | ||
474 | struct svc_rqst *rqstp; | ||
475 | unsigned int i; | ||
476 | struct svc_pool *pool; | ||
477 | |||
478 | for (i = 0; i < serv->sv_nrpools; i++) { | ||
479 | pool = &serv->sv_pools[i]; | ||
480 | |||
481 | spin_lock_bh(&pool->sp_lock); | ||
482 | if (!list_empty(&pool->sp_threads)) { | ||
483 | rqstp = list_entry(pool->sp_threads.next, | ||
484 | struct svc_rqst, | ||
485 | rq_list); | ||
486 | dprintk("svc: daemon %p woken up.\n", rqstp); | ||
487 | /* | ||
488 | svc_thread_dequeue(pool, rqstp); | ||
489 | rqstp->rq_xprt = NULL; | ||
490 | */ | ||
491 | wake_up(&rqstp->rq_wait); | ||
492 | } | ||
493 | spin_unlock_bh(&pool->sp_lock); | ||
494 | } | ||
495 | } | ||
496 | EXPORT_SYMBOL(svc_wake_up); | ||
497 | |||
498 | int svc_port_is_privileged(struct sockaddr *sin) | ||
499 | { | ||
500 | switch (sin->sa_family) { | ||
501 | case AF_INET: | ||
502 | return ntohs(((struct sockaddr_in *)sin)->sin_port) | ||
503 | < PROT_SOCK; | ||
504 | case AF_INET6: | ||
505 | return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) | ||
506 | < PROT_SOCK; | ||
507 | default: | ||
508 | return 0; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | /* | ||
513 | * Make sure that we don't have too many active connections. If we | ||
514 | * have, something must be dropped. | ||
515 | * | ||
516 | * There's no point in trying to do random drop here for DoS | ||
517 | * prevention. The NFS clients does 1 reconnect in 15 seconds. An | ||
518 | * attacker can easily beat that. | ||
519 | * | ||
520 | * The only somewhat efficient mechanism would be if drop old | ||
521 | * connections from the same IP first. But right now we don't even | ||
522 | * record the client IP in svc_sock. | ||
523 | */ | ||
524 | static void svc_check_conn_limits(struct svc_serv *serv) | ||
525 | { | ||
526 | if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*20) { | ||
527 | struct svc_xprt *xprt = NULL; | ||
528 | spin_lock_bh(&serv->sv_lock); | ||
529 | if (!list_empty(&serv->sv_tempsocks)) { | ||
530 | if (net_ratelimit()) { | ||
531 | /* Try to help the admin */ | ||
532 | printk(KERN_NOTICE "%s: too many open " | ||
533 | "connections, consider increasing the " | ||
534 | "number of nfsd threads\n", | ||
535 | serv->sv_name); | ||
536 | } | ||
537 | /* | ||
538 | * Always select the oldest connection. It's not fair, | ||
539 | * but so is life | ||
540 | */ | ||
541 | xprt = list_entry(serv->sv_tempsocks.prev, | ||
542 | struct svc_xprt, | ||
543 | xpt_list); | ||
544 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
545 | svc_xprt_get(xprt); | ||
546 | } | ||
547 | spin_unlock_bh(&serv->sv_lock); | ||
548 | |||
549 | if (xprt) { | ||
550 | svc_xprt_enqueue(xprt); | ||
551 | svc_xprt_put(xprt); | ||
552 | } | ||
553 | } | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * Receive the next request on any transport. This code is carefully | ||
558 | * organised not to touch any cachelines in the shared svc_serv | ||
559 | * structure, only cachelines in the local svc_pool. | ||
560 | */ | ||
561 | int svc_recv(struct svc_rqst *rqstp, long timeout) | ||
562 | { | ||
563 | struct svc_xprt *xprt = NULL; | ||
564 | struct svc_serv *serv = rqstp->rq_server; | ||
565 | struct svc_pool *pool = rqstp->rq_pool; | ||
566 | int len, i; | ||
567 | int pages; | ||
568 | struct xdr_buf *arg; | ||
569 | DECLARE_WAITQUEUE(wait, current); | ||
570 | |||
571 | dprintk("svc: server %p waiting for data (to = %ld)\n", | ||
572 | rqstp, timeout); | ||
573 | |||
574 | if (rqstp->rq_xprt) | ||
575 | printk(KERN_ERR | ||
576 | "svc_recv: service %p, transport not NULL!\n", | ||
577 | rqstp); | ||
578 | if (waitqueue_active(&rqstp->rq_wait)) | ||
579 | printk(KERN_ERR | ||
580 | "svc_recv: service %p, wait queue active!\n", | ||
581 | rqstp); | ||
582 | |||
583 | /* now allocate needed pages. If we get a failure, sleep briefly */ | ||
584 | pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; | ||
585 | for (i = 0; i < pages ; i++) | ||
586 | while (rqstp->rq_pages[i] == NULL) { | ||
587 | struct page *p = alloc_page(GFP_KERNEL); | ||
588 | if (!p) { | ||
589 | int j = msecs_to_jiffies(500); | ||
590 | schedule_timeout_uninterruptible(j); | ||
591 | } | ||
592 | rqstp->rq_pages[i] = p; | ||
593 | } | ||
594 | rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ | ||
595 | BUG_ON(pages >= RPCSVC_MAXPAGES); | ||
596 | |||
597 | /* Make arg->head point to first page and arg->pages point to rest */ | ||
598 | arg = &rqstp->rq_arg; | ||
599 | arg->head[0].iov_base = page_address(rqstp->rq_pages[0]); | ||
600 | arg->head[0].iov_len = PAGE_SIZE; | ||
601 | arg->pages = rqstp->rq_pages + 1; | ||
602 | arg->page_base = 0; | ||
603 | /* save at least one page for response */ | ||
604 | arg->page_len = (pages-2)*PAGE_SIZE; | ||
605 | arg->len = (pages-1)*PAGE_SIZE; | ||
606 | arg->tail[0].iov_len = 0; | ||
607 | |||
608 | try_to_freeze(); | ||
609 | cond_resched(); | ||
610 | if (signalled()) | ||
611 | return -EINTR; | ||
612 | |||
613 | spin_lock_bh(&pool->sp_lock); | ||
614 | xprt = svc_xprt_dequeue(pool); | ||
615 | if (xprt) { | ||
616 | rqstp->rq_xprt = xprt; | ||
617 | svc_xprt_get(xprt); | ||
618 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
619 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | ||
620 | } else { | ||
621 | /* No data pending. Go to sleep */ | ||
622 | svc_thread_enqueue(pool, rqstp); | ||
623 | |||
624 | /* | ||
625 | * We have to be able to interrupt this wait | ||
626 | * to bring down the daemons ... | ||
627 | */ | ||
628 | set_current_state(TASK_INTERRUPTIBLE); | ||
629 | add_wait_queue(&rqstp->rq_wait, &wait); | ||
630 | spin_unlock_bh(&pool->sp_lock); | ||
631 | |||
632 | schedule_timeout(timeout); | ||
633 | |||
634 | try_to_freeze(); | ||
635 | |||
636 | spin_lock_bh(&pool->sp_lock); | ||
637 | remove_wait_queue(&rqstp->rq_wait, &wait); | ||
638 | |||
639 | xprt = rqstp->rq_xprt; | ||
640 | if (!xprt) { | ||
641 | svc_thread_dequeue(pool, rqstp); | ||
642 | spin_unlock_bh(&pool->sp_lock); | ||
643 | dprintk("svc: server %p, no data yet\n", rqstp); | ||
644 | return signalled()? -EINTR : -EAGAIN; | ||
645 | } | ||
646 | } | ||
647 | spin_unlock_bh(&pool->sp_lock); | ||
648 | |||
649 | len = 0; | ||
650 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | ||
651 | dprintk("svc_recv: found XPT_CLOSE\n"); | ||
652 | svc_delete_xprt(xprt); | ||
653 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
654 | struct svc_xprt *newxpt; | ||
655 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | ||
656 | if (newxpt) { | ||
657 | /* | ||
658 | * We know this module_get will succeed because the | ||
659 | * listener holds a reference too | ||
660 | */ | ||
661 | __module_get(newxpt->xpt_class->xcl_owner); | ||
662 | svc_check_conn_limits(xprt->xpt_server); | ||
663 | spin_lock_bh(&serv->sv_lock); | ||
664 | set_bit(XPT_TEMP, &newxpt->xpt_flags); | ||
665 | list_add(&newxpt->xpt_list, &serv->sv_tempsocks); | ||
666 | serv->sv_tmpcnt++; | ||
667 | if (serv->sv_temptimer.function == NULL) { | ||
668 | /* setup timer to age temp transports */ | ||
669 | setup_timer(&serv->sv_temptimer, | ||
670 | svc_age_temp_xprts, | ||
671 | (unsigned long)serv); | ||
672 | mod_timer(&serv->sv_temptimer, | ||
673 | jiffies + svc_conn_age_period * HZ); | ||
674 | } | ||
675 | spin_unlock_bh(&serv->sv_lock); | ||
676 | svc_xprt_received(newxpt); | ||
677 | } | ||
678 | svc_xprt_received(xprt); | ||
679 | } else { | ||
680 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | ||
681 | rqstp, pool->sp_id, xprt, | ||
682 | atomic_read(&xprt->xpt_ref.refcount)); | ||
683 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | ||
684 | if (rqstp->rq_deferred) { | ||
685 | svc_xprt_received(xprt); | ||
686 | len = svc_deferred_recv(rqstp); | ||
687 | } else | ||
688 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | ||
689 | dprintk("svc: got len=%d\n", len); | ||
690 | } | ||
691 | |||
692 | /* No data, incomplete (TCP) read, or accept() */ | ||
693 | if (len == 0 || len == -EAGAIN) { | ||
694 | rqstp->rq_res.len = 0; | ||
695 | svc_xprt_release(rqstp); | ||
696 | return -EAGAIN; | ||
697 | } | ||
698 | clear_bit(XPT_OLD, &xprt->xpt_flags); | ||
699 | |||
700 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); | ||
701 | rqstp->rq_chandle.defer = svc_defer; | ||
702 | |||
703 | if (serv->sv_stats) | ||
704 | serv->sv_stats->netcnt++; | ||
705 | return len; | ||
706 | } | ||
707 | EXPORT_SYMBOL(svc_recv); | ||
708 | |||
709 | /* | ||
710 | * Drop request | ||
711 | */ | ||
712 | void svc_drop(struct svc_rqst *rqstp) | ||
713 | { | ||
714 | dprintk("svc: xprt %p dropped request\n", rqstp->rq_xprt); | ||
715 | svc_xprt_release(rqstp); | ||
716 | } | ||
717 | EXPORT_SYMBOL(svc_drop); | ||
718 | |||
719 | /* | ||
720 | * Return reply to client. | ||
721 | */ | ||
722 | int svc_send(struct svc_rqst *rqstp) | ||
723 | { | ||
724 | struct svc_xprt *xprt; | ||
725 | int len; | ||
726 | struct xdr_buf *xb; | ||
727 | |||
728 | xprt = rqstp->rq_xprt; | ||
729 | if (!xprt) | ||
730 | return -EFAULT; | ||
731 | |||
732 | /* release the receive skb before sending the reply */ | ||
733 | rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); | ||
734 | |||
735 | /* calculate over-all length */ | ||
736 | xb = &rqstp->rq_res; | ||
737 | xb->len = xb->head[0].iov_len + | ||
738 | xb->page_len + | ||
739 | xb->tail[0].iov_len; | ||
740 | |||
741 | /* Grab mutex to serialize outgoing data. */ | ||
742 | mutex_lock(&xprt->xpt_mutex); | ||
743 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | ||
744 | len = -ENOTCONN; | ||
745 | else | ||
746 | len = xprt->xpt_ops->xpo_sendto(rqstp); | ||
747 | mutex_unlock(&xprt->xpt_mutex); | ||
748 | svc_xprt_release(rqstp); | ||
749 | |||
750 | if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) | ||
751 | return 0; | ||
752 | return len; | ||
753 | } | ||
754 | |||
755 | /* | ||
756 | * Timer function to close old temporary transports, using | ||
757 | * a mark-and-sweep algorithm. | ||
758 | */ | ||
759 | static void svc_age_temp_xprts(unsigned long closure) | ||
760 | { | ||
761 | struct svc_serv *serv = (struct svc_serv *)closure; | ||
762 | struct svc_xprt *xprt; | ||
763 | struct list_head *le, *next; | ||
764 | LIST_HEAD(to_be_aged); | ||
765 | |||
766 | dprintk("svc_age_temp_xprts\n"); | ||
767 | |||
768 | if (!spin_trylock_bh(&serv->sv_lock)) { | ||
769 | /* busy, try again 1 sec later */ | ||
770 | dprintk("svc_age_temp_xprts: busy\n"); | ||
771 | mod_timer(&serv->sv_temptimer, jiffies + HZ); | ||
772 | return; | ||
773 | } | ||
774 | |||
775 | list_for_each_safe(le, next, &serv->sv_tempsocks) { | ||
776 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
777 | |||
778 | /* First time through, just mark it OLD. Second time | ||
779 | * through, close it. */ | ||
780 | if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags)) | ||
781 | continue; | ||
782 | if (atomic_read(&xprt->xpt_ref.refcount) > 1 | ||
783 | || test_bit(XPT_BUSY, &xprt->xpt_flags)) | ||
784 | continue; | ||
785 | svc_xprt_get(xprt); | ||
786 | list_move(le, &to_be_aged); | ||
787 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
788 | set_bit(XPT_DETACHED, &xprt->xpt_flags); | ||
789 | } | ||
790 | spin_unlock_bh(&serv->sv_lock); | ||
791 | |||
792 | while (!list_empty(&to_be_aged)) { | ||
793 | le = to_be_aged.next; | ||
794 | /* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */ | ||
795 | list_del_init(le); | ||
796 | xprt = list_entry(le, struct svc_xprt, xpt_list); | ||
797 | |||
798 | dprintk("queuing xprt %p for closing\n", xprt); | ||
799 | |||
800 | /* a thread will dequeue and close it soon */ | ||
801 | svc_xprt_enqueue(xprt); | ||
802 | svc_xprt_put(xprt); | ||
803 | } | ||
804 | |||
805 | mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); | ||
806 | } | ||
807 | |||
808 | /* | ||
809 | * Remove a dead transport | ||
810 | */ | ||
811 | void svc_delete_xprt(struct svc_xprt *xprt) | ||
812 | { | ||
813 | struct svc_serv *serv = xprt->xpt_server; | ||
814 | |||
815 | dprintk("svc: svc_delete_xprt(%p)\n", xprt); | ||
816 | xprt->xpt_ops->xpo_detach(xprt); | ||
817 | |||
818 | spin_lock_bh(&serv->sv_lock); | ||
819 | if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) | ||
820 | list_del_init(&xprt->xpt_list); | ||
821 | /* | ||
822 | * We used to delete the transport from whichever list | ||
823 | * it's sk_xprt.xpt_ready node was on, but we don't actually | ||
824 | * need to. This is because the only time we're called | ||
825 | * while still attached to a queue, the queue itself | ||
826 | * is about to be destroyed (in svc_destroy). | ||
827 | */ | ||
828 | if (!test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) { | ||
829 | BUG_ON(atomic_read(&xprt->xpt_ref.refcount) < 2); | ||
830 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | ||
831 | serv->sv_tmpcnt--; | ||
832 | svc_xprt_put(xprt); | ||
833 | } | ||
834 | spin_unlock_bh(&serv->sv_lock); | ||
835 | } | ||
836 | |||
837 | void svc_close_xprt(struct svc_xprt *xprt) | ||
838 | { | ||
839 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
840 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) | ||
841 | /* someone else will have to effect the close */ | ||
842 | return; | ||
843 | |||
844 | svc_xprt_get(xprt); | ||
845 | svc_delete_xprt(xprt); | ||
846 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
847 | svc_xprt_put(xprt); | ||
848 | } | ||
849 | EXPORT_SYMBOL_GPL(svc_close_xprt); | ||
850 | |||
851 | void svc_close_all(struct list_head *xprt_list) | ||
852 | { | ||
853 | struct svc_xprt *xprt; | ||
854 | struct svc_xprt *tmp; | ||
855 | |||
856 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { | ||
857 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
858 | if (test_bit(XPT_BUSY, &xprt->xpt_flags)) { | ||
859 | /* Waiting to be processed, but no threads left, | ||
860 | * So just remove it from the waiting list | ||
861 | */ | ||
862 | list_del_init(&xprt->xpt_ready); | ||
863 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
864 | } | ||
865 | svc_close_xprt(xprt); | ||
866 | } | ||
867 | } | ||
868 | |||
869 | /* | ||
870 | * Handle defer and revisit of requests | ||
871 | */ | ||
872 | |||
873 | static void svc_revisit(struct cache_deferred_req *dreq, int too_many) | ||
874 | { | ||
875 | struct svc_deferred_req *dr = | ||
876 | container_of(dreq, struct svc_deferred_req, handle); | ||
877 | struct svc_xprt *xprt = dr->xprt; | ||
878 | |||
879 | if (too_many) { | ||
880 | svc_xprt_put(xprt); | ||
881 | kfree(dr); | ||
882 | return; | ||
883 | } | ||
884 | dprintk("revisit queued\n"); | ||
885 | dr->xprt = NULL; | ||
886 | spin_lock(&xprt->xpt_lock); | ||
887 | list_add(&dr->handle.recent, &xprt->xpt_deferred); | ||
888 | spin_unlock(&xprt->xpt_lock); | ||
889 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
890 | svc_xprt_enqueue(xprt); | ||
891 | svc_xprt_put(xprt); | ||
892 | } | ||
893 | |||
894 | /* | ||
895 | * Save the request off for later processing. The request buffer looks | ||
896 | * like this: | ||
897 | * | ||
898 | * <xprt-header><rpc-header><rpc-pagelist><rpc-tail> | ||
899 | * | ||
900 | * This code can only handle requests that consist of an xprt-header | ||
901 | * and rpc-header. | ||
902 | */ | ||
903 | static struct cache_deferred_req *svc_defer(struct cache_req *req) | ||
904 | { | ||
905 | struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); | ||
906 | struct svc_deferred_req *dr; | ||
907 | |||
908 | if (rqstp->rq_arg.page_len) | ||
909 | return NULL; /* if more than a page, give up FIXME */ | ||
910 | if (rqstp->rq_deferred) { | ||
911 | dr = rqstp->rq_deferred; | ||
912 | rqstp->rq_deferred = NULL; | ||
913 | } else { | ||
914 | size_t skip; | ||
915 | size_t size; | ||
916 | /* FIXME maybe discard if size too large */ | ||
917 | size = sizeof(struct svc_deferred_req) + rqstp->rq_arg.len; | ||
918 | dr = kmalloc(size, GFP_KERNEL); | ||
919 | if (dr == NULL) | ||
920 | return NULL; | ||
921 | |||
922 | dr->handle.owner = rqstp->rq_server; | ||
923 | dr->prot = rqstp->rq_prot; | ||
924 | memcpy(&dr->addr, &rqstp->rq_addr, rqstp->rq_addrlen); | ||
925 | dr->addrlen = rqstp->rq_addrlen; | ||
926 | dr->daddr = rqstp->rq_daddr; | ||
927 | dr->argslen = rqstp->rq_arg.len >> 2; | ||
928 | dr->xprt_hlen = rqstp->rq_xprt_hlen; | ||
929 | |||
930 | /* back up head to the start of the buffer and copy */ | ||
931 | skip = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len; | ||
932 | memcpy(dr->args, rqstp->rq_arg.head[0].iov_base - skip, | ||
933 | dr->argslen << 2); | ||
934 | } | ||
935 | svc_xprt_get(rqstp->rq_xprt); | ||
936 | dr->xprt = rqstp->rq_xprt; | ||
937 | |||
938 | dr->handle.revisit = svc_revisit; | ||
939 | return &dr->handle; | ||
940 | } | ||
941 | |||
942 | /* | ||
943 | * recv data from a deferred request into an active one | ||
944 | */ | ||
945 | static int svc_deferred_recv(struct svc_rqst *rqstp) | ||
946 | { | ||
947 | struct svc_deferred_req *dr = rqstp->rq_deferred; | ||
948 | |||
949 | /* setup iov_base past transport header */ | ||
950 | rqstp->rq_arg.head[0].iov_base = dr->args + (dr->xprt_hlen>>2); | ||
951 | /* The iov_len does not include the transport header bytes */ | ||
952 | rqstp->rq_arg.head[0].iov_len = (dr->argslen<<2) - dr->xprt_hlen; | ||
953 | rqstp->rq_arg.page_len = 0; | ||
954 | /* The rq_arg.len includes the transport header bytes */ | ||
955 | rqstp->rq_arg.len = dr->argslen<<2; | ||
956 | rqstp->rq_prot = dr->prot; | ||
957 | memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen); | ||
958 | rqstp->rq_addrlen = dr->addrlen; | ||
959 | /* Save off transport header len in case we get deferred again */ | ||
960 | rqstp->rq_xprt_hlen = dr->xprt_hlen; | ||
961 | rqstp->rq_daddr = dr->daddr; | ||
962 | rqstp->rq_respages = rqstp->rq_pages; | ||
963 | return (dr->argslen<<2) - dr->xprt_hlen; | ||
964 | } | ||
965 | |||
966 | |||
967 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) | ||
968 | { | ||
969 | struct svc_deferred_req *dr = NULL; | ||
970 | |||
971 | if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) | ||
972 | return NULL; | ||
973 | spin_lock(&xprt->xpt_lock); | ||
974 | clear_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
975 | if (!list_empty(&xprt->xpt_deferred)) { | ||
976 | dr = list_entry(xprt->xpt_deferred.next, | ||
977 | struct svc_deferred_req, | ||
978 | handle.recent); | ||
979 | list_del_init(&dr->handle.recent); | ||
980 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
981 | } | ||
982 | spin_unlock(&xprt->xpt_lock); | ||
983 | return dr; | ||
984 | } | ||
985 | |||
986 | /* | ||
987 | * Return the transport instance pointer for the endpoint accepting | ||
988 | * connections/peer traffic from the specified transport class, | ||
989 | * address family and port. | ||
990 | * | ||
991 | * Specifying 0 for the address family or port is effectively a | ||
992 | * wild-card, and will result in matching the first transport in the | ||
993 | * service's list that has a matching class name. | ||
994 | */ | ||
995 | struct svc_xprt *svc_find_xprt(struct svc_serv *serv, char *xcl_name, | ||
996 | int af, int port) | ||
997 | { | ||
998 | struct svc_xprt *xprt; | ||
999 | struct svc_xprt *found = NULL; | ||
1000 | |||
1001 | /* Sanity check the args */ | ||
1002 | if (!serv || !xcl_name) | ||
1003 | return found; | ||
1004 | |||
1005 | spin_lock_bh(&serv->sv_lock); | ||
1006 | list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) { | ||
1007 | if (strcmp(xprt->xpt_class->xcl_name, xcl_name)) | ||
1008 | continue; | ||
1009 | if (af != AF_UNSPEC && af != xprt->xpt_local.ss_family) | ||
1010 | continue; | ||
1011 | if (port && port != svc_xprt_local_port(xprt)) | ||
1012 | continue; | ||
1013 | found = xprt; | ||
1014 | svc_xprt_get(xprt); | ||
1015 | break; | ||
1016 | } | ||
1017 | spin_unlock_bh(&serv->sv_lock); | ||
1018 | return found; | ||
1019 | } | ||
1020 | EXPORT_SYMBOL_GPL(svc_find_xprt); | ||
1021 | |||
1022 | /* | ||
1023 | * Format a buffer with a list of the active transports. A zero for | ||
1024 | * the buflen parameter disables target buffer overflow checking. | ||
1025 | */ | ||
1026 | int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen) | ||
1027 | { | ||
1028 | struct svc_xprt *xprt; | ||
1029 | char xprt_str[64]; | ||
1030 | int totlen = 0; | ||
1031 | int len; | ||
1032 | |||
1033 | /* Sanity check args */ | ||
1034 | if (!serv) | ||
1035 | return 0; | ||
1036 | |||
1037 | spin_lock_bh(&serv->sv_lock); | ||
1038 | list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) { | ||
1039 | len = snprintf(xprt_str, sizeof(xprt_str), | ||
1040 | "%s %d\n", xprt->xpt_class->xcl_name, | ||
1041 | svc_xprt_local_port(xprt)); | ||
1042 | /* If the string was truncated, replace with error string */ | ||
1043 | if (len >= sizeof(xprt_str)) | ||
1044 | strcpy(xprt_str, "name-too-long\n"); | ||
1045 | /* Don't overflow buffer */ | ||
1046 | len = strlen(xprt_str); | ||
1047 | if (buflen && (len + totlen >= buflen)) | ||
1048 | break; | ||
1049 | strcpy(buf+totlen, xprt_str); | ||
1050 | totlen += len; | ||
1051 | } | ||
1052 | spin_unlock_bh(&serv->sv_lock); | ||
1053 | return totlen; | ||
1054 | } | ||
1055 | EXPORT_SYMBOL_GPL(svc_xprt_names); | ||
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index af7c5f05c6e1..8a73cbb16052 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c | |||
@@ -57,11 +57,13 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) | |||
57 | rqstp->rq_authop = aops; | 57 | rqstp->rq_authop = aops; |
58 | return aops->accept(rqstp, authp); | 58 | return aops->accept(rqstp, authp); |
59 | } | 59 | } |
60 | EXPORT_SYMBOL(svc_authenticate); | ||
60 | 61 | ||
61 | int svc_set_client(struct svc_rqst *rqstp) | 62 | int svc_set_client(struct svc_rqst *rqstp) |
62 | { | 63 | { |
63 | return rqstp->rq_authop->set_client(rqstp); | 64 | return rqstp->rq_authop->set_client(rqstp); |
64 | } | 65 | } |
66 | EXPORT_SYMBOL(svc_set_client); | ||
65 | 67 | ||
66 | /* A request, which was authenticated, has now executed. | 68 | /* A request, which was authenticated, has now executed. |
67 | * Time to finalise the credentials and verifier | 69 | * Time to finalise the credentials and verifier |
@@ -93,6 +95,7 @@ svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops) | |||
93 | spin_unlock(&authtab_lock); | 95 | spin_unlock(&authtab_lock); |
94 | return rv; | 96 | return rv; |
95 | } | 97 | } |
98 | EXPORT_SYMBOL(svc_auth_register); | ||
96 | 99 | ||
97 | void | 100 | void |
98 | svc_auth_unregister(rpc_authflavor_t flavor) | 101 | svc_auth_unregister(rpc_authflavor_t flavor) |
@@ -129,6 +132,7 @@ void auth_domain_put(struct auth_domain *dom) | |||
129 | spin_unlock(&auth_domain_lock); | 132 | spin_unlock(&auth_domain_lock); |
130 | } | 133 | } |
131 | } | 134 | } |
135 | EXPORT_SYMBOL(auth_domain_put); | ||
132 | 136 | ||
133 | struct auth_domain * | 137 | struct auth_domain * |
134 | auth_domain_lookup(char *name, struct auth_domain *new) | 138 | auth_domain_lookup(char *name, struct auth_domain *new) |
@@ -153,8 +157,10 @@ auth_domain_lookup(char *name, struct auth_domain *new) | |||
153 | spin_unlock(&auth_domain_lock); | 157 | spin_unlock(&auth_domain_lock); |
154 | return new; | 158 | return new; |
155 | } | 159 | } |
160 | EXPORT_SYMBOL(auth_domain_lookup); | ||
156 | 161 | ||
157 | struct auth_domain *auth_domain_find(char *name) | 162 | struct auth_domain *auth_domain_find(char *name) |
158 | { | 163 | { |
159 | return auth_domain_lookup(name, NULL); | 164 | return auth_domain_lookup(name, NULL); |
160 | } | 165 | } |
166 | EXPORT_SYMBOL(auth_domain_find); | ||
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 411479411b21..3c64051e4555 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -63,6 +63,7 @@ struct auth_domain *unix_domain_find(char *name) | |||
63 | rv = auth_domain_lookup(name, &new->h); | 63 | rv = auth_domain_lookup(name, &new->h); |
64 | } | 64 | } |
65 | } | 65 | } |
66 | EXPORT_SYMBOL(unix_domain_find); | ||
66 | 67 | ||
67 | static void svcauth_unix_domain_release(struct auth_domain *dom) | 68 | static void svcauth_unix_domain_release(struct auth_domain *dom) |
68 | { | 69 | { |
@@ -340,6 +341,7 @@ int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) | |||
340 | else | 341 | else |
341 | return -ENOMEM; | 342 | return -ENOMEM; |
342 | } | 343 | } |
344 | EXPORT_SYMBOL(auth_unix_add_addr); | ||
343 | 345 | ||
344 | int auth_unix_forget_old(struct auth_domain *dom) | 346 | int auth_unix_forget_old(struct auth_domain *dom) |
345 | { | 347 | { |
@@ -351,6 +353,7 @@ int auth_unix_forget_old(struct auth_domain *dom) | |||
351 | udom->addr_changes++; | 353 | udom->addr_changes++; |
352 | return 0; | 354 | return 0; |
353 | } | 355 | } |
356 | EXPORT_SYMBOL(auth_unix_forget_old); | ||
354 | 357 | ||
355 | struct auth_domain *auth_unix_lookup(struct in_addr addr) | 358 | struct auth_domain *auth_unix_lookup(struct in_addr addr) |
356 | { | 359 | { |
@@ -375,50 +378,56 @@ struct auth_domain *auth_unix_lookup(struct in_addr addr) | |||
375 | cache_put(&ipm->h, &ip_map_cache); | 378 | cache_put(&ipm->h, &ip_map_cache); |
376 | return rv; | 379 | return rv; |
377 | } | 380 | } |
381 | EXPORT_SYMBOL(auth_unix_lookup); | ||
378 | 382 | ||
379 | void svcauth_unix_purge(void) | 383 | void svcauth_unix_purge(void) |
380 | { | 384 | { |
381 | cache_purge(&ip_map_cache); | 385 | cache_purge(&ip_map_cache); |
382 | } | 386 | } |
387 | EXPORT_SYMBOL(svcauth_unix_purge); | ||
383 | 388 | ||
384 | static inline struct ip_map * | 389 | static inline struct ip_map * |
385 | ip_map_cached_get(struct svc_rqst *rqstp) | 390 | ip_map_cached_get(struct svc_rqst *rqstp) |
386 | { | 391 | { |
387 | struct ip_map *ipm; | 392 | struct ip_map *ipm = NULL; |
388 | struct svc_sock *svsk = rqstp->rq_sock; | 393 | struct svc_xprt *xprt = rqstp->rq_xprt; |
389 | spin_lock(&svsk->sk_lock); | 394 | |
390 | ipm = svsk->sk_info_authunix; | 395 | if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { |
391 | if (ipm != NULL) { | 396 | spin_lock(&xprt->xpt_lock); |
392 | if (!cache_valid(&ipm->h)) { | 397 | ipm = xprt->xpt_auth_cache; |
393 | /* | 398 | if (ipm != NULL) { |
394 | * The entry has been invalidated since it was | 399 | if (!cache_valid(&ipm->h)) { |
395 | * remembered, e.g. by a second mount from the | 400 | /* |
396 | * same IP address. | 401 | * The entry has been invalidated since it was |
397 | */ | 402 | * remembered, e.g. by a second mount from the |
398 | svsk->sk_info_authunix = NULL; | 403 | * same IP address. |
399 | spin_unlock(&svsk->sk_lock); | 404 | */ |
400 | cache_put(&ipm->h, &ip_map_cache); | 405 | xprt->xpt_auth_cache = NULL; |
401 | return NULL; | 406 | spin_unlock(&xprt->xpt_lock); |
407 | cache_put(&ipm->h, &ip_map_cache); | ||
408 | return NULL; | ||
409 | } | ||
410 | cache_get(&ipm->h); | ||
402 | } | 411 | } |
403 | cache_get(&ipm->h); | 412 | spin_unlock(&xprt->xpt_lock); |
404 | } | 413 | } |
405 | spin_unlock(&svsk->sk_lock); | ||
406 | return ipm; | 414 | return ipm; |
407 | } | 415 | } |
408 | 416 | ||
409 | static inline void | 417 | static inline void |
410 | ip_map_cached_put(struct svc_rqst *rqstp, struct ip_map *ipm) | 418 | ip_map_cached_put(struct svc_rqst *rqstp, struct ip_map *ipm) |
411 | { | 419 | { |
412 | struct svc_sock *svsk = rqstp->rq_sock; | 420 | struct svc_xprt *xprt = rqstp->rq_xprt; |
413 | 421 | ||
414 | spin_lock(&svsk->sk_lock); | 422 | if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { |
415 | if (svsk->sk_sock->type == SOCK_STREAM && | 423 | spin_lock(&xprt->xpt_lock); |
416 | svsk->sk_info_authunix == NULL) { | 424 | if (xprt->xpt_auth_cache == NULL) { |
417 | /* newly cached, keep the reference */ | 425 | /* newly cached, keep the reference */ |
418 | svsk->sk_info_authunix = ipm; | 426 | xprt->xpt_auth_cache = ipm; |
419 | ipm = NULL; | 427 | ipm = NULL; |
428 | } | ||
429 | spin_unlock(&xprt->xpt_lock); | ||
420 | } | 430 | } |
421 | spin_unlock(&svsk->sk_lock); | ||
422 | if (ipm) | 431 | if (ipm) |
423 | cache_put(&ipm->h, &ip_map_cache); | 432 | cache_put(&ipm->h, &ip_map_cache); |
424 | } | 433 | } |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index c75bffeb89eb..1d3e5fcc2cc4 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * The server scheduling algorithm does not always distribute the load | 6 | * The server scheduling algorithm does not always distribute the load |
7 | * evenly when servicing a single client. May need to modify the | 7 | * evenly when servicing a single client. May need to modify the |
8 | * svc_sock_enqueue procedure... | 8 | * svc_xprt_enqueue procedure... |
9 | * | 9 | * |
10 | * TCP support is largely untested and may be a little slow. The problem | 10 | * TCP support is largely untested and may be a little slow. The problem |
11 | * is that we currently do two separate recvfrom's, one for the 4-byte | 11 | * is that we currently do two separate recvfrom's, one for the 4-byte |
@@ -48,72 +48,40 @@ | |||
48 | #include <linux/sunrpc/svcsock.h> | 48 | #include <linux/sunrpc/svcsock.h> |
49 | #include <linux/sunrpc/stats.h> | 49 | #include <linux/sunrpc/stats.h> |
50 | 50 | ||
51 | /* SMP locking strategy: | 51 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
52 | * | ||
53 | * svc_pool->sp_lock protects most of the fields of that pool. | ||
54 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. | ||
55 | * when both need to be taken (rare), svc_serv->sv_lock is first. | ||
56 | * BKL protects svc_serv->sv_nrthread. | ||
57 | * svc_sock->sk_lock protects the svc_sock->sk_deferred list | ||
58 | * and the ->sk_info_authunix cache. | ||
59 | * svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply. | ||
60 | * | ||
61 | * Some flags can be set to certain values at any time | ||
62 | * providing that certain rules are followed: | ||
63 | * | ||
64 | * SK_CONN, SK_DATA, can be set or cleared at any time. | ||
65 | * after a set, svc_sock_enqueue must be called. | ||
66 | * after a clear, the socket must be read/accepted | ||
67 | * if this succeeds, it must be set again. | ||
68 | * SK_CLOSE can set at any time. It is never cleared. | ||
69 | * sk_inuse contains a bias of '1' until SK_DEAD is set. | ||
70 | * so when sk_inuse hits zero, we know the socket is dead | ||
71 | * and no-one is using it. | ||
72 | * SK_DEAD can only be set while SK_BUSY is held which ensures | ||
73 | * no other thread will be using the socket or will try to | ||
74 | * set SK_DEAD. | ||
75 | * | ||
76 | */ | ||
77 | |||
78 | #define RPCDBG_FACILITY RPCDBG_SVCSOCK | ||
79 | 52 | ||
80 | 53 | ||
81 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, | 54 | static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *, |
82 | int *errp, int flags); | 55 | int *errp, int flags); |
83 | static void svc_delete_socket(struct svc_sock *svsk); | ||
84 | static void svc_udp_data_ready(struct sock *, int); | 56 | static void svc_udp_data_ready(struct sock *, int); |
85 | static int svc_udp_recvfrom(struct svc_rqst *); | 57 | static int svc_udp_recvfrom(struct svc_rqst *); |
86 | static int svc_udp_sendto(struct svc_rqst *); | 58 | static int svc_udp_sendto(struct svc_rqst *); |
87 | static void svc_close_socket(struct svc_sock *svsk); | 59 | static void svc_sock_detach(struct svc_xprt *); |
88 | 60 | static void svc_sock_free(struct svc_xprt *); | |
89 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk); | ||
90 | static int svc_deferred_recv(struct svc_rqst *rqstp); | ||
91 | static struct cache_deferred_req *svc_defer(struct cache_req *req); | ||
92 | |||
93 | /* apparently the "standard" is that clients close | ||
94 | * idle connections after 5 minutes, servers after | ||
95 | * 6 minutes | ||
96 | * http://www.connectathon.org/talks96/nfstcp.pdf | ||
97 | */ | ||
98 | static int svc_conn_age_period = 6*60; | ||
99 | 61 | ||
62 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | ||
63 | struct sockaddr *, int, int); | ||
100 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 64 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
101 | static struct lock_class_key svc_key[2]; | 65 | static struct lock_class_key svc_key[2]; |
102 | static struct lock_class_key svc_slock_key[2]; | 66 | static struct lock_class_key svc_slock_key[2]; |
103 | 67 | ||
104 | static inline void svc_reclassify_socket(struct socket *sock) | 68 | static void svc_reclassify_socket(struct socket *sock) |
105 | { | 69 | { |
106 | struct sock *sk = sock->sk; | 70 | struct sock *sk = sock->sk; |
107 | BUG_ON(sock_owned_by_user(sk)); | 71 | BUG_ON(sock_owned_by_user(sk)); |
108 | switch (sk->sk_family) { | 72 | switch (sk->sk_family) { |
109 | case AF_INET: | 73 | case AF_INET: |
110 | sock_lock_init_class_and_name(sk, "slock-AF_INET-NFSD", | 74 | sock_lock_init_class_and_name(sk, "slock-AF_INET-NFSD", |
111 | &svc_slock_key[0], "sk_lock-AF_INET-NFSD", &svc_key[0]); | 75 | &svc_slock_key[0], |
76 | "sk_xprt.xpt_lock-AF_INET-NFSD", | ||
77 | &svc_key[0]); | ||
112 | break; | 78 | break; |
113 | 79 | ||
114 | case AF_INET6: | 80 | case AF_INET6: |
115 | sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFSD", | 81 | sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFSD", |
116 | &svc_slock_key[1], "sk_lock-AF_INET6-NFSD", &svc_key[1]); | 82 | &svc_slock_key[1], |
83 | "sk_xprt.xpt_lock-AF_INET6-NFSD", | ||
84 | &svc_key[1]); | ||
117 | break; | 85 | break; |
118 | 86 | ||
119 | default: | 87 | default: |
@@ -121,81 +89,26 @@ static inline void svc_reclassify_socket(struct socket *sock) | |||
121 | } | 89 | } |
122 | } | 90 | } |
123 | #else | 91 | #else |
124 | static inline void svc_reclassify_socket(struct socket *sock) | 92 | static void svc_reclassify_socket(struct socket *sock) |
125 | { | 93 | { |
126 | } | 94 | } |
127 | #endif | 95 | #endif |
128 | 96 | ||
129 | static char *__svc_print_addr(struct sockaddr *addr, char *buf, size_t len) | ||
130 | { | ||
131 | switch (addr->sa_family) { | ||
132 | case AF_INET: | ||
133 | snprintf(buf, len, "%u.%u.%u.%u, port=%u", | ||
134 | NIPQUAD(((struct sockaddr_in *) addr)->sin_addr), | ||
135 | ntohs(((struct sockaddr_in *) addr)->sin_port)); | ||
136 | break; | ||
137 | |||
138 | case AF_INET6: | ||
139 | snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u", | ||
140 | NIP6(((struct sockaddr_in6 *) addr)->sin6_addr), | ||
141 | ntohs(((struct sockaddr_in6 *) addr)->sin6_port)); | ||
142 | break; | ||
143 | |||
144 | default: | ||
145 | snprintf(buf, len, "unknown address type: %d", addr->sa_family); | ||
146 | break; | ||
147 | } | ||
148 | return buf; | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * svc_print_addr - Format rq_addr field for printing | ||
153 | * @rqstp: svc_rqst struct containing address to print | ||
154 | * @buf: target buffer for formatted address | ||
155 | * @len: length of target buffer | ||
156 | * | ||
157 | */ | ||
158 | char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len) | ||
159 | { | ||
160 | return __svc_print_addr(svc_addr(rqstp), buf, len); | ||
161 | } | ||
162 | EXPORT_SYMBOL_GPL(svc_print_addr); | ||
163 | |||
164 | /* | ||
165 | * Queue up an idle server thread. Must have pool->sp_lock held. | ||
166 | * Note: this is really a stack rather than a queue, so that we only | ||
167 | * use as many different threads as we need, and the rest don't pollute | ||
168 | * the cache. | ||
169 | */ | ||
170 | static inline void | ||
171 | svc_thread_enqueue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
172 | { | ||
173 | list_add(&rqstp->rq_list, &pool->sp_threads); | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Dequeue an nfsd thread. Must have pool->sp_lock held. | ||
178 | */ | ||
179 | static inline void | ||
180 | svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp) | ||
181 | { | ||
182 | list_del(&rqstp->rq_list); | ||
183 | } | ||
184 | |||
185 | /* | 97 | /* |
186 | * Release an skbuff after use | 98 | * Release an skbuff after use |
187 | */ | 99 | */ |
188 | static inline void | 100 | static void svc_release_skb(struct svc_rqst *rqstp) |
189 | svc_release_skb(struct svc_rqst *rqstp) | ||
190 | { | 101 | { |
191 | struct sk_buff *skb = rqstp->rq_skbuff; | 102 | struct sk_buff *skb = rqstp->rq_xprt_ctxt; |
192 | struct svc_deferred_req *dr = rqstp->rq_deferred; | 103 | struct svc_deferred_req *dr = rqstp->rq_deferred; |
193 | 104 | ||
194 | if (skb) { | 105 | if (skb) { |
195 | rqstp->rq_skbuff = NULL; | 106 | struct svc_sock *svsk = |
107 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | ||
108 | rqstp->rq_xprt_ctxt = NULL; | ||
196 | 109 | ||
197 | dprintk("svc: service %p, releasing skb %p\n", rqstp, skb); | 110 | dprintk("svc: service %p, releasing skb %p\n", rqstp, skb); |
198 | skb_free_datagram(rqstp->rq_sock->sk_sk, skb); | 111 | skb_free_datagram(svsk->sk_sk, skb); |
199 | } | 112 | } |
200 | if (dr) { | 113 | if (dr) { |
201 | rqstp->rq_deferred = NULL; | 114 | rqstp->rq_deferred = NULL; |
@@ -203,253 +116,6 @@ svc_release_skb(struct svc_rqst *rqstp) | |||
203 | } | 116 | } |
204 | } | 117 | } |
205 | 118 | ||
206 | /* | ||
207 | * Any space to write? | ||
208 | */ | ||
209 | static inline unsigned long | ||
210 | svc_sock_wspace(struct svc_sock *svsk) | ||
211 | { | ||
212 | int wspace; | ||
213 | |||
214 | if (svsk->sk_sock->type == SOCK_STREAM) | ||
215 | wspace = sk_stream_wspace(svsk->sk_sk); | ||
216 | else | ||
217 | wspace = sock_wspace(svsk->sk_sk); | ||
218 | |||
219 | return wspace; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Queue up a socket with data pending. If there are idle nfsd | ||
224 | * processes, wake 'em up. | ||
225 | * | ||
226 | */ | ||
227 | static void | ||
228 | svc_sock_enqueue(struct svc_sock *svsk) | ||
229 | { | ||
230 | struct svc_serv *serv = svsk->sk_server; | ||
231 | struct svc_pool *pool; | ||
232 | struct svc_rqst *rqstp; | ||
233 | int cpu; | ||
234 | |||
235 | if (!(svsk->sk_flags & | ||
236 | ( (1<<SK_CONN)|(1<<SK_DATA)|(1<<SK_CLOSE)|(1<<SK_DEFERRED)) )) | ||
237 | return; | ||
238 | if (test_bit(SK_DEAD, &svsk->sk_flags)) | ||
239 | return; | ||
240 | |||
241 | cpu = get_cpu(); | ||
242 | pool = svc_pool_for_cpu(svsk->sk_server, cpu); | ||
243 | put_cpu(); | ||
244 | |||
245 | spin_lock_bh(&pool->sp_lock); | ||
246 | |||
247 | if (!list_empty(&pool->sp_threads) && | ||
248 | !list_empty(&pool->sp_sockets)) | ||
249 | printk(KERN_ERR | ||
250 | "svc_sock_enqueue: threads and sockets both waiting??\n"); | ||
251 | |||
252 | if (test_bit(SK_DEAD, &svsk->sk_flags)) { | ||
253 | /* Don't enqueue dead sockets */ | ||
254 | dprintk("svc: socket %p is dead, not enqueued\n", svsk->sk_sk); | ||
255 | goto out_unlock; | ||
256 | } | ||
257 | |||
258 | /* Mark socket as busy. It will remain in this state until the | ||
259 | * server has processed all pending data and put the socket back | ||
260 | * on the idle list. We update SK_BUSY atomically because | ||
261 | * it also guards against trying to enqueue the svc_sock twice. | ||
262 | */ | ||
263 | if (test_and_set_bit(SK_BUSY, &svsk->sk_flags)) { | ||
264 | /* Don't enqueue socket while already enqueued */ | ||
265 | dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk); | ||
266 | goto out_unlock; | ||
267 | } | ||
268 | BUG_ON(svsk->sk_pool != NULL); | ||
269 | svsk->sk_pool = pool; | ||
270 | |||
271 | set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); | ||
272 | if (((atomic_read(&svsk->sk_reserved) + serv->sv_max_mesg)*2 | ||
273 | > svc_sock_wspace(svsk)) | ||
274 | && !test_bit(SK_CLOSE, &svsk->sk_flags) | ||
275 | && !test_bit(SK_CONN, &svsk->sk_flags)) { | ||
276 | /* Don't enqueue while not enough space for reply */ | ||
277 | dprintk("svc: socket %p no space, %d*2 > %ld, not enqueued\n", | ||
278 | svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_max_mesg, | ||
279 | svc_sock_wspace(svsk)); | ||
280 | svsk->sk_pool = NULL; | ||
281 | clear_bit(SK_BUSY, &svsk->sk_flags); | ||
282 | goto out_unlock; | ||
283 | } | ||
284 | clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); | ||
285 | |||
286 | |||
287 | if (!list_empty(&pool->sp_threads)) { | ||
288 | rqstp = list_entry(pool->sp_threads.next, | ||
289 | struct svc_rqst, | ||
290 | rq_list); | ||
291 | dprintk("svc: socket %p served by daemon %p\n", | ||
292 | svsk->sk_sk, rqstp); | ||
293 | svc_thread_dequeue(pool, rqstp); | ||
294 | if (rqstp->rq_sock) | ||
295 | printk(KERN_ERR | ||
296 | "svc_sock_enqueue: server %p, rq_sock=%p!\n", | ||
297 | rqstp, rqstp->rq_sock); | ||
298 | rqstp->rq_sock = svsk; | ||
299 | atomic_inc(&svsk->sk_inuse); | ||
300 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
301 | atomic_add(rqstp->rq_reserved, &svsk->sk_reserved); | ||
302 | BUG_ON(svsk->sk_pool != pool); | ||
303 | wake_up(&rqstp->rq_wait); | ||
304 | } else { | ||
305 | dprintk("svc: socket %p put into queue\n", svsk->sk_sk); | ||
306 | list_add_tail(&svsk->sk_ready, &pool->sp_sockets); | ||
307 | BUG_ON(svsk->sk_pool != pool); | ||
308 | } | ||
309 | |||
310 | out_unlock: | ||
311 | spin_unlock_bh(&pool->sp_lock); | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * Dequeue the first socket. Must be called with the pool->sp_lock held. | ||
316 | */ | ||
317 | static inline struct svc_sock * | ||
318 | svc_sock_dequeue(struct svc_pool *pool) | ||
319 | { | ||
320 | struct svc_sock *svsk; | ||
321 | |||
322 | if (list_empty(&pool->sp_sockets)) | ||
323 | return NULL; | ||
324 | |||
325 | svsk = list_entry(pool->sp_sockets.next, | ||
326 | struct svc_sock, sk_ready); | ||
327 | list_del_init(&svsk->sk_ready); | ||
328 | |||
329 | dprintk("svc: socket %p dequeued, inuse=%d\n", | ||
330 | svsk->sk_sk, atomic_read(&svsk->sk_inuse)); | ||
331 | |||
332 | return svsk; | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Having read something from a socket, check whether it | ||
337 | * needs to be re-enqueued. | ||
338 | * Note: SK_DATA only gets cleared when a read-attempt finds | ||
339 | * no (or insufficient) data. | ||
340 | */ | ||
341 | static inline void | ||
342 | svc_sock_received(struct svc_sock *svsk) | ||
343 | { | ||
344 | svsk->sk_pool = NULL; | ||
345 | clear_bit(SK_BUSY, &svsk->sk_flags); | ||
346 | svc_sock_enqueue(svsk); | ||
347 | } | ||
348 | |||
349 | |||
350 | /** | ||
351 | * svc_reserve - change the space reserved for the reply to a request. | ||
352 | * @rqstp: The request in question | ||
353 | * @space: new max space to reserve | ||
354 | * | ||
355 | * Each request reserves some space on the output queue of the socket | ||
356 | * to make sure the reply fits. This function reduces that reserved | ||
357 | * space to be the amount of space used already, plus @space. | ||
358 | * | ||
359 | */ | ||
360 | void svc_reserve(struct svc_rqst *rqstp, int space) | ||
361 | { | ||
362 | space += rqstp->rq_res.head[0].iov_len; | ||
363 | |||
364 | if (space < rqstp->rq_reserved) { | ||
365 | struct svc_sock *svsk = rqstp->rq_sock; | ||
366 | atomic_sub((rqstp->rq_reserved - space), &svsk->sk_reserved); | ||
367 | rqstp->rq_reserved = space; | ||
368 | |||
369 | svc_sock_enqueue(svsk); | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * Release a socket after use. | ||
375 | */ | ||
376 | static inline void | ||
377 | svc_sock_put(struct svc_sock *svsk) | ||
378 | { | ||
379 | if (atomic_dec_and_test(&svsk->sk_inuse)) { | ||
380 | BUG_ON(! test_bit(SK_DEAD, &svsk->sk_flags)); | ||
381 | |||
382 | dprintk("svc: releasing dead socket\n"); | ||
383 | if (svsk->sk_sock->file) | ||
384 | sockfd_put(svsk->sk_sock); | ||
385 | else | ||
386 | sock_release(svsk->sk_sock); | ||
387 | if (svsk->sk_info_authunix != NULL) | ||
388 | svcauth_unix_info_release(svsk->sk_info_authunix); | ||
389 | kfree(svsk); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | static void | ||
394 | svc_sock_release(struct svc_rqst *rqstp) | ||
395 | { | ||
396 | struct svc_sock *svsk = rqstp->rq_sock; | ||
397 | |||
398 | svc_release_skb(rqstp); | ||
399 | |||
400 | svc_free_res_pages(rqstp); | ||
401 | rqstp->rq_res.page_len = 0; | ||
402 | rqstp->rq_res.page_base = 0; | ||
403 | |||
404 | |||
405 | /* Reset response buffer and release | ||
406 | * the reservation. | ||
407 | * But first, check that enough space was reserved | ||
408 | * for the reply, otherwise we have a bug! | ||
409 | */ | ||
410 | if ((rqstp->rq_res.len) > rqstp->rq_reserved) | ||
411 | printk(KERN_ERR "RPC request reserved %d but used %d\n", | ||
412 | rqstp->rq_reserved, | ||
413 | rqstp->rq_res.len); | ||
414 | |||
415 | rqstp->rq_res.head[0].iov_len = 0; | ||
416 | svc_reserve(rqstp, 0); | ||
417 | rqstp->rq_sock = NULL; | ||
418 | |||
419 | svc_sock_put(svsk); | ||
420 | } | ||
421 | |||
422 | /* | ||
423 | * External function to wake up a server waiting for data | ||
424 | * This really only makes sense for services like lockd | ||
425 | * which have exactly one thread anyway. | ||
426 | */ | ||
427 | void | ||
428 | svc_wake_up(struct svc_serv *serv) | ||
429 | { | ||
430 | struct svc_rqst *rqstp; | ||
431 | unsigned int i; | ||
432 | struct svc_pool *pool; | ||
433 | |||
434 | for (i = 0; i < serv->sv_nrpools; i++) { | ||
435 | pool = &serv->sv_pools[i]; | ||
436 | |||
437 | spin_lock_bh(&pool->sp_lock); | ||
438 | if (!list_empty(&pool->sp_threads)) { | ||
439 | rqstp = list_entry(pool->sp_threads.next, | ||
440 | struct svc_rqst, | ||
441 | rq_list); | ||
442 | dprintk("svc: daemon %p woken up.\n", rqstp); | ||
443 | /* | ||
444 | svc_thread_dequeue(pool, rqstp); | ||
445 | rqstp->rq_sock = NULL; | ||
446 | */ | ||
447 | wake_up(&rqstp->rq_wait); | ||
448 | } | ||
449 | spin_unlock_bh(&pool->sp_lock); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | union svc_pktinfo_u { | 119 | union svc_pktinfo_u { |
454 | struct in_pktinfo pkti; | 120 | struct in_pktinfo pkti; |
455 | struct in6_pktinfo pkti6; | 121 | struct in6_pktinfo pkti6; |
@@ -459,7 +125,9 @@ union svc_pktinfo_u { | |||
459 | 125 | ||
460 | static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh) | 126 | static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh) |
461 | { | 127 | { |
462 | switch (rqstp->rq_sock->sk_sk->sk_family) { | 128 | struct svc_sock *svsk = |
129 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | ||
130 | switch (svsk->sk_sk->sk_family) { | ||
463 | case AF_INET: { | 131 | case AF_INET: { |
464 | struct in_pktinfo *pki = CMSG_DATA(cmh); | 132 | struct in_pktinfo *pki = CMSG_DATA(cmh); |
465 | 133 | ||
@@ -489,10 +157,10 @@ static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh) | |||
489 | /* | 157 | /* |
490 | * Generic sendto routine | 158 | * Generic sendto routine |
491 | */ | 159 | */ |
492 | static int | 160 | static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) |
493 | svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | ||
494 | { | 161 | { |
495 | struct svc_sock *svsk = rqstp->rq_sock; | 162 | struct svc_sock *svsk = |
163 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | ||
496 | struct socket *sock = svsk->sk_sock; | 164 | struct socket *sock = svsk->sk_sock; |
497 | int slen; | 165 | int slen; |
498 | union { | 166 | union { |
@@ -565,7 +233,7 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | |||
565 | } | 233 | } |
566 | out: | 234 | out: |
567 | dprintk("svc: socket %p sendto([%p %Zu... ], %d) = %d (addr %s)\n", | 235 | dprintk("svc: socket %p sendto([%p %Zu... ], %d) = %d (addr %s)\n", |
568 | rqstp->rq_sock, xdr->head[0].iov_base, xdr->head[0].iov_len, | 236 | svsk, xdr->head[0].iov_base, xdr->head[0].iov_len, |
569 | xdr->len, len, svc_print_addr(rqstp, buf, sizeof(buf))); | 237 | xdr->len, len, svc_print_addr(rqstp, buf, sizeof(buf))); |
570 | 238 | ||
571 | return len; | 239 | return len; |
@@ -602,7 +270,7 @@ svc_sock_names(char *buf, struct svc_serv *serv, char *toclose) | |||
602 | if (!serv) | 270 | if (!serv) |
603 | return 0; | 271 | return 0; |
604 | spin_lock_bh(&serv->sv_lock); | 272 | spin_lock_bh(&serv->sv_lock); |
605 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) { | 273 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list) { |
606 | int onelen = one_sock_name(buf+len, svsk); | 274 | int onelen = one_sock_name(buf+len, svsk); |
607 | if (toclose && strcmp(toclose, buf+len) == 0) | 275 | if (toclose && strcmp(toclose, buf+len) == 0) |
608 | closesk = svsk; | 276 | closesk = svsk; |
@@ -614,7 +282,7 @@ svc_sock_names(char *buf, struct svc_serv *serv, char *toclose) | |||
614 | /* Should unregister with portmap, but you cannot | 282 | /* Should unregister with portmap, but you cannot |
615 | * unregister just one protocol... | 283 | * unregister just one protocol... |
616 | */ | 284 | */ |
617 | svc_close_socket(closesk); | 285 | svc_close_xprt(&closesk->sk_xprt); |
618 | else if (toclose) | 286 | else if (toclose) |
619 | return -ENOENT; | 287 | return -ENOENT; |
620 | return len; | 288 | return len; |
@@ -624,8 +292,7 @@ EXPORT_SYMBOL(svc_sock_names); | |||
624 | /* | 292 | /* |
625 | * Check input queue length | 293 | * Check input queue length |
626 | */ | 294 | */ |
627 | static int | 295 | static int svc_recv_available(struct svc_sock *svsk) |
628 | svc_recv_available(struct svc_sock *svsk) | ||
629 | { | 296 | { |
630 | struct socket *sock = svsk->sk_sock; | 297 | struct socket *sock = svsk->sk_sock; |
631 | int avail, err; | 298 | int avail, err; |
@@ -638,48 +305,31 @@ svc_recv_available(struct svc_sock *svsk) | |||
638 | /* | 305 | /* |
639 | * Generic recvfrom routine. | 306 | * Generic recvfrom routine. |
640 | */ | 307 | */ |
641 | static int | 308 | static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, |
642 | svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen) | 309 | int buflen) |
643 | { | 310 | { |
644 | struct svc_sock *svsk = rqstp->rq_sock; | 311 | struct svc_sock *svsk = |
312 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | ||
645 | struct msghdr msg = { | 313 | struct msghdr msg = { |
646 | .msg_flags = MSG_DONTWAIT, | 314 | .msg_flags = MSG_DONTWAIT, |
647 | }; | 315 | }; |
648 | struct sockaddr *sin; | ||
649 | int len; | 316 | int len; |
650 | 317 | ||
318 | rqstp->rq_xprt_hlen = 0; | ||
319 | |||
651 | len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen, | 320 | len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen, |
652 | msg.msg_flags); | 321 | msg.msg_flags); |
653 | 322 | ||
654 | /* sock_recvmsg doesn't fill in the name/namelen, so we must.. | ||
655 | */ | ||
656 | memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen); | ||
657 | rqstp->rq_addrlen = svsk->sk_remotelen; | ||
658 | |||
659 | /* Destination address in request is needed for binding the | ||
660 | * source address in RPC callbacks later. | ||
661 | */ | ||
662 | sin = (struct sockaddr *)&svsk->sk_local; | ||
663 | switch (sin->sa_family) { | ||
664 | case AF_INET: | ||
665 | rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr; | ||
666 | break; | ||
667 | case AF_INET6: | ||
668 | rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr; | ||
669 | break; | ||
670 | } | ||
671 | |||
672 | dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", | 323 | dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", |
673 | svsk, iov[0].iov_base, iov[0].iov_len, len); | 324 | svsk, iov[0].iov_base, iov[0].iov_len, len); |
674 | |||
675 | return len; | 325 | return len; |
676 | } | 326 | } |
677 | 327 | ||
678 | /* | 328 | /* |
679 | * Set socket snd and rcv buffer lengths | 329 | * Set socket snd and rcv buffer lengths |
680 | */ | 330 | */ |
681 | static inline void | 331 | static void svc_sock_setbufsize(struct socket *sock, unsigned int snd, |
682 | svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv) | 332 | unsigned int rcv) |
683 | { | 333 | { |
684 | #if 0 | 334 | #if 0 |
685 | mm_segment_t oldfs; | 335 | mm_segment_t oldfs; |
@@ -704,16 +354,16 @@ svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv) | |||
704 | /* | 354 | /* |
705 | * INET callback when data has been received on the socket. | 355 | * INET callback when data has been received on the socket. |
706 | */ | 356 | */ |
707 | static void | 357 | static void svc_udp_data_ready(struct sock *sk, int count) |
708 | svc_udp_data_ready(struct sock *sk, int count) | ||
709 | { | 358 | { |
710 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 359 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
711 | 360 | ||
712 | if (svsk) { | 361 | if (svsk) { |
713 | dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n", | 362 | dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n", |
714 | svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags)); | 363 | svsk, sk, count, |
715 | set_bit(SK_DATA, &svsk->sk_flags); | 364 | test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags)); |
716 | svc_sock_enqueue(svsk); | 365 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
366 | svc_xprt_enqueue(&svsk->sk_xprt); | ||
717 | } | 367 | } |
718 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 368 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
719 | wake_up_interruptible(sk->sk_sleep); | 369 | wake_up_interruptible(sk->sk_sleep); |
@@ -722,15 +372,14 @@ svc_udp_data_ready(struct sock *sk, int count) | |||
722 | /* | 372 | /* |
723 | * INET callback when space is newly available on the socket. | 373 | * INET callback when space is newly available on the socket. |
724 | */ | 374 | */ |
725 | static void | 375 | static void svc_write_space(struct sock *sk) |
726 | svc_write_space(struct sock *sk) | ||
727 | { | 376 | { |
728 | struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data); | 377 | struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data); |
729 | 378 | ||
730 | if (svsk) { | 379 | if (svsk) { |
731 | dprintk("svc: socket %p(inet %p), write_space busy=%d\n", | 380 | dprintk("svc: socket %p(inet %p), write_space busy=%d\n", |
732 | svsk, sk, test_bit(SK_BUSY, &svsk->sk_flags)); | 381 | svsk, sk, test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags)); |
733 | svc_sock_enqueue(svsk); | 382 | svc_xprt_enqueue(&svsk->sk_xprt); |
734 | } | 383 | } |
735 | 384 | ||
736 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) { | 385 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) { |
@@ -740,10 +389,19 @@ svc_write_space(struct sock *sk) | |||
740 | } | 389 | } |
741 | } | 390 | } |
742 | 391 | ||
743 | static inline void svc_udp_get_dest_address(struct svc_rqst *rqstp, | 392 | /* |
744 | struct cmsghdr *cmh) | 393 | * Copy the UDP datagram's destination address to the rqstp structure. |
394 | * The 'destination' address in this case is the address to which the | ||
395 | * peer sent the datagram, i.e. our local address. For multihomed | ||
396 | * hosts, this can change from msg to msg. Note that only the IP | ||
397 | * address changes, the port number should remain the same. | ||
398 | */ | ||
399 | static void svc_udp_get_dest_address(struct svc_rqst *rqstp, | ||
400 | struct cmsghdr *cmh) | ||
745 | { | 401 | { |
746 | switch (rqstp->rq_sock->sk_sk->sk_family) { | 402 | struct svc_sock *svsk = |
403 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); | ||
404 | switch (svsk->sk_sk->sk_family) { | ||
747 | case AF_INET: { | 405 | case AF_INET: { |
748 | struct in_pktinfo *pki = CMSG_DATA(cmh); | 406 | struct in_pktinfo *pki = CMSG_DATA(cmh); |
749 | rqstp->rq_daddr.addr.s_addr = pki->ipi_spec_dst.s_addr; | 407 | rqstp->rq_daddr.addr.s_addr = pki->ipi_spec_dst.s_addr; |
@@ -760,11 +418,11 @@ static inline void svc_udp_get_dest_address(struct svc_rqst *rqstp, | |||
760 | /* | 418 | /* |
761 | * Receive a datagram from a UDP socket. | 419 | * Receive a datagram from a UDP socket. |
762 | */ | 420 | */ |
763 | static int | 421 | static int svc_udp_recvfrom(struct svc_rqst *rqstp) |
764 | svc_udp_recvfrom(struct svc_rqst *rqstp) | ||
765 | { | 422 | { |
766 | struct svc_sock *svsk = rqstp->rq_sock; | 423 | struct svc_sock *svsk = |
767 | struct svc_serv *serv = svsk->sk_server; | 424 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); |
425 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; | ||
768 | struct sk_buff *skb; | 426 | struct sk_buff *skb; |
769 | union { | 427 | union { |
770 | struct cmsghdr hdr; | 428 | struct cmsghdr hdr; |
@@ -779,7 +437,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
779 | .msg_flags = MSG_DONTWAIT, | 437 | .msg_flags = MSG_DONTWAIT, |
780 | }; | 438 | }; |
781 | 439 | ||
782 | if (test_and_clear_bit(SK_CHNGBUF, &svsk->sk_flags)) | 440 | if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags)) |
783 | /* udp sockets need large rcvbuf as all pending | 441 | /* udp sockets need large rcvbuf as all pending |
784 | * requests are still in that buffer. sndbuf must | 442 | * requests are still in that buffer. sndbuf must |
785 | * also be large enough that there is enough space | 443 | * also be large enough that there is enough space |
@@ -792,17 +450,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
792 | (serv->sv_nrthreads+3) * serv->sv_max_mesg, | 450 | (serv->sv_nrthreads+3) * serv->sv_max_mesg, |
793 | (serv->sv_nrthreads+3) * serv->sv_max_mesg); | 451 | (serv->sv_nrthreads+3) * serv->sv_max_mesg); |
794 | 452 | ||
795 | if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) { | 453 | clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
796 | svc_sock_received(svsk); | ||
797 | return svc_deferred_recv(rqstp); | ||
798 | } | ||
799 | |||
800 | if (test_bit(SK_CLOSE, &svsk->sk_flags)) { | ||
801 | svc_delete_socket(svsk); | ||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | clear_bit(SK_DATA, &svsk->sk_flags); | ||
806 | skb = NULL; | 454 | skb = NULL; |
807 | err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, | 455 | err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, |
808 | 0, 0, MSG_PEEK | MSG_DONTWAIT); | 456 | 0, 0, MSG_PEEK | MSG_DONTWAIT); |
@@ -813,24 +461,27 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
813 | if (err != -EAGAIN) { | 461 | if (err != -EAGAIN) { |
814 | /* possibly an icmp error */ | 462 | /* possibly an icmp error */ |
815 | dprintk("svc: recvfrom returned error %d\n", -err); | 463 | dprintk("svc: recvfrom returned error %d\n", -err); |
816 | set_bit(SK_DATA, &svsk->sk_flags); | 464 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
817 | } | 465 | } |
818 | svc_sock_received(svsk); | 466 | svc_xprt_received(&svsk->sk_xprt); |
819 | return -EAGAIN; | 467 | return -EAGAIN; |
820 | } | 468 | } |
821 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); | 469 | len = svc_addr_len(svc_addr(rqstp)); |
470 | if (len < 0) | ||
471 | return len; | ||
472 | rqstp->rq_addrlen = len; | ||
822 | if (skb->tstamp.tv64 == 0) { | 473 | if (skb->tstamp.tv64 == 0) { |
823 | skb->tstamp = ktime_get_real(); | 474 | skb->tstamp = ktime_get_real(); |
824 | /* Don't enable netstamp, sunrpc doesn't | 475 | /* Don't enable netstamp, sunrpc doesn't |
825 | need that much accuracy */ | 476 | need that much accuracy */ |
826 | } | 477 | } |
827 | svsk->sk_sk->sk_stamp = skb->tstamp; | 478 | svsk->sk_sk->sk_stamp = skb->tstamp; |
828 | set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */ | 479 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ |
829 | 480 | ||
830 | /* | 481 | /* |
831 | * Maybe more packets - kick another thread ASAP. | 482 | * Maybe more packets - kick another thread ASAP. |
832 | */ | 483 | */ |
833 | svc_sock_received(svsk); | 484 | svc_xprt_received(&svsk->sk_xprt); |
834 | 485 | ||
835 | len = skb->len - sizeof(struct udphdr); | 486 | len = skb->len - sizeof(struct udphdr); |
836 | rqstp->rq_arg.len = len; | 487 | rqstp->rq_arg.len = len; |
@@ -861,13 +512,14 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
861 | skb_free_datagram(svsk->sk_sk, skb); | 512 | skb_free_datagram(svsk->sk_sk, skb); |
862 | } else { | 513 | } else { |
863 | /* we can use it in-place */ | 514 | /* we can use it in-place */ |
864 | rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); | 515 | rqstp->rq_arg.head[0].iov_base = skb->data + |
516 | sizeof(struct udphdr); | ||
865 | rqstp->rq_arg.head[0].iov_len = len; | 517 | rqstp->rq_arg.head[0].iov_len = len; |
866 | if (skb_checksum_complete(skb)) { | 518 | if (skb_checksum_complete(skb)) { |
867 | skb_free_datagram(svsk->sk_sk, skb); | 519 | skb_free_datagram(svsk->sk_sk, skb); |
868 | return 0; | 520 | return 0; |
869 | } | 521 | } |
870 | rqstp->rq_skbuff = skb; | 522 | rqstp->rq_xprt_ctxt = skb; |
871 | } | 523 | } |
872 | 524 | ||
873 | rqstp->rq_arg.page_base = 0; | 525 | rqstp->rq_arg.page_base = 0; |
@@ -900,27 +552,81 @@ svc_udp_sendto(struct svc_rqst *rqstp) | |||
900 | return error; | 552 | return error; |
901 | } | 553 | } |
902 | 554 | ||
903 | static void | 555 | static void svc_udp_prep_reply_hdr(struct svc_rqst *rqstp) |
904 | svc_udp_init(struct svc_sock *svsk) | 556 | { |
557 | } | ||
558 | |||
559 | static int svc_udp_has_wspace(struct svc_xprt *xprt) | ||
560 | { | ||
561 | struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); | ||
562 | struct svc_serv *serv = xprt->xpt_server; | ||
563 | unsigned long required; | ||
564 | |||
565 | /* | ||
566 | * Set the SOCK_NOSPACE flag before checking the available | ||
567 | * sock space. | ||
568 | */ | ||
569 | set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); | ||
570 | required = atomic_read(&svsk->sk_xprt.xpt_reserved) + serv->sv_max_mesg; | ||
571 | if (required*2 > sock_wspace(svsk->sk_sk)) | ||
572 | return 0; | ||
573 | clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); | ||
574 | return 1; | ||
575 | } | ||
576 | |||
577 | static struct svc_xprt *svc_udp_accept(struct svc_xprt *xprt) | ||
578 | { | ||
579 | BUG(); | ||
580 | return NULL; | ||
581 | } | ||
582 | |||
583 | static struct svc_xprt *svc_udp_create(struct svc_serv *serv, | ||
584 | struct sockaddr *sa, int salen, | ||
585 | int flags) | ||
586 | { | ||
587 | return svc_create_socket(serv, IPPROTO_UDP, sa, salen, flags); | ||
588 | } | ||
589 | |||
590 | static struct svc_xprt_ops svc_udp_ops = { | ||
591 | .xpo_create = svc_udp_create, | ||
592 | .xpo_recvfrom = svc_udp_recvfrom, | ||
593 | .xpo_sendto = svc_udp_sendto, | ||
594 | .xpo_release_rqst = svc_release_skb, | ||
595 | .xpo_detach = svc_sock_detach, | ||
596 | .xpo_free = svc_sock_free, | ||
597 | .xpo_prep_reply_hdr = svc_udp_prep_reply_hdr, | ||
598 | .xpo_has_wspace = svc_udp_has_wspace, | ||
599 | .xpo_accept = svc_udp_accept, | ||
600 | }; | ||
601 | |||
602 | static struct svc_xprt_class svc_udp_class = { | ||
603 | .xcl_name = "udp", | ||
604 | .xcl_owner = THIS_MODULE, | ||
605 | .xcl_ops = &svc_udp_ops, | ||
606 | .xcl_max_payload = RPCSVC_MAXPAYLOAD_UDP, | ||
607 | }; | ||
608 | |||
609 | static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv) | ||
905 | { | 610 | { |
906 | int one = 1; | 611 | int one = 1; |
907 | mm_segment_t oldfs; | 612 | mm_segment_t oldfs; |
908 | 613 | ||
614 | svc_xprt_init(&svc_udp_class, &svsk->sk_xprt, serv); | ||
615 | clear_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags); | ||
909 | svsk->sk_sk->sk_data_ready = svc_udp_data_ready; | 616 | svsk->sk_sk->sk_data_ready = svc_udp_data_ready; |
910 | svsk->sk_sk->sk_write_space = svc_write_space; | 617 | svsk->sk_sk->sk_write_space = svc_write_space; |
911 | svsk->sk_recvfrom = svc_udp_recvfrom; | ||
912 | svsk->sk_sendto = svc_udp_sendto; | ||
913 | 618 | ||
914 | /* initialise setting must have enough space to | 619 | /* initialise setting must have enough space to |
915 | * receive and respond to one request. | 620 | * receive and respond to one request. |
916 | * svc_udp_recvfrom will re-adjust if necessary | 621 | * svc_udp_recvfrom will re-adjust if necessary |
917 | */ | 622 | */ |
918 | svc_sock_setbufsize(svsk->sk_sock, | 623 | svc_sock_setbufsize(svsk->sk_sock, |
919 | 3 * svsk->sk_server->sv_max_mesg, | 624 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg, |
920 | 3 * svsk->sk_server->sv_max_mesg); | 625 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg); |
921 | 626 | ||
922 | set_bit(SK_DATA, &svsk->sk_flags); /* might have come in before data_ready set up */ | 627 | /* data might have come in before data_ready set up */ |
923 | set_bit(SK_CHNGBUF, &svsk->sk_flags); | 628 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
629 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); | ||
924 | 630 | ||
925 | oldfs = get_fs(); | 631 | oldfs = get_fs(); |
926 | set_fs(KERNEL_DS); | 632 | set_fs(KERNEL_DS); |
@@ -934,8 +640,7 @@ svc_udp_init(struct svc_sock *svsk) | |||
934 | * A data_ready event on a listening socket means there's a connection | 640 | * A data_ready event on a listening socket means there's a connection |
935 | * pending. Do not use state_change as a substitute for it. | 641 | * pending. Do not use state_change as a substitute for it. |
936 | */ | 642 | */ |
937 | static void | 643 | static void svc_tcp_listen_data_ready(struct sock *sk, int count_unused) |
938 | svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | ||
939 | { | 644 | { |
940 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 645 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
941 | 646 | ||
@@ -954,8 +659,8 @@ svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | |||
954 | */ | 659 | */ |
955 | if (sk->sk_state == TCP_LISTEN) { | 660 | if (sk->sk_state == TCP_LISTEN) { |
956 | if (svsk) { | 661 | if (svsk) { |
957 | set_bit(SK_CONN, &svsk->sk_flags); | 662 | set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); |
958 | svc_sock_enqueue(svsk); | 663 | svc_xprt_enqueue(&svsk->sk_xprt); |
959 | } else | 664 | } else |
960 | printk("svc: socket %p: no user data\n", sk); | 665 | printk("svc: socket %p: no user data\n", sk); |
961 | } | 666 | } |
@@ -967,8 +672,7 @@ svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | |||
967 | /* | 672 | /* |
968 | * A state change on a connected socket means it's dying or dead. | 673 | * A state change on a connected socket means it's dying or dead. |
969 | */ | 674 | */ |
970 | static void | 675 | static void svc_tcp_state_change(struct sock *sk) |
971 | svc_tcp_state_change(struct sock *sk) | ||
972 | { | 676 | { |
973 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 677 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
974 | 678 | ||
@@ -978,51 +682,36 @@ svc_tcp_state_change(struct sock *sk) | |||
978 | if (!svsk) | 682 | if (!svsk) |
979 | printk("svc: socket %p: no user data\n", sk); | 683 | printk("svc: socket %p: no user data\n", sk); |
980 | else { | 684 | else { |
981 | set_bit(SK_CLOSE, &svsk->sk_flags); | 685 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
982 | svc_sock_enqueue(svsk); | 686 | svc_xprt_enqueue(&svsk->sk_xprt); |
983 | } | 687 | } |
984 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 688 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
985 | wake_up_interruptible_all(sk->sk_sleep); | 689 | wake_up_interruptible_all(sk->sk_sleep); |
986 | } | 690 | } |
987 | 691 | ||
988 | static void | 692 | static void svc_tcp_data_ready(struct sock *sk, int count) |
989 | svc_tcp_data_ready(struct sock *sk, int count) | ||
990 | { | 693 | { |
991 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; | 694 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
992 | 695 | ||
993 | dprintk("svc: socket %p TCP data ready (svsk %p)\n", | 696 | dprintk("svc: socket %p TCP data ready (svsk %p)\n", |
994 | sk, sk->sk_user_data); | 697 | sk, sk->sk_user_data); |
995 | if (svsk) { | 698 | if (svsk) { |
996 | set_bit(SK_DATA, &svsk->sk_flags); | 699 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
997 | svc_sock_enqueue(svsk); | 700 | svc_xprt_enqueue(&svsk->sk_xprt); |
998 | } | 701 | } |
999 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 702 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
1000 | wake_up_interruptible(sk->sk_sleep); | 703 | wake_up_interruptible(sk->sk_sleep); |
1001 | } | 704 | } |
1002 | 705 | ||
1003 | static inline int svc_port_is_privileged(struct sockaddr *sin) | ||
1004 | { | ||
1005 | switch (sin->sa_family) { | ||
1006 | case AF_INET: | ||
1007 | return ntohs(((struct sockaddr_in *)sin)->sin_port) | ||
1008 | < PROT_SOCK; | ||
1009 | case AF_INET6: | ||
1010 | return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) | ||
1011 | < PROT_SOCK; | ||
1012 | default: | ||
1013 | return 0; | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | /* | 706 | /* |
1018 | * Accept a TCP connection | 707 | * Accept a TCP connection |
1019 | */ | 708 | */ |
1020 | static void | 709 | static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt) |
1021 | svc_tcp_accept(struct svc_sock *svsk) | ||
1022 | { | 710 | { |
711 | struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); | ||
1023 | struct sockaddr_storage addr; | 712 | struct sockaddr_storage addr; |
1024 | struct sockaddr *sin = (struct sockaddr *) &addr; | 713 | struct sockaddr *sin = (struct sockaddr *) &addr; |
1025 | struct svc_serv *serv = svsk->sk_server; | 714 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; |
1026 | struct socket *sock = svsk->sk_sock; | 715 | struct socket *sock = svsk->sk_sock; |
1027 | struct socket *newsock; | 716 | struct socket *newsock; |
1028 | struct svc_sock *newsvsk; | 717 | struct svc_sock *newsvsk; |
@@ -1031,9 +720,9 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
1031 | 720 | ||
1032 | dprintk("svc: tcp_accept %p sock %p\n", svsk, sock); | 721 | dprintk("svc: tcp_accept %p sock %p\n", svsk, sock); |
1033 | if (!sock) | 722 | if (!sock) |
1034 | return; | 723 | return NULL; |
1035 | 724 | ||
1036 | clear_bit(SK_CONN, &svsk->sk_flags); | 725 | clear_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); |
1037 | err = kernel_accept(sock, &newsock, O_NONBLOCK); | 726 | err = kernel_accept(sock, &newsock, O_NONBLOCK); |
1038 | if (err < 0) { | 727 | if (err < 0) { |
1039 | if (err == -ENOMEM) | 728 | if (err == -ENOMEM) |
@@ -1042,11 +731,9 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
1042 | else if (err != -EAGAIN && net_ratelimit()) | 731 | else if (err != -EAGAIN && net_ratelimit()) |
1043 | printk(KERN_WARNING "%s: accept failed (err %d)!\n", | 732 | printk(KERN_WARNING "%s: accept failed (err %d)!\n", |
1044 | serv->sv_name, -err); | 733 | serv->sv_name, -err); |
1045 | return; | 734 | return NULL; |
1046 | } | 735 | } |
1047 | 736 | set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); | |
1048 | set_bit(SK_CONN, &svsk->sk_flags); | ||
1049 | svc_sock_enqueue(svsk); | ||
1050 | 737 | ||
1051 | err = kernel_getpeername(newsock, sin, &slen); | 738 | err = kernel_getpeername(newsock, sin, &slen); |
1052 | if (err < 0) { | 739 | if (err < 0) { |
@@ -1077,106 +764,42 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
1077 | if (!(newsvsk = svc_setup_socket(serv, newsock, &err, | 764 | if (!(newsvsk = svc_setup_socket(serv, newsock, &err, |
1078 | (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY)))) | 765 | (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY)))) |
1079 | goto failed; | 766 | goto failed; |
1080 | memcpy(&newsvsk->sk_remote, sin, slen); | 767 | svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen); |
1081 | newsvsk->sk_remotelen = slen; | ||
1082 | err = kernel_getsockname(newsock, sin, &slen); | 768 | err = kernel_getsockname(newsock, sin, &slen); |
1083 | if (unlikely(err < 0)) { | 769 | if (unlikely(err < 0)) { |
1084 | dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err); | 770 | dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err); |
1085 | slen = offsetof(struct sockaddr, sa_data); | 771 | slen = offsetof(struct sockaddr, sa_data); |
1086 | } | 772 | } |
1087 | memcpy(&newsvsk->sk_local, sin, slen); | 773 | svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen); |
1088 | |||
1089 | svc_sock_received(newsvsk); | ||
1090 | |||
1091 | /* make sure that we don't have too many active connections. | ||
1092 | * If we have, something must be dropped. | ||
1093 | * | ||
1094 | * There's no point in trying to do random drop here for | ||
1095 | * DoS prevention. The NFS clients does 1 reconnect in 15 | ||
1096 | * seconds. An attacker can easily beat that. | ||
1097 | * | ||
1098 | * The only somewhat efficient mechanism would be if drop | ||
1099 | * old connections from the same IP first. But right now | ||
1100 | * we don't even record the client IP in svc_sock. | ||
1101 | */ | ||
1102 | if (serv->sv_tmpcnt > (serv->sv_nrthreads+3)*20) { | ||
1103 | struct svc_sock *svsk = NULL; | ||
1104 | spin_lock_bh(&serv->sv_lock); | ||
1105 | if (!list_empty(&serv->sv_tempsocks)) { | ||
1106 | if (net_ratelimit()) { | ||
1107 | /* Try to help the admin */ | ||
1108 | printk(KERN_NOTICE "%s: too many open TCP " | ||
1109 | "sockets, consider increasing the " | ||
1110 | "number of nfsd threads\n", | ||
1111 | serv->sv_name); | ||
1112 | printk(KERN_NOTICE | ||
1113 | "%s: last TCP connect from %s\n", | ||
1114 | serv->sv_name, __svc_print_addr(sin, | ||
1115 | buf, sizeof(buf))); | ||
1116 | } | ||
1117 | /* | ||
1118 | * Always select the oldest socket. It's not fair, | ||
1119 | * but so is life | ||
1120 | */ | ||
1121 | svsk = list_entry(serv->sv_tempsocks.prev, | ||
1122 | struct svc_sock, | ||
1123 | sk_list); | ||
1124 | set_bit(SK_CLOSE, &svsk->sk_flags); | ||
1125 | atomic_inc(&svsk->sk_inuse); | ||
1126 | } | ||
1127 | spin_unlock_bh(&serv->sv_lock); | ||
1128 | |||
1129 | if (svsk) { | ||
1130 | svc_sock_enqueue(svsk); | ||
1131 | svc_sock_put(svsk); | ||
1132 | } | ||
1133 | |||
1134 | } | ||
1135 | 774 | ||
1136 | if (serv->sv_stats) | 775 | if (serv->sv_stats) |
1137 | serv->sv_stats->nettcpconn++; | 776 | serv->sv_stats->nettcpconn++; |
1138 | 777 | ||
1139 | return; | 778 | return &newsvsk->sk_xprt; |
1140 | 779 | ||
1141 | failed: | 780 | failed: |
1142 | sock_release(newsock); | 781 | sock_release(newsock); |
1143 | return; | 782 | return NULL; |
1144 | } | 783 | } |
1145 | 784 | ||
1146 | /* | 785 | /* |
1147 | * Receive data from a TCP socket. | 786 | * Receive data from a TCP socket. |
1148 | */ | 787 | */ |
1149 | static int | 788 | static int svc_tcp_recvfrom(struct svc_rqst *rqstp) |
1150 | svc_tcp_recvfrom(struct svc_rqst *rqstp) | ||
1151 | { | 789 | { |
1152 | struct svc_sock *svsk = rqstp->rq_sock; | 790 | struct svc_sock *svsk = |
1153 | struct svc_serv *serv = svsk->sk_server; | 791 | container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); |
792 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; | ||
1154 | int len; | 793 | int len; |
1155 | struct kvec *vec; | 794 | struct kvec *vec; |
1156 | int pnum, vlen; | 795 | int pnum, vlen; |
1157 | 796 | ||
1158 | dprintk("svc: tcp_recv %p data %d conn %d close %d\n", | 797 | dprintk("svc: tcp_recv %p data %d conn %d close %d\n", |
1159 | svsk, test_bit(SK_DATA, &svsk->sk_flags), | 798 | svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags), |
1160 | test_bit(SK_CONN, &svsk->sk_flags), | 799 | test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags), |
1161 | test_bit(SK_CLOSE, &svsk->sk_flags)); | 800 | test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags)); |
1162 | 801 | ||
1163 | if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) { | 802 | if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags)) |
1164 | svc_sock_received(svsk); | ||
1165 | return svc_deferred_recv(rqstp); | ||
1166 | } | ||
1167 | |||
1168 | if (test_bit(SK_CLOSE, &svsk->sk_flags)) { | ||
1169 | svc_delete_socket(svsk); | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | if (svsk->sk_sk->sk_state == TCP_LISTEN) { | ||
1174 | svc_tcp_accept(svsk); | ||
1175 | svc_sock_received(svsk); | ||
1176 | return 0; | ||
1177 | } | ||
1178 | |||
1179 | if (test_and_clear_bit(SK_CHNGBUF, &svsk->sk_flags)) | ||
1180 | /* sndbuf needs to have room for one request | 803 | /* sndbuf needs to have room for one request |
1181 | * per thread, otherwise we can stall even when the | 804 | * per thread, otherwise we can stall even when the |
1182 | * network isn't a bottleneck. | 805 | * network isn't a bottleneck. |
@@ -1193,7 +816,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1193 | (serv->sv_nrthreads+3) * serv->sv_max_mesg, | 816 | (serv->sv_nrthreads+3) * serv->sv_max_mesg, |
1194 | 3 * serv->sv_max_mesg); | 817 | 3 * serv->sv_max_mesg); |
1195 | 818 | ||
1196 | clear_bit(SK_DATA, &svsk->sk_flags); | 819 | clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
1197 | 820 | ||
1198 | /* Receive data. If we haven't got the record length yet, get | 821 | /* Receive data. If we haven't got the record length yet, get |
1199 | * the next four bytes. Otherwise try to gobble up as much as | 822 | * the next four bytes. Otherwise try to gobble up as much as |
@@ -1212,7 +835,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1212 | if (len < want) { | 835 | if (len < want) { |
1213 | dprintk("svc: short recvfrom while reading record length (%d of %lu)\n", | 836 | dprintk("svc: short recvfrom while reading record length (%d of %lu)\n", |
1214 | len, want); | 837 | len, want); |
1215 | svc_sock_received(svsk); | 838 | svc_xprt_received(&svsk->sk_xprt); |
1216 | return -EAGAIN; /* record header not complete */ | 839 | return -EAGAIN; /* record header not complete */ |
1217 | } | 840 | } |
1218 | 841 | ||
@@ -1248,11 +871,11 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1248 | if (len < svsk->sk_reclen) { | 871 | if (len < svsk->sk_reclen) { |
1249 | dprintk("svc: incomplete TCP record (%d of %d)\n", | 872 | dprintk("svc: incomplete TCP record (%d of %d)\n", |
1250 | len, svsk->sk_reclen); | 873 | len, svsk->sk_reclen); |
1251 | svc_sock_received(svsk); | 874 | svc_xprt_received(&svsk->sk_xprt); |
1252 | return -EAGAIN; /* record not complete */ | 875 | return -EAGAIN; /* record not complete */ |
1253 | } | 876 | } |
1254 | len = svsk->sk_reclen; | 877 | len = svsk->sk_reclen; |
1255 | set_bit(SK_DATA, &svsk->sk_flags); | 878 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
1256 | 879 | ||
1257 | vec = rqstp->rq_vec; | 880 | vec = rqstp->rq_vec; |
1258 | vec[0] = rqstp->rq_arg.head[0]; | 881 | vec[0] = rqstp->rq_arg.head[0]; |
@@ -1281,30 +904,31 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1281 | rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len; | 904 | rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len; |
1282 | } | 905 | } |
1283 | 906 | ||
1284 | rqstp->rq_skbuff = NULL; | 907 | rqstp->rq_xprt_ctxt = NULL; |
1285 | rqstp->rq_prot = IPPROTO_TCP; | 908 | rqstp->rq_prot = IPPROTO_TCP; |
1286 | 909 | ||
1287 | /* Reset TCP read info */ | 910 | /* Reset TCP read info */ |
1288 | svsk->sk_reclen = 0; | 911 | svsk->sk_reclen = 0; |
1289 | svsk->sk_tcplen = 0; | 912 | svsk->sk_tcplen = 0; |
1290 | 913 | ||
1291 | svc_sock_received(svsk); | 914 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); |
915 | svc_xprt_received(&svsk->sk_xprt); | ||
1292 | if (serv->sv_stats) | 916 | if (serv->sv_stats) |
1293 | serv->sv_stats->nettcpcnt++; | 917 | serv->sv_stats->nettcpcnt++; |
1294 | 918 | ||
1295 | return len; | 919 | return len; |
1296 | 920 | ||
1297 | err_delete: | 921 | err_delete: |
1298 | svc_delete_socket(svsk); | 922 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
1299 | return -EAGAIN; | 923 | return -EAGAIN; |
1300 | 924 | ||
1301 | error: | 925 | error: |
1302 | if (len == -EAGAIN) { | 926 | if (len == -EAGAIN) { |
1303 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); | 927 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); |
1304 | svc_sock_received(svsk); | 928 | svc_xprt_received(&svsk->sk_xprt); |
1305 | } else { | 929 | } else { |
1306 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", | 930 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", |
1307 | svsk->sk_server->sv_name, -len); | 931 | svsk->sk_xprt.xpt_server->sv_name, -len); |
1308 | goto err_delete; | 932 | goto err_delete; |
1309 | } | 933 | } |
1310 | 934 | ||
@@ -1314,8 +938,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1314 | /* | 938 | /* |
1315 | * Send out data on TCP socket. | 939 | * Send out data on TCP socket. |
1316 | */ | 940 | */ |
1317 | static int | 941 | static int svc_tcp_sendto(struct svc_rqst *rqstp) |
1318 | svc_tcp_sendto(struct svc_rqst *rqstp) | ||
1319 | { | 942 | { |
1320 | struct xdr_buf *xbufp = &rqstp->rq_res; | 943 | struct xdr_buf *xbufp = &rqstp->rq_res; |
1321 | int sent; | 944 | int sent; |
@@ -1328,35 +951,109 @@ svc_tcp_sendto(struct svc_rqst *rqstp) | |||
1328 | reclen = htonl(0x80000000|((xbufp->len ) - 4)); | 951 | reclen = htonl(0x80000000|((xbufp->len ) - 4)); |
1329 | memcpy(xbufp->head[0].iov_base, &reclen, 4); | 952 | memcpy(xbufp->head[0].iov_base, &reclen, 4); |
1330 | 953 | ||
1331 | if (test_bit(SK_DEAD, &rqstp->rq_sock->sk_flags)) | 954 | if (test_bit(XPT_DEAD, &rqstp->rq_xprt->xpt_flags)) |
1332 | return -ENOTCONN; | 955 | return -ENOTCONN; |
1333 | 956 | ||
1334 | sent = svc_sendto(rqstp, &rqstp->rq_res); | 957 | sent = svc_sendto(rqstp, &rqstp->rq_res); |
1335 | if (sent != xbufp->len) { | 958 | if (sent != xbufp->len) { |
1336 | printk(KERN_NOTICE "rpc-srv/tcp: %s: %s %d when sending %d bytes - shutting down socket\n", | 959 | printk(KERN_NOTICE |
1337 | rqstp->rq_sock->sk_server->sv_name, | 960 | "rpc-srv/tcp: %s: %s %d when sending %d bytes " |
961 | "- shutting down socket\n", | ||
962 | rqstp->rq_xprt->xpt_server->sv_name, | ||
1338 | (sent<0)?"got error":"sent only", | 963 | (sent<0)?"got error":"sent only", |
1339 | sent, xbufp->len); | 964 | sent, xbufp->len); |
1340 | set_bit(SK_CLOSE, &rqstp->rq_sock->sk_flags); | 965 | set_bit(XPT_CLOSE, &rqstp->rq_xprt->xpt_flags); |
1341 | svc_sock_enqueue(rqstp->rq_sock); | 966 | svc_xprt_enqueue(rqstp->rq_xprt); |
1342 | sent = -EAGAIN; | 967 | sent = -EAGAIN; |
1343 | } | 968 | } |
1344 | return sent; | 969 | return sent; |
1345 | } | 970 | } |
1346 | 971 | ||
1347 | static void | 972 | /* |
1348 | svc_tcp_init(struct svc_sock *svsk) | 973 | * Setup response header. TCP has a 4B record length field. |
974 | */ | ||
975 | static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp) | ||
976 | { | ||
977 | struct kvec *resv = &rqstp->rq_res.head[0]; | ||
978 | |||
979 | /* tcp needs a space for the record length... */ | ||
980 | svc_putnl(resv, 0); | ||
981 | } | ||
982 | |||
983 | static int svc_tcp_has_wspace(struct svc_xprt *xprt) | ||
984 | { | ||
985 | struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); | ||
986 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; | ||
987 | int required; | ||
988 | int wspace; | ||
989 | |||
990 | /* | ||
991 | * Set the SOCK_NOSPACE flag before checking the available | ||
992 | * sock space. | ||
993 | */ | ||
994 | set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); | ||
995 | required = atomic_read(&svsk->sk_xprt.xpt_reserved) + serv->sv_max_mesg; | ||
996 | wspace = sk_stream_wspace(svsk->sk_sk); | ||
997 | |||
998 | if (wspace < sk_stream_min_wspace(svsk->sk_sk)) | ||
999 | return 0; | ||
1000 | if (required * 2 > wspace) | ||
1001 | return 0; | ||
1002 | |||
1003 | clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); | ||
1004 | return 1; | ||
1005 | } | ||
1006 | |||
1007 | static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, | ||
1008 | struct sockaddr *sa, int salen, | ||
1009 | int flags) | ||
1010 | { | ||
1011 | return svc_create_socket(serv, IPPROTO_TCP, sa, salen, flags); | ||
1012 | } | ||
1013 | |||
1014 | static struct svc_xprt_ops svc_tcp_ops = { | ||
1015 | .xpo_create = svc_tcp_create, | ||
1016 | .xpo_recvfrom = svc_tcp_recvfrom, | ||
1017 | .xpo_sendto = svc_tcp_sendto, | ||
1018 | .xpo_release_rqst = svc_release_skb, | ||
1019 | .xpo_detach = svc_sock_detach, | ||
1020 | .xpo_free = svc_sock_free, | ||
1021 | .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr, | ||
1022 | .xpo_has_wspace = svc_tcp_has_wspace, | ||
1023 | .xpo_accept = svc_tcp_accept, | ||
1024 | }; | ||
1025 | |||
1026 | static struct svc_xprt_class svc_tcp_class = { | ||
1027 | .xcl_name = "tcp", | ||
1028 | .xcl_owner = THIS_MODULE, | ||
1029 | .xcl_ops = &svc_tcp_ops, | ||
1030 | .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP, | ||
1031 | }; | ||
1032 | |||
1033 | void svc_init_xprt_sock(void) | ||
1034 | { | ||
1035 | svc_reg_xprt_class(&svc_tcp_class); | ||
1036 | svc_reg_xprt_class(&svc_udp_class); | ||
1037 | } | ||
1038 | |||
1039 | void svc_cleanup_xprt_sock(void) | ||
1040 | { | ||
1041 | svc_unreg_xprt_class(&svc_tcp_class); | ||
1042 | svc_unreg_xprt_class(&svc_udp_class); | ||
1043 | } | ||
1044 | |||
1045 | static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | ||
1349 | { | 1046 | { |
1350 | struct sock *sk = svsk->sk_sk; | 1047 | struct sock *sk = svsk->sk_sk; |
1351 | struct tcp_sock *tp = tcp_sk(sk); | 1048 | struct tcp_sock *tp = tcp_sk(sk); |
1352 | 1049 | ||
1353 | svsk->sk_recvfrom = svc_tcp_recvfrom; | 1050 | svc_xprt_init(&svc_tcp_class, &svsk->sk_xprt, serv); |
1354 | svsk->sk_sendto = svc_tcp_sendto; | 1051 | set_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags); |
1355 | |||
1356 | if (sk->sk_state == TCP_LISTEN) { | 1052 | if (sk->sk_state == TCP_LISTEN) { |
1357 | dprintk("setting up TCP socket for listening\n"); | 1053 | dprintk("setting up TCP socket for listening\n"); |
1054 | set_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags); | ||
1358 | sk->sk_data_ready = svc_tcp_listen_data_ready; | 1055 | sk->sk_data_ready = svc_tcp_listen_data_ready; |
1359 | set_bit(SK_CONN, &svsk->sk_flags); | 1056 | set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); |
1360 | } else { | 1057 | } else { |
1361 | dprintk("setting up TCP socket for reading\n"); | 1058 | dprintk("setting up TCP socket for reading\n"); |
1362 | sk->sk_state_change = svc_tcp_state_change; | 1059 | sk->sk_state_change = svc_tcp_state_change; |
@@ -1373,18 +1070,17 @@ svc_tcp_init(struct svc_sock *svsk) | |||
1373 | * svc_tcp_recvfrom will re-adjust if necessary | 1070 | * svc_tcp_recvfrom will re-adjust if necessary |
1374 | */ | 1071 | */ |
1375 | svc_sock_setbufsize(svsk->sk_sock, | 1072 | svc_sock_setbufsize(svsk->sk_sock, |
1376 | 3 * svsk->sk_server->sv_max_mesg, | 1073 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg, |
1377 | 3 * svsk->sk_server->sv_max_mesg); | 1074 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg); |
1378 | 1075 | ||
1379 | set_bit(SK_CHNGBUF, &svsk->sk_flags); | 1076 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); |
1380 | set_bit(SK_DATA, &svsk->sk_flags); | 1077 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
1381 | if (sk->sk_state != TCP_ESTABLISHED) | 1078 | if (sk->sk_state != TCP_ESTABLISHED) |
1382 | set_bit(SK_CLOSE, &svsk->sk_flags); | 1079 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
1383 | } | 1080 | } |
1384 | } | 1081 | } |
1385 | 1082 | ||
1386 | void | 1083 | void svc_sock_update_bufs(struct svc_serv *serv) |
1387 | svc_sock_update_bufs(struct svc_serv *serv) | ||
1388 | { | 1084 | { |
1389 | /* | 1085 | /* |
1390 | * The number of server threads has changed. Update | 1086 | * The number of server threads has changed. Update |
@@ -1395,232 +1091,18 @@ svc_sock_update_bufs(struct svc_serv *serv) | |||
1395 | spin_lock_bh(&serv->sv_lock); | 1091 | spin_lock_bh(&serv->sv_lock); |
1396 | list_for_each(le, &serv->sv_permsocks) { | 1092 | list_for_each(le, &serv->sv_permsocks) { |
1397 | struct svc_sock *svsk = | 1093 | struct svc_sock *svsk = |
1398 | list_entry(le, struct svc_sock, sk_list); | 1094 | list_entry(le, struct svc_sock, sk_xprt.xpt_list); |
1399 | set_bit(SK_CHNGBUF, &svsk->sk_flags); | 1095 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); |
1400 | } | 1096 | } |
1401 | list_for_each(le, &serv->sv_tempsocks) { | 1097 | list_for_each(le, &serv->sv_tempsocks) { |
1402 | struct svc_sock *svsk = | 1098 | struct svc_sock *svsk = |
1403 | list_entry(le, struct svc_sock, sk_list); | 1099 | list_entry(le, struct svc_sock, sk_xprt.xpt_list); |
1404 | set_bit(SK_CHNGBUF, &svsk->sk_flags); | 1100 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); |
1405 | } | 1101 | } |
1406 | spin_unlock_bh(&serv->sv_lock); | 1102 | spin_unlock_bh(&serv->sv_lock); |
1407 | } | 1103 | } |
1408 | 1104 | ||
1409 | /* | 1105 | /* |
1410 | * Receive the next request on any socket. This code is carefully | ||
1411 | * organised not to touch any cachelines in the shared svc_serv | ||
1412 | * structure, only cachelines in the local svc_pool. | ||
1413 | */ | ||
1414 | int | ||
1415 | svc_recv(struct svc_rqst *rqstp, long timeout) | ||
1416 | { | ||
1417 | struct svc_sock *svsk = NULL; | ||
1418 | struct svc_serv *serv = rqstp->rq_server; | ||
1419 | struct svc_pool *pool = rqstp->rq_pool; | ||
1420 | int len, i; | ||
1421 | int pages; | ||
1422 | struct xdr_buf *arg; | ||
1423 | DECLARE_WAITQUEUE(wait, current); | ||
1424 | |||
1425 | dprintk("svc: server %p waiting for data (to = %ld)\n", | ||
1426 | rqstp, timeout); | ||
1427 | |||
1428 | if (rqstp->rq_sock) | ||
1429 | printk(KERN_ERR | ||
1430 | "svc_recv: service %p, socket not NULL!\n", | ||
1431 | rqstp); | ||
1432 | if (waitqueue_active(&rqstp->rq_wait)) | ||
1433 | printk(KERN_ERR | ||
1434 | "svc_recv: service %p, wait queue active!\n", | ||
1435 | rqstp); | ||
1436 | |||
1437 | |||
1438 | /* now allocate needed pages. If we get a failure, sleep briefly */ | ||
1439 | pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; | ||
1440 | for (i=0; i < pages ; i++) | ||
1441 | while (rqstp->rq_pages[i] == NULL) { | ||
1442 | struct page *p = alloc_page(GFP_KERNEL); | ||
1443 | if (!p) | ||
1444 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | ||
1445 | rqstp->rq_pages[i] = p; | ||
1446 | } | ||
1447 | rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ | ||
1448 | BUG_ON(pages >= RPCSVC_MAXPAGES); | ||
1449 | |||
1450 | /* Make arg->head point to first page and arg->pages point to rest */ | ||
1451 | arg = &rqstp->rq_arg; | ||
1452 | arg->head[0].iov_base = page_address(rqstp->rq_pages[0]); | ||
1453 | arg->head[0].iov_len = PAGE_SIZE; | ||
1454 | arg->pages = rqstp->rq_pages + 1; | ||
1455 | arg->page_base = 0; | ||
1456 | /* save at least one page for response */ | ||
1457 | arg->page_len = (pages-2)*PAGE_SIZE; | ||
1458 | arg->len = (pages-1)*PAGE_SIZE; | ||
1459 | arg->tail[0].iov_len = 0; | ||
1460 | |||
1461 | try_to_freeze(); | ||
1462 | cond_resched(); | ||
1463 | if (signalled()) | ||
1464 | return -EINTR; | ||
1465 | |||
1466 | spin_lock_bh(&pool->sp_lock); | ||
1467 | if ((svsk = svc_sock_dequeue(pool)) != NULL) { | ||
1468 | rqstp->rq_sock = svsk; | ||
1469 | atomic_inc(&svsk->sk_inuse); | ||
1470 | rqstp->rq_reserved = serv->sv_max_mesg; | ||
1471 | atomic_add(rqstp->rq_reserved, &svsk->sk_reserved); | ||
1472 | } else { | ||
1473 | /* No data pending. Go to sleep */ | ||
1474 | svc_thread_enqueue(pool, rqstp); | ||
1475 | |||
1476 | /* | ||
1477 | * We have to be able to interrupt this wait | ||
1478 | * to bring down the daemons ... | ||
1479 | */ | ||
1480 | set_current_state(TASK_INTERRUPTIBLE); | ||
1481 | add_wait_queue(&rqstp->rq_wait, &wait); | ||
1482 | spin_unlock_bh(&pool->sp_lock); | ||
1483 | |||
1484 | schedule_timeout(timeout); | ||
1485 | |||
1486 | try_to_freeze(); | ||
1487 | |||
1488 | spin_lock_bh(&pool->sp_lock); | ||
1489 | remove_wait_queue(&rqstp->rq_wait, &wait); | ||
1490 | |||
1491 | if (!(svsk = rqstp->rq_sock)) { | ||
1492 | svc_thread_dequeue(pool, rqstp); | ||
1493 | spin_unlock_bh(&pool->sp_lock); | ||
1494 | dprintk("svc: server %p, no data yet\n", rqstp); | ||
1495 | return signalled()? -EINTR : -EAGAIN; | ||
1496 | } | ||
1497 | } | ||
1498 | spin_unlock_bh(&pool->sp_lock); | ||
1499 | |||
1500 | dprintk("svc: server %p, pool %u, socket %p, inuse=%d\n", | ||
1501 | rqstp, pool->sp_id, svsk, atomic_read(&svsk->sk_inuse)); | ||
1502 | len = svsk->sk_recvfrom(rqstp); | ||
1503 | dprintk("svc: got len=%d\n", len); | ||
1504 | |||
1505 | /* No data, incomplete (TCP) read, or accept() */ | ||
1506 | if (len == 0 || len == -EAGAIN) { | ||
1507 | rqstp->rq_res.len = 0; | ||
1508 | svc_sock_release(rqstp); | ||
1509 | return -EAGAIN; | ||
1510 | } | ||
1511 | svsk->sk_lastrecv = get_seconds(); | ||
1512 | clear_bit(SK_OLD, &svsk->sk_flags); | ||
1513 | |||
1514 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); | ||
1515 | rqstp->rq_chandle.defer = svc_defer; | ||
1516 | |||
1517 | if (serv->sv_stats) | ||
1518 | serv->sv_stats->netcnt++; | ||
1519 | return len; | ||
1520 | } | ||
1521 | |||
1522 | /* | ||
1523 | * Drop request | ||
1524 | */ | ||
1525 | void | ||
1526 | svc_drop(struct svc_rqst *rqstp) | ||
1527 | { | ||
1528 | dprintk("svc: socket %p dropped request\n", rqstp->rq_sock); | ||
1529 | svc_sock_release(rqstp); | ||
1530 | } | ||
1531 | |||
1532 | /* | ||
1533 | * Return reply to client. | ||
1534 | */ | ||
1535 | int | ||
1536 | svc_send(struct svc_rqst *rqstp) | ||
1537 | { | ||
1538 | struct svc_sock *svsk; | ||
1539 | int len; | ||
1540 | struct xdr_buf *xb; | ||
1541 | |||
1542 | if ((svsk = rqstp->rq_sock) == NULL) { | ||
1543 | printk(KERN_WARNING "NULL socket pointer in %s:%d\n", | ||
1544 | __FILE__, __LINE__); | ||
1545 | return -EFAULT; | ||
1546 | } | ||
1547 | |||
1548 | /* release the receive skb before sending the reply */ | ||
1549 | svc_release_skb(rqstp); | ||
1550 | |||
1551 | /* calculate over-all length */ | ||
1552 | xb = & rqstp->rq_res; | ||
1553 | xb->len = xb->head[0].iov_len + | ||
1554 | xb->page_len + | ||
1555 | xb->tail[0].iov_len; | ||
1556 | |||
1557 | /* Grab svsk->sk_mutex to serialize outgoing data. */ | ||
1558 | mutex_lock(&svsk->sk_mutex); | ||
1559 | if (test_bit(SK_DEAD, &svsk->sk_flags)) | ||
1560 | len = -ENOTCONN; | ||
1561 | else | ||
1562 | len = svsk->sk_sendto(rqstp); | ||
1563 | mutex_unlock(&svsk->sk_mutex); | ||
1564 | svc_sock_release(rqstp); | ||
1565 | |||
1566 | if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) | ||
1567 | return 0; | ||
1568 | return len; | ||
1569 | } | ||
1570 | |||
1571 | /* | ||
1572 | * Timer function to close old temporary sockets, using | ||
1573 | * a mark-and-sweep algorithm. | ||
1574 | */ | ||
1575 | static void | ||
1576 | svc_age_temp_sockets(unsigned long closure) | ||
1577 | { | ||
1578 | struct svc_serv *serv = (struct svc_serv *)closure; | ||
1579 | struct svc_sock *svsk; | ||
1580 | struct list_head *le, *next; | ||
1581 | LIST_HEAD(to_be_aged); | ||
1582 | |||
1583 | dprintk("svc_age_temp_sockets\n"); | ||
1584 | |||
1585 | if (!spin_trylock_bh(&serv->sv_lock)) { | ||
1586 | /* busy, try again 1 sec later */ | ||
1587 | dprintk("svc_age_temp_sockets: busy\n"); | ||
1588 | mod_timer(&serv->sv_temptimer, jiffies + HZ); | ||
1589 | return; | ||
1590 | } | ||
1591 | |||
1592 | list_for_each_safe(le, next, &serv->sv_tempsocks) { | ||
1593 | svsk = list_entry(le, struct svc_sock, sk_list); | ||
1594 | |||
1595 | if (!test_and_set_bit(SK_OLD, &svsk->sk_flags)) | ||
1596 | continue; | ||
1597 | if (atomic_read(&svsk->sk_inuse) > 1 || test_bit(SK_BUSY, &svsk->sk_flags)) | ||
1598 | continue; | ||
1599 | atomic_inc(&svsk->sk_inuse); | ||
1600 | list_move(le, &to_be_aged); | ||
1601 | set_bit(SK_CLOSE, &svsk->sk_flags); | ||
1602 | set_bit(SK_DETACHED, &svsk->sk_flags); | ||
1603 | } | ||
1604 | spin_unlock_bh(&serv->sv_lock); | ||
1605 | |||
1606 | while (!list_empty(&to_be_aged)) { | ||
1607 | le = to_be_aged.next; | ||
1608 | /* fiddling the sk_list node is safe 'cos we're SK_DETACHED */ | ||
1609 | list_del_init(le); | ||
1610 | svsk = list_entry(le, struct svc_sock, sk_list); | ||
1611 | |||
1612 | dprintk("queuing svsk %p for closing, %lu seconds old\n", | ||
1613 | svsk, get_seconds() - svsk->sk_lastrecv); | ||
1614 | |||
1615 | /* a thread will dequeue and close it soon */ | ||
1616 | svc_sock_enqueue(svsk); | ||
1617 | svc_sock_put(svsk); | ||
1618 | } | ||
1619 | |||
1620 | mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); | ||
1621 | } | ||
1622 | |||
1623 | /* | ||
1624 | * Initialize socket for RPC use and create svc_sock struct | 1106 | * Initialize socket for RPC use and create svc_sock struct |
1625 | * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF. | 1107 | * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF. |
1626 | */ | 1108 | */ |
@@ -1631,7 +1113,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
1631 | struct svc_sock *svsk; | 1113 | struct svc_sock *svsk; |
1632 | struct sock *inet; | 1114 | struct sock *inet; |
1633 | int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); | 1115 | int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); |
1634 | int is_temporary = flags & SVC_SOCK_TEMPORARY; | ||
1635 | 1116 | ||
1636 | dprintk("svc: svc_setup_socket %p\n", sock); | 1117 | dprintk("svc: svc_setup_socket %p\n", sock); |
1637 | if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { | 1118 | if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { |
@@ -1651,44 +1132,18 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
1651 | return NULL; | 1132 | return NULL; |
1652 | } | 1133 | } |
1653 | 1134 | ||
1654 | set_bit(SK_BUSY, &svsk->sk_flags); | ||
1655 | inet->sk_user_data = svsk; | 1135 | inet->sk_user_data = svsk; |
1656 | svsk->sk_sock = sock; | 1136 | svsk->sk_sock = sock; |
1657 | svsk->sk_sk = inet; | 1137 | svsk->sk_sk = inet; |
1658 | svsk->sk_ostate = inet->sk_state_change; | 1138 | svsk->sk_ostate = inet->sk_state_change; |
1659 | svsk->sk_odata = inet->sk_data_ready; | 1139 | svsk->sk_odata = inet->sk_data_ready; |
1660 | svsk->sk_owspace = inet->sk_write_space; | 1140 | svsk->sk_owspace = inet->sk_write_space; |
1661 | svsk->sk_server = serv; | ||
1662 | atomic_set(&svsk->sk_inuse, 1); | ||
1663 | svsk->sk_lastrecv = get_seconds(); | ||
1664 | spin_lock_init(&svsk->sk_lock); | ||
1665 | INIT_LIST_HEAD(&svsk->sk_deferred); | ||
1666 | INIT_LIST_HEAD(&svsk->sk_ready); | ||
1667 | mutex_init(&svsk->sk_mutex); | ||
1668 | 1141 | ||
1669 | /* Initialize the socket */ | 1142 | /* Initialize the socket */ |
1670 | if (sock->type == SOCK_DGRAM) | 1143 | if (sock->type == SOCK_DGRAM) |
1671 | svc_udp_init(svsk); | 1144 | svc_udp_init(svsk, serv); |
1672 | else | 1145 | else |
1673 | svc_tcp_init(svsk); | 1146 | svc_tcp_init(svsk, serv); |
1674 | |||
1675 | spin_lock_bh(&serv->sv_lock); | ||
1676 | if (is_temporary) { | ||
1677 | set_bit(SK_TEMP, &svsk->sk_flags); | ||
1678 | list_add(&svsk->sk_list, &serv->sv_tempsocks); | ||
1679 | serv->sv_tmpcnt++; | ||
1680 | if (serv->sv_temptimer.function == NULL) { | ||
1681 | /* setup timer to age temp sockets */ | ||
1682 | setup_timer(&serv->sv_temptimer, svc_age_temp_sockets, | ||
1683 | (unsigned long)serv); | ||
1684 | mod_timer(&serv->sv_temptimer, | ||
1685 | jiffies + svc_conn_age_period * HZ); | ||
1686 | } | ||
1687 | } else { | ||
1688 | clear_bit(SK_TEMP, &svsk->sk_flags); | ||
1689 | list_add(&svsk->sk_list, &serv->sv_permsocks); | ||
1690 | } | ||
1691 | spin_unlock_bh(&serv->sv_lock); | ||
1692 | 1147 | ||
1693 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", | 1148 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", |
1694 | svsk, svsk->sk_sk); | 1149 | svsk, svsk->sk_sk); |
@@ -1717,7 +1172,16 @@ int svc_addsock(struct svc_serv *serv, | |||
1717 | else { | 1172 | else { |
1718 | svsk = svc_setup_socket(serv, so, &err, SVC_SOCK_DEFAULTS); | 1173 | svsk = svc_setup_socket(serv, so, &err, SVC_SOCK_DEFAULTS); |
1719 | if (svsk) { | 1174 | if (svsk) { |
1720 | svc_sock_received(svsk); | 1175 | struct sockaddr_storage addr; |
1176 | struct sockaddr *sin = (struct sockaddr *)&addr; | ||
1177 | int salen; | ||
1178 | if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0) | ||
1179 | svc_xprt_set_local(&svsk->sk_xprt, sin, salen); | ||
1180 | clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags); | ||
1181 | spin_lock_bh(&serv->sv_lock); | ||
1182 | list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks); | ||
1183 | spin_unlock_bh(&serv->sv_lock); | ||
1184 | svc_xprt_received(&svsk->sk_xprt); | ||
1721 | err = 0; | 1185 | err = 0; |
1722 | } | 1186 | } |
1723 | } | 1187 | } |
@@ -1733,14 +1197,19 @@ EXPORT_SYMBOL_GPL(svc_addsock); | |||
1733 | /* | 1197 | /* |
1734 | * Create socket for RPC service. | 1198 | * Create socket for RPC service. |
1735 | */ | 1199 | */ |
1736 | static int svc_create_socket(struct svc_serv *serv, int protocol, | 1200 | static struct svc_xprt *svc_create_socket(struct svc_serv *serv, |
1737 | struct sockaddr *sin, int len, int flags) | 1201 | int protocol, |
1202 | struct sockaddr *sin, int len, | ||
1203 | int flags) | ||
1738 | { | 1204 | { |
1739 | struct svc_sock *svsk; | 1205 | struct svc_sock *svsk; |
1740 | struct socket *sock; | 1206 | struct socket *sock; |
1741 | int error; | 1207 | int error; |
1742 | int type; | 1208 | int type; |
1743 | char buf[RPC_MAX_ADDRBUFLEN]; | 1209 | char buf[RPC_MAX_ADDRBUFLEN]; |
1210 | struct sockaddr_storage addr; | ||
1211 | struct sockaddr *newsin = (struct sockaddr *)&addr; | ||
1212 | int newlen; | ||
1744 | 1213 | ||
1745 | dprintk("svc: svc_create_socket(%s, %d, %s)\n", | 1214 | dprintk("svc: svc_create_socket(%s, %d, %s)\n", |
1746 | serv->sv_program->pg_name, protocol, | 1215 | serv->sv_program->pg_name, protocol, |
@@ -1749,13 +1218,13 @@ static int svc_create_socket(struct svc_serv *serv, int protocol, | |||
1749 | if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) { | 1218 | if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) { |
1750 | printk(KERN_WARNING "svc: only UDP and TCP " | 1219 | printk(KERN_WARNING "svc: only UDP and TCP " |
1751 | "sockets supported\n"); | 1220 | "sockets supported\n"); |
1752 | return -EINVAL; | 1221 | return ERR_PTR(-EINVAL); |
1753 | } | 1222 | } |
1754 | type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM; | 1223 | type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM; |
1755 | 1224 | ||
1756 | error = sock_create_kern(sin->sa_family, type, protocol, &sock); | 1225 | error = sock_create_kern(sin->sa_family, type, protocol, &sock); |
1757 | if (error < 0) | 1226 | if (error < 0) |
1758 | return error; | 1227 | return ERR_PTR(error); |
1759 | 1228 | ||
1760 | svc_reclassify_socket(sock); | 1229 | svc_reclassify_socket(sock); |
1761 | 1230 | ||
@@ -1765,203 +1234,55 @@ static int svc_create_socket(struct svc_serv *serv, int protocol, | |||
1765 | if (error < 0) | 1234 | if (error < 0) |
1766 | goto bummer; | 1235 | goto bummer; |
1767 | 1236 | ||
1237 | newlen = len; | ||
1238 | error = kernel_getsockname(sock, newsin, &newlen); | ||
1239 | if (error < 0) | ||
1240 | goto bummer; | ||
1241 | |||
1768 | if (protocol == IPPROTO_TCP) { | 1242 | if (protocol == IPPROTO_TCP) { |
1769 | if ((error = kernel_listen(sock, 64)) < 0) | 1243 | if ((error = kernel_listen(sock, 64)) < 0) |
1770 | goto bummer; | 1244 | goto bummer; |
1771 | } | 1245 | } |
1772 | 1246 | ||
1773 | if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { | 1247 | if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { |
1774 | svc_sock_received(svsk); | 1248 | svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen); |
1775 | return ntohs(inet_sk(svsk->sk_sk)->sport); | 1249 | return (struct svc_xprt *)svsk; |
1776 | } | 1250 | } |
1777 | 1251 | ||
1778 | bummer: | 1252 | bummer: |
1779 | dprintk("svc: svc_create_socket error = %d\n", -error); | 1253 | dprintk("svc: svc_create_socket error = %d\n", -error); |
1780 | sock_release(sock); | 1254 | sock_release(sock); |
1781 | return error; | 1255 | return ERR_PTR(error); |
1782 | } | 1256 | } |
1783 | 1257 | ||
1784 | /* | 1258 | /* |
1785 | * Remove a dead socket | 1259 | * Detach the svc_sock from the socket so that no |
1260 | * more callbacks occur. | ||
1786 | */ | 1261 | */ |
1787 | static void | 1262 | static void svc_sock_detach(struct svc_xprt *xprt) |
1788 | svc_delete_socket(struct svc_sock *svsk) | ||
1789 | { | 1263 | { |
1790 | struct svc_serv *serv; | 1264 | struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); |
1791 | struct sock *sk; | 1265 | struct sock *sk = svsk->sk_sk; |
1792 | |||
1793 | dprintk("svc: svc_delete_socket(%p)\n", svsk); | ||
1794 | 1266 | ||
1795 | serv = svsk->sk_server; | 1267 | dprintk("svc: svc_sock_detach(%p)\n", svsk); |
1796 | sk = svsk->sk_sk; | ||
1797 | 1268 | ||
1269 | /* put back the old socket callbacks */ | ||
1798 | sk->sk_state_change = svsk->sk_ostate; | 1270 | sk->sk_state_change = svsk->sk_ostate; |
1799 | sk->sk_data_ready = svsk->sk_odata; | 1271 | sk->sk_data_ready = svsk->sk_odata; |
1800 | sk->sk_write_space = svsk->sk_owspace; | 1272 | sk->sk_write_space = svsk->sk_owspace; |
1801 | |||
1802 | spin_lock_bh(&serv->sv_lock); | ||
1803 | |||
1804 | if (!test_and_set_bit(SK_DETACHED, &svsk->sk_flags)) | ||
1805 | list_del_init(&svsk->sk_list); | ||
1806 | /* | ||
1807 | * We used to delete the svc_sock from whichever list | ||
1808 | * it's sk_ready node was on, but we don't actually | ||
1809 | * need to. This is because the only time we're called | ||
1810 | * while still attached to a queue, the queue itself | ||
1811 | * is about to be destroyed (in svc_destroy). | ||
1812 | */ | ||
1813 | if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags)) { | ||
1814 | BUG_ON(atomic_read(&svsk->sk_inuse)<2); | ||
1815 | atomic_dec(&svsk->sk_inuse); | ||
1816 | if (test_bit(SK_TEMP, &svsk->sk_flags)) | ||
1817 | serv->sv_tmpcnt--; | ||
1818 | } | ||
1819 | |||
1820 | spin_unlock_bh(&serv->sv_lock); | ||
1821 | } | ||
1822 | |||
1823 | static void svc_close_socket(struct svc_sock *svsk) | ||
1824 | { | ||
1825 | set_bit(SK_CLOSE, &svsk->sk_flags); | ||
1826 | if (test_and_set_bit(SK_BUSY, &svsk->sk_flags)) | ||
1827 | /* someone else will have to effect the close */ | ||
1828 | return; | ||
1829 | |||
1830 | atomic_inc(&svsk->sk_inuse); | ||
1831 | svc_delete_socket(svsk); | ||
1832 | clear_bit(SK_BUSY, &svsk->sk_flags); | ||
1833 | svc_sock_put(svsk); | ||
1834 | } | ||
1835 | |||
1836 | void svc_force_close_socket(struct svc_sock *svsk) | ||
1837 | { | ||
1838 | set_bit(SK_CLOSE, &svsk->sk_flags); | ||
1839 | if (test_bit(SK_BUSY, &svsk->sk_flags)) { | ||
1840 | /* Waiting to be processed, but no threads left, | ||
1841 | * So just remove it from the waiting list | ||
1842 | */ | ||
1843 | list_del_init(&svsk->sk_ready); | ||
1844 | clear_bit(SK_BUSY, &svsk->sk_flags); | ||
1845 | } | ||
1846 | svc_close_socket(svsk); | ||
1847 | } | ||
1848 | |||
1849 | /** | ||
1850 | * svc_makesock - Make a socket for nfsd and lockd | ||
1851 | * @serv: RPC server structure | ||
1852 | * @protocol: transport protocol to use | ||
1853 | * @port: port to use | ||
1854 | * @flags: requested socket characteristics | ||
1855 | * | ||
1856 | */ | ||
1857 | int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port, | ||
1858 | int flags) | ||
1859 | { | ||
1860 | struct sockaddr_in sin = { | ||
1861 | .sin_family = AF_INET, | ||
1862 | .sin_addr.s_addr = INADDR_ANY, | ||
1863 | .sin_port = htons(port), | ||
1864 | }; | ||
1865 | |||
1866 | dprintk("svc: creating socket proto = %d\n", protocol); | ||
1867 | return svc_create_socket(serv, protocol, (struct sockaddr *) &sin, | ||
1868 | sizeof(sin), flags); | ||
1869 | } | 1273 | } |
1870 | 1274 | ||
1871 | /* | 1275 | /* |
1872 | * Handle defer and revisit of requests | 1276 | * Free the svc_sock's socket resources and the svc_sock itself. |
1873 | */ | 1277 | */ |
1874 | 1278 | static void svc_sock_free(struct svc_xprt *xprt) | |
1875 | static void svc_revisit(struct cache_deferred_req *dreq, int too_many) | ||
1876 | { | 1279 | { |
1877 | struct svc_deferred_req *dr = container_of(dreq, struct svc_deferred_req, handle); | 1280 | struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); |
1878 | struct svc_sock *svsk; | 1281 | dprintk("svc: svc_sock_free(%p)\n", svsk); |
1879 | 1282 | ||
1880 | if (too_many) { | 1283 | if (svsk->sk_sock->file) |
1881 | svc_sock_put(dr->svsk); | 1284 | sockfd_put(svsk->sk_sock); |
1882 | kfree(dr); | 1285 | else |
1883 | return; | 1286 | sock_release(svsk->sk_sock); |
1884 | } | 1287 | kfree(svsk); |
1885 | dprintk("revisit queued\n"); | ||
1886 | svsk = dr->svsk; | ||
1887 | dr->svsk = NULL; | ||
1888 | spin_lock(&svsk->sk_lock); | ||
1889 | list_add(&dr->handle.recent, &svsk->sk_deferred); | ||
1890 | spin_unlock(&svsk->sk_lock); | ||
1891 | set_bit(SK_DEFERRED, &svsk->sk_flags); | ||
1892 | svc_sock_enqueue(svsk); | ||
1893 | svc_sock_put(svsk); | ||
1894 | } | ||
1895 | |||
1896 | static struct cache_deferred_req * | ||
1897 | svc_defer(struct cache_req *req) | ||
1898 | { | ||
1899 | struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); | ||
1900 | int size = sizeof(struct svc_deferred_req) + (rqstp->rq_arg.len); | ||
1901 | struct svc_deferred_req *dr; | ||
1902 | |||
1903 | if (rqstp->rq_arg.page_len) | ||
1904 | return NULL; /* if more than a page, give up FIXME */ | ||
1905 | if (rqstp->rq_deferred) { | ||
1906 | dr = rqstp->rq_deferred; | ||
1907 | rqstp->rq_deferred = NULL; | ||
1908 | } else { | ||
1909 | int skip = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len; | ||
1910 | /* FIXME maybe discard if size too large */ | ||
1911 | dr = kmalloc(size, GFP_KERNEL); | ||
1912 | if (dr == NULL) | ||
1913 | return NULL; | ||
1914 | |||
1915 | dr->handle.owner = rqstp->rq_server; | ||
1916 | dr->prot = rqstp->rq_prot; | ||
1917 | memcpy(&dr->addr, &rqstp->rq_addr, rqstp->rq_addrlen); | ||
1918 | dr->addrlen = rqstp->rq_addrlen; | ||
1919 | dr->daddr = rqstp->rq_daddr; | ||
1920 | dr->argslen = rqstp->rq_arg.len >> 2; | ||
1921 | memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2); | ||
1922 | } | ||
1923 | atomic_inc(&rqstp->rq_sock->sk_inuse); | ||
1924 | dr->svsk = rqstp->rq_sock; | ||
1925 | |||
1926 | dr->handle.revisit = svc_revisit; | ||
1927 | return &dr->handle; | ||
1928 | } | ||
1929 | |||
1930 | /* | ||
1931 | * recv data from a deferred request into an active one | ||
1932 | */ | ||
1933 | static int svc_deferred_recv(struct svc_rqst *rqstp) | ||
1934 | { | ||
1935 | struct svc_deferred_req *dr = rqstp->rq_deferred; | ||
1936 | |||
1937 | rqstp->rq_arg.head[0].iov_base = dr->args; | ||
1938 | rqstp->rq_arg.head[0].iov_len = dr->argslen<<2; | ||
1939 | rqstp->rq_arg.page_len = 0; | ||
1940 | rqstp->rq_arg.len = dr->argslen<<2; | ||
1941 | rqstp->rq_prot = dr->prot; | ||
1942 | memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen); | ||
1943 | rqstp->rq_addrlen = dr->addrlen; | ||
1944 | rqstp->rq_daddr = dr->daddr; | ||
1945 | rqstp->rq_respages = rqstp->rq_pages; | ||
1946 | return dr->argslen<<2; | ||
1947 | } | ||
1948 | |||
1949 | |||
1950 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk) | ||
1951 | { | ||
1952 | struct svc_deferred_req *dr = NULL; | ||
1953 | |||
1954 | if (!test_bit(SK_DEFERRED, &svsk->sk_flags)) | ||
1955 | return NULL; | ||
1956 | spin_lock(&svsk->sk_lock); | ||
1957 | clear_bit(SK_DEFERRED, &svsk->sk_flags); | ||
1958 | if (!list_empty(&svsk->sk_deferred)) { | ||
1959 | dr = list_entry(svsk->sk_deferred.next, | ||
1960 | struct svc_deferred_req, | ||
1961 | handle.recent); | ||
1962 | list_del_init(&dr->handle.recent); | ||
1963 | set_bit(SK_DEFERRED, &svsk->sk_flags); | ||
1964 | } | ||
1965 | spin_unlock(&svsk->sk_lock); | ||
1966 | return dr; | ||
1967 | } | 1288 | } |
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c index bada7de0c2fc..0f8c439b848a 100644 --- a/net/sunrpc/sysctl.c +++ b/net/sunrpc/sysctl.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/sunrpc/types.h> | 18 | #include <linux/sunrpc/types.h> |
19 | #include <linux/sunrpc/sched.h> | 19 | #include <linux/sunrpc/sched.h> |
20 | #include <linux/sunrpc/stats.h> | 20 | #include <linux/sunrpc/stats.h> |
21 | #include <linux/sunrpc/svc_xprt.h> | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * Declare the debug flags here | 24 | * Declare the debug flags here |
@@ -55,6 +56,30 @@ rpc_unregister_sysctl(void) | |||
55 | } | 56 | } |
56 | } | 57 | } |
57 | 58 | ||
59 | static int proc_do_xprt(ctl_table *table, int write, struct file *file, | ||
60 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
61 | { | ||
62 | char tmpbuf[256]; | ||
63 | int len; | ||
64 | if ((*ppos && !write) || !*lenp) { | ||
65 | *lenp = 0; | ||
66 | return 0; | ||
67 | } | ||
68 | if (write) | ||
69 | return -EINVAL; | ||
70 | else { | ||
71 | len = svc_print_xprts(tmpbuf, sizeof(tmpbuf)); | ||
72 | if (!access_ok(VERIFY_WRITE, buffer, len)) | ||
73 | return -EFAULT; | ||
74 | |||
75 | if (__copy_to_user(buffer, tmpbuf, len)) | ||
76 | return -EFAULT; | ||
77 | } | ||
78 | *lenp -= len; | ||
79 | *ppos += len; | ||
80 | return 0; | ||
81 | } | ||
82 | |||
58 | static int | 83 | static int |
59 | proc_dodebug(ctl_table *table, int write, struct file *file, | 84 | proc_dodebug(ctl_table *table, int write, struct file *file, |
60 | void __user *buffer, size_t *lenp, loff_t *ppos) | 85 | void __user *buffer, size_t *lenp, loff_t *ppos) |
@@ -147,6 +172,12 @@ static ctl_table debug_table[] = { | |||
147 | .mode = 0644, | 172 | .mode = 0644, |
148 | .proc_handler = &proc_dodebug | 173 | .proc_handler = &proc_dodebug |
149 | }, | 174 | }, |
175 | { | ||
176 | .procname = "transports", | ||
177 | .maxlen = 256, | ||
178 | .mode = 0444, | ||
179 | .proc_handler = &proc_do_xprt, | ||
180 | }, | ||
150 | { .ctl_name = 0 } | 181 | { .ctl_name = 0 } |
151 | }; | 182 | }; |
152 | 183 | ||
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 54264062ea69..995c3fdc16c2 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -96,11 +96,13 @@ xdr_encode_string(__be32 *p, const char *string) | |||
96 | EXPORT_SYMBOL(xdr_encode_string); | 96 | EXPORT_SYMBOL(xdr_encode_string); |
97 | 97 | ||
98 | __be32 * | 98 | __be32 * |
99 | xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen) | 99 | xdr_decode_string_inplace(__be32 *p, char **sp, |
100 | unsigned int *lenp, unsigned int maxlen) | ||
100 | { | 101 | { |
101 | unsigned int len; | 102 | u32 len; |
102 | 103 | ||
103 | if ((len = ntohl(*p++)) > maxlen) | 104 | len = ntohl(*p++); |
105 | if (len > maxlen) | ||
104 | return NULL; | 106 | return NULL; |
105 | *lenp = len; | 107 | *lenp = len; |
106 | *sp = (char *) p; | 108 | *sp = (char *) p; |
diff --git a/net/sunrpc/xprtrdma/Makefile b/net/sunrpc/xprtrdma/Makefile index 264f0feeb513..5a8f268bdd30 100644 --- a/net/sunrpc/xprtrdma/Makefile +++ b/net/sunrpc/xprtrdma/Makefile | |||
@@ -1,3 +1,8 @@ | |||
1 | obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma.o | 1 | obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma.o |
2 | 2 | ||
3 | xprtrdma-y := transport.o rpc_rdma.o verbs.o | 3 | xprtrdma-y := transport.o rpc_rdma.o verbs.o |
4 | |||
5 | obj-$(CONFIG_SUNRPC_XPRT_RDMA) += svcrdma.o | ||
6 | |||
7 | svcrdma-y := svc_rdma.o svc_rdma_transport.o \ | ||
8 | svc_rdma_marshal.o svc_rdma_sendto.o svc_rdma_recvfrom.o | ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c new file mode 100644 index 000000000000..88c0ca20bb1e --- /dev/null +++ b/net/sunrpc/xprtrdma/svc_rdma.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the BSD-type | ||
8 | * license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * | ||
17 | * Redistributions in binary form must reproduce the above | ||
18 | * copyright notice, this list of conditions and the following | ||
19 | * disclaimer in the documentation and/or other materials provided | ||
20 | * with the distribution. | ||
21 | * | ||
22 | * Neither the name of the Network Appliance, Inc. nor the names of | ||
23 | * its contributors may be used to endorse or promote products | ||
24 | * derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
30 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
31 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
32 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
33 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | * | ||
39 | * Author: Tom Tucker <tom@opengridcomputing.com> | ||
40 | */ | ||
41 | #include <linux/module.h> | ||
42 | #include <linux/init.h> | ||
43 | #include <linux/fs.h> | ||
44 | #include <linux/sysctl.h> | ||
45 | #include <linux/sunrpc/clnt.h> | ||
46 | #include <linux/sunrpc/sched.h> | ||
47 | #include <linux/sunrpc/svc_rdma.h> | ||
48 | |||
49 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | ||
50 | |||
51 | /* RPC/RDMA parameters */ | ||
52 | unsigned int svcrdma_ord = RPCRDMA_ORD; | ||
53 | static unsigned int min_ord = 1; | ||
54 | static unsigned int max_ord = 4096; | ||
55 | unsigned int svcrdma_max_requests = RPCRDMA_MAX_REQUESTS; | ||
56 | static unsigned int min_max_requests = 4; | ||
57 | static unsigned int max_max_requests = 16384; | ||
58 | unsigned int svcrdma_max_req_size = RPCRDMA_MAX_REQ_SIZE; | ||
59 | static unsigned int min_max_inline = 4096; | ||
60 | static unsigned int max_max_inline = 65536; | ||
61 | |||
62 | atomic_t rdma_stat_recv; | ||
63 | atomic_t rdma_stat_read; | ||
64 | atomic_t rdma_stat_write; | ||
65 | atomic_t rdma_stat_sq_starve; | ||
66 | atomic_t rdma_stat_rq_starve; | ||
67 | atomic_t rdma_stat_rq_poll; | ||
68 | atomic_t rdma_stat_rq_prod; | ||
69 | atomic_t rdma_stat_sq_poll; | ||
70 | atomic_t rdma_stat_sq_prod; | ||
71 | |||
72 | /* | ||
73 | * This function implements reading and resetting an atomic_t stat | ||
74 | * variable through read/write to a proc file. Any write to the file | ||
75 | * resets the associated statistic to zero. Any read returns it's | ||
76 | * current value. | ||
77 | */ | ||
78 | static int read_reset_stat(ctl_table *table, int write, | ||
79 | struct file *filp, void __user *buffer, size_t *lenp, | ||
80 | loff_t *ppos) | ||
81 | { | ||
82 | atomic_t *stat = (atomic_t *)table->data; | ||
83 | |||
84 | if (!stat) | ||
85 | return -EINVAL; | ||
86 | |||
87 | if (write) | ||
88 | atomic_set(stat, 0); | ||
89 | else { | ||
90 | char str_buf[32]; | ||
91 | char *data; | ||
92 | int len = snprintf(str_buf, 32, "%d\n", atomic_read(stat)); | ||
93 | if (len >= 32) | ||
94 | return -EFAULT; | ||
95 | len = strlen(str_buf); | ||
96 | if (*ppos > len) { | ||
97 | *lenp = 0; | ||
98 | return 0; | ||
99 | } | ||
100 | data = &str_buf[*ppos]; | ||
101 | len -= *ppos; | ||
102 | if (len > *lenp) | ||
103 | len = *lenp; | ||
104 | if (len && copy_to_user(buffer, str_buf, len)) | ||
105 | return -EFAULT; | ||
106 | *lenp = len; | ||
107 | *ppos += len; | ||
108 | } | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static struct ctl_table_header *svcrdma_table_header; | ||
113 | static ctl_table svcrdma_parm_table[] = { | ||
114 | { | ||
115 | .procname = "max_requests", | ||
116 | .data = &svcrdma_max_requests, | ||
117 | .maxlen = sizeof(unsigned int), | ||
118 | .mode = 0644, | ||
119 | .proc_handler = &proc_dointvec_minmax, | ||
120 | .strategy = &sysctl_intvec, | ||
121 | .extra1 = &min_max_requests, | ||
122 | .extra2 = &max_max_requests | ||
123 | }, | ||
124 | { | ||
125 | .procname = "max_req_size", | ||
126 | .data = &svcrdma_max_req_size, | ||
127 | .maxlen = sizeof(unsigned int), | ||
128 | .mode = 0644, | ||
129 | .proc_handler = &proc_dointvec_minmax, | ||
130 | .strategy = &sysctl_intvec, | ||
131 | .extra1 = &min_max_inline, | ||
132 | .extra2 = &max_max_inline | ||
133 | }, | ||
134 | { | ||
135 | .procname = "max_outbound_read_requests", | ||
136 | .data = &svcrdma_ord, | ||
137 | .maxlen = sizeof(unsigned int), | ||
138 | .mode = 0644, | ||
139 | .proc_handler = &proc_dointvec_minmax, | ||
140 | .strategy = &sysctl_intvec, | ||
141 | .extra1 = &min_ord, | ||
142 | .extra2 = &max_ord, | ||
143 | }, | ||
144 | |||
145 | { | ||
146 | .procname = "rdma_stat_read", | ||
147 | .data = &rdma_stat_read, | ||
148 | .maxlen = sizeof(atomic_t), | ||
149 | .mode = 0644, | ||
150 | .proc_handler = &read_reset_stat, | ||
151 | }, | ||
152 | { | ||
153 | .procname = "rdma_stat_recv", | ||
154 | .data = &rdma_stat_recv, | ||
155 | .maxlen = sizeof(atomic_t), | ||
156 | .mode = 0644, | ||
157 | .proc_handler = &read_reset_stat, | ||
158 | }, | ||
159 | { | ||
160 | .procname = "rdma_stat_write", | ||
161 | .data = &rdma_stat_write, | ||
162 | .maxlen = sizeof(atomic_t), | ||
163 | .mode = 0644, | ||
164 | .proc_handler = &read_reset_stat, | ||
165 | }, | ||
166 | { | ||
167 | .procname = "rdma_stat_sq_starve", | ||
168 | .data = &rdma_stat_sq_starve, | ||
169 | .maxlen = sizeof(atomic_t), | ||
170 | .mode = 0644, | ||
171 | .proc_handler = &read_reset_stat, | ||
172 | }, | ||
173 | { | ||
174 | .procname = "rdma_stat_rq_starve", | ||
175 | .data = &rdma_stat_rq_starve, | ||
176 | .maxlen = sizeof(atomic_t), | ||
177 | .mode = 0644, | ||
178 | .proc_handler = &read_reset_stat, | ||
179 | }, | ||
180 | { | ||
181 | .procname = "rdma_stat_rq_poll", | ||
182 | .data = &rdma_stat_rq_poll, | ||
183 | .maxlen = sizeof(atomic_t), | ||
184 | .mode = 0644, | ||
185 | .proc_handler = &read_reset_stat, | ||
186 | }, | ||
187 | { | ||
188 | .procname = "rdma_stat_rq_prod", | ||
189 | .data = &rdma_stat_rq_prod, | ||
190 | .maxlen = sizeof(atomic_t), | ||
191 | .mode = 0644, | ||
192 | .proc_handler = &read_reset_stat, | ||
193 | }, | ||
194 | { | ||
195 | .procname = "rdma_stat_sq_poll", | ||
196 | .data = &rdma_stat_sq_poll, | ||
197 | .maxlen = sizeof(atomic_t), | ||
198 | .mode = 0644, | ||
199 | .proc_handler = &read_reset_stat, | ||
200 | }, | ||
201 | { | ||
202 | .procname = "rdma_stat_sq_prod", | ||
203 | .data = &rdma_stat_sq_prod, | ||
204 | .maxlen = sizeof(atomic_t), | ||
205 | .mode = 0644, | ||
206 | .proc_handler = &read_reset_stat, | ||
207 | }, | ||
208 | { | ||
209 | .ctl_name = 0, | ||
210 | }, | ||
211 | }; | ||
212 | |||
213 | static ctl_table svcrdma_table[] = { | ||
214 | { | ||
215 | .procname = "svc_rdma", | ||
216 | .mode = 0555, | ||
217 | .child = svcrdma_parm_table | ||
218 | }, | ||
219 | { | ||
220 | .ctl_name = 0, | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | static ctl_table svcrdma_root_table[] = { | ||
225 | { | ||
226 | .ctl_name = CTL_SUNRPC, | ||
227 | .procname = "sunrpc", | ||
228 | .mode = 0555, | ||
229 | .child = svcrdma_table | ||
230 | }, | ||
231 | { | ||
232 | .ctl_name = 0, | ||
233 | }, | ||
234 | }; | ||
235 | |||
236 | void svc_rdma_cleanup(void) | ||
237 | { | ||
238 | dprintk("SVCRDMA Module Removed, deregister RPC RDMA transport\n"); | ||
239 | if (svcrdma_table_header) { | ||
240 | unregister_sysctl_table(svcrdma_table_header); | ||
241 | svcrdma_table_header = NULL; | ||
242 | } | ||
243 | svc_unreg_xprt_class(&svc_rdma_class); | ||
244 | } | ||
245 | |||
246 | int svc_rdma_init(void) | ||
247 | { | ||
248 | dprintk("SVCRDMA Module Init, register RPC RDMA transport\n"); | ||
249 | dprintk("\tsvcrdma_ord : %d\n", svcrdma_ord); | ||
250 | dprintk("\tmax_requests : %d\n", svcrdma_max_requests); | ||
251 | dprintk("\tsq_depth : %d\n", | ||
252 | svcrdma_max_requests * RPCRDMA_SQ_DEPTH_MULT); | ||
253 | dprintk("\tmax_inline : %d\n", svcrdma_max_req_size); | ||
254 | if (!svcrdma_table_header) | ||
255 | svcrdma_table_header = | ||
256 | register_sysctl_table(svcrdma_root_table); | ||
257 | |||
258 | /* Register RDMA with the SVC transport switch */ | ||
259 | svc_reg_xprt_class(&svc_rdma_class); | ||
260 | return 0; | ||
261 | } | ||
262 | MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>"); | ||
263 | MODULE_DESCRIPTION("SVC RDMA Transport"); | ||
264 | MODULE_LICENSE("Dual BSD/GPL"); | ||
265 | module_init(svc_rdma_init); | ||
266 | module_exit(svc_rdma_cleanup); | ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c b/net/sunrpc/xprtrdma/svc_rdma_marshal.c new file mode 100644 index 000000000000..9530ef2d40dc --- /dev/null +++ b/net/sunrpc/xprtrdma/svc_rdma_marshal.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the BSD-type | ||
8 | * license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * | ||
17 | * Redistributions in binary form must reproduce the above | ||
18 | * copyright notice, this list of conditions and the following | ||
19 | * disclaimer in the documentation and/or other materials provided | ||
20 | * with the distribution. | ||
21 | * | ||
22 | * Neither the name of the Network Appliance, Inc. nor the names of | ||
23 | * its contributors may be used to endorse or promote products | ||
24 | * derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
30 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
31 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
32 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
33 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | * | ||
39 | * Author: Tom Tucker <tom@opengridcomputing.com> | ||
40 | */ | ||
41 | |||
42 | #include <linux/sunrpc/xdr.h> | ||
43 | #include <linux/sunrpc/debug.h> | ||
44 | #include <asm/unaligned.h> | ||
45 | #include <linux/sunrpc/rpc_rdma.h> | ||
46 | #include <linux/sunrpc/svc_rdma.h> | ||
47 | |||
48 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | ||
49 | |||
50 | /* | ||
51 | * Decodes a read chunk list. The expected format is as follows: | ||
52 | * descrim : xdr_one | ||
53 | * position : u32 offset into XDR stream | ||
54 | * handle : u32 RKEY | ||
55 | * . . . | ||
56 | * end-of-list: xdr_zero | ||
57 | */ | ||
58 | static u32 *decode_read_list(u32 *va, u32 *vaend) | ||
59 | { | ||
60 | struct rpcrdma_read_chunk *ch = (struct rpcrdma_read_chunk *)va; | ||
61 | |||
62 | while (ch->rc_discrim != xdr_zero) { | ||
63 | u64 ch_offset; | ||
64 | |||
65 | if (((unsigned long)ch + sizeof(struct rpcrdma_read_chunk)) > | ||
66 | (unsigned long)vaend) { | ||
67 | dprintk("svcrdma: vaend=%p, ch=%p\n", vaend, ch); | ||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | ch->rc_discrim = ntohl(ch->rc_discrim); | ||
72 | ch->rc_position = ntohl(ch->rc_position); | ||
73 | ch->rc_target.rs_handle = ntohl(ch->rc_target.rs_handle); | ||
74 | ch->rc_target.rs_length = ntohl(ch->rc_target.rs_length); | ||
75 | va = (u32 *)&ch->rc_target.rs_offset; | ||
76 | xdr_decode_hyper(va, &ch_offset); | ||
77 | put_unaligned(ch_offset, (u64 *)va); | ||
78 | ch++; | ||
79 | } | ||
80 | return (u32 *)&ch->rc_position; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Determine number of chunks and total bytes in chunk list. The chunk | ||
85 | * list has already been verified to fit within the RPCRDMA header. | ||
86 | */ | ||
87 | void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch, | ||
88 | int *ch_count, int *byte_count) | ||
89 | { | ||
90 | /* compute the number of bytes represented by read chunks */ | ||
91 | *byte_count = 0; | ||
92 | *ch_count = 0; | ||
93 | for (; ch->rc_discrim != 0; ch++) { | ||
94 | *byte_count = *byte_count + ch->rc_target.rs_length; | ||
95 | *ch_count = *ch_count + 1; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Decodes a write chunk list. The expected format is as follows: | ||
101 | * descrim : xdr_one | ||
102 | * nchunks : <count> | ||
103 | * handle : u32 RKEY ---+ | ||
104 | * length : u32 <len of segment> | | ||
105 | * offset : remove va + <count> | ||
106 | * . . . | | ||
107 | * ---+ | ||
108 | */ | ||
109 | static u32 *decode_write_list(u32 *va, u32 *vaend) | ||
110 | { | ||
111 | int ch_no; | ||
112 | struct rpcrdma_write_array *ary = | ||
113 | (struct rpcrdma_write_array *)va; | ||
114 | |||
115 | /* Check for not write-array */ | ||
116 | if (ary->wc_discrim == xdr_zero) | ||
117 | return (u32 *)&ary->wc_nchunks; | ||
118 | |||
119 | if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) > | ||
120 | (unsigned long)vaend) { | ||
121 | dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend); | ||
122 | return NULL; | ||
123 | } | ||
124 | ary->wc_discrim = ntohl(ary->wc_discrim); | ||
125 | ary->wc_nchunks = ntohl(ary->wc_nchunks); | ||
126 | if (((unsigned long)&ary->wc_array[0] + | ||
127 | (sizeof(struct rpcrdma_write_chunk) * ary->wc_nchunks)) > | ||
128 | (unsigned long)vaend) { | ||
129 | dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n", | ||
130 | ary, ary->wc_nchunks, vaend); | ||
131 | return NULL; | ||
132 | } | ||
133 | for (ch_no = 0; ch_no < ary->wc_nchunks; ch_no++) { | ||
134 | u64 ch_offset; | ||
135 | |||
136 | ary->wc_array[ch_no].wc_target.rs_handle = | ||
137 | ntohl(ary->wc_array[ch_no].wc_target.rs_handle); | ||
138 | ary->wc_array[ch_no].wc_target.rs_length = | ||
139 | ntohl(ary->wc_array[ch_no].wc_target.rs_length); | ||
140 | va = (u32 *)&ary->wc_array[ch_no].wc_target.rs_offset; | ||
141 | xdr_decode_hyper(va, &ch_offset); | ||
142 | put_unaligned(ch_offset, (u64 *)va); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * rs_length is the 2nd 4B field in wc_target and taking its | ||
147 | * address skips the list terminator | ||
148 | */ | ||
149 | return (u32 *)&ary->wc_array[ch_no].wc_target.rs_length; | ||
150 | } | ||
151 | |||
152 | static u32 *decode_reply_array(u32 *va, u32 *vaend) | ||
153 | { | ||
154 | int ch_no; | ||
155 | struct rpcrdma_write_array *ary = | ||
156 | (struct rpcrdma_write_array *)va; | ||
157 | |||
158 | /* Check for no reply-array */ | ||
159 | if (ary->wc_discrim == xdr_zero) | ||
160 | return (u32 *)&ary->wc_nchunks; | ||
161 | |||
162 | if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) > | ||
163 | (unsigned long)vaend) { | ||
164 | dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend); | ||
165 | return NULL; | ||
166 | } | ||
167 | ary->wc_discrim = ntohl(ary->wc_discrim); | ||
168 | ary->wc_nchunks = ntohl(ary->wc_nchunks); | ||
169 | if (((unsigned long)&ary->wc_array[0] + | ||
170 | (sizeof(struct rpcrdma_write_chunk) * ary->wc_nchunks)) > | ||
171 | (unsigned long)vaend) { | ||
172 | dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n", | ||
173 | ary, ary->wc_nchunks, vaend); | ||
174 | return NULL; | ||
175 | } | ||
176 | for (ch_no = 0; ch_no < ary->wc_nchunks; ch_no++) { | ||
177 | u64 ch_offset; | ||
178 | |||
179 | ary->wc_array[ch_no].wc_target.rs_handle = | ||
180 | ntohl(ary->wc_array[ch_no].wc_target.rs_handle); | ||
181 | ary->wc_array[ch_no].wc_target.rs_length = | ||
182 | ntohl(ary->wc_array[ch_no].wc_target.rs_length); | ||
183 | va = (u32 *)&ary->wc_array[ch_no].wc_target.rs_offset; | ||
184 | xdr_decode_hyper(va, &ch_offset); | ||
185 | put_unaligned(ch_offset, (u64 *)va); | ||
186 | } | ||
187 | |||
188 | return (u32 *)&ary->wc_array[ch_no]; | ||
189 | } | ||
190 | |||
191 | int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, | ||
192 | struct svc_rqst *rqstp) | ||
193 | { | ||
194 | struct rpcrdma_msg *rmsgp = NULL; | ||
195 | u32 *va; | ||
196 | u32 *vaend; | ||
197 | u32 hdr_len; | ||
198 | |||
199 | rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; | ||
200 | |||
201 | /* Verify that there's enough bytes for header + something */ | ||
202 | if (rqstp->rq_arg.len <= RPCRDMA_HDRLEN_MIN) { | ||
203 | dprintk("svcrdma: header too short = %d\n", | ||
204 | rqstp->rq_arg.len); | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | /* Decode the header */ | ||
209 | rmsgp->rm_xid = ntohl(rmsgp->rm_xid); | ||
210 | rmsgp->rm_vers = ntohl(rmsgp->rm_vers); | ||
211 | rmsgp->rm_credit = ntohl(rmsgp->rm_credit); | ||
212 | rmsgp->rm_type = ntohl(rmsgp->rm_type); | ||
213 | |||
214 | if (rmsgp->rm_vers != RPCRDMA_VERSION) | ||
215 | return -ENOSYS; | ||
216 | |||
217 | /* Pull in the extra for the padded case and bump our pointer */ | ||
218 | if (rmsgp->rm_type == RDMA_MSGP) { | ||
219 | int hdrlen; | ||
220 | rmsgp->rm_body.rm_padded.rm_align = | ||
221 | ntohl(rmsgp->rm_body.rm_padded.rm_align); | ||
222 | rmsgp->rm_body.rm_padded.rm_thresh = | ||
223 | ntohl(rmsgp->rm_body.rm_padded.rm_thresh); | ||
224 | |||
225 | va = &rmsgp->rm_body.rm_padded.rm_pempty[4]; | ||
226 | rqstp->rq_arg.head[0].iov_base = va; | ||
227 | hdrlen = (u32)((unsigned long)va - (unsigned long)rmsgp); | ||
228 | rqstp->rq_arg.head[0].iov_len -= hdrlen; | ||
229 | if (hdrlen > rqstp->rq_arg.len) | ||
230 | return -EINVAL; | ||
231 | return hdrlen; | ||
232 | } | ||
233 | |||
234 | /* The chunk list may contain either a read chunk list or a write | ||
235 | * chunk list and a reply chunk list. | ||
236 | */ | ||
237 | va = &rmsgp->rm_body.rm_chunks[0]; | ||
238 | vaend = (u32 *)((unsigned long)rmsgp + rqstp->rq_arg.len); | ||
239 | va = decode_read_list(va, vaend); | ||
240 | if (!va) | ||
241 | return -EINVAL; | ||
242 | va = decode_write_list(va, vaend); | ||
243 | if (!va) | ||
244 | return -EINVAL; | ||
245 | va = decode_reply_array(va, vaend); | ||
246 | if (!va) | ||
247 | return -EINVAL; | ||
248 | |||
249 | rqstp->rq_arg.head[0].iov_base = va; | ||
250 | hdr_len = (unsigned long)va - (unsigned long)rmsgp; | ||
251 | rqstp->rq_arg.head[0].iov_len -= hdr_len; | ||
252 | |||
253 | *rdma_req = rmsgp; | ||
254 | return hdr_len; | ||
255 | } | ||
256 | |||
257 | int svc_rdma_xdr_decode_deferred_req(struct svc_rqst *rqstp) | ||
258 | { | ||
259 | struct rpcrdma_msg *rmsgp = NULL; | ||
260 | struct rpcrdma_read_chunk *ch; | ||
261 | struct rpcrdma_write_array *ary; | ||
262 | u32 *va; | ||
263 | u32 hdrlen; | ||
264 | |||
265 | dprintk("svcrdma: processing deferred RDMA header on rqstp=%p\n", | ||
266 | rqstp); | ||
267 | rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; | ||
268 | |||
269 | /* Pull in the extra for the padded case and bump our pointer */ | ||
270 | if (rmsgp->rm_type == RDMA_MSGP) { | ||
271 | va = &rmsgp->rm_body.rm_padded.rm_pempty[4]; | ||
272 | rqstp->rq_arg.head[0].iov_base = va; | ||
273 | hdrlen = (u32)((unsigned long)va - (unsigned long)rmsgp); | ||
274 | rqstp->rq_arg.head[0].iov_len -= hdrlen; | ||
275 | return hdrlen; | ||
276 | } | ||
277 | |||
278 | /* | ||
279 | * Skip all chunks to find RPC msg. These were previously processed | ||
280 | */ | ||
281 | va = &rmsgp->rm_body.rm_chunks[0]; | ||
282 | |||
283 | /* Skip read-list */ | ||
284 | for (ch = (struct rpcrdma_read_chunk *)va; | ||
285 | ch->rc_discrim != xdr_zero; ch++); | ||
286 | va = (u32 *)&ch->rc_position; | ||
287 | |||
288 | /* Skip write-list */ | ||
289 | ary = (struct rpcrdma_write_array *)va; | ||
290 | if (ary->wc_discrim == xdr_zero) | ||
291 | va = (u32 *)&ary->wc_nchunks; | ||
292 | else | ||
293 | /* | ||
294 | * rs_length is the 2nd 4B field in wc_target and taking its | ||
295 | * address skips the list terminator | ||
296 | */ | ||
297 | va = (u32 *)&ary->wc_array[ary->wc_nchunks].wc_target.rs_length; | ||
298 | |||
299 | /* Skip reply-array */ | ||
300 | ary = (struct rpcrdma_write_array *)va; | ||
301 | if (ary->wc_discrim == xdr_zero) | ||
302 | va = (u32 *)&ary->wc_nchunks; | ||
303 | else | ||
304 | va = (u32 *)&ary->wc_array[ary->wc_nchunks]; | ||
305 | |||
306 | rqstp->rq_arg.head[0].iov_base = va; | ||
307 | hdrlen = (unsigned long)va - (unsigned long)rmsgp; | ||
308 | rqstp->rq_arg.head[0].iov_len -= hdrlen; | ||
309 | |||
310 | return hdrlen; | ||
311 | } | ||
312 | |||
313 | int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt, | ||
314 | struct rpcrdma_msg *rmsgp, | ||
315 | enum rpcrdma_errcode err, u32 *va) | ||
316 | { | ||
317 | u32 *startp = va; | ||
318 | |||
319 | *va++ = htonl(rmsgp->rm_xid); | ||
320 | *va++ = htonl(rmsgp->rm_vers); | ||
321 | *va++ = htonl(xprt->sc_max_requests); | ||
322 | *va++ = htonl(RDMA_ERROR); | ||
323 | *va++ = htonl(err); | ||
324 | if (err == ERR_VERS) { | ||
325 | *va++ = htonl(RPCRDMA_VERSION); | ||
326 | *va++ = htonl(RPCRDMA_VERSION); | ||
327 | } | ||
328 | |||
329 | return (int)((unsigned long)va - (unsigned long)startp); | ||
330 | } | ||
331 | |||
332 | int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *rmsgp) | ||
333 | { | ||
334 | struct rpcrdma_write_array *wr_ary; | ||
335 | |||
336 | /* There is no read-list in a reply */ | ||
337 | |||
338 | /* skip write list */ | ||
339 | wr_ary = (struct rpcrdma_write_array *) | ||
340 | &rmsgp->rm_body.rm_chunks[1]; | ||
341 | if (wr_ary->wc_discrim) | ||
342 | wr_ary = (struct rpcrdma_write_array *) | ||
343 | &wr_ary->wc_array[ntohl(wr_ary->wc_nchunks)]. | ||
344 | wc_target.rs_length; | ||
345 | else | ||
346 | wr_ary = (struct rpcrdma_write_array *) | ||
347 | &wr_ary->wc_nchunks; | ||
348 | |||
349 | /* skip reply array */ | ||
350 | if (wr_ary->wc_discrim) | ||
351 | wr_ary = (struct rpcrdma_write_array *) | ||
352 | &wr_ary->wc_array[ntohl(wr_ary->wc_nchunks)]; | ||
353 | else | ||
354 | wr_ary = (struct rpcrdma_write_array *) | ||
355 | &wr_ary->wc_nchunks; | ||
356 | |||
357 | return (unsigned long) wr_ary - (unsigned long) rmsgp; | ||
358 | } | ||
359 | |||
360 | void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *rmsgp, int chunks) | ||
361 | { | ||
362 | struct rpcrdma_write_array *ary; | ||
363 | |||
364 | /* no read-list */ | ||
365 | rmsgp->rm_body.rm_chunks[0] = xdr_zero; | ||
366 | |||
367 | /* write-array discrim */ | ||
368 | ary = (struct rpcrdma_write_array *) | ||
369 | &rmsgp->rm_body.rm_chunks[1]; | ||
370 | ary->wc_discrim = xdr_one; | ||
371 | ary->wc_nchunks = htonl(chunks); | ||
372 | |||
373 | /* write-list terminator */ | ||
374 | ary->wc_array[chunks].wc_target.rs_handle = xdr_zero; | ||
375 | |||
376 | /* reply-array discriminator */ | ||
377 | ary->wc_array[chunks].wc_target.rs_length = xdr_zero; | ||
378 | } | ||
379 | |||
380 | void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *ary, | ||
381 | int chunks) | ||
382 | { | ||
383 | ary->wc_discrim = xdr_one; | ||
384 | ary->wc_nchunks = htonl(chunks); | ||
385 | } | ||
386 | |||
387 | void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary, | ||
388 | int chunk_no, | ||
389 | u32 rs_handle, u64 rs_offset, | ||
390 | u32 write_len) | ||
391 | { | ||
392 | struct rpcrdma_segment *seg = &ary->wc_array[chunk_no].wc_target; | ||
393 | seg->rs_handle = htonl(rs_handle); | ||
394 | seg->rs_length = htonl(write_len); | ||
395 | xdr_encode_hyper((u32 *) &seg->rs_offset, rs_offset); | ||
396 | } | ||
397 | |||
398 | void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt, | ||
399 | struct rpcrdma_msg *rdma_argp, | ||
400 | struct rpcrdma_msg *rdma_resp, | ||
401 | enum rpcrdma_proc rdma_type) | ||
402 | { | ||
403 | rdma_resp->rm_xid = htonl(rdma_argp->rm_xid); | ||
404 | rdma_resp->rm_vers = htonl(rdma_argp->rm_vers); | ||
405 | rdma_resp->rm_credit = htonl(xprt->sc_max_requests); | ||
406 | rdma_resp->rm_type = htonl(rdma_type); | ||
407 | |||
408 | /* Encode <nul> chunks lists */ | ||
409 | rdma_resp->rm_body.rm_chunks[0] = xdr_zero; | ||
410 | rdma_resp->rm_body.rm_chunks[1] = xdr_zero; | ||
411 | rdma_resp->rm_body.rm_chunks[2] = xdr_zero; | ||
412 | } | ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c new file mode 100644 index 000000000000..ab54a736486e --- /dev/null +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | |||
@@ -0,0 +1,586 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the BSD-type | ||
8 | * license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * | ||
17 | * Redistributions in binary form must reproduce the above | ||
18 | * copyright notice, this list of conditions and the following | ||
19 | * disclaimer in the documentation and/or other materials provided | ||
20 | * with the distribution. | ||
21 | * | ||
22 | * Neither the name of the Network Appliance, Inc. nor the names of | ||
23 | * its contributors may be used to endorse or promote products | ||
24 | * derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
30 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
31 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
32 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
33 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | * | ||
39 | * Author: Tom Tucker <tom@opengridcomputing.com> | ||
40 | */ | ||
41 | |||
42 | #include <linux/sunrpc/debug.h> | ||
43 | #include <linux/sunrpc/rpc_rdma.h> | ||
44 | #include <linux/spinlock.h> | ||
45 | #include <asm/unaligned.h> | ||
46 | #include <rdma/ib_verbs.h> | ||
47 | #include <rdma/rdma_cm.h> | ||
48 | #include <linux/sunrpc/svc_rdma.h> | ||
49 | |||
50 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | ||
51 | |||
52 | /* | ||
53 | * Replace the pages in the rq_argpages array with the pages from the SGE in | ||
54 | * the RDMA_RECV completion. The SGL should contain full pages up until the | ||
55 | * last one. | ||
56 | */ | ||
57 | static void rdma_build_arg_xdr(struct svc_rqst *rqstp, | ||
58 | struct svc_rdma_op_ctxt *ctxt, | ||
59 | u32 byte_count) | ||
60 | { | ||
61 | struct page *page; | ||
62 | u32 bc; | ||
63 | int sge_no; | ||
64 | |||
65 | /* Swap the page in the SGE with the page in argpages */ | ||
66 | page = ctxt->pages[0]; | ||
67 | put_page(rqstp->rq_pages[0]); | ||
68 | rqstp->rq_pages[0] = page; | ||
69 | |||
70 | /* Set up the XDR head */ | ||
71 | rqstp->rq_arg.head[0].iov_base = page_address(page); | ||
72 | rqstp->rq_arg.head[0].iov_len = min(byte_count, ctxt->sge[0].length); | ||
73 | rqstp->rq_arg.len = byte_count; | ||
74 | rqstp->rq_arg.buflen = byte_count; | ||
75 | |||
76 | /* Compute bytes past head in the SGL */ | ||
77 | bc = byte_count - rqstp->rq_arg.head[0].iov_len; | ||
78 | |||
79 | /* If data remains, store it in the pagelist */ | ||
80 | rqstp->rq_arg.page_len = bc; | ||
81 | rqstp->rq_arg.page_base = 0; | ||
82 | rqstp->rq_arg.pages = &rqstp->rq_pages[1]; | ||
83 | sge_no = 1; | ||
84 | while (bc && sge_no < ctxt->count) { | ||
85 | page = ctxt->pages[sge_no]; | ||
86 | put_page(rqstp->rq_pages[sge_no]); | ||
87 | rqstp->rq_pages[sge_no] = page; | ||
88 | bc -= min(bc, ctxt->sge[sge_no].length); | ||
89 | rqstp->rq_arg.buflen += ctxt->sge[sge_no].length; | ||
90 | sge_no++; | ||
91 | } | ||
92 | rqstp->rq_respages = &rqstp->rq_pages[sge_no]; | ||
93 | |||
94 | /* We should never run out of SGE because the limit is defined to | ||
95 | * support the max allowed RPC data length | ||
96 | */ | ||
97 | BUG_ON(bc && (sge_no == ctxt->count)); | ||
98 | BUG_ON((rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len) | ||
99 | != byte_count); | ||
100 | BUG_ON(rqstp->rq_arg.len != byte_count); | ||
101 | |||
102 | /* If not all pages were used from the SGL, free the remaining ones */ | ||
103 | bc = sge_no; | ||
104 | while (sge_no < ctxt->count) { | ||
105 | page = ctxt->pages[sge_no++]; | ||
106 | put_page(page); | ||
107 | } | ||
108 | ctxt->count = bc; | ||
109 | |||
110 | /* Set up tail */ | ||
111 | rqstp->rq_arg.tail[0].iov_base = NULL; | ||
112 | rqstp->rq_arg.tail[0].iov_len = 0; | ||
113 | } | ||
114 | |||
115 | struct chunk_sge { | ||
116 | int start; /* sge no for this chunk */ | ||
117 | int count; /* sge count for this chunk */ | ||
118 | }; | ||
119 | |||
120 | /* Encode a read-chunk-list as an array of IB SGE | ||
121 | * | ||
122 | * Assumptions: | ||
123 | * - chunk[0]->position points to pages[0] at an offset of 0 | ||
124 | * - pages[] is not physically or virtually contigous and consists of | ||
125 | * PAGE_SIZE elements. | ||
126 | * | ||
127 | * Output: | ||
128 | * - sge array pointing into pages[] array. | ||
129 | * - chunk_sge array specifying sge index and count for each | ||
130 | * chunk in the read list | ||
131 | * | ||
132 | */ | ||
133 | static int rdma_rcl_to_sge(struct svcxprt_rdma *xprt, | ||
134 | struct svc_rqst *rqstp, | ||
135 | struct svc_rdma_op_ctxt *head, | ||
136 | struct rpcrdma_msg *rmsgp, | ||
137 | struct ib_sge *sge, | ||
138 | struct chunk_sge *ch_sge_ary, | ||
139 | int ch_count, | ||
140 | int byte_count) | ||
141 | { | ||
142 | int sge_no; | ||
143 | int sge_bytes; | ||
144 | int page_off; | ||
145 | int page_no; | ||
146 | int ch_bytes; | ||
147 | int ch_no; | ||
148 | struct rpcrdma_read_chunk *ch; | ||
149 | |||
150 | sge_no = 0; | ||
151 | page_no = 0; | ||
152 | page_off = 0; | ||
153 | ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; | ||
154 | ch_no = 0; | ||
155 | ch_bytes = ch->rc_target.rs_length; | ||
156 | head->arg.head[0] = rqstp->rq_arg.head[0]; | ||
157 | head->arg.tail[0] = rqstp->rq_arg.tail[0]; | ||
158 | head->arg.pages = &head->pages[head->count]; | ||
159 | head->sge[0].length = head->count; /* save count of hdr pages */ | ||
160 | head->arg.page_base = 0; | ||
161 | head->arg.page_len = ch_bytes; | ||
162 | head->arg.len = rqstp->rq_arg.len + ch_bytes; | ||
163 | head->arg.buflen = rqstp->rq_arg.buflen + ch_bytes; | ||
164 | head->count++; | ||
165 | ch_sge_ary[0].start = 0; | ||
166 | while (byte_count) { | ||
167 | sge_bytes = min_t(int, PAGE_SIZE-page_off, ch_bytes); | ||
168 | sge[sge_no].addr = | ||
169 | ib_dma_map_page(xprt->sc_cm_id->device, | ||
170 | rqstp->rq_arg.pages[page_no], | ||
171 | page_off, sge_bytes, | ||
172 | DMA_FROM_DEVICE); | ||
173 | sge[sge_no].length = sge_bytes; | ||
174 | sge[sge_no].lkey = xprt->sc_phys_mr->lkey; | ||
175 | /* | ||
176 | * Don't bump head->count here because the same page | ||
177 | * may be used by multiple SGE. | ||
178 | */ | ||
179 | head->arg.pages[page_no] = rqstp->rq_arg.pages[page_no]; | ||
180 | rqstp->rq_respages = &rqstp->rq_arg.pages[page_no+1]; | ||
181 | |||
182 | byte_count -= sge_bytes; | ||
183 | ch_bytes -= sge_bytes; | ||
184 | sge_no++; | ||
185 | /* | ||
186 | * If all bytes for this chunk have been mapped to an | ||
187 | * SGE, move to the next SGE | ||
188 | */ | ||
189 | if (ch_bytes == 0) { | ||
190 | ch_sge_ary[ch_no].count = | ||
191 | sge_no - ch_sge_ary[ch_no].start; | ||
192 | ch_no++; | ||
193 | ch++; | ||
194 | ch_sge_ary[ch_no].start = sge_no; | ||
195 | ch_bytes = ch->rc_target.rs_length; | ||
196 | /* If bytes remaining account for next chunk */ | ||
197 | if (byte_count) { | ||
198 | head->arg.page_len += ch_bytes; | ||
199 | head->arg.len += ch_bytes; | ||
200 | head->arg.buflen += ch_bytes; | ||
201 | } | ||
202 | } | ||
203 | /* | ||
204 | * If this SGE consumed all of the page, move to the | ||
205 | * next page | ||
206 | */ | ||
207 | if ((sge_bytes + page_off) == PAGE_SIZE) { | ||
208 | page_no++; | ||
209 | page_off = 0; | ||
210 | /* | ||
211 | * If there are still bytes left to map, bump | ||
212 | * the page count | ||
213 | */ | ||
214 | if (byte_count) | ||
215 | head->count++; | ||
216 | } else | ||
217 | page_off += sge_bytes; | ||
218 | } | ||
219 | BUG_ON(byte_count != 0); | ||
220 | return sge_no; | ||
221 | } | ||
222 | |||
223 | static void rdma_set_ctxt_sge(struct svc_rdma_op_ctxt *ctxt, | ||
224 | struct ib_sge *sge, | ||
225 | u64 *sgl_offset, | ||
226 | int count) | ||
227 | { | ||
228 | int i; | ||
229 | |||
230 | ctxt->count = count; | ||
231 | for (i = 0; i < count; i++) { | ||
232 | ctxt->sge[i].addr = sge[i].addr; | ||
233 | ctxt->sge[i].length = sge[i].length; | ||
234 | *sgl_offset = *sgl_offset + sge[i].length; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count) | ||
239 | { | ||
240 | #ifdef RDMA_TRANSPORT_IWARP | ||
241 | if ((RDMA_TRANSPORT_IWARP == | ||
242 | rdma_node_get_transport(xprt->sc_cm_id-> | ||
243 | device->node_type)) | ||
244 | && sge_count > 1) | ||
245 | return 1; | ||
246 | else | ||
247 | #endif | ||
248 | return min_t(int, sge_count, xprt->sc_max_sge); | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Use RDMA_READ to read data from the advertised client buffer into the | ||
253 | * XDR stream starting at rq_arg.head[0].iov_base. | ||
254 | * Each chunk in the array | ||
255 | * contains the following fields: | ||
256 | * discrim - '1', This isn't used for data placement | ||
257 | * position - The xdr stream offset (the same for every chunk) | ||
258 | * handle - RMR for client memory region | ||
259 | * length - data transfer length | ||
260 | * offset - 64 bit tagged offset in remote memory region | ||
261 | * | ||
262 | * On our side, we need to read into a pagelist. The first page immediately | ||
263 | * follows the RPC header. | ||
264 | * | ||
265 | * This function returns 1 to indicate success. The data is not yet in | ||
266 | * the pagelist and therefore the RPC request must be deferred. The | ||
267 | * I/O completion will enqueue the transport again and | ||
268 | * svc_rdma_recvfrom will complete the request. | ||
269 | * | ||
270 | * NOTE: The ctxt must not be touched after the last WR has been posted | ||
271 | * because the I/O completion processing may occur on another | ||
272 | * processor and free / modify the context. Ne touche pas! | ||
273 | */ | ||
274 | static int rdma_read_xdr(struct svcxprt_rdma *xprt, | ||
275 | struct rpcrdma_msg *rmsgp, | ||
276 | struct svc_rqst *rqstp, | ||
277 | struct svc_rdma_op_ctxt *hdr_ctxt) | ||
278 | { | ||
279 | struct ib_send_wr read_wr; | ||
280 | int err = 0; | ||
281 | int ch_no; | ||
282 | struct ib_sge *sge; | ||
283 | int ch_count; | ||
284 | int byte_count; | ||
285 | int sge_count; | ||
286 | u64 sgl_offset; | ||
287 | struct rpcrdma_read_chunk *ch; | ||
288 | struct svc_rdma_op_ctxt *ctxt = NULL; | ||
289 | struct svc_rdma_op_ctxt *head; | ||
290 | struct svc_rdma_op_ctxt *tmp_sge_ctxt; | ||
291 | struct svc_rdma_op_ctxt *tmp_ch_ctxt; | ||
292 | struct chunk_sge *ch_sge_ary; | ||
293 | |||
294 | /* If no read list is present, return 0 */ | ||
295 | ch = svc_rdma_get_read_chunk(rmsgp); | ||
296 | if (!ch) | ||
297 | return 0; | ||
298 | |||
299 | /* Allocate temporary contexts to keep SGE */ | ||
300 | BUG_ON(sizeof(struct ib_sge) < sizeof(struct chunk_sge)); | ||
301 | tmp_sge_ctxt = svc_rdma_get_context(xprt); | ||
302 | sge = tmp_sge_ctxt->sge; | ||
303 | tmp_ch_ctxt = svc_rdma_get_context(xprt); | ||
304 | ch_sge_ary = (struct chunk_sge *)tmp_ch_ctxt->sge; | ||
305 | |||
306 | svc_rdma_rcl_chunk_counts(ch, &ch_count, &byte_count); | ||
307 | sge_count = rdma_rcl_to_sge(xprt, rqstp, hdr_ctxt, rmsgp, | ||
308 | sge, ch_sge_ary, | ||
309 | ch_count, byte_count); | ||
310 | head = svc_rdma_get_context(xprt); | ||
311 | sgl_offset = 0; | ||
312 | ch_no = 0; | ||
313 | |||
314 | for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; | ||
315 | ch->rc_discrim != 0; ch++, ch_no++) { | ||
316 | next_sge: | ||
317 | if (!ctxt) | ||
318 | ctxt = head; | ||
319 | else { | ||
320 | ctxt->next = svc_rdma_get_context(xprt); | ||
321 | ctxt = ctxt->next; | ||
322 | } | ||
323 | ctxt->next = NULL; | ||
324 | ctxt->direction = DMA_FROM_DEVICE; | ||
325 | clear_bit(RDMACTXT_F_READ_DONE, &ctxt->flags); | ||
326 | clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); | ||
327 | if ((ch+1)->rc_discrim == 0) { | ||
328 | /* | ||
329 | * Checked in sq_cq_reap to see if we need to | ||
330 | * be enqueued | ||
331 | */ | ||
332 | set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); | ||
333 | ctxt->next = hdr_ctxt; | ||
334 | hdr_ctxt->next = head; | ||
335 | } | ||
336 | |||
337 | /* Prepare READ WR */ | ||
338 | memset(&read_wr, 0, sizeof read_wr); | ||
339 | ctxt->wr_op = IB_WR_RDMA_READ; | ||
340 | read_wr.wr_id = (unsigned long)ctxt; | ||
341 | read_wr.opcode = IB_WR_RDMA_READ; | ||
342 | read_wr.send_flags = IB_SEND_SIGNALED; | ||
343 | read_wr.wr.rdma.rkey = ch->rc_target.rs_handle; | ||
344 | read_wr.wr.rdma.remote_addr = | ||
345 | get_unaligned(&(ch->rc_target.rs_offset)) + | ||
346 | sgl_offset; | ||
347 | read_wr.sg_list = &sge[ch_sge_ary[ch_no].start]; | ||
348 | read_wr.num_sge = | ||
349 | rdma_read_max_sge(xprt, ch_sge_ary[ch_no].count); | ||
350 | rdma_set_ctxt_sge(ctxt, &sge[ch_sge_ary[ch_no].start], | ||
351 | &sgl_offset, | ||
352 | read_wr.num_sge); | ||
353 | |||
354 | /* Post the read */ | ||
355 | err = svc_rdma_send(xprt, &read_wr); | ||
356 | if (err) { | ||
357 | printk(KERN_ERR "svcrdma: Error posting send = %d\n", | ||
358 | err); | ||
359 | /* | ||
360 | * Break the circular list so free knows when | ||
361 | * to stop if the error happened to occur on | ||
362 | * the last read | ||
363 | */ | ||
364 | ctxt->next = NULL; | ||
365 | goto out; | ||
366 | } | ||
367 | atomic_inc(&rdma_stat_read); | ||
368 | |||
369 | if (read_wr.num_sge < ch_sge_ary[ch_no].count) { | ||
370 | ch_sge_ary[ch_no].count -= read_wr.num_sge; | ||
371 | ch_sge_ary[ch_no].start += read_wr.num_sge; | ||
372 | goto next_sge; | ||
373 | } | ||
374 | sgl_offset = 0; | ||
375 | err = 0; | ||
376 | } | ||
377 | |||
378 | out: | ||
379 | svc_rdma_put_context(tmp_sge_ctxt, 0); | ||
380 | svc_rdma_put_context(tmp_ch_ctxt, 0); | ||
381 | |||
382 | /* Detach arg pages. svc_recv will replenish them */ | ||
383 | for (ch_no = 0; &rqstp->rq_pages[ch_no] < rqstp->rq_respages; ch_no++) | ||
384 | rqstp->rq_pages[ch_no] = NULL; | ||
385 | |||
386 | /* | ||
387 | * Detach res pages. svc_release must see a resused count of | ||
388 | * zero or it will attempt to put them. | ||
389 | */ | ||
390 | while (rqstp->rq_resused) | ||
391 | rqstp->rq_respages[--rqstp->rq_resused] = NULL; | ||
392 | |||
393 | if (err) { | ||
394 | printk(KERN_ERR "svcrdma : RDMA_READ error = %d\n", err); | ||
395 | set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); | ||
396 | /* Free the linked list of read contexts */ | ||
397 | while (head != NULL) { | ||
398 | ctxt = head->next; | ||
399 | svc_rdma_put_context(head, 1); | ||
400 | head = ctxt; | ||
401 | } | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | return 1; | ||
406 | } | ||
407 | |||
408 | static int rdma_read_complete(struct svc_rqst *rqstp, | ||
409 | struct svc_rdma_op_ctxt *data) | ||
410 | { | ||
411 | struct svc_rdma_op_ctxt *head = data->next; | ||
412 | int page_no; | ||
413 | int ret; | ||
414 | |||
415 | BUG_ON(!head); | ||
416 | |||
417 | /* Copy RPC pages */ | ||
418 | for (page_no = 0; page_no < head->count; page_no++) { | ||
419 | put_page(rqstp->rq_pages[page_no]); | ||
420 | rqstp->rq_pages[page_no] = head->pages[page_no]; | ||
421 | } | ||
422 | /* Point rq_arg.pages past header */ | ||
423 | rqstp->rq_arg.pages = &rqstp->rq_pages[head->sge[0].length]; | ||
424 | rqstp->rq_arg.page_len = head->arg.page_len; | ||
425 | rqstp->rq_arg.page_base = head->arg.page_base; | ||
426 | |||
427 | /* rq_respages starts after the last arg page */ | ||
428 | rqstp->rq_respages = &rqstp->rq_arg.pages[page_no]; | ||
429 | rqstp->rq_resused = 0; | ||
430 | |||
431 | /* Rebuild rq_arg head and tail. */ | ||
432 | rqstp->rq_arg.head[0] = head->arg.head[0]; | ||
433 | rqstp->rq_arg.tail[0] = head->arg.tail[0]; | ||
434 | rqstp->rq_arg.len = head->arg.len; | ||
435 | rqstp->rq_arg.buflen = head->arg.buflen; | ||
436 | |||
437 | /* XXX: What should this be? */ | ||
438 | rqstp->rq_prot = IPPROTO_MAX; | ||
439 | |||
440 | /* | ||
441 | * Free the contexts we used to build the RDMA_READ. We have | ||
442 | * to be careful here because the context list uses the same | ||
443 | * next pointer used to chain the contexts associated with the | ||
444 | * RDMA_READ | ||
445 | */ | ||
446 | data->next = NULL; /* terminate circular list */ | ||
447 | do { | ||
448 | data = head->next; | ||
449 | svc_rdma_put_context(head, 0); | ||
450 | head = data; | ||
451 | } while (head != NULL); | ||
452 | |||
453 | ret = rqstp->rq_arg.head[0].iov_len | ||
454 | + rqstp->rq_arg.page_len | ||
455 | + rqstp->rq_arg.tail[0].iov_len; | ||
456 | dprintk("svcrdma: deferred read ret=%d, rq_arg.len =%d, " | ||
457 | "rq_arg.head[0].iov_base=%p, rq_arg.head[0].iov_len = %zd\n", | ||
458 | ret, rqstp->rq_arg.len, rqstp->rq_arg.head[0].iov_base, | ||
459 | rqstp->rq_arg.head[0].iov_len); | ||
460 | |||
461 | /* Indicate that we've consumed an RQ credit */ | ||
462 | rqstp->rq_xprt_ctxt = rqstp->rq_xprt; | ||
463 | svc_xprt_received(rqstp->rq_xprt); | ||
464 | return ret; | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * Set up the rqstp thread context to point to the RQ buffer. If | ||
469 | * necessary, pull additional data from the client with an RDMA_READ | ||
470 | * request. | ||
471 | */ | ||
472 | int svc_rdma_recvfrom(struct svc_rqst *rqstp) | ||
473 | { | ||
474 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
475 | struct svcxprt_rdma *rdma_xprt = | ||
476 | container_of(xprt, struct svcxprt_rdma, sc_xprt); | ||
477 | struct svc_rdma_op_ctxt *ctxt = NULL; | ||
478 | struct rpcrdma_msg *rmsgp; | ||
479 | int ret = 0; | ||
480 | int len; | ||
481 | |||
482 | dprintk("svcrdma: rqstp=%p\n", rqstp); | ||
483 | |||
484 | /* | ||
485 | * The rq_xprt_ctxt indicates if we've consumed an RQ credit | ||
486 | * or not. It is used in the rdma xpo_release_rqst function to | ||
487 | * determine whether or not to return an RQ WQE to the RQ. | ||
488 | */ | ||
489 | rqstp->rq_xprt_ctxt = NULL; | ||
490 | |||
491 | spin_lock_bh(&rdma_xprt->sc_read_complete_lock); | ||
492 | if (!list_empty(&rdma_xprt->sc_read_complete_q)) { | ||
493 | ctxt = list_entry(rdma_xprt->sc_read_complete_q.next, | ||
494 | struct svc_rdma_op_ctxt, | ||
495 | dto_q); | ||
496 | list_del_init(&ctxt->dto_q); | ||
497 | } | ||
498 | spin_unlock_bh(&rdma_xprt->sc_read_complete_lock); | ||
499 | if (ctxt) | ||
500 | return rdma_read_complete(rqstp, ctxt); | ||
501 | |||
502 | spin_lock_bh(&rdma_xprt->sc_rq_dto_lock); | ||
503 | if (!list_empty(&rdma_xprt->sc_rq_dto_q)) { | ||
504 | ctxt = list_entry(rdma_xprt->sc_rq_dto_q.next, | ||
505 | struct svc_rdma_op_ctxt, | ||
506 | dto_q); | ||
507 | list_del_init(&ctxt->dto_q); | ||
508 | } else { | ||
509 | atomic_inc(&rdma_stat_rq_starve); | ||
510 | clear_bit(XPT_DATA, &xprt->xpt_flags); | ||
511 | ctxt = NULL; | ||
512 | } | ||
513 | spin_unlock_bh(&rdma_xprt->sc_rq_dto_lock); | ||
514 | if (!ctxt) { | ||
515 | /* This is the EAGAIN path. The svc_recv routine will | ||
516 | * return -EAGAIN, the nfsd thread will go to call into | ||
517 | * svc_recv again and we shouldn't be on the active | ||
518 | * transport list | ||
519 | */ | ||
520 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) | ||
521 | goto close_out; | ||
522 | |||
523 | BUG_ON(ret); | ||
524 | goto out; | ||
525 | } | ||
526 | dprintk("svcrdma: processing ctxt=%p on xprt=%p, rqstp=%p, status=%d\n", | ||
527 | ctxt, rdma_xprt, rqstp, ctxt->wc_status); | ||
528 | BUG_ON(ctxt->wc_status != IB_WC_SUCCESS); | ||
529 | atomic_inc(&rdma_stat_recv); | ||
530 | |||
531 | /* Build up the XDR from the receive buffers. */ | ||
532 | rdma_build_arg_xdr(rqstp, ctxt, ctxt->byte_len); | ||
533 | |||
534 | /* Decode the RDMA header. */ | ||
535 | len = svc_rdma_xdr_decode_req(&rmsgp, rqstp); | ||
536 | rqstp->rq_xprt_hlen = len; | ||
537 | |||
538 | /* If the request is invalid, reply with an error */ | ||
539 | if (len < 0) { | ||
540 | if (len == -ENOSYS) | ||
541 | (void)svc_rdma_send_error(rdma_xprt, rmsgp, ERR_VERS); | ||
542 | goto close_out; | ||
543 | } | ||
544 | |||
545 | /* Read read-list data. If we would need to wait, defer | ||
546 | * it. Not that in this case, we don't return the RQ credit | ||
547 | * until after the read completes. | ||
548 | */ | ||
549 | if (rdma_read_xdr(rdma_xprt, rmsgp, rqstp, ctxt)) { | ||
550 | svc_xprt_received(xprt); | ||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | /* Indicate we've consumed an RQ credit */ | ||
555 | rqstp->rq_xprt_ctxt = rqstp->rq_xprt; | ||
556 | |||
557 | ret = rqstp->rq_arg.head[0].iov_len | ||
558 | + rqstp->rq_arg.page_len | ||
559 | + rqstp->rq_arg.tail[0].iov_len; | ||
560 | svc_rdma_put_context(ctxt, 0); | ||
561 | out: | ||
562 | dprintk("svcrdma: ret = %d, rq_arg.len =%d, " | ||
563 | "rq_arg.head[0].iov_base=%p, rq_arg.head[0].iov_len = %zd\n", | ||
564 | ret, rqstp->rq_arg.len, | ||
565 | rqstp->rq_arg.head[0].iov_base, | ||
566 | rqstp->rq_arg.head[0].iov_len); | ||
567 | rqstp->rq_prot = IPPROTO_MAX; | ||
568 | svc_xprt_copy_addrs(rqstp, xprt); | ||
569 | svc_xprt_received(xprt); | ||
570 | return ret; | ||
571 | |||
572 | close_out: | ||
573 | if (ctxt) { | ||
574 | svc_rdma_put_context(ctxt, 1); | ||
575 | /* Indicate we've consumed an RQ credit */ | ||
576 | rqstp->rq_xprt_ctxt = rqstp->rq_xprt; | ||
577 | } | ||
578 | dprintk("svcrdma: transport %p is closing\n", xprt); | ||
579 | /* | ||
580 | * Set the close bit and enqueue it. svc_recv will see the | ||
581 | * close bit and call svc_xprt_delete | ||
582 | */ | ||
583 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
584 | svc_xprt_received(xprt); | ||
585 | return 0; | ||
586 | } | ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c new file mode 100644 index 000000000000..3e321949e1dc --- /dev/null +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c | |||
@@ -0,0 +1,520 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the BSD-type | ||
8 | * license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * | ||
17 | * Redistributions in binary form must reproduce the above | ||
18 | * copyright notice, this list of conditions and the following | ||
19 | * disclaimer in the documentation and/or other materials provided | ||
20 | * with the distribution. | ||
21 | * | ||
22 | * Neither the name of the Network Appliance, Inc. nor the names of | ||
23 | * its contributors may be used to endorse or promote products | ||
24 | * derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
30 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
31 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
32 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
33 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | * | ||
39 | * Author: Tom Tucker <tom@opengridcomputing.com> | ||
40 | */ | ||
41 | |||
42 | #include <linux/sunrpc/debug.h> | ||
43 | #include <linux/sunrpc/rpc_rdma.h> | ||
44 | #include <linux/spinlock.h> | ||
45 | #include <asm/unaligned.h> | ||
46 | #include <rdma/ib_verbs.h> | ||
47 | #include <rdma/rdma_cm.h> | ||
48 | #include <linux/sunrpc/svc_rdma.h> | ||
49 | |||
50 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | ||
51 | |||
52 | /* Encode an XDR as an array of IB SGE | ||
53 | * | ||
54 | * Assumptions: | ||
55 | * - head[0] is physically contiguous. | ||
56 | * - tail[0] is physically contiguous. | ||
57 | * - pages[] is not physically or virtually contigous and consists of | ||
58 | * PAGE_SIZE elements. | ||
59 | * | ||
60 | * Output: | ||
61 | * SGE[0] reserved for RCPRDMA header | ||
62 | * SGE[1] data from xdr->head[] | ||
63 | * SGE[2..sge_count-2] data from xdr->pages[] | ||
64 | * SGE[sge_count-1] data from xdr->tail. | ||
65 | * | ||
66 | */ | ||
67 | static struct ib_sge *xdr_to_sge(struct svcxprt_rdma *xprt, | ||
68 | struct xdr_buf *xdr, | ||
69 | struct ib_sge *sge, | ||
70 | int *sge_count) | ||
71 | { | ||
72 | /* Max we need is the length of the XDR / pagesize + one for | ||
73 | * head + one for tail + one for RPCRDMA header | ||
74 | */ | ||
75 | int sge_max = (xdr->len+PAGE_SIZE-1) / PAGE_SIZE + 3; | ||
76 | int sge_no; | ||
77 | u32 byte_count = xdr->len; | ||
78 | u32 sge_bytes; | ||
79 | u32 page_bytes; | ||
80 | int page_off; | ||
81 | int page_no; | ||
82 | |||
83 | /* Skip the first sge, this is for the RPCRDMA header */ | ||
84 | sge_no = 1; | ||
85 | |||
86 | /* Head SGE */ | ||
87 | sge[sge_no].addr = ib_dma_map_single(xprt->sc_cm_id->device, | ||
88 | xdr->head[0].iov_base, | ||
89 | xdr->head[0].iov_len, | ||
90 | DMA_TO_DEVICE); | ||
91 | sge_bytes = min_t(u32, byte_count, xdr->head[0].iov_len); | ||
92 | byte_count -= sge_bytes; | ||
93 | sge[sge_no].length = sge_bytes; | ||
94 | sge[sge_no].lkey = xprt->sc_phys_mr->lkey; | ||
95 | sge_no++; | ||
96 | |||
97 | /* pages SGE */ | ||
98 | page_no = 0; | ||
99 | page_bytes = xdr->page_len; | ||
100 | page_off = xdr->page_base; | ||
101 | while (byte_count && page_bytes) { | ||
102 | sge_bytes = min_t(u32, byte_count, (PAGE_SIZE-page_off)); | ||
103 | sge[sge_no].addr = | ||
104 | ib_dma_map_page(xprt->sc_cm_id->device, | ||
105 | xdr->pages[page_no], page_off, | ||
106 | sge_bytes, DMA_TO_DEVICE); | ||
107 | sge_bytes = min(sge_bytes, page_bytes); | ||
108 | byte_count -= sge_bytes; | ||
109 | page_bytes -= sge_bytes; | ||
110 | sge[sge_no].length = sge_bytes; | ||
111 | sge[sge_no].lkey = xprt->sc_phys_mr->lkey; | ||
112 | |||
113 | sge_no++; | ||
114 | page_no++; | ||
115 | page_off = 0; /* reset for next time through loop */ | ||
116 | } | ||
117 | |||
118 | /* Tail SGE */ | ||
119 | if (byte_count && xdr->tail[0].iov_len) { | ||
120 | sge[sge_no].addr = | ||
121 | ib_dma_map_single(xprt->sc_cm_id->device, | ||
122 | xdr->tail[0].iov_base, | ||
123 | xdr->tail[0].iov_len, | ||
124 | DMA_TO_DEVICE); | ||
125 | sge_bytes = min_t(u32, byte_count, xdr->tail[0].iov_len); | ||
126 | byte_count -= sge_bytes; | ||
127 | sge[sge_no].length = sge_bytes; | ||
128 | sge[sge_no].lkey = xprt->sc_phys_mr->lkey; | ||
129 | sge_no++; | ||
130 | } | ||
131 | |||
132 | BUG_ON(sge_no > sge_max); | ||
133 | BUG_ON(byte_count != 0); | ||
134 | |||
135 | *sge_count = sge_no; | ||
136 | return sge; | ||
137 | } | ||
138 | |||
139 | |||
140 | /* Assumptions: | ||
141 | * - The specified write_len can be represented in sc_max_sge * PAGE_SIZE | ||
142 | */ | ||
143 | static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, | ||
144 | u32 rmr, u64 to, | ||
145 | u32 xdr_off, int write_len, | ||
146 | struct ib_sge *xdr_sge, int sge_count) | ||
147 | { | ||
148 | struct svc_rdma_op_ctxt *tmp_sge_ctxt; | ||
149 | struct ib_send_wr write_wr; | ||
150 | struct ib_sge *sge; | ||
151 | int xdr_sge_no; | ||
152 | int sge_no; | ||
153 | int sge_bytes; | ||
154 | int sge_off; | ||
155 | int bc; | ||
156 | struct svc_rdma_op_ctxt *ctxt; | ||
157 | int ret = 0; | ||
158 | |||
159 | BUG_ON(sge_count >= 32); | ||
160 | dprintk("svcrdma: RDMA_WRITE rmr=%x, to=%llx, xdr_off=%d, " | ||
161 | "write_len=%d, xdr_sge=%p, sge_count=%d\n", | ||
162 | rmr, to, xdr_off, write_len, xdr_sge, sge_count); | ||
163 | |||
164 | ctxt = svc_rdma_get_context(xprt); | ||
165 | ctxt->count = 0; | ||
166 | tmp_sge_ctxt = svc_rdma_get_context(xprt); | ||
167 | sge = tmp_sge_ctxt->sge; | ||
168 | |||
169 | /* Find the SGE associated with xdr_off */ | ||
170 | for (bc = xdr_off, xdr_sge_no = 1; bc && xdr_sge_no < sge_count; | ||
171 | xdr_sge_no++) { | ||
172 | if (xdr_sge[xdr_sge_no].length > bc) | ||
173 | break; | ||
174 | bc -= xdr_sge[xdr_sge_no].length; | ||
175 | } | ||
176 | |||
177 | sge_off = bc; | ||
178 | bc = write_len; | ||
179 | sge_no = 0; | ||
180 | |||
181 | /* Copy the remaining SGE */ | ||
182 | while (bc != 0 && xdr_sge_no < sge_count) { | ||
183 | sge[sge_no].addr = xdr_sge[xdr_sge_no].addr + sge_off; | ||
184 | sge[sge_no].lkey = xdr_sge[xdr_sge_no].lkey; | ||
185 | sge_bytes = min((size_t)bc, | ||
186 | (size_t)(xdr_sge[xdr_sge_no].length-sge_off)); | ||
187 | sge[sge_no].length = sge_bytes; | ||
188 | |||
189 | sge_off = 0; | ||
190 | sge_no++; | ||
191 | xdr_sge_no++; | ||
192 | bc -= sge_bytes; | ||
193 | } | ||
194 | |||
195 | BUG_ON(bc != 0); | ||
196 | BUG_ON(xdr_sge_no > sge_count); | ||
197 | |||
198 | /* Prepare WRITE WR */ | ||
199 | memset(&write_wr, 0, sizeof write_wr); | ||
200 | ctxt->wr_op = IB_WR_RDMA_WRITE; | ||
201 | write_wr.wr_id = (unsigned long)ctxt; | ||
202 | write_wr.sg_list = &sge[0]; | ||
203 | write_wr.num_sge = sge_no; | ||
204 | write_wr.opcode = IB_WR_RDMA_WRITE; | ||
205 | write_wr.send_flags = IB_SEND_SIGNALED; | ||
206 | write_wr.wr.rdma.rkey = rmr; | ||
207 | write_wr.wr.rdma.remote_addr = to; | ||
208 | |||
209 | /* Post It */ | ||
210 | atomic_inc(&rdma_stat_write); | ||
211 | if (svc_rdma_send(xprt, &write_wr)) { | ||
212 | svc_rdma_put_context(ctxt, 1); | ||
213 | /* Fatal error, close transport */ | ||
214 | ret = -EIO; | ||
215 | } | ||
216 | svc_rdma_put_context(tmp_sge_ctxt, 0); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | static int send_write_chunks(struct svcxprt_rdma *xprt, | ||
221 | struct rpcrdma_msg *rdma_argp, | ||
222 | struct rpcrdma_msg *rdma_resp, | ||
223 | struct svc_rqst *rqstp, | ||
224 | struct ib_sge *sge, | ||
225 | int sge_count) | ||
226 | { | ||
227 | u32 xfer_len = rqstp->rq_res.page_len + rqstp->rq_res.tail[0].iov_len; | ||
228 | int write_len; | ||
229 | int max_write; | ||
230 | u32 xdr_off; | ||
231 | int chunk_off; | ||
232 | int chunk_no; | ||
233 | struct rpcrdma_write_array *arg_ary; | ||
234 | struct rpcrdma_write_array *res_ary; | ||
235 | int ret; | ||
236 | |||
237 | arg_ary = svc_rdma_get_write_array(rdma_argp); | ||
238 | if (!arg_ary) | ||
239 | return 0; | ||
240 | res_ary = (struct rpcrdma_write_array *) | ||
241 | &rdma_resp->rm_body.rm_chunks[1]; | ||
242 | |||
243 | max_write = xprt->sc_max_sge * PAGE_SIZE; | ||
244 | |||
245 | /* Write chunks start at the pagelist */ | ||
246 | for (xdr_off = rqstp->rq_res.head[0].iov_len, chunk_no = 0; | ||
247 | xfer_len && chunk_no < arg_ary->wc_nchunks; | ||
248 | chunk_no++) { | ||
249 | struct rpcrdma_segment *arg_ch; | ||
250 | u64 rs_offset; | ||
251 | |||
252 | arg_ch = &arg_ary->wc_array[chunk_no].wc_target; | ||
253 | write_len = min(xfer_len, arg_ch->rs_length); | ||
254 | |||
255 | /* Prepare the response chunk given the length actually | ||
256 | * written */ | ||
257 | rs_offset = get_unaligned(&(arg_ch->rs_offset)); | ||
258 | svc_rdma_xdr_encode_array_chunk(res_ary, chunk_no, | ||
259 | arg_ch->rs_handle, | ||
260 | rs_offset, | ||
261 | write_len); | ||
262 | chunk_off = 0; | ||
263 | while (write_len) { | ||
264 | int this_write; | ||
265 | this_write = min(write_len, max_write); | ||
266 | ret = send_write(xprt, rqstp, | ||
267 | arg_ch->rs_handle, | ||
268 | rs_offset + chunk_off, | ||
269 | xdr_off, | ||
270 | this_write, | ||
271 | sge, | ||
272 | sge_count); | ||
273 | if (ret) { | ||
274 | dprintk("svcrdma: RDMA_WRITE failed, ret=%d\n", | ||
275 | ret); | ||
276 | return -EIO; | ||
277 | } | ||
278 | chunk_off += this_write; | ||
279 | xdr_off += this_write; | ||
280 | xfer_len -= this_write; | ||
281 | write_len -= this_write; | ||
282 | } | ||
283 | } | ||
284 | /* Update the req with the number of chunks actually used */ | ||
285 | svc_rdma_xdr_encode_write_list(rdma_resp, chunk_no); | ||
286 | |||
287 | return rqstp->rq_res.page_len + rqstp->rq_res.tail[0].iov_len; | ||
288 | } | ||
289 | |||
290 | static int send_reply_chunks(struct svcxprt_rdma *xprt, | ||
291 | struct rpcrdma_msg *rdma_argp, | ||
292 | struct rpcrdma_msg *rdma_resp, | ||
293 | struct svc_rqst *rqstp, | ||
294 | struct ib_sge *sge, | ||
295 | int sge_count) | ||
296 | { | ||
297 | u32 xfer_len = rqstp->rq_res.len; | ||
298 | int write_len; | ||
299 | int max_write; | ||
300 | u32 xdr_off; | ||
301 | int chunk_no; | ||
302 | int chunk_off; | ||
303 | struct rpcrdma_segment *ch; | ||
304 | struct rpcrdma_write_array *arg_ary; | ||
305 | struct rpcrdma_write_array *res_ary; | ||
306 | int ret; | ||
307 | |||
308 | arg_ary = svc_rdma_get_reply_array(rdma_argp); | ||
309 | if (!arg_ary) | ||
310 | return 0; | ||
311 | /* XXX: need to fix when reply lists occur with read-list and or | ||
312 | * write-list */ | ||
313 | res_ary = (struct rpcrdma_write_array *) | ||
314 | &rdma_resp->rm_body.rm_chunks[2]; | ||
315 | |||
316 | max_write = xprt->sc_max_sge * PAGE_SIZE; | ||
317 | |||
318 | /* xdr offset starts at RPC message */ | ||
319 | for (xdr_off = 0, chunk_no = 0; | ||
320 | xfer_len && chunk_no < arg_ary->wc_nchunks; | ||
321 | chunk_no++) { | ||
322 | u64 rs_offset; | ||
323 | ch = &arg_ary->wc_array[chunk_no].wc_target; | ||
324 | write_len = min(xfer_len, ch->rs_length); | ||
325 | |||
326 | |||
327 | /* Prepare the reply chunk given the length actually | ||
328 | * written */ | ||
329 | rs_offset = get_unaligned(&(ch->rs_offset)); | ||
330 | svc_rdma_xdr_encode_array_chunk(res_ary, chunk_no, | ||
331 | ch->rs_handle, rs_offset, | ||
332 | write_len); | ||
333 | chunk_off = 0; | ||
334 | while (write_len) { | ||
335 | int this_write; | ||
336 | |||
337 | this_write = min(write_len, max_write); | ||
338 | ret = send_write(xprt, rqstp, | ||
339 | ch->rs_handle, | ||
340 | rs_offset + chunk_off, | ||
341 | xdr_off, | ||
342 | this_write, | ||
343 | sge, | ||
344 | sge_count); | ||
345 | if (ret) { | ||
346 | dprintk("svcrdma: RDMA_WRITE failed, ret=%d\n", | ||
347 | ret); | ||
348 | return -EIO; | ||
349 | } | ||
350 | chunk_off += this_write; | ||
351 | xdr_off += this_write; | ||
352 | xfer_len -= this_write; | ||
353 | write_len -= this_write; | ||
354 | } | ||
355 | } | ||
356 | /* Update the req with the number of chunks actually used */ | ||
357 | svc_rdma_xdr_encode_reply_array(res_ary, chunk_no); | ||
358 | |||
359 | return rqstp->rq_res.len; | ||
360 | } | ||
361 | |||
362 | /* This function prepares the portion of the RPCRDMA message to be | ||
363 | * sent in the RDMA_SEND. This function is called after data sent via | ||
364 | * RDMA has already been transmitted. There are three cases: | ||
365 | * - The RPCRDMA header, RPC header, and payload are all sent in a | ||
366 | * single RDMA_SEND. This is the "inline" case. | ||
367 | * - The RPCRDMA header and some portion of the RPC header and data | ||
368 | * are sent via this RDMA_SEND and another portion of the data is | ||
369 | * sent via RDMA. | ||
370 | * - The RPCRDMA header [NOMSG] is sent in this RDMA_SEND and the RPC | ||
371 | * header and data are all transmitted via RDMA. | ||
372 | * In all three cases, this function prepares the RPCRDMA header in | ||
373 | * sge[0], the 'type' parameter indicates the type to place in the | ||
374 | * RPCRDMA header, and the 'byte_count' field indicates how much of | ||
375 | * the XDR to include in this RDMA_SEND. | ||
376 | */ | ||
377 | static int send_reply(struct svcxprt_rdma *rdma, | ||
378 | struct svc_rqst *rqstp, | ||
379 | struct page *page, | ||
380 | struct rpcrdma_msg *rdma_resp, | ||
381 | struct svc_rdma_op_ctxt *ctxt, | ||
382 | int sge_count, | ||
383 | int byte_count) | ||
384 | { | ||
385 | struct ib_send_wr send_wr; | ||
386 | int sge_no; | ||
387 | int sge_bytes; | ||
388 | int page_no; | ||
389 | int ret; | ||
390 | |||
391 | /* Prepare the context */ | ||
392 | ctxt->pages[0] = page; | ||
393 | ctxt->count = 1; | ||
394 | |||
395 | /* Prepare the SGE for the RPCRDMA Header */ | ||
396 | ctxt->sge[0].addr = | ||
397 | ib_dma_map_page(rdma->sc_cm_id->device, | ||
398 | page, 0, PAGE_SIZE, DMA_TO_DEVICE); | ||
399 | ctxt->direction = DMA_TO_DEVICE; | ||
400 | ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp); | ||
401 | ctxt->sge[0].lkey = rdma->sc_phys_mr->lkey; | ||
402 | |||
403 | /* Determine how many of our SGE are to be transmitted */ | ||
404 | for (sge_no = 1; byte_count && sge_no < sge_count; sge_no++) { | ||
405 | sge_bytes = min((size_t)ctxt->sge[sge_no].length, | ||
406 | (size_t)byte_count); | ||
407 | byte_count -= sge_bytes; | ||
408 | } | ||
409 | BUG_ON(byte_count != 0); | ||
410 | |||
411 | /* Save all respages in the ctxt and remove them from the | ||
412 | * respages array. They are our pages until the I/O | ||
413 | * completes. | ||
414 | */ | ||
415 | for (page_no = 0; page_no < rqstp->rq_resused; page_no++) { | ||
416 | ctxt->pages[page_no+1] = rqstp->rq_respages[page_no]; | ||
417 | ctxt->count++; | ||
418 | rqstp->rq_respages[page_no] = NULL; | ||
419 | } | ||
420 | |||
421 | BUG_ON(sge_no > rdma->sc_max_sge); | ||
422 | memset(&send_wr, 0, sizeof send_wr); | ||
423 | ctxt->wr_op = IB_WR_SEND; | ||
424 | send_wr.wr_id = (unsigned long)ctxt; | ||
425 | send_wr.sg_list = ctxt->sge; | ||
426 | send_wr.num_sge = sge_no; | ||
427 | send_wr.opcode = IB_WR_SEND; | ||
428 | send_wr.send_flags = IB_SEND_SIGNALED; | ||
429 | |||
430 | ret = svc_rdma_send(rdma, &send_wr); | ||
431 | if (ret) | ||
432 | svc_rdma_put_context(ctxt, 1); | ||
433 | |||
434 | return ret; | ||
435 | } | ||
436 | |||
437 | void svc_rdma_prep_reply_hdr(struct svc_rqst *rqstp) | ||
438 | { | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * Return the start of an xdr buffer. | ||
443 | */ | ||
444 | static void *xdr_start(struct xdr_buf *xdr) | ||
445 | { | ||
446 | return xdr->head[0].iov_base - | ||
447 | (xdr->len - | ||
448 | xdr->page_len - | ||
449 | xdr->tail[0].iov_len - | ||
450 | xdr->head[0].iov_len); | ||
451 | } | ||
452 | |||
453 | int svc_rdma_sendto(struct svc_rqst *rqstp) | ||
454 | { | ||
455 | struct svc_xprt *xprt = rqstp->rq_xprt; | ||
456 | struct svcxprt_rdma *rdma = | ||
457 | container_of(xprt, struct svcxprt_rdma, sc_xprt); | ||
458 | struct rpcrdma_msg *rdma_argp; | ||
459 | struct rpcrdma_msg *rdma_resp; | ||
460 | struct rpcrdma_write_array *reply_ary; | ||
461 | enum rpcrdma_proc reply_type; | ||
462 | int ret; | ||
463 | int inline_bytes; | ||
464 | struct ib_sge *sge; | ||
465 | int sge_count = 0; | ||
466 | struct page *res_page; | ||
467 | struct svc_rdma_op_ctxt *ctxt; | ||
468 | |||
469 | dprintk("svcrdma: sending response for rqstp=%p\n", rqstp); | ||
470 | |||
471 | /* Get the RDMA request header. */ | ||
472 | rdma_argp = xdr_start(&rqstp->rq_arg); | ||
473 | |||
474 | /* Build an SGE for the XDR */ | ||
475 | ctxt = svc_rdma_get_context(rdma); | ||
476 | ctxt->direction = DMA_TO_DEVICE; | ||
477 | sge = xdr_to_sge(rdma, &rqstp->rq_res, ctxt->sge, &sge_count); | ||
478 | |||
479 | inline_bytes = rqstp->rq_res.len; | ||
480 | |||
481 | /* Create the RDMA response header */ | ||
482 | res_page = svc_rdma_get_page(); | ||
483 | rdma_resp = page_address(res_page); | ||
484 | reply_ary = svc_rdma_get_reply_array(rdma_argp); | ||
485 | if (reply_ary) | ||
486 | reply_type = RDMA_NOMSG; | ||
487 | else | ||
488 | reply_type = RDMA_MSG; | ||
489 | svc_rdma_xdr_encode_reply_header(rdma, rdma_argp, | ||
490 | rdma_resp, reply_type); | ||
491 | |||
492 | /* Send any write-chunk data and build resp write-list */ | ||
493 | ret = send_write_chunks(rdma, rdma_argp, rdma_resp, | ||
494 | rqstp, sge, sge_count); | ||
495 | if (ret < 0) { | ||
496 | printk(KERN_ERR "svcrdma: failed to send write chunks, rc=%d\n", | ||
497 | ret); | ||
498 | goto error; | ||
499 | } | ||
500 | inline_bytes -= ret; | ||
501 | |||
502 | /* Send any reply-list data and update resp reply-list */ | ||
503 | ret = send_reply_chunks(rdma, rdma_argp, rdma_resp, | ||
504 | rqstp, sge, sge_count); | ||
505 | if (ret < 0) { | ||
506 | printk(KERN_ERR "svcrdma: failed to send reply chunks, rc=%d\n", | ||
507 | ret); | ||
508 | goto error; | ||
509 | } | ||
510 | inline_bytes -= ret; | ||
511 | |||
512 | ret = send_reply(rdma, rqstp, res_page, rdma_resp, ctxt, sge_count, | ||
513 | inline_bytes); | ||
514 | dprintk("svcrdma: send_reply returns %d\n", ret); | ||
515 | return ret; | ||
516 | error: | ||
517 | svc_rdma_put_context(ctxt, 0); | ||
518 | put_page(res_page); | ||
519 | return ret; | ||
520 | } | ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c new file mode 100644 index 000000000000..f09444c451bc --- /dev/null +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -0,0 +1,1080 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2007 Network Appliance, Inc. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the BSD-type | ||
8 | * license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * | ||
17 | * Redistributions in binary form must reproduce the above | ||
18 | * copyright notice, this list of conditions and the following | ||
19 | * disclaimer in the documentation and/or other materials provided | ||
20 | * with the distribution. | ||
21 | * | ||
22 | * Neither the name of the Network Appliance, Inc. nor the names of | ||
23 | * its contributors may be used to endorse or promote products | ||
24 | * derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
30 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
31 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
32 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
33 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | * | ||
39 | * Author: Tom Tucker <tom@opengridcomputing.com> | ||
40 | */ | ||
41 | |||
42 | #include <linux/sunrpc/svc_xprt.h> | ||
43 | #include <linux/sunrpc/debug.h> | ||
44 | #include <linux/sunrpc/rpc_rdma.h> | ||
45 | #include <linux/spinlock.h> | ||
46 | #include <rdma/ib_verbs.h> | ||
47 | #include <rdma/rdma_cm.h> | ||
48 | #include <linux/sunrpc/svc_rdma.h> | ||
49 | |||
50 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | ||
51 | |||
52 | static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, | ||
53 | struct sockaddr *sa, int salen, | ||
54 | int flags); | ||
55 | static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt); | ||
56 | static void svc_rdma_release_rqst(struct svc_rqst *); | ||
57 | static void rdma_destroy_xprt(struct svcxprt_rdma *xprt); | ||
58 | static void dto_tasklet_func(unsigned long data); | ||
59 | static void svc_rdma_detach(struct svc_xprt *xprt); | ||
60 | static void svc_rdma_free(struct svc_xprt *xprt); | ||
61 | static int svc_rdma_has_wspace(struct svc_xprt *xprt); | ||
62 | static void rq_cq_reap(struct svcxprt_rdma *xprt); | ||
63 | static void sq_cq_reap(struct svcxprt_rdma *xprt); | ||
64 | |||
65 | DECLARE_TASKLET(dto_tasklet, dto_tasklet_func, 0UL); | ||
66 | static DEFINE_SPINLOCK(dto_lock); | ||
67 | static LIST_HEAD(dto_xprt_q); | ||
68 | |||
69 | static struct svc_xprt_ops svc_rdma_ops = { | ||
70 | .xpo_create = svc_rdma_create, | ||
71 | .xpo_recvfrom = svc_rdma_recvfrom, | ||
72 | .xpo_sendto = svc_rdma_sendto, | ||
73 | .xpo_release_rqst = svc_rdma_release_rqst, | ||
74 | .xpo_detach = svc_rdma_detach, | ||
75 | .xpo_free = svc_rdma_free, | ||
76 | .xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr, | ||
77 | .xpo_has_wspace = svc_rdma_has_wspace, | ||
78 | .xpo_accept = svc_rdma_accept, | ||
79 | }; | ||
80 | |||
81 | struct svc_xprt_class svc_rdma_class = { | ||
82 | .xcl_name = "rdma", | ||
83 | .xcl_owner = THIS_MODULE, | ||
84 | .xcl_ops = &svc_rdma_ops, | ||
85 | .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP, | ||
86 | }; | ||
87 | |||
88 | static int rdma_bump_context_cache(struct svcxprt_rdma *xprt) | ||
89 | { | ||
90 | int target; | ||
91 | int at_least_one = 0; | ||
92 | struct svc_rdma_op_ctxt *ctxt; | ||
93 | |||
94 | target = min(xprt->sc_ctxt_cnt + xprt->sc_ctxt_bump, | ||
95 | xprt->sc_ctxt_max); | ||
96 | |||
97 | spin_lock_bh(&xprt->sc_ctxt_lock); | ||
98 | while (xprt->sc_ctxt_cnt < target) { | ||
99 | xprt->sc_ctxt_cnt++; | ||
100 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
101 | |||
102 | ctxt = kmalloc(sizeof(*ctxt), GFP_KERNEL); | ||
103 | |||
104 | spin_lock_bh(&xprt->sc_ctxt_lock); | ||
105 | if (ctxt) { | ||
106 | at_least_one = 1; | ||
107 | ctxt->next = xprt->sc_ctxt_head; | ||
108 | xprt->sc_ctxt_head = ctxt; | ||
109 | } else { | ||
110 | /* kmalloc failed...give up for now */ | ||
111 | xprt->sc_ctxt_cnt--; | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
116 | dprintk("svcrdma: sc_ctxt_max=%d, sc_ctxt_cnt=%d\n", | ||
117 | xprt->sc_ctxt_max, xprt->sc_ctxt_cnt); | ||
118 | return at_least_one; | ||
119 | } | ||
120 | |||
121 | struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt) | ||
122 | { | ||
123 | struct svc_rdma_op_ctxt *ctxt; | ||
124 | |||
125 | while (1) { | ||
126 | spin_lock_bh(&xprt->sc_ctxt_lock); | ||
127 | if (unlikely(xprt->sc_ctxt_head == NULL)) { | ||
128 | /* Try to bump my cache. */ | ||
129 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
130 | |||
131 | if (rdma_bump_context_cache(xprt)) | ||
132 | continue; | ||
133 | |||
134 | printk(KERN_INFO "svcrdma: sleeping waiting for " | ||
135 | "context memory on xprt=%p\n", | ||
136 | xprt); | ||
137 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | ||
138 | continue; | ||
139 | } | ||
140 | ctxt = xprt->sc_ctxt_head; | ||
141 | xprt->sc_ctxt_head = ctxt->next; | ||
142 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
143 | ctxt->xprt = xprt; | ||
144 | INIT_LIST_HEAD(&ctxt->dto_q); | ||
145 | ctxt->count = 0; | ||
146 | break; | ||
147 | } | ||
148 | return ctxt; | ||
149 | } | ||
150 | |||
151 | void svc_rdma_put_context(struct svc_rdma_op_ctxt *ctxt, int free_pages) | ||
152 | { | ||
153 | struct svcxprt_rdma *xprt; | ||
154 | int i; | ||
155 | |||
156 | BUG_ON(!ctxt); | ||
157 | xprt = ctxt->xprt; | ||
158 | if (free_pages) | ||
159 | for (i = 0; i < ctxt->count; i++) | ||
160 | put_page(ctxt->pages[i]); | ||
161 | |||
162 | for (i = 0; i < ctxt->count; i++) | ||
163 | dma_unmap_single(xprt->sc_cm_id->device->dma_device, | ||
164 | ctxt->sge[i].addr, | ||
165 | ctxt->sge[i].length, | ||
166 | ctxt->direction); | ||
167 | spin_lock_bh(&xprt->sc_ctxt_lock); | ||
168 | ctxt->next = xprt->sc_ctxt_head; | ||
169 | xprt->sc_ctxt_head = ctxt; | ||
170 | spin_unlock_bh(&xprt->sc_ctxt_lock); | ||
171 | } | ||
172 | |||
173 | /* ib_cq event handler */ | ||
174 | static void cq_event_handler(struct ib_event *event, void *context) | ||
175 | { | ||
176 | struct svc_xprt *xprt = context; | ||
177 | dprintk("svcrdma: received CQ event id=%d, context=%p\n", | ||
178 | event->event, context); | ||
179 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
180 | } | ||
181 | |||
182 | /* QP event handler */ | ||
183 | static void qp_event_handler(struct ib_event *event, void *context) | ||
184 | { | ||
185 | struct svc_xprt *xprt = context; | ||
186 | |||
187 | switch (event->event) { | ||
188 | /* These are considered benign events */ | ||
189 | case IB_EVENT_PATH_MIG: | ||
190 | case IB_EVENT_COMM_EST: | ||
191 | case IB_EVENT_SQ_DRAINED: | ||
192 | case IB_EVENT_QP_LAST_WQE_REACHED: | ||
193 | dprintk("svcrdma: QP event %d received for QP=%p\n", | ||
194 | event->event, event->element.qp); | ||
195 | break; | ||
196 | /* These are considered fatal events */ | ||
197 | case IB_EVENT_PATH_MIG_ERR: | ||
198 | case IB_EVENT_QP_FATAL: | ||
199 | case IB_EVENT_QP_REQ_ERR: | ||
200 | case IB_EVENT_QP_ACCESS_ERR: | ||
201 | case IB_EVENT_DEVICE_FATAL: | ||
202 | default: | ||
203 | dprintk("svcrdma: QP ERROR event %d received for QP=%p, " | ||
204 | "closing transport\n", | ||
205 | event->event, event->element.qp); | ||
206 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
207 | break; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Data Transfer Operation Tasklet | ||
213 | * | ||
214 | * Walks a list of transports with I/O pending, removing entries as | ||
215 | * they are added to the server's I/O pending list. Two bits indicate | ||
216 | * if SQ, RQ, or both have I/O pending. The dto_lock is an irqsave | ||
217 | * spinlock that serializes access to the transport list with the RQ | ||
218 | * and SQ interrupt handlers. | ||
219 | */ | ||
220 | static void dto_tasklet_func(unsigned long data) | ||
221 | { | ||
222 | struct svcxprt_rdma *xprt; | ||
223 | unsigned long flags; | ||
224 | |||
225 | spin_lock_irqsave(&dto_lock, flags); | ||
226 | while (!list_empty(&dto_xprt_q)) { | ||
227 | xprt = list_entry(dto_xprt_q.next, | ||
228 | struct svcxprt_rdma, sc_dto_q); | ||
229 | list_del_init(&xprt->sc_dto_q); | ||
230 | spin_unlock_irqrestore(&dto_lock, flags); | ||
231 | |||
232 | if (test_and_clear_bit(RDMAXPRT_RQ_PENDING, &xprt->sc_flags)) { | ||
233 | ib_req_notify_cq(xprt->sc_rq_cq, IB_CQ_NEXT_COMP); | ||
234 | rq_cq_reap(xprt); | ||
235 | set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags); | ||
236 | /* | ||
237 | * If data arrived before established event, | ||
238 | * don't enqueue. This defers RPC I/O until the | ||
239 | * RDMA connection is complete. | ||
240 | */ | ||
241 | if (!test_bit(RDMAXPRT_CONN_PENDING, &xprt->sc_flags)) | ||
242 | svc_xprt_enqueue(&xprt->sc_xprt); | ||
243 | } | ||
244 | |||
245 | if (test_and_clear_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags)) { | ||
246 | ib_req_notify_cq(xprt->sc_sq_cq, IB_CQ_NEXT_COMP); | ||
247 | sq_cq_reap(xprt); | ||
248 | } | ||
249 | |||
250 | spin_lock_irqsave(&dto_lock, flags); | ||
251 | } | ||
252 | spin_unlock_irqrestore(&dto_lock, flags); | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * Receive Queue Completion Handler | ||
257 | * | ||
258 | * Since an RQ completion handler is called on interrupt context, we | ||
259 | * need to defer the handling of the I/O to a tasklet | ||
260 | */ | ||
261 | static void rq_comp_handler(struct ib_cq *cq, void *cq_context) | ||
262 | { | ||
263 | struct svcxprt_rdma *xprt = cq_context; | ||
264 | unsigned long flags; | ||
265 | |||
266 | /* | ||
267 | * Set the bit regardless of whether or not it's on the list | ||
268 | * because it may be on the list already due to an SQ | ||
269 | * completion. | ||
270 | */ | ||
271 | set_bit(RDMAXPRT_RQ_PENDING, &xprt->sc_flags); | ||
272 | |||
273 | /* | ||
274 | * If this transport is not already on the DTO transport queue, | ||
275 | * add it | ||
276 | */ | ||
277 | spin_lock_irqsave(&dto_lock, flags); | ||
278 | if (list_empty(&xprt->sc_dto_q)) | ||
279 | list_add_tail(&xprt->sc_dto_q, &dto_xprt_q); | ||
280 | spin_unlock_irqrestore(&dto_lock, flags); | ||
281 | |||
282 | /* Tasklet does all the work to avoid irqsave locks. */ | ||
283 | tasklet_schedule(&dto_tasklet); | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | * rq_cq_reap - Process the RQ CQ. | ||
288 | * | ||
289 | * Take all completing WC off the CQE and enqueue the associated DTO | ||
290 | * context on the dto_q for the transport. | ||
291 | */ | ||
292 | static void rq_cq_reap(struct svcxprt_rdma *xprt) | ||
293 | { | ||
294 | int ret; | ||
295 | struct ib_wc wc; | ||
296 | struct svc_rdma_op_ctxt *ctxt = NULL; | ||
297 | |||
298 | atomic_inc(&rdma_stat_rq_poll); | ||
299 | |||
300 | spin_lock_bh(&xprt->sc_rq_dto_lock); | ||
301 | while ((ret = ib_poll_cq(xprt->sc_rq_cq, 1, &wc)) > 0) { | ||
302 | ctxt = (struct svc_rdma_op_ctxt *)(unsigned long)wc.wr_id; | ||
303 | ctxt->wc_status = wc.status; | ||
304 | ctxt->byte_len = wc.byte_len; | ||
305 | if (wc.status != IB_WC_SUCCESS) { | ||
306 | /* Close the transport */ | ||
307 | set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); | ||
308 | svc_rdma_put_context(ctxt, 1); | ||
309 | continue; | ||
310 | } | ||
311 | list_add_tail(&ctxt->dto_q, &xprt->sc_rq_dto_q); | ||
312 | } | ||
313 | spin_unlock_bh(&xprt->sc_rq_dto_lock); | ||
314 | |||
315 | if (ctxt) | ||
316 | atomic_inc(&rdma_stat_rq_prod); | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Send Queue Completion Handler - potentially called on interrupt context. | ||
321 | */ | ||
322 | static void sq_cq_reap(struct svcxprt_rdma *xprt) | ||
323 | { | ||
324 | struct svc_rdma_op_ctxt *ctxt = NULL; | ||
325 | struct ib_wc wc; | ||
326 | struct ib_cq *cq = xprt->sc_sq_cq; | ||
327 | int ret; | ||
328 | |||
329 | atomic_inc(&rdma_stat_sq_poll); | ||
330 | while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) { | ||
331 | ctxt = (struct svc_rdma_op_ctxt *)(unsigned long)wc.wr_id; | ||
332 | xprt = ctxt->xprt; | ||
333 | |||
334 | if (wc.status != IB_WC_SUCCESS) | ||
335 | /* Close the transport */ | ||
336 | set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); | ||
337 | |||
338 | /* Decrement used SQ WR count */ | ||
339 | atomic_dec(&xprt->sc_sq_count); | ||
340 | wake_up(&xprt->sc_send_wait); | ||
341 | |||
342 | switch (ctxt->wr_op) { | ||
343 | case IB_WR_SEND: | ||
344 | case IB_WR_RDMA_WRITE: | ||
345 | svc_rdma_put_context(ctxt, 1); | ||
346 | break; | ||
347 | |||
348 | case IB_WR_RDMA_READ: | ||
349 | if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) { | ||
350 | set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags); | ||
351 | set_bit(RDMACTXT_F_READ_DONE, &ctxt->flags); | ||
352 | spin_lock_bh(&xprt->sc_read_complete_lock); | ||
353 | list_add_tail(&ctxt->dto_q, | ||
354 | &xprt->sc_read_complete_q); | ||
355 | spin_unlock_bh(&xprt->sc_read_complete_lock); | ||
356 | svc_xprt_enqueue(&xprt->sc_xprt); | ||
357 | } | ||
358 | break; | ||
359 | |||
360 | default: | ||
361 | printk(KERN_ERR "svcrdma: unexpected completion type, " | ||
362 | "opcode=%d, status=%d\n", | ||
363 | wc.opcode, wc.status); | ||
364 | break; | ||
365 | } | ||
366 | } | ||
367 | |||
368 | if (ctxt) | ||
369 | atomic_inc(&rdma_stat_sq_prod); | ||
370 | } | ||
371 | |||
372 | static void sq_comp_handler(struct ib_cq *cq, void *cq_context) | ||
373 | { | ||
374 | struct svcxprt_rdma *xprt = cq_context; | ||
375 | unsigned long flags; | ||
376 | |||
377 | /* | ||
378 | * Set the bit regardless of whether or not it's on the list | ||
379 | * because it may be on the list already due to an RQ | ||
380 | * completion. | ||
381 | */ | ||
382 | set_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags); | ||
383 | |||
384 | /* | ||
385 | * If this transport is not already on the DTO transport queue, | ||
386 | * add it | ||
387 | */ | ||
388 | spin_lock_irqsave(&dto_lock, flags); | ||
389 | if (list_empty(&xprt->sc_dto_q)) | ||
390 | list_add_tail(&xprt->sc_dto_q, &dto_xprt_q); | ||
391 | spin_unlock_irqrestore(&dto_lock, flags); | ||
392 | |||
393 | /* Tasklet does all the work to avoid irqsave locks. */ | ||
394 | tasklet_schedule(&dto_tasklet); | ||
395 | } | ||
396 | |||
397 | static void create_context_cache(struct svcxprt_rdma *xprt, | ||
398 | int ctxt_count, int ctxt_bump, int ctxt_max) | ||
399 | { | ||
400 | struct svc_rdma_op_ctxt *ctxt; | ||
401 | int i; | ||
402 | |||
403 | xprt->sc_ctxt_max = ctxt_max; | ||
404 | xprt->sc_ctxt_bump = ctxt_bump; | ||
405 | xprt->sc_ctxt_cnt = 0; | ||
406 | xprt->sc_ctxt_head = NULL; | ||
407 | for (i = 0; i < ctxt_count; i++) { | ||
408 | ctxt = kmalloc(sizeof(*ctxt), GFP_KERNEL); | ||
409 | if (ctxt) { | ||
410 | ctxt->next = xprt->sc_ctxt_head; | ||
411 | xprt->sc_ctxt_head = ctxt; | ||
412 | xprt->sc_ctxt_cnt++; | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void destroy_context_cache(struct svc_rdma_op_ctxt *ctxt) | ||
418 | { | ||
419 | struct svc_rdma_op_ctxt *next; | ||
420 | if (!ctxt) | ||
421 | return; | ||
422 | |||
423 | do { | ||
424 | next = ctxt->next; | ||
425 | kfree(ctxt); | ||
426 | ctxt = next; | ||
427 | } while (next); | ||
428 | } | ||
429 | |||
430 | static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv, | ||
431 | int listener) | ||
432 | { | ||
433 | struct svcxprt_rdma *cma_xprt = kzalloc(sizeof *cma_xprt, GFP_KERNEL); | ||
434 | |||
435 | if (!cma_xprt) | ||
436 | return NULL; | ||
437 | svc_xprt_init(&svc_rdma_class, &cma_xprt->sc_xprt, serv); | ||
438 | INIT_LIST_HEAD(&cma_xprt->sc_accept_q); | ||
439 | INIT_LIST_HEAD(&cma_xprt->sc_dto_q); | ||
440 | INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q); | ||
441 | INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q); | ||
442 | init_waitqueue_head(&cma_xprt->sc_send_wait); | ||
443 | |||
444 | spin_lock_init(&cma_xprt->sc_lock); | ||
445 | spin_lock_init(&cma_xprt->sc_read_complete_lock); | ||
446 | spin_lock_init(&cma_xprt->sc_ctxt_lock); | ||
447 | spin_lock_init(&cma_xprt->sc_rq_dto_lock); | ||
448 | |||
449 | cma_xprt->sc_ord = svcrdma_ord; | ||
450 | |||
451 | cma_xprt->sc_max_req_size = svcrdma_max_req_size; | ||
452 | cma_xprt->sc_max_requests = svcrdma_max_requests; | ||
453 | cma_xprt->sc_sq_depth = svcrdma_max_requests * RPCRDMA_SQ_DEPTH_MULT; | ||
454 | atomic_set(&cma_xprt->sc_sq_count, 0); | ||
455 | |||
456 | if (!listener) { | ||
457 | int reqs = cma_xprt->sc_max_requests; | ||
458 | create_context_cache(cma_xprt, | ||
459 | reqs << 1, /* starting size */ | ||
460 | reqs, /* bump amount */ | ||
461 | reqs + | ||
462 | cma_xprt->sc_sq_depth + | ||
463 | RPCRDMA_MAX_THREADS + 1); /* max */ | ||
464 | if (!cma_xprt->sc_ctxt_head) { | ||
465 | kfree(cma_xprt); | ||
466 | return NULL; | ||
467 | } | ||
468 | clear_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); | ||
469 | } else | ||
470 | set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); | ||
471 | |||
472 | return cma_xprt; | ||
473 | } | ||
474 | |||
475 | struct page *svc_rdma_get_page(void) | ||
476 | { | ||
477 | struct page *page; | ||
478 | |||
479 | while ((page = alloc_page(GFP_KERNEL)) == NULL) { | ||
480 | /* If we can't get memory, wait a bit and try again */ | ||
481 | printk(KERN_INFO "svcrdma: out of memory...retrying in 1000 " | ||
482 | "jiffies.\n"); | ||
483 | schedule_timeout_uninterruptible(msecs_to_jiffies(1000)); | ||
484 | } | ||
485 | return page; | ||
486 | } | ||
487 | |||
488 | int svc_rdma_post_recv(struct svcxprt_rdma *xprt) | ||
489 | { | ||
490 | struct ib_recv_wr recv_wr, *bad_recv_wr; | ||
491 | struct svc_rdma_op_ctxt *ctxt; | ||
492 | struct page *page; | ||
493 | unsigned long pa; | ||
494 | int sge_no; | ||
495 | int buflen; | ||
496 | int ret; | ||
497 | |||
498 | ctxt = svc_rdma_get_context(xprt); | ||
499 | buflen = 0; | ||
500 | ctxt->direction = DMA_FROM_DEVICE; | ||
501 | for (sge_no = 0; buflen < xprt->sc_max_req_size; sge_no++) { | ||
502 | BUG_ON(sge_no >= xprt->sc_max_sge); | ||
503 | page = svc_rdma_get_page(); | ||
504 | ctxt->pages[sge_no] = page; | ||
505 | pa = ib_dma_map_page(xprt->sc_cm_id->device, | ||
506 | page, 0, PAGE_SIZE, | ||
507 | DMA_FROM_DEVICE); | ||
508 | ctxt->sge[sge_no].addr = pa; | ||
509 | ctxt->sge[sge_no].length = PAGE_SIZE; | ||
510 | ctxt->sge[sge_no].lkey = xprt->sc_phys_mr->lkey; | ||
511 | buflen += PAGE_SIZE; | ||
512 | } | ||
513 | ctxt->count = sge_no; | ||
514 | recv_wr.next = NULL; | ||
515 | recv_wr.sg_list = &ctxt->sge[0]; | ||
516 | recv_wr.num_sge = ctxt->count; | ||
517 | recv_wr.wr_id = (u64)(unsigned long)ctxt; | ||
518 | |||
519 | ret = ib_post_recv(xprt->sc_qp, &recv_wr, &bad_recv_wr); | ||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | /* | ||
524 | * This function handles the CONNECT_REQUEST event on a listening | ||
525 | * endpoint. It is passed the cma_id for the _new_ connection. The context in | ||
526 | * this cma_id is inherited from the listening cma_id and is the svc_xprt | ||
527 | * structure for the listening endpoint. | ||
528 | * | ||
529 | * This function creates a new xprt for the new connection and enqueues it on | ||
530 | * the accept queue for the listent xprt. When the listen thread is kicked, it | ||
531 | * will call the recvfrom method on the listen xprt which will accept the new | ||
532 | * connection. | ||
533 | */ | ||
534 | static void handle_connect_req(struct rdma_cm_id *new_cma_id) | ||
535 | { | ||
536 | struct svcxprt_rdma *listen_xprt = new_cma_id->context; | ||
537 | struct svcxprt_rdma *newxprt; | ||
538 | |||
539 | /* Create a new transport */ | ||
540 | newxprt = rdma_create_xprt(listen_xprt->sc_xprt.xpt_server, 0); | ||
541 | if (!newxprt) { | ||
542 | dprintk("svcrdma: failed to create new transport\n"); | ||
543 | return; | ||
544 | } | ||
545 | newxprt->sc_cm_id = new_cma_id; | ||
546 | new_cma_id->context = newxprt; | ||
547 | dprintk("svcrdma: Creating newxprt=%p, cm_id=%p, listenxprt=%p\n", | ||
548 | newxprt, newxprt->sc_cm_id, listen_xprt); | ||
549 | |||
550 | /* | ||
551 | * Enqueue the new transport on the accept queue of the listening | ||
552 | * transport | ||
553 | */ | ||
554 | spin_lock_bh(&listen_xprt->sc_lock); | ||
555 | list_add_tail(&newxprt->sc_accept_q, &listen_xprt->sc_accept_q); | ||
556 | spin_unlock_bh(&listen_xprt->sc_lock); | ||
557 | |||
558 | /* | ||
559 | * Can't use svc_xprt_received here because we are not on a | ||
560 | * rqstp thread | ||
561 | */ | ||
562 | set_bit(XPT_CONN, &listen_xprt->sc_xprt.xpt_flags); | ||
563 | svc_xprt_enqueue(&listen_xprt->sc_xprt); | ||
564 | } | ||
565 | |||
566 | /* | ||
567 | * Handles events generated on the listening endpoint. These events will be | ||
568 | * either be incoming connect requests or adapter removal events. | ||
569 | */ | ||
570 | static int rdma_listen_handler(struct rdma_cm_id *cma_id, | ||
571 | struct rdma_cm_event *event) | ||
572 | { | ||
573 | struct svcxprt_rdma *xprt = cma_id->context; | ||
574 | int ret = 0; | ||
575 | |||
576 | switch (event->event) { | ||
577 | case RDMA_CM_EVENT_CONNECT_REQUEST: | ||
578 | dprintk("svcrdma: Connect request on cma_id=%p, xprt = %p, " | ||
579 | "event=%d\n", cma_id, cma_id->context, event->event); | ||
580 | handle_connect_req(cma_id); | ||
581 | break; | ||
582 | |||
583 | case RDMA_CM_EVENT_ESTABLISHED: | ||
584 | /* Accept complete */ | ||
585 | dprintk("svcrdma: Connection completed on LISTEN xprt=%p, " | ||
586 | "cm_id=%p\n", xprt, cma_id); | ||
587 | break; | ||
588 | |||
589 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | ||
590 | dprintk("svcrdma: Device removal xprt=%p, cm_id=%p\n", | ||
591 | xprt, cma_id); | ||
592 | if (xprt) | ||
593 | set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); | ||
594 | break; | ||
595 | |||
596 | default: | ||
597 | dprintk("svcrdma: Unexpected event on listening endpoint %p, " | ||
598 | "event=%d\n", cma_id, event->event); | ||
599 | break; | ||
600 | } | ||
601 | |||
602 | return ret; | ||
603 | } | ||
604 | |||
605 | static int rdma_cma_handler(struct rdma_cm_id *cma_id, | ||
606 | struct rdma_cm_event *event) | ||
607 | { | ||
608 | struct svc_xprt *xprt = cma_id->context; | ||
609 | struct svcxprt_rdma *rdma = | ||
610 | container_of(xprt, struct svcxprt_rdma, sc_xprt); | ||
611 | switch (event->event) { | ||
612 | case RDMA_CM_EVENT_ESTABLISHED: | ||
613 | /* Accept complete */ | ||
614 | dprintk("svcrdma: Connection completed on DTO xprt=%p, " | ||
615 | "cm_id=%p\n", xprt, cma_id); | ||
616 | clear_bit(RDMAXPRT_CONN_PENDING, &rdma->sc_flags); | ||
617 | svc_xprt_enqueue(xprt); | ||
618 | break; | ||
619 | case RDMA_CM_EVENT_DISCONNECTED: | ||
620 | dprintk("svcrdma: Disconnect on DTO xprt=%p, cm_id=%p\n", | ||
621 | xprt, cma_id); | ||
622 | if (xprt) { | ||
623 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
624 | svc_xprt_enqueue(xprt); | ||
625 | } | ||
626 | break; | ||
627 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | ||
628 | dprintk("svcrdma: Device removal cma_id=%p, xprt = %p, " | ||
629 | "event=%d\n", cma_id, xprt, event->event); | ||
630 | if (xprt) { | ||
631 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | ||
632 | svc_xprt_enqueue(xprt); | ||
633 | } | ||
634 | break; | ||
635 | default: | ||
636 | dprintk("svcrdma: Unexpected event on DTO endpoint %p, " | ||
637 | "event=%d\n", cma_id, event->event); | ||
638 | break; | ||
639 | } | ||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | /* | ||
644 | * Create a listening RDMA service endpoint. | ||
645 | */ | ||
646 | static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, | ||
647 | struct sockaddr *sa, int salen, | ||
648 | int flags) | ||
649 | { | ||
650 | struct rdma_cm_id *listen_id; | ||
651 | struct svcxprt_rdma *cma_xprt; | ||
652 | struct svc_xprt *xprt; | ||
653 | int ret; | ||
654 | |||
655 | dprintk("svcrdma: Creating RDMA socket\n"); | ||
656 | |||
657 | cma_xprt = rdma_create_xprt(serv, 1); | ||
658 | if (!cma_xprt) | ||
659 | return ERR_PTR(ENOMEM); | ||
660 | xprt = &cma_xprt->sc_xprt; | ||
661 | |||
662 | listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP); | ||
663 | if (IS_ERR(listen_id)) { | ||
664 | rdma_destroy_xprt(cma_xprt); | ||
665 | dprintk("svcrdma: rdma_create_id failed = %ld\n", | ||
666 | PTR_ERR(listen_id)); | ||
667 | return (void *)listen_id; | ||
668 | } | ||
669 | ret = rdma_bind_addr(listen_id, sa); | ||
670 | if (ret) { | ||
671 | rdma_destroy_xprt(cma_xprt); | ||
672 | rdma_destroy_id(listen_id); | ||
673 | dprintk("svcrdma: rdma_bind_addr failed = %d\n", ret); | ||
674 | return ERR_PTR(ret); | ||
675 | } | ||
676 | cma_xprt->sc_cm_id = listen_id; | ||
677 | |||
678 | ret = rdma_listen(listen_id, RPCRDMA_LISTEN_BACKLOG); | ||
679 | if (ret) { | ||
680 | rdma_destroy_id(listen_id); | ||
681 | rdma_destroy_xprt(cma_xprt); | ||
682 | dprintk("svcrdma: rdma_listen failed = %d\n", ret); | ||
683 | } | ||
684 | |||
685 | /* | ||
686 | * We need to use the address from the cm_id in case the | ||
687 | * caller specified 0 for the port number. | ||
688 | */ | ||
689 | sa = (struct sockaddr *)&cma_xprt->sc_cm_id->route.addr.src_addr; | ||
690 | svc_xprt_set_local(&cma_xprt->sc_xprt, sa, salen); | ||
691 | |||
692 | return &cma_xprt->sc_xprt; | ||
693 | } | ||
694 | |||
695 | /* | ||
696 | * This is the xpo_recvfrom function for listening endpoints. Its | ||
697 | * purpose is to accept incoming connections. The CMA callback handler | ||
698 | * has already created a new transport and attached it to the new CMA | ||
699 | * ID. | ||
700 | * | ||
701 | * There is a queue of pending connections hung on the listening | ||
702 | * transport. This queue contains the new svc_xprt structure. This | ||
703 | * function takes svc_xprt structures off the accept_q and completes | ||
704 | * the connection. | ||
705 | */ | ||
706 | static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) | ||
707 | { | ||
708 | struct svcxprt_rdma *listen_rdma; | ||
709 | struct svcxprt_rdma *newxprt = NULL; | ||
710 | struct rdma_conn_param conn_param; | ||
711 | struct ib_qp_init_attr qp_attr; | ||
712 | struct ib_device_attr devattr; | ||
713 | struct sockaddr *sa; | ||
714 | int ret; | ||
715 | int i; | ||
716 | |||
717 | listen_rdma = container_of(xprt, struct svcxprt_rdma, sc_xprt); | ||
718 | clear_bit(XPT_CONN, &xprt->xpt_flags); | ||
719 | /* Get the next entry off the accept list */ | ||
720 | spin_lock_bh(&listen_rdma->sc_lock); | ||
721 | if (!list_empty(&listen_rdma->sc_accept_q)) { | ||
722 | newxprt = list_entry(listen_rdma->sc_accept_q.next, | ||
723 | struct svcxprt_rdma, sc_accept_q); | ||
724 | list_del_init(&newxprt->sc_accept_q); | ||
725 | } | ||
726 | if (!list_empty(&listen_rdma->sc_accept_q)) | ||
727 | set_bit(XPT_CONN, &listen_rdma->sc_xprt.xpt_flags); | ||
728 | spin_unlock_bh(&listen_rdma->sc_lock); | ||
729 | if (!newxprt) | ||
730 | return NULL; | ||
731 | |||
732 | dprintk("svcrdma: newxprt from accept queue = %p, cm_id=%p\n", | ||
733 | newxprt, newxprt->sc_cm_id); | ||
734 | |||
735 | ret = ib_query_device(newxprt->sc_cm_id->device, &devattr); | ||
736 | if (ret) { | ||
737 | dprintk("svcrdma: could not query device attributes on " | ||
738 | "device %p, rc=%d\n", newxprt->sc_cm_id->device, ret); | ||
739 | goto errout; | ||
740 | } | ||
741 | |||
742 | /* Qualify the transport resource defaults with the | ||
743 | * capabilities of this particular device */ | ||
744 | newxprt->sc_max_sge = min((size_t)devattr.max_sge, | ||
745 | (size_t)RPCSVC_MAXPAGES); | ||
746 | newxprt->sc_max_requests = min((size_t)devattr.max_qp_wr, | ||
747 | (size_t)svcrdma_max_requests); | ||
748 | newxprt->sc_sq_depth = RPCRDMA_SQ_DEPTH_MULT * newxprt->sc_max_requests; | ||
749 | |||
750 | newxprt->sc_ord = min((size_t)devattr.max_qp_rd_atom, | ||
751 | (size_t)svcrdma_ord); | ||
752 | |||
753 | newxprt->sc_pd = ib_alloc_pd(newxprt->sc_cm_id->device); | ||
754 | if (IS_ERR(newxprt->sc_pd)) { | ||
755 | dprintk("svcrdma: error creating PD for connect request\n"); | ||
756 | goto errout; | ||
757 | } | ||
758 | newxprt->sc_sq_cq = ib_create_cq(newxprt->sc_cm_id->device, | ||
759 | sq_comp_handler, | ||
760 | cq_event_handler, | ||
761 | newxprt, | ||
762 | newxprt->sc_sq_depth, | ||
763 | 0); | ||
764 | if (IS_ERR(newxprt->sc_sq_cq)) { | ||
765 | dprintk("svcrdma: error creating SQ CQ for connect request\n"); | ||
766 | goto errout; | ||
767 | } | ||
768 | newxprt->sc_rq_cq = ib_create_cq(newxprt->sc_cm_id->device, | ||
769 | rq_comp_handler, | ||
770 | cq_event_handler, | ||
771 | newxprt, | ||
772 | newxprt->sc_max_requests, | ||
773 | 0); | ||
774 | if (IS_ERR(newxprt->sc_rq_cq)) { | ||
775 | dprintk("svcrdma: error creating RQ CQ for connect request\n"); | ||
776 | goto errout; | ||
777 | } | ||
778 | |||
779 | memset(&qp_attr, 0, sizeof qp_attr); | ||
780 | qp_attr.event_handler = qp_event_handler; | ||
781 | qp_attr.qp_context = &newxprt->sc_xprt; | ||
782 | qp_attr.cap.max_send_wr = newxprt->sc_sq_depth; | ||
783 | qp_attr.cap.max_recv_wr = newxprt->sc_max_requests; | ||
784 | qp_attr.cap.max_send_sge = newxprt->sc_max_sge; | ||
785 | qp_attr.cap.max_recv_sge = newxprt->sc_max_sge; | ||
786 | qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; | ||
787 | qp_attr.qp_type = IB_QPT_RC; | ||
788 | qp_attr.send_cq = newxprt->sc_sq_cq; | ||
789 | qp_attr.recv_cq = newxprt->sc_rq_cq; | ||
790 | dprintk("svcrdma: newxprt->sc_cm_id=%p, newxprt->sc_pd=%p\n" | ||
791 | " cm_id->device=%p, sc_pd->device=%p\n" | ||
792 | " cap.max_send_wr = %d\n" | ||
793 | " cap.max_recv_wr = %d\n" | ||
794 | " cap.max_send_sge = %d\n" | ||
795 | " cap.max_recv_sge = %d\n", | ||
796 | newxprt->sc_cm_id, newxprt->sc_pd, | ||
797 | newxprt->sc_cm_id->device, newxprt->sc_pd->device, | ||
798 | qp_attr.cap.max_send_wr, | ||
799 | qp_attr.cap.max_recv_wr, | ||
800 | qp_attr.cap.max_send_sge, | ||
801 | qp_attr.cap.max_recv_sge); | ||
802 | |||
803 | ret = rdma_create_qp(newxprt->sc_cm_id, newxprt->sc_pd, &qp_attr); | ||
804 | if (ret) { | ||
805 | /* | ||
806 | * XXX: This is a hack. We need a xx_request_qp interface | ||
807 | * that will adjust the qp_attr's with a best-effort | ||
808 | * number | ||
809 | */ | ||
810 | qp_attr.cap.max_send_sge -= 2; | ||
811 | qp_attr.cap.max_recv_sge -= 2; | ||
812 | ret = rdma_create_qp(newxprt->sc_cm_id, newxprt->sc_pd, | ||
813 | &qp_attr); | ||
814 | if (ret) { | ||
815 | dprintk("svcrdma: failed to create QP, ret=%d\n", ret); | ||
816 | goto errout; | ||
817 | } | ||
818 | newxprt->sc_max_sge = qp_attr.cap.max_send_sge; | ||
819 | newxprt->sc_max_sge = qp_attr.cap.max_recv_sge; | ||
820 | newxprt->sc_sq_depth = qp_attr.cap.max_send_wr; | ||
821 | newxprt->sc_max_requests = qp_attr.cap.max_recv_wr; | ||
822 | } | ||
823 | newxprt->sc_qp = newxprt->sc_cm_id->qp; | ||
824 | |||
825 | /* Register all of physical memory */ | ||
826 | newxprt->sc_phys_mr = ib_get_dma_mr(newxprt->sc_pd, | ||
827 | IB_ACCESS_LOCAL_WRITE | | ||
828 | IB_ACCESS_REMOTE_WRITE); | ||
829 | if (IS_ERR(newxprt->sc_phys_mr)) { | ||
830 | dprintk("svcrdma: Failed to create DMA MR ret=%d\n", ret); | ||
831 | goto errout; | ||
832 | } | ||
833 | |||
834 | /* Post receive buffers */ | ||
835 | for (i = 0; i < newxprt->sc_max_requests; i++) { | ||
836 | ret = svc_rdma_post_recv(newxprt); | ||
837 | if (ret) { | ||
838 | dprintk("svcrdma: failure posting receive buffers\n"); | ||
839 | goto errout; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | /* Swap out the handler */ | ||
844 | newxprt->sc_cm_id->event_handler = rdma_cma_handler; | ||
845 | |||
846 | /* Accept Connection */ | ||
847 | set_bit(RDMAXPRT_CONN_PENDING, &newxprt->sc_flags); | ||
848 | memset(&conn_param, 0, sizeof conn_param); | ||
849 | conn_param.responder_resources = 0; | ||
850 | conn_param.initiator_depth = newxprt->sc_ord; | ||
851 | ret = rdma_accept(newxprt->sc_cm_id, &conn_param); | ||
852 | if (ret) { | ||
853 | dprintk("svcrdma: failed to accept new connection, ret=%d\n", | ||
854 | ret); | ||
855 | goto errout; | ||
856 | } | ||
857 | |||
858 | dprintk("svcrdma: new connection %p accepted with the following " | ||
859 | "attributes:\n" | ||
860 | " local_ip : %d.%d.%d.%d\n" | ||
861 | " local_port : %d\n" | ||
862 | " remote_ip : %d.%d.%d.%d\n" | ||
863 | " remote_port : %d\n" | ||
864 | " max_sge : %d\n" | ||
865 | " sq_depth : %d\n" | ||
866 | " max_requests : %d\n" | ||
867 | " ord : %d\n", | ||
868 | newxprt, | ||
869 | NIPQUAD(((struct sockaddr_in *)&newxprt->sc_cm_id-> | ||
870 | route.addr.src_addr)->sin_addr.s_addr), | ||
871 | ntohs(((struct sockaddr_in *)&newxprt->sc_cm_id-> | ||
872 | route.addr.src_addr)->sin_port), | ||
873 | NIPQUAD(((struct sockaddr_in *)&newxprt->sc_cm_id-> | ||
874 | route.addr.dst_addr)->sin_addr.s_addr), | ||
875 | ntohs(((struct sockaddr_in *)&newxprt->sc_cm_id-> | ||
876 | route.addr.dst_addr)->sin_port), | ||
877 | newxprt->sc_max_sge, | ||
878 | newxprt->sc_sq_depth, | ||
879 | newxprt->sc_max_requests, | ||
880 | newxprt->sc_ord); | ||
881 | |||
882 | /* Set the local and remote addresses in the transport */ | ||
883 | sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr; | ||
884 | svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa)); | ||
885 | sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr; | ||
886 | svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa)); | ||
887 | |||
888 | ib_req_notify_cq(newxprt->sc_sq_cq, IB_CQ_NEXT_COMP); | ||
889 | ib_req_notify_cq(newxprt->sc_rq_cq, IB_CQ_NEXT_COMP); | ||
890 | return &newxprt->sc_xprt; | ||
891 | |||
892 | errout: | ||
893 | dprintk("svcrdma: failure accepting new connection rc=%d.\n", ret); | ||
894 | rdma_destroy_id(newxprt->sc_cm_id); | ||
895 | rdma_destroy_xprt(newxprt); | ||
896 | return NULL; | ||
897 | } | ||
898 | |||
899 | /* | ||
900 | * Post an RQ WQE to the RQ when the rqst is being released. This | ||
901 | * effectively returns an RQ credit to the client. The rq_xprt_ctxt | ||
902 | * will be null if the request is deferred due to an RDMA_READ or the | ||
903 | * transport had no data ready (EAGAIN). Note that an RPC deferred in | ||
904 | * svc_process will still return the credit, this is because the data | ||
905 | * is copied and no longer consume a WQE/WC. | ||
906 | */ | ||
907 | static void svc_rdma_release_rqst(struct svc_rqst *rqstp) | ||
908 | { | ||
909 | int err; | ||
910 | struct svcxprt_rdma *rdma = | ||
911 | container_of(rqstp->rq_xprt, struct svcxprt_rdma, sc_xprt); | ||
912 | if (rqstp->rq_xprt_ctxt) { | ||
913 | BUG_ON(rqstp->rq_xprt_ctxt != rdma); | ||
914 | err = svc_rdma_post_recv(rdma); | ||
915 | if (err) | ||
916 | dprintk("svcrdma: failed to post an RQ WQE error=%d\n", | ||
917 | err); | ||
918 | } | ||
919 | rqstp->rq_xprt_ctxt = NULL; | ||
920 | } | ||
921 | |||
922 | /* Disable data ready events for this connection */ | ||
923 | static void svc_rdma_detach(struct svc_xprt *xprt) | ||
924 | { | ||
925 | struct svcxprt_rdma *rdma = | ||
926 | container_of(xprt, struct svcxprt_rdma, sc_xprt); | ||
927 | unsigned long flags; | ||
928 | |||
929 | dprintk("svc: svc_rdma_detach(%p)\n", xprt); | ||
930 | /* | ||
931 | * Shutdown the connection. This will ensure we don't get any | ||
932 | * more events from the provider. | ||
933 | */ | ||
934 | rdma_disconnect(rdma->sc_cm_id); | ||
935 | rdma_destroy_id(rdma->sc_cm_id); | ||
936 | |||
937 | /* We may already be on the DTO list */ | ||
938 | spin_lock_irqsave(&dto_lock, flags); | ||
939 | if (!list_empty(&rdma->sc_dto_q)) | ||
940 | list_del_init(&rdma->sc_dto_q); | ||
941 | spin_unlock_irqrestore(&dto_lock, flags); | ||
942 | } | ||
943 | |||
944 | static void svc_rdma_free(struct svc_xprt *xprt) | ||
945 | { | ||
946 | struct svcxprt_rdma *rdma = (struct svcxprt_rdma *)xprt; | ||
947 | dprintk("svcrdma: svc_rdma_free(%p)\n", rdma); | ||
948 | rdma_destroy_xprt(rdma); | ||
949 | kfree(rdma); | ||
950 | } | ||
951 | |||
952 | static void rdma_destroy_xprt(struct svcxprt_rdma *xprt) | ||
953 | { | ||
954 | if (xprt->sc_qp && !IS_ERR(xprt->sc_qp)) | ||
955 | ib_destroy_qp(xprt->sc_qp); | ||
956 | |||
957 | if (xprt->sc_sq_cq && !IS_ERR(xprt->sc_sq_cq)) | ||
958 | ib_destroy_cq(xprt->sc_sq_cq); | ||
959 | |||
960 | if (xprt->sc_rq_cq && !IS_ERR(xprt->sc_rq_cq)) | ||
961 | ib_destroy_cq(xprt->sc_rq_cq); | ||
962 | |||
963 | if (xprt->sc_phys_mr && !IS_ERR(xprt->sc_phys_mr)) | ||
964 | ib_dereg_mr(xprt->sc_phys_mr); | ||
965 | |||
966 | if (xprt->sc_pd && !IS_ERR(xprt->sc_pd)) | ||
967 | ib_dealloc_pd(xprt->sc_pd); | ||
968 | |||
969 | destroy_context_cache(xprt->sc_ctxt_head); | ||
970 | } | ||
971 | |||
972 | static int svc_rdma_has_wspace(struct svc_xprt *xprt) | ||
973 | { | ||
974 | struct svcxprt_rdma *rdma = | ||
975 | container_of(xprt, struct svcxprt_rdma, sc_xprt); | ||
976 | |||
977 | /* | ||
978 | * If there are fewer SQ WR available than required to send a | ||
979 | * simple response, return false. | ||
980 | */ | ||
981 | if ((rdma->sc_sq_depth - atomic_read(&rdma->sc_sq_count) < 3)) | ||
982 | return 0; | ||
983 | |||
984 | /* | ||
985 | * ...or there are already waiters on the SQ, | ||
986 | * return false. | ||
987 | */ | ||
988 | if (waitqueue_active(&rdma->sc_send_wait)) | ||
989 | return 0; | ||
990 | |||
991 | /* Otherwise return true. */ | ||
992 | return 1; | ||
993 | } | ||
994 | |||
995 | int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr) | ||
996 | { | ||
997 | struct ib_send_wr *bad_wr; | ||
998 | int ret; | ||
999 | |||
1000 | if (test_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags)) | ||
1001 | return 0; | ||
1002 | |||
1003 | BUG_ON(wr->send_flags != IB_SEND_SIGNALED); | ||
1004 | BUG_ON(((struct svc_rdma_op_ctxt *)(unsigned long)wr->wr_id)->wr_op != | ||
1005 | wr->opcode); | ||
1006 | /* If the SQ is full, wait until an SQ entry is available */ | ||
1007 | while (1) { | ||
1008 | spin_lock_bh(&xprt->sc_lock); | ||
1009 | if (xprt->sc_sq_depth == atomic_read(&xprt->sc_sq_count)) { | ||
1010 | spin_unlock_bh(&xprt->sc_lock); | ||
1011 | atomic_inc(&rdma_stat_sq_starve); | ||
1012 | /* See if we can reap some SQ WR */ | ||
1013 | sq_cq_reap(xprt); | ||
1014 | |||
1015 | /* Wait until SQ WR available if SQ still full */ | ||
1016 | wait_event(xprt->sc_send_wait, | ||
1017 | atomic_read(&xprt->sc_sq_count) < | ||
1018 | xprt->sc_sq_depth); | ||
1019 | continue; | ||
1020 | } | ||
1021 | /* Bumped used SQ WR count and post */ | ||
1022 | ret = ib_post_send(xprt->sc_qp, wr, &bad_wr); | ||
1023 | if (!ret) | ||
1024 | atomic_inc(&xprt->sc_sq_count); | ||
1025 | else | ||
1026 | dprintk("svcrdma: failed to post SQ WR rc=%d, " | ||
1027 | "sc_sq_count=%d, sc_sq_depth=%d\n", | ||
1028 | ret, atomic_read(&xprt->sc_sq_count), | ||
1029 | xprt->sc_sq_depth); | ||
1030 | spin_unlock_bh(&xprt->sc_lock); | ||
1031 | break; | ||
1032 | } | ||
1033 | return ret; | ||
1034 | } | ||
1035 | |||
1036 | int svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp, | ||
1037 | enum rpcrdma_errcode err) | ||
1038 | { | ||
1039 | struct ib_send_wr err_wr; | ||
1040 | struct ib_sge sge; | ||
1041 | struct page *p; | ||
1042 | struct svc_rdma_op_ctxt *ctxt; | ||
1043 | u32 *va; | ||
1044 | int length; | ||
1045 | int ret; | ||
1046 | |||
1047 | p = svc_rdma_get_page(); | ||
1048 | va = page_address(p); | ||
1049 | |||
1050 | /* XDR encode error */ | ||
1051 | length = svc_rdma_xdr_encode_error(xprt, rmsgp, err, va); | ||
1052 | |||
1053 | /* Prepare SGE for local address */ | ||
1054 | sge.addr = ib_dma_map_page(xprt->sc_cm_id->device, | ||
1055 | p, 0, PAGE_SIZE, DMA_FROM_DEVICE); | ||
1056 | sge.lkey = xprt->sc_phys_mr->lkey; | ||
1057 | sge.length = length; | ||
1058 | |||
1059 | ctxt = svc_rdma_get_context(xprt); | ||
1060 | ctxt->count = 1; | ||
1061 | ctxt->pages[0] = p; | ||
1062 | |||
1063 | /* Prepare SEND WR */ | ||
1064 | memset(&err_wr, 0, sizeof err_wr); | ||
1065 | ctxt->wr_op = IB_WR_SEND; | ||
1066 | err_wr.wr_id = (unsigned long)ctxt; | ||
1067 | err_wr.sg_list = &sge; | ||
1068 | err_wr.num_sge = 1; | ||
1069 | err_wr.opcode = IB_WR_SEND; | ||
1070 | err_wr.send_flags = IB_SEND_SIGNALED; | ||
1071 | |||
1072 | /* Post It */ | ||
1073 | ret = svc_rdma_send(xprt, &err_wr); | ||
1074 | if (ret) { | ||
1075 | dprintk("svcrdma: Error posting send = %d\n", ret); | ||
1076 | svc_rdma_put_context(ctxt, 1); | ||
1077 | } | ||
1078 | |||
1079 | return ret; | ||
1080 | } | ||
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index d802b5afae89..9ddf944cce29 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -155,7 +155,7 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod) | |||
155 | * Some modules (visor) have empty slots as placeholder for | 155 | * Some modules (visor) have empty slots as placeholder for |
156 | * run-time specification that results in catch-all alias | 156 | * run-time specification that results in catch-all alias |
157 | */ | 157 | */ |
158 | if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass)) | 158 | if (!(id->idVendor | id->idProduct | id->bDeviceClass | id->bInterfaceClass)) |
159 | return; | 159 | return; |
160 | 160 | ||
161 | /* Convert numeric bcdDevice range into fnmatch-able pattern(s) */ | 161 | /* Convert numeric bcdDevice range into fnmatch-able pattern(s) */ |