diff options
218 files changed, 7396 insertions, 3637 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index a07c0f366f91..a986e9bbba3d 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb | |||
@@ -159,3 +159,14 @@ Description: | |||
159 | device. This is useful to ensure auto probing won't | 159 | device. This is useful to ensure auto probing won't |
160 | match the driver to the device. For example: | 160 | match the driver to the device. For example: |
161 | # echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id | 161 | # echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id |
162 | |||
163 | What: /sys/bus/usb/device/.../avoid_reset | ||
164 | Date: December 2009 | ||
165 | Contact: Oliver Neukum <oliver@neukum.org> | ||
166 | Description: | ||
167 | Writing 1 to this file tells the kernel that this | ||
168 | device will morph into another mode when it is reset. | ||
169 | Drivers will not use reset for error handling for | ||
170 | such devices. | ||
171 | Users: | ||
172 | usb_modeswitch | ||
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 35cf64d4436d..35c9b51d20ea 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt | |||
@@ -139,7 +139,6 @@ Code Seq#(hex) Include File Comments | |||
139 | 'K' all linux/kd.h | 139 | 'K' all linux/kd.h |
140 | 'L' 00-1F linux/loop.h conflict! | 140 | 'L' 00-1F linux/loop.h conflict! |
141 | 'L' 10-1F drivers/scsi/mpt2sas/mpt2sas_ctl.h conflict! | 141 | 'L' 10-1F drivers/scsi/mpt2sas/mpt2sas_ctl.h conflict! |
142 | 'L' 20-2F linux/usb/vstusb.h | ||
143 | 'L' E0-FF linux/ppdd.h encrypted disk device driver | 142 | 'L' E0-FF linux/ppdd.h encrypted disk device driver |
144 | <http://linux01.gwdg.de/~alatham/ppdd.html> | 143 | <http://linux01.gwdg.de/~alatham/ppdd.html> |
145 | 'M' all linux/soundcard.h conflict! | 144 | 'M' all linux/soundcard.h conflict! |
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index 50189bf07d53..fe5c099b8fc8 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX | |||
@@ -32,6 +32,8 @@ cs89x0.txt | |||
32 | - the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver | 32 | - the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver |
33 | cxacru.txt | 33 | cxacru.txt |
34 | - Conexant AccessRunner USB ADSL Modem | 34 | - Conexant AccessRunner USB ADSL Modem |
35 | cxacru-cf.py | ||
36 | - Conexant AccessRunner USB ADSL Modem configuration file parser | ||
35 | de4x5.txt | 37 | de4x5.txt |
36 | - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver | 38 | - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver |
37 | decnet.txt | 39 | decnet.txt |
diff --git a/Documentation/networking/cxacru-cf.py b/Documentation/networking/cxacru-cf.py new file mode 100644 index 000000000000..b41d298398c8 --- /dev/null +++ b/Documentation/networking/cxacru-cf.py | |||
@@ -0,0 +1,48 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # Copyright 2009 Simon Arlott | ||
3 | # | ||
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 Free | ||
6 | # Software Foundation; either version 2 of the License, or (at your option) | ||
7 | # any later version. | ||
8 | # | ||
9 | # This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | # more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License along with | ||
15 | # this program; if not, write to the Free Software Foundation, Inc., 59 | ||
16 | # Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | # | ||
18 | # Usage: cxacru-cf.py < cxacru-cf.bin | ||
19 | # Output: values string suitable for the sysfs adsl_config attribute | ||
20 | # | ||
21 | # Warning: cxacru-cf.bin with MD5 hash cdbac2689969d5ed5d4850f117702110 | ||
22 | # contains mis-aligned values which will stop the modem from being able | ||
23 | # to make a connection. If the first and last two bytes are removed then | ||
24 | # the values become valid, but the modulation will be forced to ANSI | ||
25 | # T1.413 only which may not be appropriate. | ||
26 | # | ||
27 | # The original binary format is a packed list of le32 values. | ||
28 | |||
29 | import sys | ||
30 | import struct | ||
31 | |||
32 | i = 0 | ||
33 | while True: | ||
34 | buf = sys.stdin.read(4) | ||
35 | |||
36 | if len(buf) == 0: | ||
37 | break | ||
38 | elif len(buf) != 4: | ||
39 | sys.stdout.write("\n") | ||
40 | sys.stderr.write("Error: read {0} not 4 bytes\n".format(len(buf))) | ||
41 | sys.exit(1) | ||
42 | |||
43 | if i > 0: | ||
44 | sys.stdout.write(" ") | ||
45 | sys.stdout.write("{0:x}={1}".format(i, struct.unpack("<I", buf)[0])) | ||
46 | i += 1 | ||
47 | |||
48 | sys.stdout.write("\n") | ||
diff --git a/Documentation/networking/cxacru.txt b/Documentation/networking/cxacru.txt index b074681a963e..2cce04457b4d 100644 --- a/Documentation/networking/cxacru.txt +++ b/Documentation/networking/cxacru.txt | |||
@@ -4,6 +4,12 @@ While it is capable of managing/maintaining the ADSL connection without the | |||
4 | module loaded, the device will sometimes stop responding after unloading the | 4 | module loaded, the device will sometimes stop responding after unloading the |
5 | driver and it is necessary to unplug/remove power to the device to fix this. | 5 | driver and it is necessary to unplug/remove power to the device to fix this. |
6 | 6 | ||
7 | Note: support for cxacru-cf.bin has been removed. It was not loaded correctly | ||
8 | so it had no effect on the device configuration. Fixing it could have stopped | ||
9 | existing devices working when an invalid configuration is supplied. | ||
10 | |||
11 | There is a script cxacru-cf.py to convert an existing file to the sysfs form. | ||
12 | |||
7 | Detected devices will appear as ATM devices named "cxacru". In /sys/class/atm/ | 13 | Detected devices will appear as ATM devices named "cxacru". In /sys/class/atm/ |
8 | these are directories named cxacruN where N is the device number. A symlink | 14 | these are directories named cxacruN where N is the device number. A symlink |
9 | named device points to the USB interface device's directory which contains | 15 | named device points to the USB interface device's directory which contains |
@@ -15,6 +21,15 @@ several sysfs attribute files for retrieving device statistics: | |||
15 | * adsl_headend_environment | 21 | * adsl_headend_environment |
16 | Information about the remote headend. | 22 | Information about the remote headend. |
17 | 23 | ||
24 | * adsl_config | ||
25 | Configuration writing interface. | ||
26 | Write parameters in hexadecimal format <index>=<value>, | ||
27 | separated by whitespace, e.g.: | ||
28 | "1=0 a=5" | ||
29 | Up to 7 parameters at a time will be sent and the modem will restart | ||
30 | the ADSL connection when any value is set. These are logged for future | ||
31 | reference. | ||
32 | |||
18 | * downstream_attenuation (dB) | 33 | * downstream_attenuation (dB) |
19 | * downstream_bits_per_frame | 34 | * downstream_bits_per_frame |
20 | * downstream_rate (kbps) | 35 | * downstream_rate (kbps) |
@@ -61,6 +76,7 @@ several sysfs attribute files for retrieving device statistics: | |||
61 | * mac_address | 76 | * mac_address |
62 | 77 | ||
63 | * modulation | 78 | * modulation |
79 | "" (when not connected) | ||
64 | "ANSI T1.413" | 80 | "ANSI T1.413" |
65 | "ITU-T G.992.1 (G.DMT)" | 81 | "ITU-T G.992.1 (G.DMT)" |
66 | "ITU-T G.992.2 (G.LITE)" | 82 | "ITU-T G.992.2 (G.LITE)" |
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt index 9cf83e8c27b8..d83703ea74b2 100644 --- a/Documentation/usb/error-codes.txt +++ b/Documentation/usb/error-codes.txt | |||
@@ -41,8 +41,8 @@ USB-specific: | |||
41 | 41 | ||
42 | -EFBIG Host controller driver can't schedule that many ISO frames. | 42 | -EFBIG Host controller driver can't schedule that many ISO frames. |
43 | 43 | ||
44 | -EPIPE Specified endpoint is stalled. For non-control endpoints, | 44 | -EPIPE The pipe type specified in the URB doesn't match the |
45 | reset this status with usb_clear_halt(). | 45 | endpoint's actual type. |
46 | 46 | ||
47 | -EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable | 47 | -EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable |
48 | in the current interface altsetting. | 48 | in the current interface altsetting. |
@@ -60,6 +60,8 @@ USB-specific: | |||
60 | 60 | ||
61 | -EHOSTUNREACH URB was rejected because the device is suspended. | 61 | -EHOSTUNREACH URB was rejected because the device is suspended. |
62 | 62 | ||
63 | -ENOEXEC A control URB doesn't contain a Setup packet. | ||
64 | |||
63 | 65 | ||
64 | ************************************************************************** | 66 | ************************************************************************** |
65 | * Error codes returned by in urb->status * | 67 | * Error codes returned by in urb->status * |
diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt index 3bf6818c8cf5..2790ad48cfc2 100644 --- a/Documentation/usb/power-management.txt +++ b/Documentation/usb/power-management.txt | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | Alan Stern <stern@rowland.harvard.edu> | 3 | Alan Stern <stern@rowland.harvard.edu> |
4 | 4 | ||
5 | November 10, 2009 | 5 | December 11, 2009 |
6 | 6 | ||
7 | 7 | ||
8 | 8 | ||
@@ -29,9 +29,9 @@ covered to some extent (see Documentation/power/*.txt for more | |||
29 | information about system PM). | 29 | information about system PM). |
30 | 30 | ||
31 | Note: Dynamic PM support for USB is present only if the kernel was | 31 | Note: Dynamic PM support for USB is present only if the kernel was |
32 | built with CONFIG_USB_SUSPEND enabled. System PM support is present | 32 | built with CONFIG_USB_SUSPEND enabled (which depends on |
33 | only if the kernel was built with CONFIG_SUSPEND or CONFIG_HIBERNATION | 33 | CONFIG_PM_RUNTIME). System PM support is present only if the kernel |
34 | enabled. | 34 | was built with CONFIG_SUSPEND or CONFIG_HIBERNATION enabled. |
35 | 35 | ||
36 | 36 | ||
37 | What is Remote Wakeup? | 37 | What is Remote Wakeup? |
@@ -229,6 +229,11 @@ necessary operations by hand or add them to a udev script. You can | |||
229 | also change the idle-delay time; 2 seconds is not the best choice for | 229 | also change the idle-delay time; 2 seconds is not the best choice for |
230 | every device. | 230 | every device. |
231 | 231 | ||
232 | If a driver knows that its device has proper suspend/resume support, | ||
233 | it can enable autosuspend all by itself. For example, the video | ||
234 | driver for a laptop's webcam might do this, since these devices are | ||
235 | rarely used and so should normally be autosuspended. | ||
236 | |||
232 | Sometimes it turns out that even when a device does work okay with | 237 | Sometimes it turns out that even when a device does work okay with |
233 | autosuspend there are still problems. For example, there are | 238 | autosuspend there are still problems. For example, there are |
234 | experimental patches adding autosuspend support to the usbhid driver, | 239 | experimental patches adding autosuspend support to the usbhid driver, |
@@ -321,69 +326,81 @@ driver does so by calling these six functions: | |||
321 | void usb_autopm_get_interface_no_resume(struct usb_interface *intf); | 326 | void usb_autopm_get_interface_no_resume(struct usb_interface *intf); |
322 | void usb_autopm_put_interface_no_suspend(struct usb_interface *intf); | 327 | void usb_autopm_put_interface_no_suspend(struct usb_interface *intf); |
323 | 328 | ||
324 | The functions work by maintaining a counter in the usb_interface | 329 | The functions work by maintaining a usage counter in the |
325 | structure. When intf->pm_usage_count is > 0 then the interface is | 330 | usb_interface's embedded device structure. When the counter is > 0 |
326 | deemed to be busy, and the kernel will not autosuspend the interface's | 331 | then the interface is deemed to be busy, and the kernel will not |
327 | device. When intf->pm_usage_count is <= 0 then the interface is | 332 | autosuspend the interface's device. When the usage counter is = 0 |
328 | considered to be idle, and the kernel may autosuspend the device. | 333 | then the interface is considered to be idle, and the kernel may |
334 | autosuspend the device. | ||
329 | 335 | ||
330 | (There is a similar pm_usage_count field in struct usb_device, | 336 | (There is a similar usage counter field in struct usb_device, |
331 | associated with the device itself rather than any of its interfaces. | 337 | associated with the device itself rather than any of its interfaces. |
332 | This field is used only by the USB core.) | 338 | This counter is used only by the USB core.) |
333 | 339 | ||
334 | Drivers must not modify intf->pm_usage_count directly; its value | 340 | Drivers need not be concerned about balancing changes to the usage |
335 | should be changed only be using the functions listed above. Drivers | 341 | counter; the USB core will undo any remaining "get"s when a driver |
336 | are responsible for insuring that the overall change to pm_usage_count | 342 | is unbound from its interface. As a corollary, drivers must not call |
337 | during their lifetime balances out to 0 (it may be necessary for the | 343 | any of the usb_autopm_* functions after their diconnect() routine has |
338 | disconnect method to call usb_autopm_put_interface() one or more times | 344 | returned. |
339 | to fulfill this requirement). The first two routines use the PM mutex | 345 | |
340 | in struct usb_device for mutual exclusion; drivers using the async | 346 | Drivers using the async routines are responsible for their own |
341 | routines are responsible for their own synchronization and mutual | 347 | synchronization and mutual exclusion. |
342 | exclusion. | 348 | |
343 | 349 | usb_autopm_get_interface() increments the usage counter and | |
344 | usb_autopm_get_interface() increments pm_usage_count and | 350 | does an autoresume if the device is suspended. If the |
345 | attempts an autoresume if the new value is > 0 and the | 351 | autoresume fails, the counter is decremented back. |
346 | device is suspended. | 352 | |
347 | 353 | usb_autopm_put_interface() decrements the usage counter and | |
348 | usb_autopm_put_interface() decrements pm_usage_count and | 354 | attempts an autosuspend if the new value is = 0. |
349 | attempts an autosuspend if the new value is <= 0 and the | ||
350 | device isn't suspended. | ||
351 | 355 | ||
352 | usb_autopm_get_interface_async() and | 356 | usb_autopm_get_interface_async() and |
353 | usb_autopm_put_interface_async() do almost the same things as | 357 | usb_autopm_put_interface_async() do almost the same things as |
354 | their non-async counterparts. The differences are: they do | 358 | their non-async counterparts. The big difference is that they |
355 | not acquire the PM mutex, and they use a workqueue to do their | 359 | use a workqueue to do the resume or suspend part of their |
356 | jobs. As a result they can be called in an atomic context, | 360 | jobs. As a result they can be called in an atomic context, |
357 | such as an URB's completion handler, but when they return the | 361 | such as an URB's completion handler, but when they return the |
358 | device will not generally not yet be in the desired state. | 362 | device will generally not yet be in the desired state. |
359 | 363 | ||
360 | usb_autopm_get_interface_no_resume() and | 364 | usb_autopm_get_interface_no_resume() and |
361 | usb_autopm_put_interface_no_suspend() merely increment or | 365 | usb_autopm_put_interface_no_suspend() merely increment or |
362 | decrement the pm_usage_count value; they do not attempt to | 366 | decrement the usage counter; they do not attempt to carry out |
363 | carry out an autoresume or an autosuspend. Hence they can be | 367 | an autoresume or an autosuspend. Hence they can be called in |
364 | called in an atomic context. | 368 | an atomic context. |
365 | 369 | ||
366 | The conventional usage pattern is that a driver calls | 370 | The simplest usage pattern is that a driver calls |
367 | usb_autopm_get_interface() in its open routine and | 371 | usb_autopm_get_interface() in its open routine and |
368 | usb_autopm_put_interface() in its close or release routine. But | 372 | usb_autopm_put_interface() in its close or release routine. But other |
369 | other patterns are possible. | 373 | patterns are possible. |
370 | 374 | ||
371 | The autosuspend attempts mentioned above will often fail for one | 375 | The autosuspend attempts mentioned above will often fail for one |
372 | reason or another. For example, the power/level attribute might be | 376 | reason or another. For example, the power/level attribute might be |
373 | set to "on", or another interface in the same device might not be | 377 | set to "on", or another interface in the same device might not be |
374 | idle. This is perfectly normal. If the reason for failure was that | 378 | idle. This is perfectly normal. If the reason for failure was that |
375 | the device hasn't been idle for long enough, a delayed workqueue | 379 | the device hasn't been idle for long enough, a timer is scheduled to |
376 | routine is automatically set up to carry out the operation when the | 380 | carry out the operation automatically when the autosuspend idle-delay |
377 | autosuspend idle-delay has expired. | 381 | has expired. |
378 | 382 | ||
379 | Autoresume attempts also can fail, although failure would mean that | 383 | Autoresume attempts also can fail, although failure would mean that |
380 | the device is no longer present or operating properly. Unlike | 384 | the device is no longer present or operating properly. Unlike |
381 | autosuspend, there's no delay for an autoresume. | 385 | autosuspend, there's no idle-delay for an autoresume. |
382 | 386 | ||
383 | 387 | ||
384 | Other parts of the driver interface | 388 | Other parts of the driver interface |
385 | ----------------------------------- | 389 | ----------------------------------- |
386 | 390 | ||
391 | Drivers can enable autosuspend for their devices by calling | ||
392 | |||
393 | usb_enable_autosuspend(struct usb_device *udev); | ||
394 | |||
395 | in their probe() routine, if they know that the device is capable of | ||
396 | suspending and resuming correctly. This is exactly equivalent to | ||
397 | writing "auto" to the device's power/level attribute. Likewise, | ||
398 | drivers can disable autosuspend by calling | ||
399 | |||
400 | usb_disable_autosuspend(struct usb_device *udev); | ||
401 | |||
402 | This is exactly the same as writing "on" to the power/level attribute. | ||
403 | |||
387 | Sometimes a driver needs to make sure that remote wakeup is enabled | 404 | Sometimes a driver needs to make sure that remote wakeup is enabled |
388 | during autosuspend. For example, there's not much point | 405 | during autosuspend. For example, there's not much point |
389 | autosuspending a keyboard if the user can't cause the keyboard to do a | 406 | autosuspending a keyboard if the user can't cause the keyboard to do a |
@@ -395,26 +412,27 @@ though, setting this flag won't cause the kernel to autoresume it. | |||
395 | Normally a driver would set this flag in its probe method, at which | 412 | Normally a driver would set this flag in its probe method, at which |
396 | time the device is guaranteed not to be autosuspended.) | 413 | time the device is guaranteed not to be autosuspended.) |
397 | 414 | ||
398 | The synchronous usb_autopm_* routines have to run in a sleepable | 415 | If a driver does its I/O asynchronously in interrupt context, it |
399 | process context; they must not be called from an interrupt handler or | 416 | should call usb_autopm_get_interface_async() before starting output and |
400 | while holding a spinlock. In fact, the entire autosuspend mechanism | 417 | usb_autopm_put_interface_async() when the output queue drains. When |
401 | is not well geared toward interrupt-driven operation. However there | 418 | it receives an input event, it should call |
402 | is one thing a driver can do in an interrupt handler: | ||
403 | 419 | ||
404 | usb_mark_last_busy(struct usb_device *udev); | 420 | usb_mark_last_busy(struct usb_device *udev); |
405 | 421 | ||
406 | This sets udev->last_busy to the current time. udev->last_busy is the | 422 | in the event handler. This sets udev->last_busy to the current time. |
407 | field used for idle-delay calculations; updating it will cause any | 423 | udev->last_busy is the field used for idle-delay calculations; |
408 | pending autosuspend to be moved back. The usb_autopm_* routines will | 424 | updating it will cause any pending autosuspend to be moved back. Most |
409 | also set the last_busy field to the current time. | 425 | of the usb_autopm_* routines will also set the last_busy field to the |
410 | 426 | current time. | |
411 | Calling urb_mark_last_busy() from within an URB completion handler is | 427 | |
412 | subject to races: The kernel may have just finished deciding the | 428 | Asynchronous operation is always subject to races. For example, a |
413 | device has been idle for long enough but not yet gotten around to | 429 | driver may call one of the usb_autopm_*_interface_async() routines at |
414 | calling the driver's suspend method. The driver would have to be | 430 | a time when the core has just finished deciding the device has been |
415 | responsible for synchronizing its suspend method with its URB | 431 | idle for long enough but not yet gotten around to calling the driver's |
416 | completion handler and causing the autosuspend to fail with -EBUSY if | 432 | suspend method. The suspend method must be responsible for |
417 | an URB had completed too recently. | 433 | synchronizing with the output request routine and the URB completion |
434 | handler; it should cause autosuspends to fail with -EBUSY if the | ||
435 | driver needs to use the device. | ||
418 | 436 | ||
419 | External suspend calls should never be allowed to fail in this way, | 437 | External suspend calls should never be allowed to fail in this way, |
420 | only autosuspend calls. The driver can tell them apart by checking | 438 | only autosuspend calls. The driver can tell them apart by checking |
@@ -422,75 +440,23 @@ the PM_EVENT_AUTO bit in the message.event argument to the suspend | |||
422 | method; this bit will be set for internal PM events (autosuspend) and | 440 | method; this bit will be set for internal PM events (autosuspend) and |
423 | clear for external PM events. | 441 | clear for external PM events. |
424 | 442 | ||
425 | Many of the ingredients in the autosuspend framework are oriented | ||
426 | towards interfaces: The usb_interface structure contains the | ||
427 | pm_usage_cnt field, and the usb_autopm_* routines take an interface | ||
428 | pointer as their argument. But somewhat confusingly, a few of the | ||
429 | pieces (i.e., usb_mark_last_busy()) use the usb_device structure | ||
430 | instead. Drivers need to keep this straight; they can call | ||
431 | interface_to_usbdev() to find the device structure for a given | ||
432 | interface. | ||
433 | |||
434 | 443 | ||
435 | Locking requirements | 444 | Mutual exclusion |
436 | -------------------- | 445 | ---------------- |
437 | 446 | ||
438 | All three suspend/resume methods are always called while holding the | 447 | For external events -- but not necessarily for autosuspend or |
439 | usb_device's PM mutex. For external events -- but not necessarily for | 448 | autoresume -- the device semaphore (udev->dev.sem) will be held when a |
440 | autosuspend or autoresume -- the device semaphore (udev->dev.sem) will | 449 | suspend or resume method is called. This implies that external |
441 | also be held. This implies that external suspend/resume events are | 450 | suspend/resume events are mutually exclusive with calls to probe, |
442 | mutually exclusive with calls to probe, disconnect, pre_reset, and | 451 | disconnect, pre_reset, and post_reset; the USB core guarantees that |
443 | post_reset; the USB core guarantees that this is true of internal | 452 | this is true of autosuspend/autoresume events as well. |
444 | suspend/resume events as well. | ||
445 | 453 | ||
446 | If a driver wants to block all suspend/resume calls during some | 454 | If a driver wants to block all suspend/resume calls during some |
447 | critical section, it can simply acquire udev->pm_mutex. Note that | 455 | critical section, the best way is to lock the device and call |
448 | calls to resume may be triggered indirectly. Block IO due to memory | 456 | usb_autopm_get_interface() (and do the reverse at the end of the |
449 | allocations can make the vm subsystem resume a device. Thus while | 457 | critical section). Holding the device semaphore will block all |
450 | holding this lock you must not allocate memory with GFP_KERNEL or | 458 | external PM calls, and the usb_autopm_get_interface() will prevent any |
451 | GFP_NOFS. | 459 | internal PM calls, even if it fails. (Exercise: Why?) |
452 | |||
453 | Alternatively, if the critical section might call some of the | ||
454 | usb_autopm_* routines, the driver can avoid deadlock by doing: | ||
455 | |||
456 | down(&udev->dev.sem); | ||
457 | rc = usb_autopm_get_interface(intf); | ||
458 | |||
459 | and at the end of the critical section: | ||
460 | |||
461 | if (!rc) | ||
462 | usb_autopm_put_interface(intf); | ||
463 | up(&udev->dev.sem); | ||
464 | |||
465 | Holding the device semaphore will block all external PM calls, and the | ||
466 | usb_autopm_get_interface() will prevent any internal PM calls, even if | ||
467 | it fails. (Exercise: Why?) | ||
468 | |||
469 | The rules for locking order are: | ||
470 | |||
471 | Never acquire any device semaphore while holding any PM mutex. | ||
472 | |||
473 | Never acquire udev->pm_mutex while holding the PM mutex for | ||
474 | a device that isn't a descendant of udev. | ||
475 | |||
476 | In other words, PM mutexes should only be acquired going up the device | ||
477 | tree, and they should be acquired only after locking all the device | ||
478 | semaphores you need to hold. These rules don't matter to drivers very | ||
479 | much; they usually affect just the USB core. | ||
480 | |||
481 | Still, drivers do need to be careful. For example, many drivers use a | ||
482 | private mutex to synchronize their normal I/O activities with their | ||
483 | disconnect method. Now if the driver supports autosuspend then it | ||
484 | must call usb_autopm_put_interface() from somewhere -- maybe from its | ||
485 | close method. It should make the call while holding the private mutex, | ||
486 | since a driver shouldn't call any of the usb_autopm_* functions for an | ||
487 | interface from which it has been unbound. | ||
488 | |||
489 | But the usb_autpm_* routines always acquire the device's PM mutex, and | ||
490 | consequently the locking order has to be: private mutex first, PM | ||
491 | mutex second. Since the suspend method is always called with the PM | ||
492 | mutex held, it mustn't try to acquire the private mutex. It has to | ||
493 | synchronize with the driver's I/O activities in some other way. | ||
494 | 460 | ||
495 | 461 | ||
496 | Interaction between dynamic PM and system PM | 462 | Interaction between dynamic PM and system PM |
@@ -499,22 +465,11 @@ synchronize with the driver's I/O activities in some other way. | |||
499 | Dynamic power management and system power management can interact in | 465 | Dynamic power management and system power management can interact in |
500 | a couple of ways. | 466 | a couple of ways. |
501 | 467 | ||
502 | Firstly, a device may already be manually suspended or autosuspended | 468 | Firstly, a device may already be autosuspended when a system suspend |
503 | when a system suspend occurs. Since system suspends are supposed to | 469 | occurs. Since system suspends are supposed to be as transparent as |
504 | be as transparent as possible, the device should remain suspended | 470 | possible, the device should remain suspended following the system |
505 | following the system resume. The 2.6.23 kernel obeys this principle | 471 | resume. But this theory may not work out well in practice; over time |
506 | for manually suspended devices but not for autosuspended devices; they | 472 | the kernel's behavior in this regard has changed. |
507 | do get resumed when the system wakes up. (Presumably they will be | ||
508 | autosuspended again after their idle-delay time expires.) In later | ||
509 | kernels this behavior will be fixed. | ||
510 | |||
511 | (There is an exception. If a device would undergo a reset-resume | ||
512 | instead of a normal resume, and the device is enabled for remote | ||
513 | wakeup, then the reset-resume takes place even if the device was | ||
514 | already suspended when the system suspend began. The justification is | ||
515 | that a reset-resume is a kind of remote-wakeup event. Or to put it | ||
516 | another way, a device which needs a reset won't be able to generate | ||
517 | normal remote-wakeup signals, so it ought to be resumed immediately.) | ||
518 | 473 | ||
519 | Secondly, a dynamic power-management event may occur as a system | 474 | Secondly, a dynamic power-management event may occur as a system |
520 | suspend is underway. The window for this is short, since system | 475 | suspend is underway. The window for this is short, since system |
diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig index 426ae948aefe..193bd334fbbf 100644 --- a/arch/arm/configs/rx51_defconfig +++ b/arch/arm/configs/rx51_defconfig | |||
@@ -445,6 +445,8 @@ CONFIG_IP_NF_FILTER=m | |||
445 | # CONFIG_LAPB is not set | 445 | # CONFIG_LAPB is not set |
446 | # CONFIG_ECONET is not set | 446 | # CONFIG_ECONET is not set |
447 | # CONFIG_WAN_ROUTER is not set | 447 | # CONFIG_WAN_ROUTER is not set |
448 | CONFIG_PHONET=y | ||
449 | # CONFIG_IEEE802154 is not set | ||
448 | # CONFIG_NET_SCHED is not set | 450 | # CONFIG_NET_SCHED is not set |
449 | # CONFIG_DCB is not set | 451 | # CONFIG_DCB is not set |
450 | 452 | ||
@@ -1325,27 +1327,34 @@ CONFIG_USB_GADGET_SELECTED=y | |||
1325 | # CONFIG_USB_GADGET_LH7A40X is not set | 1327 | # CONFIG_USB_GADGET_LH7A40X is not set |
1326 | # CONFIG_USB_GADGET_OMAP is not set | 1328 | # CONFIG_USB_GADGET_OMAP is not set |
1327 | # CONFIG_USB_GADGET_PXA25X is not set | 1329 | # CONFIG_USB_GADGET_PXA25X is not set |
1330 | # CONFIG_USB_GADGET_R8A66597 is not set | ||
1328 | # CONFIG_USB_GADGET_PXA27X is not set | 1331 | # CONFIG_USB_GADGET_PXA27X is not set |
1329 | # CONFIG_USB_GADGET_S3C2410 is not set | 1332 | # CONFIG_USB_GADGET_S3C_HSOTG is not set |
1330 | # CONFIG_USB_GADGET_IMX is not set | 1333 | # CONFIG_USB_GADGET_IMX is not set |
1334 | # CONFIG_USB_GADGET_S3C2410 is not set | ||
1331 | # CONFIG_USB_GADGET_M66592 is not set | 1335 | # CONFIG_USB_GADGET_M66592 is not set |
1332 | # CONFIG_USB_GADGET_AMD5536UDC is not set | 1336 | # CONFIG_USB_GADGET_AMD5536UDC is not set |
1333 | # CONFIG_USB_GADGET_FSL_QE is not set | 1337 | # CONFIG_USB_GADGET_FSL_QE is not set |
1334 | # CONFIG_USB_GADGET_CI13XXX is not set | 1338 | # CONFIG_USB_GADGET_CI13XXX is not set |
1335 | # CONFIG_USB_GADGET_NET2280 is not set | 1339 | # CONFIG_USB_GADGET_NET2280 is not set |
1336 | # CONFIG_USB_GADGET_GOKU is not set | 1340 | # CONFIG_USB_GADGET_GOKU is not set |
1341 | # CONFIG_USB_GADGET_LANGWELL is not set | ||
1337 | # CONFIG_USB_GADGET_DUMMY_HCD is not set | 1342 | # CONFIG_USB_GADGET_DUMMY_HCD is not set |
1338 | CONFIG_USB_GADGET_DUALSPEED=y | 1343 | CONFIG_USB_GADGET_DUALSPEED=y |
1339 | CONFIG_USB_ZERO=m | 1344 | CONFIG_USB_ZERO=m |
1340 | # CONFIG_USB_ZERO_HNPTEST is not set | 1345 | # CONFIG_USB_ZERO_HNPTEST is not set |
1346 | # CONFIG_USB_AUDIO is not set | ||
1341 | # CONFIG_USB_ETH is not set | 1347 | # CONFIG_USB_ETH is not set |
1342 | # CONFIG_USB_GADGETFS is not set | 1348 | # CONFIG_USB_GADGETFS is not set |
1343 | CONFIG_USB_FILE_STORAGE=m | 1349 | CONFIG_USB_FILE_STORAGE=m |
1344 | # CONFIG_USB_FILE_STORAGE_TEST is not set | 1350 | # CONFIG_USB_FILE_STORAGE_TEST is not set |
1351 | # CONFIG_USB_MASS_STORAGE is not set | ||
1345 | # CONFIG_USB_G_SERIAL is not set | 1352 | # CONFIG_USB_G_SERIAL is not set |
1346 | # CONFIG_USB_MIDI_GADGET is not set | 1353 | # CONFIG_USB_MIDI_GADGET is not set |
1347 | # CONFIG_USB_G_PRINTER is not set | 1354 | # CONFIG_USB_G_PRINTER is not set |
1348 | # CONFIG_USB_CDC_COMPOSITE is not set | 1355 | # CONFIG_USB_CDC_COMPOSITE is not set |
1356 | CONFIG_USB_G_NOKIA=m | ||
1357 | # CONFIG_USB_G_MULTI is not set | ||
1349 | 1358 | ||
1350 | # | 1359 | # |
1351 | # OTG and related infrastructure | 1360 | # OTG and related infrastructure |
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index 3d398ce09b31..3956d82b7c4e 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
34 | #include <linux/dma-mapping.h> | ||
34 | 35 | ||
35 | #include <mach/irqs.h> | 36 | #include <mach/irqs.h> |
36 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
@@ -292,7 +293,7 @@ struct platform_device mxc_fb_device = { | |||
292 | .num_resources = ARRAY_SIZE(mxc_fb), | 293 | .num_resources = ARRAY_SIZE(mxc_fb), |
293 | .resource = mxc_fb, | 294 | .resource = mxc_fb, |
294 | .dev = { | 295 | .dev = { |
295 | .coherent_dma_mask = 0xFFFFFFFF, | 296 | .coherent_dma_mask = DMA_BIT_MASK(32), |
296 | }, | 297 | }, |
297 | }; | 298 | }; |
298 | 299 | ||
@@ -395,17 +396,17 @@ static struct resource mxc_sdhc1_resources[] = { | |||
395 | }, | 396 | }, |
396 | }; | 397 | }; |
397 | 398 | ||
398 | static u64 mxc_sdhc1_dmamask = 0xffffffffUL; | 399 | static u64 mxc_sdhc1_dmamask = DMA_BIT_MASK(32); |
399 | 400 | ||
400 | struct platform_device mxc_sdhc_device0 = { | 401 | struct platform_device mxc_sdhc_device0 = { |
401 | .name = "mxc-mmc", | 402 | .name = "mxc-mmc", |
402 | .id = 0, | 403 | .id = 0, |
403 | .dev = { | 404 | .dev = { |
404 | .dma_mask = &mxc_sdhc1_dmamask, | 405 | .dma_mask = &mxc_sdhc1_dmamask, |
405 | .coherent_dma_mask = 0xffffffff, | 406 | .coherent_dma_mask = DMA_BIT_MASK(32), |
406 | }, | 407 | }, |
407 | .num_resources = ARRAY_SIZE(mxc_sdhc1_resources), | 408 | .num_resources = ARRAY_SIZE(mxc_sdhc1_resources), |
408 | .resource = mxc_sdhc1_resources, | 409 | .resource = mxc_sdhc1_resources, |
409 | }; | 410 | }; |
410 | 411 | ||
411 | static struct resource mxc_sdhc2_resources[] = { | 412 | static struct resource mxc_sdhc2_resources[] = { |
@@ -424,17 +425,17 @@ static struct resource mxc_sdhc2_resources[] = { | |||
424 | }, | 425 | }, |
425 | }; | 426 | }; |
426 | 427 | ||
427 | static u64 mxc_sdhc2_dmamask = 0xffffffffUL; | 428 | static u64 mxc_sdhc2_dmamask = DMA_BIT_MASK(32); |
428 | 429 | ||
429 | struct platform_device mxc_sdhc_device1 = { | 430 | struct platform_device mxc_sdhc_device1 = { |
430 | .name = "mxc-mmc", | 431 | .name = "mxc-mmc", |
431 | .id = 1, | 432 | .id = 1, |
432 | .dev = { | 433 | .dev = { |
433 | .dma_mask = &mxc_sdhc2_dmamask, | 434 | .dma_mask = &mxc_sdhc2_dmamask, |
434 | .coherent_dma_mask = 0xffffffff, | 435 | .coherent_dma_mask = DMA_BIT_MASK(32), |
435 | }, | 436 | }, |
436 | .num_resources = ARRAY_SIZE(mxc_sdhc2_resources), | 437 | .num_resources = ARRAY_SIZE(mxc_sdhc2_resources), |
437 | .resource = mxc_sdhc2_resources, | 438 | .resource = mxc_sdhc2_resources, |
438 | }; | 439 | }; |
439 | 440 | ||
440 | #ifdef CONFIG_MACH_MX27 | 441 | #ifdef CONFIG_MACH_MX27 |
@@ -450,7 +451,7 @@ static struct resource otg_resources[] = { | |||
450 | }, | 451 | }, |
451 | }; | 452 | }; |
452 | 453 | ||
453 | static u64 otg_dmamask = 0xffffffffUL; | 454 | static u64 otg_dmamask = DMA_BIT_MASK(32); |
454 | 455 | ||
455 | /* OTG gadget device */ | 456 | /* OTG gadget device */ |
456 | struct platform_device mxc_otg_udc_device = { | 457 | struct platform_device mxc_otg_udc_device = { |
@@ -458,7 +459,7 @@ struct platform_device mxc_otg_udc_device = { | |||
458 | .id = -1, | 459 | .id = -1, |
459 | .dev = { | 460 | .dev = { |
460 | .dma_mask = &otg_dmamask, | 461 | .dma_mask = &otg_dmamask, |
461 | .coherent_dma_mask = 0xffffffffUL, | 462 | .coherent_dma_mask = DMA_BIT_MASK(32), |
462 | }, | 463 | }, |
463 | .resource = otg_resources, | 464 | .resource = otg_resources, |
464 | .num_resources = ARRAY_SIZE(otg_resources), | 465 | .num_resources = ARRAY_SIZE(otg_resources), |
@@ -469,7 +470,7 @@ struct platform_device mxc_otg_host = { | |||
469 | .name = "mxc-ehci", | 470 | .name = "mxc-ehci", |
470 | .id = 0, | 471 | .id = 0, |
471 | .dev = { | 472 | .dev = { |
472 | .coherent_dma_mask = 0xffffffff, | 473 | .coherent_dma_mask = DMA_BIT_MASK(32), |
473 | .dma_mask = &otg_dmamask, | 474 | .dma_mask = &otg_dmamask, |
474 | }, | 475 | }, |
475 | .resource = otg_resources, | 476 | .resource = otg_resources, |
@@ -478,7 +479,7 @@ struct platform_device mxc_otg_host = { | |||
478 | 479 | ||
479 | /* USB host 1 */ | 480 | /* USB host 1 */ |
480 | 481 | ||
481 | static u64 usbh1_dmamask = 0xffffffffUL; | 482 | static u64 usbh1_dmamask = DMA_BIT_MASK(32); |
482 | 483 | ||
483 | static struct resource mxc_usbh1_resources[] = { | 484 | static struct resource mxc_usbh1_resources[] = { |
484 | { | 485 | { |
@@ -496,7 +497,7 @@ struct platform_device mxc_usbh1 = { | |||
496 | .name = "mxc-ehci", | 497 | .name = "mxc-ehci", |
497 | .id = 1, | 498 | .id = 1, |
498 | .dev = { | 499 | .dev = { |
499 | .coherent_dma_mask = 0xffffffff, | 500 | .coherent_dma_mask = DMA_BIT_MASK(32), |
500 | .dma_mask = &usbh1_dmamask, | 501 | .dma_mask = &usbh1_dmamask, |
501 | }, | 502 | }, |
502 | .resource = mxc_usbh1_resources, | 503 | .resource = mxc_usbh1_resources, |
@@ -504,7 +505,7 @@ struct platform_device mxc_usbh1 = { | |||
504 | }; | 505 | }; |
505 | 506 | ||
506 | /* USB host 2 */ | 507 | /* USB host 2 */ |
507 | static u64 usbh2_dmamask = 0xffffffffUL; | 508 | static u64 usbh2_dmamask = DMA_BIT_MASK(32); |
508 | 509 | ||
509 | static struct resource mxc_usbh2_resources[] = { | 510 | static struct resource mxc_usbh2_resources[] = { |
510 | { | 511 | { |
@@ -522,7 +523,7 @@ struct platform_device mxc_usbh2 = { | |||
522 | .name = "mxc-ehci", | 523 | .name = "mxc-ehci", |
523 | .id = 2, | 524 | .id = 2, |
524 | .dev = { | 525 | .dev = { |
525 | .coherent_dma_mask = 0xffffffff, | 526 | .coherent_dma_mask = DMA_BIT_MASK(32), |
526 | .dma_mask = &usbh2_dmamask, | 527 | .dma_mask = &usbh2_dmamask, |
527 | }, | 528 | }, |
528 | .resource = mxc_usbh2_resources, | 529 | .resource = mxc_usbh2_resources, |
@@ -642,3 +643,30 @@ int __init mxc_register_gpios(void) | |||
642 | { | 643 | { |
643 | return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); | 644 | return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); |
644 | } | 645 | } |
646 | |||
647 | #ifdef CONFIG_MACH_MX21 | ||
648 | static struct resource mx21_usbhc_resources[] = { | ||
649 | { | ||
650 | .start = USBOTG_BASE_ADDR, | ||
651 | .end = USBOTG_BASE_ADDR + 0x1FFF, | ||
652 | .flags = IORESOURCE_MEM, | ||
653 | }, | ||
654 | { | ||
655 | .start = MXC_INT_USBHOST, | ||
656 | .end = MXC_INT_USBHOST, | ||
657 | .flags = IORESOURCE_IRQ, | ||
658 | }, | ||
659 | }; | ||
660 | |||
661 | struct platform_device mx21_usbhc_device = { | ||
662 | .name = "imx21-hcd", | ||
663 | .id = 0, | ||
664 | .dev = { | ||
665 | .dma_mask = &mx21_usbhc_device.dev.coherent_dma_mask, | ||
666 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
667 | }, | ||
668 | .num_resources = ARRAY_SIZE(mx21_usbhc_resources), | ||
669 | .resource = mx21_usbhc_resources, | ||
670 | }; | ||
671 | #endif | ||
672 | |||
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h index 97306aa18f1c..f12694b07369 100644 --- a/arch/arm/mach-mx2/devices.h +++ b/arch/arm/mach-mx2/devices.h | |||
@@ -26,5 +26,6 @@ extern struct platform_device mxc_usbh2; | |||
26 | extern struct platform_device mxc_spi_device0; | 26 | extern struct platform_device mxc_spi_device0; |
27 | extern struct platform_device mxc_spi_device1; | 27 | extern struct platform_device mxc_spi_device1; |
28 | extern struct platform_device mxc_spi_device2; | 28 | extern struct platform_device mxc_spi_device2; |
29 | extern struct platform_device mx21_usbhc_device; | ||
29 | extern struct platform_device imx_ssi_device0; | 30 | extern struct platform_device imx_ssi_device0; |
30 | extern struct platform_device imx_ssi_device1; | 31 | extern struct platform_device imx_ssi_device1; |
diff --git a/arch/arm/plat-mxc/include/mach/mx21-usbhost.h b/arch/arm/plat-mxc/include/mach/mx21-usbhost.h new file mode 100644 index 000000000000..22d0b596262c --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx21-usbhost.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Martin Fuzzey <mfuzzey@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ASM_ARCH_MX21_USBH | ||
16 | #define __ASM_ARCH_MX21_USBH | ||
17 | |||
18 | enum mx21_usbh_xcvr { | ||
19 | /* Values below as used by hardware (HWMODE register) */ | ||
20 | MX21_USBXCVR_TXDIF_RXDIF = 0, | ||
21 | MX21_USBXCVR_TXDIF_RXSE = 1, | ||
22 | MX21_USBXCVR_TXSE_RXDIF = 2, | ||
23 | MX21_USBXCVR_TXSE_RXSE = 3, | ||
24 | }; | ||
25 | |||
26 | struct mx21_usbh_platform_data { | ||
27 | enum mx21_usbh_xcvr host_xcvr; /* tranceiver mode host 1,2 ports */ | ||
28 | enum mx21_usbh_xcvr otg_xcvr; /* tranceiver mode otg (as host) port */ | ||
29 | u16 enable_host1:1, | ||
30 | enable_host2:1, | ||
31 | enable_otg_host:1, /* enable "OTG" port (as host) */ | ||
32 | host1_xcverless:1, /* traceiverless host1 port */ | ||
33 | host1_txenoe:1, /* output enable host1 transmit enable */ | ||
34 | otg_ext_xcvr:1, /* external tranceiver for OTG port */ | ||
35 | unused:10; | ||
36 | }; | ||
37 | |||
38 | #endif /* __ASM_ARCH_MX21_USBH */ | ||
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index b13d1879e51b..3a4bc1a18433 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c | |||
@@ -1770,10 +1770,13 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data) | |||
1770 | ARRAY_SIZE(usba0_resource))) | 1770 | ARRAY_SIZE(usba0_resource))) |
1771 | goto out_free_pdev; | 1771 | goto out_free_pdev; |
1772 | 1772 | ||
1773 | if (data) | 1773 | if (data) { |
1774 | usba_data.pdata.vbus_pin = data->vbus_pin; | 1774 | usba_data.pdata.vbus_pin = data->vbus_pin; |
1775 | else | 1775 | usba_data.pdata.vbus_pin_inverted = data->vbus_pin_inverted; |
1776 | } else { | ||
1776 | usba_data.pdata.vbus_pin = -EINVAL; | 1777 | usba_data.pdata.vbus_pin = -EINVAL; |
1778 | usba_data.pdata.vbus_pin_inverted = -EINVAL; | ||
1779 | } | ||
1777 | 1780 | ||
1778 | data = &usba_data.pdata; | 1781 | data = &usba_data.pdata; |
1779 | data->num_ep = ARRAY_SIZE(at32_usba_ep); | 1782 | data->num_ep = ARRAY_SIZE(at32_usba_ep); |
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index f27c4d6d956e..af8d97715728 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c | |||
@@ -231,9 +231,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
231 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 231 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
232 | 232 | ||
233 | /** | 233 | /** |
234 | * tty_insert_flip_string - Add characters to the tty buffer | 234 | * tty_insert_flip_string_fixed_flag - Add characters to the tty buffer |
235 | * @tty: tty structure | 235 | * @tty: tty structure |
236 | * @chars: characters | 236 | * @chars: characters |
237 | * @flag: flag value for each character | ||
237 | * @size: size | 238 | * @size: size |
238 | * | 239 | * |
239 | * Queue a series of bytes to the tty buffering. All the characters | 240 | * Queue a series of bytes to the tty buffering. All the characters |
@@ -242,8 +243,8 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); | |||
242 | * Locking: Called functions may take tty->buf.lock | 243 | * Locking: Called functions may take tty->buf.lock |
243 | */ | 244 | */ |
244 | 245 | ||
245 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | 246 | int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, |
246 | size_t size) | 247 | const unsigned char *chars, char flag, size_t size) |
247 | { | 248 | { |
248 | int copied = 0; | 249 | int copied = 0; |
249 | do { | 250 | do { |
@@ -254,7 +255,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | |||
254 | if (unlikely(space == 0)) | 255 | if (unlikely(space == 0)) |
255 | break; | 256 | break; |
256 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 257 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
257 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | 258 | memset(tb->flag_buf_ptr + tb->used, flag, space); |
258 | tb->used += space; | 259 | tb->used += space; |
259 | copied += space; | 260 | copied += space; |
260 | chars += space; | 261 | chars += space; |
@@ -263,7 +264,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | |||
263 | } while (unlikely(size > copied)); | 264 | } while (unlikely(size > copied)); |
264 | return copied; | 265 | return copied; |
265 | } | 266 | } |
266 | EXPORT_SYMBOL(tty_insert_flip_string); | 267 | EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); |
267 | 268 | ||
268 | /** | 269 | /** |
269 | * tty_insert_flip_string_flags - Add characters to the tty buffer | 270 | * tty_insert_flip_string_flags - Add characters to the tty buffer |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 867e08433e4b..433602aed468 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -265,9 +265,10 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
265 | static int hiddev_open(struct inode *inode, struct file *file) | 265 | static int hiddev_open(struct inode *inode, struct file *file) |
266 | { | 266 | { |
267 | struct hiddev_list *list; | 267 | struct hiddev_list *list; |
268 | int res; | 268 | int res, i; |
269 | 269 | ||
270 | int i = iminor(inode) - HIDDEV_MINOR_BASE; | 270 | lock_kernel(); |
271 | i = iminor(inode) - HIDDEV_MINOR_BASE; | ||
271 | 272 | ||
272 | if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i]) | 273 | if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i]) |
273 | return -ENODEV; | 274 | return -ENODEV; |
@@ -313,10 +314,12 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
313 | usbhid_open(hid); | 314 | usbhid_open(hid); |
314 | } | 315 | } |
315 | 316 | ||
317 | unlock_kernel(); | ||
316 | return 0; | 318 | return 0; |
317 | bail: | 319 | bail: |
318 | file->private_data = NULL; | 320 | file->private_data = NULL; |
319 | kfree(list); | 321 | kfree(list); |
322 | unlock_kernel(); | ||
320 | return res; | 323 | return res; |
321 | } | 324 | } |
322 | 325 | ||
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index 9b413a35e048..0f505086774c 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c | |||
@@ -616,10 +616,12 @@ static int dabusb_open (struct inode *inode, struct file *file) | |||
616 | { | 616 | { |
617 | int devnum = iminor(inode); | 617 | int devnum = iminor(inode); |
618 | pdabusb_t s; | 618 | pdabusb_t s; |
619 | int r; | ||
619 | 620 | ||
620 | if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB)) | 621 | if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB)) |
621 | return -EIO; | 622 | return -EIO; |
622 | 623 | ||
624 | lock_kernel(); | ||
623 | s = &dabusb[devnum - DABUSB_MINOR]; | 625 | s = &dabusb[devnum - DABUSB_MINOR]; |
624 | 626 | ||
625 | dbg("dabusb_open"); | 627 | dbg("dabusb_open"); |
@@ -634,6 +636,7 @@ static int dabusb_open (struct inode *inode, struct file *file) | |||
634 | msleep_interruptible(500); | 636 | msleep_interruptible(500); |
635 | 637 | ||
636 | if (signal_pending (current)) { | 638 | if (signal_pending (current)) { |
639 | unlock_kernel(); | ||
637 | return -EAGAIN; | 640 | return -EAGAIN; |
638 | } | 641 | } |
639 | mutex_lock(&s->mutex); | 642 | mutex_lock(&s->mutex); |
@@ -641,6 +644,7 @@ static int dabusb_open (struct inode *inode, struct file *file) | |||
641 | if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { | 644 | if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { |
642 | mutex_unlock(&s->mutex); | 645 | mutex_unlock(&s->mutex); |
643 | dev_err(&s->usbdev->dev, "set_interface failed\n"); | 646 | dev_err(&s->usbdev->dev, "set_interface failed\n"); |
647 | unlock_kernel(); | ||
644 | return -EINVAL; | 648 | return -EINVAL; |
645 | } | 649 | } |
646 | s->opened = 1; | 650 | s->opened = 1; |
@@ -649,7 +653,9 @@ static int dabusb_open (struct inode *inode, struct file *file) | |||
649 | file->f_pos = 0; | 653 | file->f_pos = 0; |
650 | file->private_data = s; | 654 | file->private_data = s; |
651 | 655 | ||
652 | return nonseekable_open(inode, file); | 656 | r = nonseekable_open(inode, file); |
657 | unlock_kernel(); | ||
658 | return r; | ||
653 | } | 659 | } |
654 | 660 | ||
655 | static int dabusb_release (struct inode *inode, struct file *file) | 661 | static int dabusb_release (struct inode *inode, struct file *file) |
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index d8992d10d555..f6e34e03c8e4 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c | |||
@@ -144,7 +144,7 @@ static int valid_args(__u32 rhport, enum usb_device_speed speed) | |||
144 | case USB_SPEED_LOW: | 144 | case USB_SPEED_LOW: |
145 | case USB_SPEED_FULL: | 145 | case USB_SPEED_FULL: |
146 | case USB_SPEED_HIGH: | 146 | case USB_SPEED_HIGH: |
147 | case USB_SPEED_VARIABLE: | 147 | case USB_SPEED_WIRELESS: |
148 | break; | 148 | break; |
149 | default: | 149 | default: |
150 | usbip_uerr("speed %d\n", speed); | 150 | usbip_uerr("speed %d\n", speed); |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 4f5bb5698f5d..6a58cb1330c1 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD | |||
21 | default y if USB_ARCH_HAS_EHCI | 21 | default y if USB_ARCH_HAS_EHCI |
22 | default y if PCMCIA && !M32R # sl811_cs | 22 | default y if PCMCIA && !M32R # sl811_cs |
23 | default y if ARM # SL-811 | 23 | default y if ARM # SL-811 |
24 | default y if BLACKFIN # SL-811 | ||
24 | default y if SUPERH # r8a66597-hcd | 25 | default y if SUPERH # r8a66597-hcd |
25 | default PCI | 26 | default PCI |
26 | 27 | ||
@@ -39,6 +40,7 @@ config USB_ARCH_HAS_OHCI | |||
39 | default y if ARCH_PNX4008 && I2C | 40 | default y if ARCH_PNX4008 && I2C |
40 | default y if MFD_TC6393XB | 41 | default y if MFD_TC6393XB |
41 | default y if ARCH_W90X900 | 42 | default y if ARCH_W90X900 |
43 | default y if ARCH_DAVINCI_DA8XX | ||
42 | # PPC: | 44 | # PPC: |
43 | default y if STB03xxx | 45 | default y if STB03xxx |
44 | default y if PPC_MPC52xx | 46 | default y if PPC_MPC52xx |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index be3c9b80bc9f..80b4008c89ba 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_USB_U132_HCD) += host/ | |||
21 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ | 21 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ |
22 | obj-$(CONFIG_USB_HWA_HCD) += host/ | 22 | obj-$(CONFIG_USB_HWA_HCD) += host/ |
23 | obj-$(CONFIG_USB_ISP1760_HCD) += host/ | 23 | obj-$(CONFIG_USB_ISP1760_HCD) += host/ |
24 | obj-$(CONFIG_USB_IMX21_HCD) += host/ | ||
24 | 25 | ||
25 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ | 26 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ |
26 | 27 | ||
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 56802d2e994b..c89990f5e018 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan | 5 | * Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan |
6 | * Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru) | 6 | * Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru) |
7 | * Copyright (C) 2007 Simon Arlott | 7 | * Copyright (C) 2007 Simon Arlott |
8 | * Copyright (C) 2009 Simon Arlott | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the Free | 11 | * under the terms of the GNU General Public License as published by the Free |
@@ -43,7 +44,7 @@ | |||
43 | #include "usbatm.h" | 44 | #include "usbatm.h" |
44 | 45 | ||
45 | #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott" | 46 | #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott" |
46 | #define DRIVER_VERSION "0.3" | 47 | #define DRIVER_VERSION "0.4" |
47 | #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" | 48 | #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" |
48 | 49 | ||
49 | static const char cxacru_driver_name[] = "cxacru"; | 50 | static const char cxacru_driver_name[] = "cxacru"; |
@@ -52,6 +53,7 @@ static const char cxacru_driver_name[] = "cxacru"; | |||
52 | #define CXACRU_EP_DATA 0x02 /* Bulk in/out */ | 53 | #define CXACRU_EP_DATA 0x02 /* Bulk in/out */ |
53 | 54 | ||
54 | #define CMD_PACKET_SIZE 64 /* Should be maxpacket(ep)? */ | 55 | #define CMD_PACKET_SIZE 64 /* Should be maxpacket(ep)? */ |
56 | #define CMD_MAX_CONFIG ((CMD_PACKET_SIZE / 4 - 1) / 2) | ||
55 | 57 | ||
56 | /* Addresses */ | 58 | /* Addresses */ |
57 | #define PLLFCLK_ADDR 0x00350068 | 59 | #define PLLFCLK_ADDR 0x00350068 |
@@ -105,6 +107,26 @@ enum cxacru_cm_request { | |||
105 | CM_REQUEST_MAX, | 107 | CM_REQUEST_MAX, |
106 | }; | 108 | }; |
107 | 109 | ||
110 | /* commands for interaction with the flash memory | ||
111 | * | ||
112 | * read: response is the contents of the first 60 bytes of flash memory | ||
113 | * write: request contains the 60 bytes of data to write to flash memory | ||
114 | * response is the contents of the first 60 bytes of flash memory | ||
115 | * | ||
116 | * layout: PP PP VV VV MM MM MM MM MM MM ?? ?? SS SS SS SS SS SS SS SS | ||
117 | * SS SS SS SS SS SS SS SS 00 00 00 00 00 00 00 00 00 00 00 00 | ||
118 | * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
119 | * | ||
120 | * P: le16 USB Product ID | ||
121 | * V: le16 USB Vendor ID | ||
122 | * M: be48 MAC Address | ||
123 | * S: le16 ASCII Serial Number | ||
124 | */ | ||
125 | enum cxacru_cm_flash { | ||
126 | CM_FLASH_READ = 0xa1, | ||
127 | CM_FLASH_WRITE = 0xa2 | ||
128 | }; | ||
129 | |||
108 | /* reply codes to the commands above */ | 130 | /* reply codes to the commands above */ |
109 | enum cxacru_cm_status { | 131 | enum cxacru_cm_status { |
110 | CM_STATUS_UNDEFINED, | 132 | CM_STATUS_UNDEFINED, |
@@ -196,23 +218,32 @@ static DEVICE_ATTR(_name, S_IRUGO, cxacru_sysfs_show_##_name, NULL) | |||
196 | static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ | 218 | static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ |
197 | cxacru_sysfs_show_##_name, cxacru_sysfs_store_##_name) | 219 | cxacru_sysfs_show_##_name, cxacru_sysfs_store_##_name) |
198 | 220 | ||
221 | #define CXACRU_SET_INIT(_name) \ | ||
222 | static DEVICE_ATTR(_name, S_IWUSR, \ | ||
223 | NULL, cxacru_sysfs_store_##_name) | ||
224 | |||
199 | #define CXACRU_ATTR_INIT(_value, _type, _name) \ | 225 | #define CXACRU_ATTR_INIT(_value, _type, _name) \ |
200 | static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \ | 226 | static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \ |
201 | struct device_attribute *attr, char *buf) \ | 227 | struct device_attribute *attr, char *buf) \ |
202 | { \ | 228 | { \ |
203 | struct usb_interface *intf = to_usb_interface(dev); \ | 229 | struct cxacru_data *instance = to_usbatm_driver_data(\ |
204 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); \ | 230 | to_usb_interface(dev)); \ |
205 | struct cxacru_data *instance = usbatm_instance->driver_data; \ | 231 | \ |
232 | if (instance == NULL) \ | ||
233 | return -ENODEV; \ | ||
234 | \ | ||
206 | return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \ | 235 | return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \ |
207 | } \ | 236 | } \ |
208 | CXACRU__ATTR_INIT(_name) | 237 | CXACRU__ATTR_INIT(_name) |
209 | 238 | ||
210 | #define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name) | 239 | #define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name) |
211 | #define CXACRU_CMD_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) | 240 | #define CXACRU_CMD_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) |
241 | #define CXACRU_SET_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) | ||
212 | #define CXACRU__ATTR_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) | 242 | #define CXACRU__ATTR_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) |
213 | 243 | ||
214 | #define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name) | 244 | #define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name) |
215 | #define CXACRU_CMD_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) | 245 | #define CXACRU_CMD_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) |
246 | #define CXACRU_SET_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) | ||
216 | #define CXACRU__ATTR_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) | 247 | #define CXACRU__ATTR_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) |
217 | 248 | ||
218 | static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf) | 249 | static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf) |
@@ -267,12 +298,12 @@ static ssize_t cxacru_sysfs_showattr_LINE(u32 value, char *buf) | |||
267 | static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) | 298 | static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) |
268 | { | 299 | { |
269 | static char *str[] = { | 300 | static char *str[] = { |
270 | NULL, | 301 | "", |
271 | "ANSI T1.413", | 302 | "ANSI T1.413", |
272 | "ITU-T G.992.1 (G.DMT)", | 303 | "ITU-T G.992.1 (G.DMT)", |
273 | "ITU-T G.992.2 (G.LITE)" | 304 | "ITU-T G.992.2 (G.LITE)" |
274 | }; | 305 | }; |
275 | if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL)) | 306 | if (unlikely(value >= ARRAY_SIZE(str))) |
276 | return snprintf(buf, PAGE_SIZE, "%u\n", value); | 307 | return snprintf(buf, PAGE_SIZE, "%u\n", value); |
277 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); | 308 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); |
278 | } | 309 | } |
@@ -288,22 +319,28 @@ static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) | |||
288 | static ssize_t cxacru_sysfs_show_mac_address(struct device *dev, | 319 | static ssize_t cxacru_sysfs_show_mac_address(struct device *dev, |
289 | struct device_attribute *attr, char *buf) | 320 | struct device_attribute *attr, char *buf) |
290 | { | 321 | { |
291 | struct usb_interface *intf = to_usb_interface(dev); | 322 | struct cxacru_data *instance = to_usbatm_driver_data( |
292 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); | 323 | to_usb_interface(dev)); |
293 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; | ||
294 | 324 | ||
295 | return snprintf(buf, PAGE_SIZE, "%pM\n", atm_dev->esi); | 325 | if (instance == NULL || instance->usbatm->atm_dev == NULL) |
326 | return -ENODEV; | ||
327 | |||
328 | return snprintf(buf, PAGE_SIZE, "%pM\n", | ||
329 | instance->usbatm->atm_dev->esi); | ||
296 | } | 330 | } |
297 | 331 | ||
298 | static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, | 332 | static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, |
299 | struct device_attribute *attr, char *buf) | 333 | struct device_attribute *attr, char *buf) |
300 | { | 334 | { |
301 | struct usb_interface *intf = to_usb_interface(dev); | ||
302 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); | ||
303 | struct cxacru_data *instance = usbatm_instance->driver_data; | ||
304 | u32 value = instance->card_info[CXINF_LINE_STARTABLE]; | ||
305 | |||
306 | static char *str[] = { "running", "stopped" }; | 335 | static char *str[] = { "running", "stopped" }; |
336 | struct cxacru_data *instance = to_usbatm_driver_data( | ||
337 | to_usb_interface(dev)); | ||
338 | u32 value; | ||
339 | |||
340 | if (instance == NULL) | ||
341 | return -ENODEV; | ||
342 | |||
343 | value = instance->card_info[CXINF_LINE_STARTABLE]; | ||
307 | if (unlikely(value >= ARRAY_SIZE(str))) | 344 | if (unlikely(value >= ARRAY_SIZE(str))) |
308 | return snprintf(buf, PAGE_SIZE, "%u\n", value); | 345 | return snprintf(buf, PAGE_SIZE, "%u\n", value); |
309 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); | 346 | return snprintf(buf, PAGE_SIZE, "%s\n", str[value]); |
@@ -312,9 +349,8 @@ static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, | |||
312 | static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | 349 | static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, |
313 | struct device_attribute *attr, const char *buf, size_t count) | 350 | struct device_attribute *attr, const char *buf, size_t count) |
314 | { | 351 | { |
315 | struct usb_interface *intf = to_usb_interface(dev); | 352 | struct cxacru_data *instance = to_usbatm_driver_data( |
316 | struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); | 353 | to_usb_interface(dev)); |
317 | struct cxacru_data *instance = usbatm_instance->driver_data; | ||
318 | int ret; | 354 | int ret; |
319 | int poll = -1; | 355 | int poll = -1; |
320 | char str_cmd[8]; | 356 | char str_cmd[8]; |
@@ -328,13 +364,16 @@ static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | |||
328 | return -EINVAL; | 364 | return -EINVAL; |
329 | ret = 0; | 365 | ret = 0; |
330 | 366 | ||
367 | if (instance == NULL) | ||
368 | return -ENODEV; | ||
369 | |||
331 | if (mutex_lock_interruptible(&instance->adsl_state_serialize)) | 370 | if (mutex_lock_interruptible(&instance->adsl_state_serialize)) |
332 | return -ERESTARTSYS; | 371 | return -ERESTARTSYS; |
333 | 372 | ||
334 | if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) { | 373 | if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) { |
335 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0); | 374 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0); |
336 | if (ret < 0) { | 375 | if (ret < 0) { |
337 | atm_err(usbatm_instance, "change adsl state:" | 376 | atm_err(instance->usbatm, "change adsl state:" |
338 | " CHIP_ADSL_LINE_STOP returned %d\n", ret); | 377 | " CHIP_ADSL_LINE_STOP returned %d\n", ret); |
339 | 378 | ||
340 | ret = -EIO; | 379 | ret = -EIO; |
@@ -354,7 +393,7 @@ static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | |||
354 | if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) { | 393 | if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) { |
355 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); | 394 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); |
356 | if (ret < 0) { | 395 | if (ret < 0) { |
357 | atm_err(usbatm_instance, "change adsl state:" | 396 | atm_err(instance->usbatm, "change adsl state:" |
358 | " CHIP_ADSL_LINE_START returned %d\n", ret); | 397 | " CHIP_ADSL_LINE_START returned %d\n", ret); |
359 | 398 | ||
360 | ret = -EIO; | 399 | ret = -EIO; |
@@ -407,6 +446,72 @@ static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, | |||
407 | return ret; | 446 | return ret; |
408 | } | 447 | } |
409 | 448 | ||
449 | /* CM_REQUEST_CARD_DATA_GET times out, so no show attribute */ | ||
450 | |||
451 | static ssize_t cxacru_sysfs_store_adsl_config(struct device *dev, | ||
452 | struct device_attribute *attr, const char *buf, size_t count) | ||
453 | { | ||
454 | struct cxacru_data *instance = to_usbatm_driver_data( | ||
455 | to_usb_interface(dev)); | ||
456 | int len = strlen(buf); | ||
457 | int ret, pos, num; | ||
458 | __le32 data[CMD_PACKET_SIZE / 4]; | ||
459 | |||
460 | if (!capable(CAP_NET_ADMIN)) | ||
461 | return -EACCES; | ||
462 | |||
463 | if (instance == NULL) | ||
464 | return -ENODEV; | ||
465 | |||
466 | pos = 0; | ||
467 | num = 0; | ||
468 | while (pos < len) { | ||
469 | int tmp; | ||
470 | u32 index; | ||
471 | u32 value; | ||
472 | |||
473 | ret = sscanf(buf + pos, "%x=%x%n", &index, &value, &tmp); | ||
474 | if (ret < 2) | ||
475 | return -EINVAL; | ||
476 | if (index < 0 || index > 0x7f) | ||
477 | return -EINVAL; | ||
478 | pos += tmp; | ||
479 | |||
480 | /* skip trailing newline */ | ||
481 | if (buf[pos] == '\n' && pos == len-1) | ||
482 | pos++; | ||
483 | |||
484 | data[num * 2 + 1] = cpu_to_le32(index); | ||
485 | data[num * 2 + 2] = cpu_to_le32(value); | ||
486 | num++; | ||
487 | |||
488 | /* send config values when data buffer is full | ||
489 | * or no more data | ||
490 | */ | ||
491 | if (pos >= len || num >= CMD_MAX_CONFIG) { | ||
492 | char log[CMD_MAX_CONFIG * 12 + 1]; /* %02x=%08x */ | ||
493 | |||
494 | data[0] = cpu_to_le32(num); | ||
495 | ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET, | ||
496 | (u8 *) data, 4 + num * 8, NULL, 0); | ||
497 | if (ret < 0) { | ||
498 | atm_err(instance->usbatm, | ||
499 | "set card data returned %d\n", ret); | ||
500 | return -EIO; | ||
501 | } | ||
502 | |||
503 | for (tmp = 0; tmp < num; tmp++) | ||
504 | snprintf(log + tmp*12, 13, " %02x=%08x", | ||
505 | le32_to_cpu(data[tmp * 2 + 1]), | ||
506 | le32_to_cpu(data[tmp * 2 + 2])); | ||
507 | atm_info(instance->usbatm, "config%s\n", log); | ||
508 | num = 0; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | return len; | ||
513 | } | ||
514 | |||
410 | /* | 515 | /* |
411 | * All device attributes are included in CXACRU_ALL_FILES | 516 | * All device attributes are included in CXACRU_ALL_FILES |
412 | * so that the same list can be used multiple times: | 517 | * so that the same list can be used multiple times: |
@@ -442,7 +547,8 @@ CXACRU_ATTR_##_action(CXINF_MODULATION, MODU, modulation); \ | |||
442 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \ | 547 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \ |
443 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \ | 548 | CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \ |
444 | CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); \ | 549 | CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); \ |
445 | CXACRU_CMD_##_action( adsl_state); | 550 | CXACRU_CMD_##_action( adsl_state); \ |
551 | CXACRU_SET_##_action( adsl_config); | ||
446 | 552 | ||
447 | CXACRU_ALL_FILES(INIT); | 553 | CXACRU_ALL_FILES(INIT); |
448 | 554 | ||
@@ -596,7 +702,7 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ | |||
596 | len = ret / 4; | 702 | len = ret / 4; |
597 | for (offb = 0; offb < len; ) { | 703 | for (offb = 0; offb < len; ) { |
598 | int l = le32_to_cpu(buf[offb++]); | 704 | int l = le32_to_cpu(buf[offb++]); |
599 | if (l > stride || l > (len - offb) / 2) { | 705 | if (l < 0 || l > stride || l > (len - offb) / 2) { |
600 | if (printk_ratelimit()) | 706 | if (printk_ratelimit()) |
601 | usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n", | 707 | usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n", |
602 | cm, l); | 708 | cm, l); |
@@ -649,9 +755,6 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
649 | { | 755 | { |
650 | struct cxacru_data *instance = usbatm_instance->driver_data; | 756 | struct cxacru_data *instance = usbatm_instance->driver_data; |
651 | struct usb_interface *intf = usbatm_instance->usb_intf; | 757 | struct usb_interface *intf = usbatm_instance->usb_intf; |
652 | /* | ||
653 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; | ||
654 | */ | ||
655 | int ret; | 758 | int ret; |
656 | int start_polling = 1; | 759 | int start_polling = 1; |
657 | 760 | ||
@@ -697,6 +800,9 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
697 | mutex_unlock(&instance->poll_state_serialize); | 800 | mutex_unlock(&instance->poll_state_serialize); |
698 | mutex_unlock(&instance->adsl_state_serialize); | 801 | mutex_unlock(&instance->adsl_state_serialize); |
699 | 802 | ||
803 | printk(KERN_INFO "%s%d: %s %pM\n", atm_dev->type, atm_dev->number, | ||
804 | usbatm_instance->description, atm_dev->esi); | ||
805 | |||
700 | if (start_polling) | 806 | if (start_polling) |
701 | cxacru_poll_status(&instance->poll_work.work); | 807 | cxacru_poll_status(&instance->poll_work.work); |
702 | return 0; | 808 | return 0; |
@@ -873,11 +979,9 @@ cleanup: | |||
873 | 979 | ||
874 | static void cxacru_upload_firmware(struct cxacru_data *instance, | 980 | static void cxacru_upload_firmware(struct cxacru_data *instance, |
875 | const struct firmware *fw, | 981 | const struct firmware *fw, |
876 | const struct firmware *bp, | 982 | const struct firmware *bp) |
877 | const struct firmware *cf) | ||
878 | { | 983 | { |
879 | int ret; | 984 | int ret; |
880 | int off; | ||
881 | struct usbatm_data *usbatm = instance->usbatm; | 985 | struct usbatm_data *usbatm = instance->usbatm; |
882 | struct usb_device *usb_dev = usbatm->usb_dev; | 986 | struct usb_device *usb_dev = usbatm->usb_dev; |
883 | __le16 signature[] = { usb_dev->descriptor.idVendor, | 987 | __le16 signature[] = { usb_dev->descriptor.idVendor, |
@@ -911,6 +1015,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
911 | } | 1015 | } |
912 | 1016 | ||
913 | /* Firmware */ | 1017 | /* Firmware */ |
1018 | usb_info(usbatm, "loading firmware\n"); | ||
914 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); | 1019 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); |
915 | if (ret) { | 1020 | if (ret) { |
916 | usb_err(usbatm, "Firmware upload failed: %d\n", ret); | 1021 | usb_err(usbatm, "Firmware upload failed: %d\n", ret); |
@@ -919,6 +1024,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
919 | 1024 | ||
920 | /* Boot ROM patch */ | 1025 | /* Boot ROM patch */ |
921 | if (instance->modem_type->boot_rom_patch) { | 1026 | if (instance->modem_type->boot_rom_patch) { |
1027 | usb_info(usbatm, "loading boot ROM patch\n"); | ||
922 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); | 1028 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); |
923 | if (ret) { | 1029 | if (ret) { |
924 | usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); | 1030 | usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); |
@@ -933,6 +1039,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
933 | return; | 1039 | return; |
934 | } | 1040 | } |
935 | 1041 | ||
1042 | usb_info(usbatm, "starting device\n"); | ||
936 | if (instance->modem_type->boot_rom_patch) { | 1043 | if (instance->modem_type->boot_rom_patch) { |
937 | val = cpu_to_le32(BR_ADDR); | 1044 | val = cpu_to_le32(BR_ADDR); |
938 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); | 1045 | ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); |
@@ -958,26 +1065,6 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, | |||
958 | usb_err(usbatm, "modem failed to initialize: %d\n", ret); | 1065 | usb_err(usbatm, "modem failed to initialize: %d\n", ret); |
959 | return; | 1066 | return; |
960 | } | 1067 | } |
961 | |||
962 | /* Load config data (le32), doing one packet at a time */ | ||
963 | if (cf) | ||
964 | for (off = 0; off < cf->size / 4; ) { | ||
965 | __le32 buf[CMD_PACKET_SIZE / 4 - 1]; | ||
966 | int i, len = min_t(int, cf->size / 4 - off, CMD_PACKET_SIZE / 4 / 2 - 1); | ||
967 | buf[0] = cpu_to_le32(len); | ||
968 | for (i = 0; i < len; i++, off++) { | ||
969 | buf[i * 2 + 1] = cpu_to_le32(off); | ||
970 | memcpy(buf + i * 2 + 2, cf->data + off * 4, 4); | ||
971 | } | ||
972 | ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET, | ||
973 | (u8 *) buf, len, NULL, 0); | ||
974 | if (ret < 0) { | ||
975 | usb_err(usbatm, "load config data failed: %d\n", ret); | ||
976 | return; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | msleep_interruptible(4000); | ||
981 | } | 1068 | } |
982 | 1069 | ||
983 | static int cxacru_find_firmware(struct cxacru_data *instance, | 1070 | static int cxacru_find_firmware(struct cxacru_data *instance, |
@@ -1003,7 +1090,7 @@ static int cxacru_find_firmware(struct cxacru_data *instance, | |||
1003 | static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, | 1090 | static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, |
1004 | struct usb_interface *usb_intf) | 1091 | struct usb_interface *usb_intf) |
1005 | { | 1092 | { |
1006 | const struct firmware *fw, *bp, *cf; | 1093 | const struct firmware *fw, *bp; |
1007 | struct cxacru_data *instance = usbatm_instance->driver_data; | 1094 | struct cxacru_data *instance = usbatm_instance->driver_data; |
1008 | 1095 | ||
1009 | int ret = cxacru_find_firmware(instance, "fw", &fw); | 1096 | int ret = cxacru_find_firmware(instance, "fw", &fw); |
@@ -1021,13 +1108,8 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, | |||
1021 | } | 1108 | } |
1022 | } | 1109 | } |
1023 | 1110 | ||
1024 | if (cxacru_find_firmware(instance, "cf", &cf)) /* optional */ | 1111 | cxacru_upload_firmware(instance, fw, bp); |
1025 | cf = NULL; | ||
1026 | |||
1027 | cxacru_upload_firmware(instance, fw, bp, cf); | ||
1028 | 1112 | ||
1029 | if (cf) | ||
1030 | release_firmware(cf); | ||
1031 | if (instance->modem_type->boot_rom_patch) | 1113 | if (instance->modem_type->boot_rom_patch) |
1032 | release_firmware(bp); | 1114 | release_firmware(bp); |
1033 | release_firmware(fw); | 1115 | release_firmware(fw); |
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index fbea8563df1e..9b53e8df4648 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -1333,6 +1333,7 @@ void usbatm_usb_disconnect(struct usb_interface *intf) | |||
1333 | if (instance->atm_dev) { | 1333 | if (instance->atm_dev) { |
1334 | sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); | 1334 | sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); |
1335 | atm_dev_deregister(instance->atm_dev); | 1335 | atm_dev_deregister(instance->atm_dev); |
1336 | instance->atm_dev = NULL; | ||
1336 | } | 1337 | } |
1337 | 1338 | ||
1338 | usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ | 1339 | usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ |
@@ -1348,7 +1349,7 @@ static int __init usbatm_usb_init(void) | |||
1348 | { | 1349 | { |
1349 | dbg("%s: driver version %s", __func__, DRIVER_VERSION); | 1350 | dbg("%s: driver version %s", __func__, DRIVER_VERSION); |
1350 | 1351 | ||
1351 | if (sizeof(struct usbatm_control) > sizeof(((struct sk_buff *) 0)->cb)) { | 1352 | if (sizeof(struct usbatm_control) > FIELD_SIZEOF(struct sk_buff, cb)) { |
1352 | printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name); | 1353 | printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name); |
1353 | return -EIO; | 1354 | return -EIO; |
1354 | } | 1355 | } |
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index f6f4508a9d42..0863f85fcc26 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h | |||
@@ -204,4 +204,19 @@ struct usbatm_data { | |||
204 | struct urb *urbs[0]; | 204 | struct urb *urbs[0]; |
205 | }; | 205 | }; |
206 | 206 | ||
207 | static inline void *to_usbatm_driver_data(struct usb_interface *intf) | ||
208 | { | ||
209 | struct usbatm_data *usbatm_instance; | ||
210 | |||
211 | if (intf == NULL) | ||
212 | return NULL; | ||
213 | |||
214 | usbatm_instance = usb_get_intfdata(intf); | ||
215 | |||
216 | if (usbatm_instance == NULL) /* set NULL before unbind() */ | ||
217 | return NULL; | ||
218 | |||
219 | return usbatm_instance->driver_data; /* set NULL after unbind() */ | ||
220 | } | ||
221 | |||
207 | #endif /* _USBATM_H_ */ | 222 | #endif /* _USBATM_H_ */ |
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 5633bc5c8bf2..029ee4a8a1f3 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c | |||
@@ -137,13 +137,13 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev) | |||
137 | if (!c67x00) | 137 | if (!c67x00) |
138 | return -ENOMEM; | 138 | return -ENOMEM; |
139 | 139 | ||
140 | if (!request_mem_region(res->start, res->end - res->start + 1, | 140 | if (!request_mem_region(res->start, resource_size(res), |
141 | pdev->name)) { | 141 | pdev->name)) { |
142 | dev_err(&pdev->dev, "Memory region busy\n"); | 142 | dev_err(&pdev->dev, "Memory region busy\n"); |
143 | ret = -EBUSY; | 143 | ret = -EBUSY; |
144 | goto request_mem_failed; | 144 | goto request_mem_failed; |
145 | } | 145 | } |
146 | c67x00->hpi.base = ioremap(res->start, res->end - res->start + 1); | 146 | c67x00->hpi.base = ioremap(res->start, resource_size(res)); |
147 | if (!c67x00->hpi.base) { | 147 | if (!c67x00->hpi.base) { |
148 | dev_err(&pdev->dev, "Unable to map HPI registers\n"); | 148 | dev_err(&pdev->dev, "Unable to map HPI registers\n"); |
149 | ret = -EIO; | 149 | ret = -EIO; |
@@ -182,7 +182,7 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev) | |||
182 | request_irq_failed: | 182 | request_irq_failed: |
183 | iounmap(c67x00->hpi.base); | 183 | iounmap(c67x00->hpi.base); |
184 | map_failed: | 184 | map_failed: |
185 | release_mem_region(res->start, res->end - res->start + 1); | 185 | release_mem_region(res->start, resource_size(res)); |
186 | request_mem_failed: | 186 | request_mem_failed: |
187 | kfree(c67x00); | 187 | kfree(c67x00); |
188 | 188 | ||
@@ -208,7 +208,7 @@ static int __devexit c67x00_drv_remove(struct platform_device *pdev) | |||
208 | 208 | ||
209 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 209 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
210 | if (res) | 210 | if (res) |
211 | release_mem_region(res->start, res->end - res->start + 1); | 211 | release_mem_region(res->start, resource_size(res)); |
212 | 212 | ||
213 | kfree(c67x00); | 213 | kfree(c67x00); |
214 | 214 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 34d4eb98829e..975d556b4787 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -170,6 +170,7 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb) | |||
170 | { | 170 | { |
171 | wb->use = 0; | 171 | wb->use = 0; |
172 | acm->transmitting--; | 172 | acm->transmitting--; |
173 | usb_autopm_put_interface_async(acm->control); | ||
173 | } | 174 | } |
174 | 175 | ||
175 | /* | 176 | /* |
@@ -211,9 +212,12 @@ static int acm_write_start(struct acm *acm, int wbn) | |||
211 | } | 212 | } |
212 | 213 | ||
213 | dbg("%s susp_count: %d", __func__, acm->susp_count); | 214 | dbg("%s susp_count: %d", __func__, acm->susp_count); |
215 | usb_autopm_get_interface_async(acm->control); | ||
214 | if (acm->susp_count) { | 216 | if (acm->susp_count) { |
215 | acm->delayed_wb = wb; | 217 | if (!acm->delayed_wb) |
216 | schedule_work(&acm->waker); | 218 | acm->delayed_wb = wb; |
219 | else | ||
220 | usb_autopm_put_interface_async(acm->control); | ||
217 | spin_unlock_irqrestore(&acm->write_lock, flags); | 221 | spin_unlock_irqrestore(&acm->write_lock, flags); |
218 | return 0; /* A white lie */ | 222 | return 0; /* A white lie */ |
219 | } | 223 | } |
@@ -424,7 +428,6 @@ next_buffer: | |||
424 | throttled = acm->throttle; | 428 | throttled = acm->throttle; |
425 | spin_unlock_irqrestore(&acm->throttle_lock, flags); | 429 | spin_unlock_irqrestore(&acm->throttle_lock, flags); |
426 | if (!throttled) { | 430 | if (!throttled) { |
427 | tty_buffer_request_room(tty, buf->size); | ||
428 | tty_insert_flip_string(tty, buf->base, buf->size); | 431 | tty_insert_flip_string(tty, buf->base, buf->size); |
429 | tty_flip_buffer_push(tty); | 432 | tty_flip_buffer_push(tty); |
430 | } else { | 433 | } else { |
@@ -534,23 +537,6 @@ static void acm_softint(struct work_struct *work) | |||
534 | tty_kref_put(tty); | 537 | tty_kref_put(tty); |
535 | } | 538 | } |
536 | 539 | ||
537 | static void acm_waker(struct work_struct *waker) | ||
538 | { | ||
539 | struct acm *acm = container_of(waker, struct acm, waker); | ||
540 | int rv; | ||
541 | |||
542 | rv = usb_autopm_get_interface(acm->control); | ||
543 | if (rv < 0) { | ||
544 | dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__); | ||
545 | return; | ||
546 | } | ||
547 | if (acm->delayed_wb) { | ||
548 | acm_start_wb(acm, acm->delayed_wb); | ||
549 | acm->delayed_wb = NULL; | ||
550 | } | ||
551 | usb_autopm_put_interface(acm->control); | ||
552 | } | ||
553 | |||
554 | /* | 540 | /* |
555 | * TTY handlers | 541 | * TTY handlers |
556 | */ | 542 | */ |
@@ -566,7 +552,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
566 | 552 | ||
567 | acm = acm_table[tty->index]; | 553 | acm = acm_table[tty->index]; |
568 | if (!acm || !acm->dev) | 554 | if (!acm || !acm->dev) |
569 | goto err_out; | 555 | goto out; |
570 | else | 556 | else |
571 | rv = 0; | 557 | rv = 0; |
572 | 558 | ||
@@ -582,8 +568,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
582 | 568 | ||
583 | mutex_lock(&acm->mutex); | 569 | mutex_lock(&acm->mutex); |
584 | if (acm->port.count++) { | 570 | if (acm->port.count++) { |
571 | mutex_unlock(&acm->mutex); | ||
585 | usb_autopm_put_interface(acm->control); | 572 | usb_autopm_put_interface(acm->control); |
586 | goto done; | 573 | goto out; |
587 | } | 574 | } |
588 | 575 | ||
589 | acm->ctrlurb->dev = acm->dev; | 576 | acm->ctrlurb->dev = acm->dev; |
@@ -612,18 +599,18 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
612 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); | 599 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); |
613 | rv = tty_port_block_til_ready(&acm->port, tty, filp); | 600 | rv = tty_port_block_til_ready(&acm->port, tty, filp); |
614 | tasklet_schedule(&acm->urb_task); | 601 | tasklet_schedule(&acm->urb_task); |
615 | done: | 602 | |
616 | mutex_unlock(&acm->mutex); | 603 | mutex_unlock(&acm->mutex); |
617 | err_out: | 604 | out: |
618 | mutex_unlock(&open_mutex); | 605 | mutex_unlock(&open_mutex); |
619 | return rv; | 606 | return rv; |
620 | 607 | ||
621 | full_bailout: | 608 | full_bailout: |
622 | usb_kill_urb(acm->ctrlurb); | 609 | usb_kill_urb(acm->ctrlurb); |
623 | bail_out: | 610 | bail_out: |
624 | usb_autopm_put_interface(acm->control); | ||
625 | acm->port.count--; | 611 | acm->port.count--; |
626 | mutex_unlock(&acm->mutex); | 612 | mutex_unlock(&acm->mutex); |
613 | usb_autopm_put_interface(acm->control); | ||
627 | early_bail: | 614 | early_bail: |
628 | mutex_unlock(&open_mutex); | 615 | mutex_unlock(&open_mutex); |
629 | tty_port_tty_set(&acm->port, NULL); | 616 | tty_port_tty_set(&acm->port, NULL); |
@@ -1023,7 +1010,7 @@ static int acm_probe(struct usb_interface *intf, | |||
1023 | case USB_CDC_CALL_MANAGEMENT_TYPE: | 1010 | case USB_CDC_CALL_MANAGEMENT_TYPE: |
1024 | call_management_function = buffer[3]; | 1011 | call_management_function = buffer[3]; |
1025 | call_interface_num = buffer[4]; | 1012 | call_interface_num = buffer[4]; |
1026 | if ((call_management_function & 3) != 3) | 1013 | if ( (quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3) |
1027 | dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n"); | 1014 | dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n"); |
1028 | break; | 1015 | break; |
1029 | default: | 1016 | default: |
@@ -1178,7 +1165,6 @@ made_compressed_probe: | |||
1178 | acm->urb_task.func = acm_rx_tasklet; | 1165 | acm->urb_task.func = acm_rx_tasklet; |
1179 | acm->urb_task.data = (unsigned long) acm; | 1166 | acm->urb_task.data = (unsigned long) acm; |
1180 | INIT_WORK(&acm->work, acm_softint); | 1167 | INIT_WORK(&acm->work, acm_softint); |
1181 | INIT_WORK(&acm->waker, acm_waker); | ||
1182 | init_waitqueue_head(&acm->drain_wait); | 1168 | init_waitqueue_head(&acm->drain_wait); |
1183 | spin_lock_init(&acm->throttle_lock); | 1169 | spin_lock_init(&acm->throttle_lock); |
1184 | spin_lock_init(&acm->write_lock); | 1170 | spin_lock_init(&acm->write_lock); |
@@ -1343,7 +1329,6 @@ static void stop_data_traffic(struct acm *acm) | |||
1343 | tasklet_enable(&acm->urb_task); | 1329 | tasklet_enable(&acm->urb_task); |
1344 | 1330 | ||
1345 | cancel_work_sync(&acm->work); | 1331 | cancel_work_sync(&acm->work); |
1346 | cancel_work_sync(&acm->waker); | ||
1347 | } | 1332 | } |
1348 | 1333 | ||
1349 | static void acm_disconnect(struct usb_interface *intf) | 1334 | static void acm_disconnect(struct usb_interface *intf) |
@@ -1435,6 +1420,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) | |||
1435 | static int acm_resume(struct usb_interface *intf) | 1420 | static int acm_resume(struct usb_interface *intf) |
1436 | { | 1421 | { |
1437 | struct acm *acm = usb_get_intfdata(intf); | 1422 | struct acm *acm = usb_get_intfdata(intf); |
1423 | struct acm_wb *wb; | ||
1438 | int rv = 0; | 1424 | int rv = 0; |
1439 | int cnt; | 1425 | int cnt; |
1440 | 1426 | ||
@@ -1449,6 +1435,21 @@ static int acm_resume(struct usb_interface *intf) | |||
1449 | mutex_lock(&acm->mutex); | 1435 | mutex_lock(&acm->mutex); |
1450 | if (acm->port.count) { | 1436 | if (acm->port.count) { |
1451 | rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); | 1437 | rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); |
1438 | |||
1439 | spin_lock_irq(&acm->write_lock); | ||
1440 | if (acm->delayed_wb) { | ||
1441 | wb = acm->delayed_wb; | ||
1442 | acm->delayed_wb = NULL; | ||
1443 | spin_unlock_irq(&acm->write_lock); | ||
1444 | acm_start_wb(acm, acm->delayed_wb); | ||
1445 | } else { | ||
1446 | spin_unlock_irq(&acm->write_lock); | ||
1447 | } | ||
1448 | |||
1449 | /* | ||
1450 | * delayed error checking because we must | ||
1451 | * do the write path at all cost | ||
1452 | */ | ||
1452 | if (rv < 0) | 1453 | if (rv < 0) |
1453 | goto err_out; | 1454 | goto err_out; |
1454 | 1455 | ||
@@ -1460,6 +1461,23 @@ err_out: | |||
1460 | return rv; | 1461 | return rv; |
1461 | } | 1462 | } |
1462 | 1463 | ||
1464 | static int acm_reset_resume(struct usb_interface *intf) | ||
1465 | { | ||
1466 | struct acm *acm = usb_get_intfdata(intf); | ||
1467 | struct tty_struct *tty; | ||
1468 | |||
1469 | mutex_lock(&acm->mutex); | ||
1470 | if (acm->port.count) { | ||
1471 | tty = tty_port_tty_get(&acm->port); | ||
1472 | if (tty) { | ||
1473 | tty_hangup(tty); | ||
1474 | tty_kref_put(tty); | ||
1475 | } | ||
1476 | } | ||
1477 | mutex_unlock(&acm->mutex); | ||
1478 | return acm_resume(intf); | ||
1479 | } | ||
1480 | |||
1463 | #endif /* CONFIG_PM */ | 1481 | #endif /* CONFIG_PM */ |
1464 | 1482 | ||
1465 | #define NOKIA_PCSUITE_ACM_INFO(x) \ | 1483 | #define NOKIA_PCSUITE_ACM_INFO(x) \ |
@@ -1471,7 +1489,7 @@ err_out: | |||
1471 | * USB driver structure. | 1489 | * USB driver structure. |
1472 | */ | 1490 | */ |
1473 | 1491 | ||
1474 | static struct usb_device_id acm_ids[] = { | 1492 | static const struct usb_device_id acm_ids[] = { |
1475 | /* quirky and broken devices */ | 1493 | /* quirky and broken devices */ |
1476 | { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ | 1494 | { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ |
1477 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1495 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
@@ -1576,6 +1594,11 @@ static struct usb_device_id acm_ids[] = { | |||
1576 | 1594 | ||
1577 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | 1595 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
1578 | 1596 | ||
1597 | /* Support Lego NXT using pbLua firmware */ | ||
1598 | { USB_DEVICE(0x0694, 0xff00), | ||
1599 | .driver_info = NOT_A_MODEM, | ||
1600 | }, | ||
1601 | |||
1579 | /* control interfaces with various AT-command sets */ | 1602 | /* control interfaces with various AT-command sets */ |
1580 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1603 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
1581 | USB_CDC_ACM_PROTO_AT_V25TER) }, | 1604 | USB_CDC_ACM_PROTO_AT_V25TER) }, |
@@ -1602,6 +1625,7 @@ static struct usb_driver acm_driver = { | |||
1602 | #ifdef CONFIG_PM | 1625 | #ifdef CONFIG_PM |
1603 | .suspend = acm_suspend, | 1626 | .suspend = acm_suspend, |
1604 | .resume = acm_resume, | 1627 | .resume = acm_resume, |
1628 | .reset_resume = acm_reset_resume, | ||
1605 | #endif | 1629 | #endif |
1606 | .id_table = acm_ids, | 1630 | .id_table = acm_ids, |
1607 | #ifdef CONFIG_PM | 1631 | #ifdef CONFIG_PM |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index c4a0ee8ffccf..4a8e87ec6ce9 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
@@ -112,7 +112,6 @@ struct acm { | |||
112 | struct mutex mutex; | 112 | struct mutex mutex; |
113 | struct usb_cdc_line_coding line; /* bits, stop, parity */ | 113 | struct usb_cdc_line_coding line; /* bits, stop, parity */ |
114 | struct work_struct work; /* work queue entry for line discipline waking up */ | 114 | struct work_struct work; /* work queue entry for line discipline waking up */ |
115 | struct work_struct waker; | ||
116 | wait_queue_head_t drain_wait; /* close processing */ | 115 | wait_queue_head_t drain_wait; /* close processing */ |
117 | struct tasklet_struct urb_task; /* rx processing */ | 116 | struct tasklet_struct urb_task; /* rx processing */ |
118 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ | 117 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ |
@@ -137,3 +136,4 @@ struct acm { | |||
137 | #define NO_UNION_NORMAL 1 | 136 | #define NO_UNION_NORMAL 1 |
138 | #define SINGLE_RX_URB 2 | 137 | #define SINGLE_RX_URB 2 |
139 | #define NO_CAP_LINE 4 | 138 | #define NO_CAP_LINE 4 |
139 | #define NOT_A_MODEM 8 | ||
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 3e564bfe17d1..18aafcb08fc8 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #define DRIVER_AUTHOR "Oliver Neukum" | 31 | #define DRIVER_AUTHOR "Oliver Neukum" |
32 | #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" | 32 | #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" |
33 | 33 | ||
34 | static struct usb_device_id wdm_ids[] = { | 34 | static const struct usb_device_id wdm_ids[] = { |
35 | { | 35 | { |
36 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | | 36 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | |
37 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | 37 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 9bc112ee7803..93b5f85d7ceb 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -163,7 +163,6 @@ struct usblp { | |||
163 | unsigned char used; /* True if open */ | 163 | unsigned char used; /* True if open */ |
164 | unsigned char present; /* True if not disconnected */ | 164 | unsigned char present; /* True if not disconnected */ |
165 | unsigned char bidir; /* interface is bidirectional */ | 165 | unsigned char bidir; /* interface is bidirectional */ |
166 | unsigned char sleeping; /* interface is suspended */ | ||
167 | unsigned char no_paper; /* Paper Out happened */ | 166 | unsigned char no_paper; /* Paper Out happened */ |
168 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ | 167 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ |
169 | /* first 2 bytes are (big-endian) length */ | 168 | /* first 2 bytes are (big-endian) length */ |
@@ -191,7 +190,6 @@ static void usblp_dump(struct usblp *usblp) { | |||
191 | dbg("quirks=%d", usblp->quirks); | 190 | dbg("quirks=%d", usblp->quirks); |
192 | dbg("used=%d", usblp->used); | 191 | dbg("used=%d", usblp->used); |
193 | dbg("bidir=%d", usblp->bidir); | 192 | dbg("bidir=%d", usblp->bidir); |
194 | dbg("sleeping=%d", usblp->sleeping); | ||
195 | dbg("device_id_string=\"%s\"", | 193 | dbg("device_id_string=\"%s\"", |
196 | usblp->device_id_string ? | 194 | usblp->device_id_string ? |
197 | usblp->device_id_string + 2 : | 195 | usblp->device_id_string + 2 : |
@@ -376,7 +374,7 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
376 | 374 | ||
377 | static int handle_bidir (struct usblp *usblp) | 375 | static int handle_bidir (struct usblp *usblp) |
378 | { | 376 | { |
379 | if (usblp->bidir && usblp->used && !usblp->sleeping) { | 377 | if (usblp->bidir && usblp->used) { |
380 | if (usblp_submit_read(usblp) < 0) | 378 | if (usblp_submit_read(usblp) < 0) |
381 | return -EIO; | 379 | return -EIO; |
382 | } | 380 | } |
@@ -503,11 +501,6 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
503 | goto done; | 501 | goto done; |
504 | } | 502 | } |
505 | 503 | ||
506 | if (usblp->sleeping) { | ||
507 | retval = -ENODEV; | ||
508 | goto done; | ||
509 | } | ||
510 | |||
511 | dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd), | 504 | dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd), |
512 | _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) ); | 505 | _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) ); |
513 | 506 | ||
@@ -914,8 +907,6 @@ static int usblp_wtest(struct usblp *usblp, int nonblock) | |||
914 | return 0; | 907 | return 0; |
915 | } | 908 | } |
916 | spin_unlock_irqrestore(&usblp->lock, flags); | 909 | spin_unlock_irqrestore(&usblp->lock, flags); |
917 | if (usblp->sleeping) | ||
918 | return -ENODEV; | ||
919 | if (nonblock) | 910 | if (nonblock) |
920 | return -EAGAIN; | 911 | return -EAGAIN; |
921 | return 1; | 912 | return 1; |
@@ -968,8 +959,6 @@ static int usblp_rtest(struct usblp *usblp, int nonblock) | |||
968 | return 0; | 959 | return 0; |
969 | } | 960 | } |
970 | spin_unlock_irqrestore(&usblp->lock, flags); | 961 | spin_unlock_irqrestore(&usblp->lock, flags); |
971 | if (usblp->sleeping) | ||
972 | return -ENODEV; | ||
973 | if (nonblock) | 962 | if (nonblock) |
974 | return -EAGAIN; | 963 | return -EAGAIN; |
975 | return 1; | 964 | return 1; |
@@ -1377,12 +1366,10 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1377 | mutex_unlock (&usblp_mutex); | 1366 | mutex_unlock (&usblp_mutex); |
1378 | } | 1367 | } |
1379 | 1368 | ||
1380 | static int usblp_suspend (struct usb_interface *intf, pm_message_t message) | 1369 | static int usblp_suspend(struct usb_interface *intf, pm_message_t message) |
1381 | { | 1370 | { |
1382 | struct usblp *usblp = usb_get_intfdata (intf); | 1371 | struct usblp *usblp = usb_get_intfdata (intf); |
1383 | 1372 | ||
1384 | /* we take no more IO */ | ||
1385 | usblp->sleeping = 1; | ||
1386 | usblp_unlink_urbs(usblp); | 1373 | usblp_unlink_urbs(usblp); |
1387 | #if 0 /* XXX Do we want this? What if someone is reading, should we fail? */ | 1374 | #if 0 /* XXX Do we want this? What if someone is reading, should we fail? */ |
1388 | /* not strictly necessary, but just in case */ | 1375 | /* not strictly necessary, but just in case */ |
@@ -1393,18 +1380,17 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message) | |||
1393 | return 0; | 1380 | return 0; |
1394 | } | 1381 | } |
1395 | 1382 | ||
1396 | static int usblp_resume (struct usb_interface *intf) | 1383 | static int usblp_resume(struct usb_interface *intf) |
1397 | { | 1384 | { |
1398 | struct usblp *usblp = usb_get_intfdata (intf); | 1385 | struct usblp *usblp = usb_get_intfdata (intf); |
1399 | int r; | 1386 | int r; |
1400 | 1387 | ||
1401 | usblp->sleeping = 0; | ||
1402 | r = handle_bidir (usblp); | 1388 | r = handle_bidir (usblp); |
1403 | 1389 | ||
1404 | return r; | 1390 | return r; |
1405 | } | 1391 | } |
1406 | 1392 | ||
1407 | static struct usb_device_id usblp_ids [] = { | 1393 | static const struct usb_device_id usblp_ids[] = { |
1408 | { USB_DEVICE_INFO(7, 1, 1) }, | 1394 | { USB_DEVICE_INFO(7, 1, 1) }, |
1409 | { USB_DEVICE_INFO(7, 1, 2) }, | 1395 | { USB_DEVICE_INFO(7, 1, 2) }, |
1410 | { USB_DEVICE_INFO(7, 1, 3) }, | 1396 | { USB_DEVICE_INFO(7, 1, 3) }, |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 7c5f4e32c920..8588c0937a89 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -48,7 +48,7 @@ | |||
48 | */ | 48 | */ |
49 | #define USBTMC_MAX_READS_TO_CLEAR_BULK_IN 100 | 49 | #define USBTMC_MAX_READS_TO_CLEAR_BULK_IN 100 |
50 | 50 | ||
51 | static struct usb_device_id usbtmc_devices[] = { | 51 | static const struct usb_device_id usbtmc_devices[] = { |
52 | { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, | 52 | { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, |
53 | { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), }, | 53 | { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), }, |
54 | { 0, } /* terminating entry */ | 54 | { 0, } /* terminating entry */ |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index ad925946f869..97a819c23ef3 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -91,8 +91,8 @@ config USB_DYNAMIC_MINORS | |||
91 | If you are unsure about this, say N here. | 91 | If you are unsure about this, say N here. |
92 | 92 | ||
93 | config USB_SUSPEND | 93 | config USB_SUSPEND |
94 | bool "USB selective suspend/resume and wakeup" | 94 | bool "USB runtime power management (suspend/resume and wakeup)" |
95 | depends on USB && PM | 95 | depends on USB && PM_RUNTIME |
96 | help | 96 | help |
97 | If you say Y here, you can use driver calls or the sysfs | 97 | If you say Y here, you can use driver calls or the sysfs |
98 | "power/level" file to suspend or resume individual USB | 98 | "power/level" file to suspend or resume individual USB |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 355dffcc23b0..c83c975152a6 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -118,6 +118,7 @@ static const char *format_endpt = | |||
118 | */ | 118 | */ |
119 | 119 | ||
120 | static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq); | 120 | static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq); |
121 | /* guarded by usbfs_mutex */ | ||
121 | static unsigned int conndiscevcnt; | 122 | static unsigned int conndiscevcnt; |
122 | 123 | ||
123 | /* this struct stores the poll state for <mountpoint>/devices pollers */ | 124 | /* this struct stores the poll state for <mountpoint>/devices pollers */ |
@@ -156,7 +157,9 @@ static const struct class_info clas_info[] = | |||
156 | 157 | ||
157 | void usbfs_conn_disc_event(void) | 158 | void usbfs_conn_disc_event(void) |
158 | { | 159 | { |
160 | mutex_lock(&usbfs_mutex); | ||
159 | conndiscevcnt++; | 161 | conndiscevcnt++; |
162 | mutex_unlock(&usbfs_mutex); | ||
160 | wake_up(&deviceconndiscwq); | 163 | wake_up(&deviceconndiscwq); |
161 | } | 164 | } |
162 | 165 | ||
@@ -629,42 +632,29 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, | |||
629 | static unsigned int usb_device_poll(struct file *file, | 632 | static unsigned int usb_device_poll(struct file *file, |
630 | struct poll_table_struct *wait) | 633 | struct poll_table_struct *wait) |
631 | { | 634 | { |
632 | struct usb_device_status *st = file->private_data; | 635 | struct usb_device_status *st; |
633 | unsigned int mask = 0; | 636 | unsigned int mask = 0; |
634 | 637 | ||
635 | lock_kernel(); | 638 | mutex_lock(&usbfs_mutex); |
639 | st = file->private_data; | ||
636 | if (!st) { | 640 | if (!st) { |
637 | st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL); | 641 | st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL); |
638 | |||
639 | /* we may have dropped BKL - | ||
640 | * need to check for having lost the race */ | ||
641 | if (file->private_data) { | ||
642 | kfree(st); | ||
643 | st = file->private_data; | ||
644 | goto lost_race; | ||
645 | } | ||
646 | /* we haven't lost - check for allocation failure now */ | ||
647 | if (!st) { | 642 | if (!st) { |
648 | unlock_kernel(); | 643 | mutex_unlock(&usbfs_mutex); |
649 | return POLLIN; | 644 | return POLLIN; |
650 | } | 645 | } |
651 | 646 | ||
652 | /* | ||
653 | * need to prevent the module from being unloaded, since | ||
654 | * proc_unregister does not call the release method and | ||
655 | * we would have a memory leak | ||
656 | */ | ||
657 | st->lastev = conndiscevcnt; | 647 | st->lastev = conndiscevcnt; |
658 | file->private_data = st; | 648 | file->private_data = st; |
659 | mask = POLLIN; | 649 | mask = POLLIN; |
660 | } | 650 | } |
661 | lost_race: | 651 | |
662 | if (file->f_mode & FMODE_READ) | 652 | if (file->f_mode & FMODE_READ) |
663 | poll_wait(file, &deviceconndiscwq, wait); | 653 | poll_wait(file, &deviceconndiscwq, wait); |
664 | if (st->lastev != conndiscevcnt) | 654 | if (st->lastev != conndiscevcnt) |
665 | mask |= POLLIN; | 655 | mask |= POLLIN; |
666 | st->lastev = conndiscevcnt; | 656 | st->lastev = conndiscevcnt; |
667 | unlock_kernel(); | 657 | mutex_unlock(&usbfs_mutex); |
668 | return mask; | 658 | return mask; |
669 | } | 659 | } |
670 | 660 | ||
@@ -685,7 +675,7 @@ static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig) | |||
685 | { | 675 | { |
686 | loff_t ret; | 676 | loff_t ret; |
687 | 677 | ||
688 | lock_kernel(); | 678 | mutex_lock(&file->f_dentry->d_inode->i_mutex); |
689 | 679 | ||
690 | switch (orig) { | 680 | switch (orig) { |
691 | case 0: | 681 | case 0: |
@@ -701,7 +691,7 @@ static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig) | |||
701 | ret = -EINVAL; | 691 | ret = -EINVAL; |
702 | } | 692 | } |
703 | 693 | ||
704 | unlock_kernel(); | 694 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
705 | return ret; | 695 | return ret; |
706 | } | 696 | } |
707 | 697 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index a678186f218f..e909ff7b9094 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -122,7 +122,7 @@ static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) | |||
122 | { | 122 | { |
123 | loff_t ret; | 123 | loff_t ret; |
124 | 124 | ||
125 | lock_kernel(); | 125 | mutex_lock(&file->f_dentry->d_inode->i_mutex); |
126 | 126 | ||
127 | switch (orig) { | 127 | switch (orig) { |
128 | case 0: | 128 | case 0: |
@@ -138,7 +138,7 @@ static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) | |||
138 | ret = -EINVAL; | 138 | ret = -EINVAL; |
139 | } | 139 | } |
140 | 140 | ||
141 | unlock_kernel(); | 141 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
142 | return ret; | 142 | return ret; |
143 | } | 143 | } |
144 | 144 | ||
@@ -310,7 +310,8 @@ static struct async *async_getpending(struct dev_state *ps, | |||
310 | 310 | ||
311 | static void snoop_urb(struct usb_device *udev, | 311 | static void snoop_urb(struct usb_device *udev, |
312 | void __user *userurb, int pipe, unsigned length, | 312 | void __user *userurb, int pipe, unsigned length, |
313 | int timeout_or_status, enum snoop_when when) | 313 | int timeout_or_status, enum snoop_when when, |
314 | unsigned char *data, unsigned data_len) | ||
314 | { | 315 | { |
315 | static const char *types[] = {"isoc", "int", "ctrl", "bulk"}; | 316 | static const char *types[] = {"isoc", "int", "ctrl", "bulk"}; |
316 | static const char *dirs[] = {"out", "in"}; | 317 | static const char *dirs[] = {"out", "in"}; |
@@ -344,6 +345,11 @@ static void snoop_urb(struct usb_device *udev, | |||
344 | "status %d\n", | 345 | "status %d\n", |
345 | ep, t, d, length, timeout_or_status); | 346 | ep, t, d, length, timeout_or_status); |
346 | } | 347 | } |
348 | |||
349 | if (data && data_len > 0) { | ||
350 | print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1, | ||
351 | data, data_len, 1); | ||
352 | } | ||
347 | } | 353 | } |
348 | 354 | ||
349 | #define AS_CONTINUATION 1 | 355 | #define AS_CONTINUATION 1 |
@@ -410,7 +416,9 @@ static void async_completed(struct urb *urb) | |||
410 | } | 416 | } |
411 | snoop(&urb->dev->dev, "urb complete\n"); | 417 | snoop(&urb->dev->dev, "urb complete\n"); |
412 | snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, | 418 | snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, |
413 | as->status, COMPLETE); | 419 | as->status, COMPLETE, |
420 | ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_OUT) ? | ||
421 | NULL : urb->transfer_buffer, urb->actual_length); | ||
414 | if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && | 422 | if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && |
415 | as->status != -ENOENT) | 423 | as->status != -ENOENT) |
416 | cancel_bulk_urbs(ps, as->bulk_addr); | 424 | cancel_bulk_urbs(ps, as->bulk_addr); |
@@ -653,20 +661,20 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
653 | const struct cred *cred = current_cred(); | 661 | const struct cred *cred = current_cred(); |
654 | int ret; | 662 | int ret; |
655 | 663 | ||
656 | lock_kernel(); | ||
657 | /* Protect against simultaneous removal or release */ | ||
658 | mutex_lock(&usbfs_mutex); | ||
659 | |||
660 | ret = -ENOMEM; | 664 | ret = -ENOMEM; |
661 | ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL); | 665 | ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL); |
662 | if (!ps) | 666 | if (!ps) |
663 | goto out; | 667 | goto out_free_ps; |
664 | 668 | ||
665 | ret = -ENODEV; | 669 | ret = -ENODEV; |
666 | 670 | ||
671 | /* Protect against simultaneous removal or release */ | ||
672 | mutex_lock(&usbfs_mutex); | ||
673 | |||
667 | /* usbdev device-node */ | 674 | /* usbdev device-node */ |
668 | if (imajor(inode) == USB_DEVICE_MAJOR) | 675 | if (imajor(inode) == USB_DEVICE_MAJOR) |
669 | dev = usbdev_lookup_by_devt(inode->i_rdev); | 676 | dev = usbdev_lookup_by_devt(inode->i_rdev); |
677 | |||
670 | #ifdef CONFIG_USB_DEVICEFS | 678 | #ifdef CONFIG_USB_DEVICEFS |
671 | /* procfs file */ | 679 | /* procfs file */ |
672 | if (!dev) { | 680 | if (!dev) { |
@@ -678,13 +686,19 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
678 | dev = NULL; | 686 | dev = NULL; |
679 | } | 687 | } |
680 | #endif | 688 | #endif |
681 | if (!dev || dev->state == USB_STATE_NOTATTACHED) | 689 | mutex_unlock(&usbfs_mutex); |
682 | goto out; | 690 | |
691 | if (!dev) | ||
692 | goto out_free_ps; | ||
693 | |||
694 | usb_lock_device(dev); | ||
695 | if (dev->state == USB_STATE_NOTATTACHED) | ||
696 | goto out_unlock_device; | ||
697 | |||
683 | ret = usb_autoresume_device(dev); | 698 | ret = usb_autoresume_device(dev); |
684 | if (ret) | 699 | if (ret) |
685 | goto out; | 700 | goto out_unlock_device; |
686 | 701 | ||
687 | ret = 0; | ||
688 | ps->dev = dev; | 702 | ps->dev = dev; |
689 | ps->file = file; | 703 | ps->file = file; |
690 | spin_lock_init(&ps->lock); | 704 | spin_lock_init(&ps->lock); |
@@ -702,15 +716,16 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
702 | smp_wmb(); | 716 | smp_wmb(); |
703 | list_add_tail(&ps->list, &dev->filelist); | 717 | list_add_tail(&ps->list, &dev->filelist); |
704 | file->private_data = ps; | 718 | file->private_data = ps; |
719 | usb_unlock_device(dev); | ||
705 | snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current), | 720 | snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current), |
706 | current->comm); | 721 | current->comm); |
707 | out: | 722 | return ret; |
708 | if (ret) { | 723 | |
709 | kfree(ps); | 724 | out_unlock_device: |
710 | usb_put_dev(dev); | 725 | usb_unlock_device(dev); |
711 | } | 726 | usb_put_dev(dev); |
712 | mutex_unlock(&usbfs_mutex); | 727 | out_free_ps: |
713 | unlock_kernel(); | 728 | kfree(ps); |
714 | return ret; | 729 | return ret; |
715 | } | 730 | } |
716 | 731 | ||
@@ -724,10 +739,7 @@ static int usbdev_release(struct inode *inode, struct file *file) | |||
724 | usb_lock_device(dev); | 739 | usb_lock_device(dev); |
725 | usb_hub_release_all_ports(dev, ps); | 740 | usb_hub_release_all_ports(dev, ps); |
726 | 741 | ||
727 | /* Protect against simultaneous open */ | ||
728 | mutex_lock(&usbfs_mutex); | ||
729 | list_del_init(&ps->list); | 742 | list_del_init(&ps->list); |
730 | mutex_unlock(&usbfs_mutex); | ||
731 | 743 | ||
732 | for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed); | 744 | for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed); |
733 | ifnum++) { | 745 | ifnum++) { |
@@ -770,6 +782,13 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
770 | if (!tbuf) | 782 | if (!tbuf) |
771 | return -ENOMEM; | 783 | return -ENOMEM; |
772 | tmo = ctrl.timeout; | 784 | tmo = ctrl.timeout; |
785 | snoop(&dev->dev, "control urb: bRequestType=%02x " | ||
786 | "bRequest=%02x wValue=%04x " | ||
787 | "wIndex=%04x wLength=%04x\n", | ||
788 | ctrl.bRequestType, ctrl.bRequest, | ||
789 | __le16_to_cpup(&ctrl.wValue), | ||
790 | __le16_to_cpup(&ctrl.wIndex), | ||
791 | __le16_to_cpup(&ctrl.wLength)); | ||
773 | if (ctrl.bRequestType & 0x80) { | 792 | if (ctrl.bRequestType & 0x80) { |
774 | if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, | 793 | if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, |
775 | ctrl.wLength)) { | 794 | ctrl.wLength)) { |
@@ -777,15 +796,15 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
777 | return -EINVAL; | 796 | return -EINVAL; |
778 | } | 797 | } |
779 | pipe = usb_rcvctrlpipe(dev, 0); | 798 | pipe = usb_rcvctrlpipe(dev, 0); |
780 | snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT); | 799 | snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, NULL, 0); |
781 | 800 | ||
782 | usb_unlock_device(dev); | 801 | usb_unlock_device(dev); |
783 | i = usb_control_msg(dev, pipe, ctrl.bRequest, | 802 | i = usb_control_msg(dev, pipe, ctrl.bRequest, |
784 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, | 803 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
785 | tbuf, ctrl.wLength, tmo); | 804 | tbuf, ctrl.wLength, tmo); |
786 | usb_lock_device(dev); | 805 | usb_lock_device(dev); |
787 | snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE); | 806 | snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, |
788 | 807 | tbuf, i); | |
789 | if ((i > 0) && ctrl.wLength) { | 808 | if ((i > 0) && ctrl.wLength) { |
790 | if (copy_to_user(ctrl.data, tbuf, i)) { | 809 | if (copy_to_user(ctrl.data, tbuf, i)) { |
791 | free_page((unsigned long)tbuf); | 810 | free_page((unsigned long)tbuf); |
@@ -800,14 +819,15 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
800 | } | 819 | } |
801 | } | 820 | } |
802 | pipe = usb_sndctrlpipe(dev, 0); | 821 | pipe = usb_sndctrlpipe(dev, 0); |
803 | snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT); | 822 | snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, |
823 | tbuf, ctrl.wLength); | ||
804 | 824 | ||
805 | usb_unlock_device(dev); | 825 | usb_unlock_device(dev); |
806 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, | 826 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, |
807 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, | 827 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
808 | tbuf, ctrl.wLength, tmo); | 828 | tbuf, ctrl.wLength, tmo); |
809 | usb_lock_device(dev); | 829 | usb_lock_device(dev); |
810 | snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE); | 830 | snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0); |
811 | } | 831 | } |
812 | free_page((unsigned long)tbuf); | 832 | free_page((unsigned long)tbuf); |
813 | if (i < 0 && i != -EPIPE) { | 833 | if (i < 0 && i != -EPIPE) { |
@@ -853,12 +873,12 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
853 | kfree(tbuf); | 873 | kfree(tbuf); |
854 | return -EINVAL; | 874 | return -EINVAL; |
855 | } | 875 | } |
856 | snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT); | 876 | snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0); |
857 | 877 | ||
858 | usb_unlock_device(dev); | 878 | usb_unlock_device(dev); |
859 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); | 879 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); |
860 | usb_lock_device(dev); | 880 | usb_lock_device(dev); |
861 | snoop_urb(dev, NULL, pipe, len2, i, COMPLETE); | 881 | snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, tbuf, len2); |
862 | 882 | ||
863 | if (!i && len2) { | 883 | if (!i && len2) { |
864 | if (copy_to_user(bulk.data, tbuf, len2)) { | 884 | if (copy_to_user(bulk.data, tbuf, len2)) { |
@@ -873,12 +893,12 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
873 | return -EFAULT; | 893 | return -EFAULT; |
874 | } | 894 | } |
875 | } | 895 | } |
876 | snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT); | 896 | snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1); |
877 | 897 | ||
878 | usb_unlock_device(dev); | 898 | usb_unlock_device(dev); |
879 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); | 899 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); |
880 | usb_lock_device(dev); | 900 | usb_lock_device(dev); |
881 | snoop_urb(dev, NULL, pipe, len2, i, COMPLETE); | 901 | snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0); |
882 | } | 902 | } |
883 | kfree(tbuf); | 903 | kfree(tbuf); |
884 | if (i < 0) | 904 | if (i < 0) |
@@ -1097,6 +1117,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1097 | is_in = 0; | 1117 | is_in = 0; |
1098 | uurb->endpoint &= ~USB_DIR_IN; | 1118 | uurb->endpoint &= ~USB_DIR_IN; |
1099 | } | 1119 | } |
1120 | snoop(&ps->dev->dev, "control urb: bRequestType=%02x " | ||
1121 | "bRequest=%02x wValue=%04x " | ||
1122 | "wIndex=%04x wLength=%04x\n", | ||
1123 | dr->bRequestType, dr->bRequest, | ||
1124 | __le16_to_cpup(&dr->wValue), | ||
1125 | __le16_to_cpup(&dr->wIndex), | ||
1126 | __le16_to_cpup(&dr->wLength)); | ||
1100 | break; | 1127 | break; |
1101 | 1128 | ||
1102 | case USBDEVFS_URB_TYPE_BULK: | 1129 | case USBDEVFS_URB_TYPE_BULK: |
@@ -1104,13 +1131,25 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1104 | case USB_ENDPOINT_XFER_CONTROL: | 1131 | case USB_ENDPOINT_XFER_CONTROL: |
1105 | case USB_ENDPOINT_XFER_ISOC: | 1132 | case USB_ENDPOINT_XFER_ISOC: |
1106 | return -EINVAL; | 1133 | return -EINVAL; |
1107 | /* allow single-shot interrupt transfers, at bogus rates */ | 1134 | case USB_ENDPOINT_XFER_INT: |
1135 | /* allow single-shot interrupt transfers */ | ||
1136 | uurb->type = USBDEVFS_URB_TYPE_INTERRUPT; | ||
1137 | goto interrupt_urb; | ||
1108 | } | 1138 | } |
1109 | uurb->number_of_packets = 0; | 1139 | uurb->number_of_packets = 0; |
1110 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1140 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1111 | return -EINVAL; | 1141 | return -EINVAL; |
1112 | break; | 1142 | break; |
1113 | 1143 | ||
1144 | case USBDEVFS_URB_TYPE_INTERRUPT: | ||
1145 | if (!usb_endpoint_xfer_int(&ep->desc)) | ||
1146 | return -EINVAL; | ||
1147 | interrupt_urb: | ||
1148 | uurb->number_of_packets = 0; | ||
1149 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | ||
1150 | return -EINVAL; | ||
1151 | break; | ||
1152 | |||
1114 | case USBDEVFS_URB_TYPE_ISO: | 1153 | case USBDEVFS_URB_TYPE_ISO: |
1115 | /* arbitrary limit */ | 1154 | /* arbitrary limit */ |
1116 | if (uurb->number_of_packets < 1 || | 1155 | if (uurb->number_of_packets < 1 || |
@@ -1143,14 +1182,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1143 | uurb->buffer_length = totlen; | 1182 | uurb->buffer_length = totlen; |
1144 | break; | 1183 | break; |
1145 | 1184 | ||
1146 | case USBDEVFS_URB_TYPE_INTERRUPT: | ||
1147 | uurb->number_of_packets = 0; | ||
1148 | if (!usb_endpoint_xfer_int(&ep->desc)) | ||
1149 | return -EINVAL; | ||
1150 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | ||
1151 | return -EINVAL; | ||
1152 | break; | ||
1153 | |||
1154 | default: | 1185 | default: |
1155 | return -EINVAL; | 1186 | return -EINVAL; |
1156 | } | 1187 | } |
@@ -1236,7 +1267,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1236 | } | 1267 | } |
1237 | } | 1268 | } |
1238 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, | 1269 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, |
1239 | as->urb->transfer_buffer_length, 0, SUBMIT); | 1270 | as->urb->transfer_buffer_length, 0, SUBMIT, |
1271 | is_in ? NULL : as->urb->transfer_buffer, | ||
1272 | uurb->buffer_length); | ||
1240 | async_newpending(as); | 1273 | async_newpending(as); |
1241 | 1274 | ||
1242 | if (usb_endpoint_xfer_bulk(&ep->desc)) { | 1275 | if (usb_endpoint_xfer_bulk(&ep->desc)) { |
@@ -1274,7 +1307,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1274 | dev_printk(KERN_DEBUG, &ps->dev->dev, | 1307 | dev_printk(KERN_DEBUG, &ps->dev->dev, |
1275 | "usbfs: usb_submit_urb returned %d\n", ret); | 1308 | "usbfs: usb_submit_urb returned %d\n", ret); |
1276 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, | 1309 | snoop_urb(ps->dev, as->userurb, as->urb->pipe, |
1277 | 0, ret, COMPLETE); | 1310 | 0, ret, COMPLETE, NULL, 0); |
1278 | async_removepending(as); | 1311 | async_removepending(as); |
1279 | free_async(as); | 1312 | free_async(as); |
1280 | return ret; | 1313 | return ret; |
@@ -1628,7 +1661,10 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1628 | if (driver == NULL || driver->ioctl == NULL) { | 1661 | if (driver == NULL || driver->ioctl == NULL) { |
1629 | retval = -ENOTTY; | 1662 | retval = -ENOTTY; |
1630 | } else { | 1663 | } else { |
1664 | /* keep API that guarantees BKL */ | ||
1665 | lock_kernel(); | ||
1631 | retval = driver->ioctl(intf, ctl->ioctl_code, buf); | 1666 | retval = driver->ioctl(intf, ctl->ioctl_code, buf); |
1667 | unlock_kernel(); | ||
1632 | if (retval == -ENOIOCTLCMD) | 1668 | if (retval == -ENOIOCTLCMD) |
1633 | retval = -ENOTTY; | 1669 | retval = -ENOTTY; |
1634 | } | 1670 | } |
@@ -1711,6 +1747,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, | |||
1711 | 1747 | ||
1712 | if (!(file->f_mode & FMODE_WRITE)) | 1748 | if (!(file->f_mode & FMODE_WRITE)) |
1713 | return -EPERM; | 1749 | return -EPERM; |
1750 | |||
1714 | usb_lock_device(dev); | 1751 | usb_lock_device(dev); |
1715 | if (!connected(ps)) { | 1752 | if (!connected(ps)) { |
1716 | usb_unlock_device(dev); | 1753 | usb_unlock_device(dev); |
@@ -1877,9 +1914,7 @@ static long usbdev_ioctl(struct file *file, unsigned int cmd, | |||
1877 | { | 1914 | { |
1878 | int ret; | 1915 | int ret; |
1879 | 1916 | ||
1880 | lock_kernel(); | ||
1881 | ret = usbdev_do_ioctl(file, cmd, (void __user *)arg); | 1917 | ret = usbdev_do_ioctl(file, cmd, (void __user *)arg); |
1882 | unlock_kernel(); | ||
1883 | 1918 | ||
1884 | return ret; | 1919 | return ret; |
1885 | } | 1920 | } |
@@ -1890,9 +1925,7 @@ static long usbdev_compat_ioctl(struct file *file, unsigned int cmd, | |||
1890 | { | 1925 | { |
1891 | int ret; | 1926 | int ret; |
1892 | 1927 | ||
1893 | lock_kernel(); | ||
1894 | ret = usbdev_do_ioctl(file, cmd, compat_ptr(arg)); | 1928 | ret = usbdev_do_ioctl(file, cmd, compat_ptr(arg)); |
1895 | unlock_kernel(); | ||
1896 | 1929 | ||
1897 | return ret; | 1930 | return ret; |
1898 | } | 1931 | } |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f2f055eb6831..a7037bf81688 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
27 | #include <linux/usb/quirks.h> | 27 | #include <linux/usb/quirks.h> |
28 | #include <linux/workqueue.h> | 28 | #include <linux/pm_runtime.h> |
29 | #include "hcd.h" | 29 | #include "hcd.h" |
30 | #include "usb.h" | 30 | #include "usb.h" |
31 | 31 | ||
@@ -221,7 +221,7 @@ static int usb_probe_device(struct device *dev) | |||
221 | { | 221 | { |
222 | struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); | 222 | struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); |
223 | struct usb_device *udev = to_usb_device(dev); | 223 | struct usb_device *udev = to_usb_device(dev); |
224 | int error = -ENODEV; | 224 | int error = 0; |
225 | 225 | ||
226 | dev_dbg(dev, "%s\n", __func__); | 226 | dev_dbg(dev, "%s\n", __func__); |
227 | 227 | ||
@@ -230,18 +230,23 @@ static int usb_probe_device(struct device *dev) | |||
230 | /* The device should always appear to be in use | 230 | /* The device should always appear to be in use |
231 | * unless the driver suports autosuspend. | 231 | * unless the driver suports autosuspend. |
232 | */ | 232 | */ |
233 | udev->pm_usage_cnt = !(udriver->supports_autosuspend); | 233 | if (!udriver->supports_autosuspend) |
234 | error = usb_autoresume_device(udev); | ||
234 | 235 | ||
235 | error = udriver->probe(udev); | 236 | if (!error) |
237 | error = udriver->probe(udev); | ||
236 | return error; | 238 | return error; |
237 | } | 239 | } |
238 | 240 | ||
239 | /* called from driver core with dev locked */ | 241 | /* called from driver core with dev locked */ |
240 | static int usb_unbind_device(struct device *dev) | 242 | static int usb_unbind_device(struct device *dev) |
241 | { | 243 | { |
244 | struct usb_device *udev = to_usb_device(dev); | ||
242 | struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); | 245 | struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); |
243 | 246 | ||
244 | udriver->disconnect(to_usb_device(dev)); | 247 | udriver->disconnect(udev); |
248 | if (!udriver->supports_autosuspend) | ||
249 | usb_autosuspend_device(udev); | ||
245 | return 0; | 250 | return 0; |
246 | } | 251 | } |
247 | 252 | ||
@@ -274,60 +279,62 @@ static int usb_probe_interface(struct device *dev) | |||
274 | intf->needs_binding = 0; | 279 | intf->needs_binding = 0; |
275 | 280 | ||
276 | if (usb_device_is_owned(udev)) | 281 | if (usb_device_is_owned(udev)) |
277 | return -ENODEV; | 282 | return error; |
278 | 283 | ||
279 | if (udev->authorized == 0) { | 284 | if (udev->authorized == 0) { |
280 | dev_err(&intf->dev, "Device is not authorized for usage\n"); | 285 | dev_err(&intf->dev, "Device is not authorized for usage\n"); |
281 | return -ENODEV; | 286 | return error; |
282 | } | 287 | } |
283 | 288 | ||
284 | id = usb_match_id(intf, driver->id_table); | 289 | id = usb_match_id(intf, driver->id_table); |
285 | if (!id) | 290 | if (!id) |
286 | id = usb_match_dynamic_id(intf, driver); | 291 | id = usb_match_dynamic_id(intf, driver); |
287 | if (id) { | 292 | if (!id) |
288 | dev_dbg(dev, "%s - got id\n", __func__); | 293 | return error; |
289 | |||
290 | error = usb_autoresume_device(udev); | ||
291 | if (error) | ||
292 | return error; | ||
293 | 294 | ||
294 | /* Interface "power state" doesn't correspond to any hardware | 295 | dev_dbg(dev, "%s - got id\n", __func__); |
295 | * state whatsoever. We use it to record when it's bound to | ||
296 | * a driver that may start I/0: it's not frozen/quiesced. | ||
297 | */ | ||
298 | mark_active(intf); | ||
299 | intf->condition = USB_INTERFACE_BINDING; | ||
300 | 296 | ||
301 | /* The interface should always appear to be in use | 297 | error = usb_autoresume_device(udev); |
302 | * unless the driver suports autosuspend. | 298 | if (error) |
303 | */ | 299 | return error; |
304 | atomic_set(&intf->pm_usage_cnt, !driver->supports_autosuspend); | ||
305 | |||
306 | /* Carry out a deferred switch to altsetting 0 */ | ||
307 | if (intf->needs_altsetting0) { | ||
308 | error = usb_set_interface(udev, intf->altsetting[0]. | ||
309 | desc.bInterfaceNumber, 0); | ||
310 | if (error < 0) | ||
311 | goto err; | ||
312 | 300 | ||
313 | intf->needs_altsetting0 = 0; | 301 | intf->condition = USB_INTERFACE_BINDING; |
314 | } | ||
315 | 302 | ||
316 | error = driver->probe(intf, id); | 303 | /* Bound interfaces are initially active. They are |
317 | if (error) | 304 | * runtime-PM-enabled only if the driver has autosuspend support. |
305 | * They are sensitive to their children's power states. | ||
306 | */ | ||
307 | pm_runtime_set_active(dev); | ||
308 | pm_suspend_ignore_children(dev, false); | ||
309 | if (driver->supports_autosuspend) | ||
310 | pm_runtime_enable(dev); | ||
311 | |||
312 | /* Carry out a deferred switch to altsetting 0 */ | ||
313 | if (intf->needs_altsetting0) { | ||
314 | error = usb_set_interface(udev, intf->altsetting[0]. | ||
315 | desc.bInterfaceNumber, 0); | ||
316 | if (error < 0) | ||
318 | goto err; | 317 | goto err; |
319 | 318 | intf->needs_altsetting0 = 0; | |
320 | intf->condition = USB_INTERFACE_BOUND; | ||
321 | usb_autosuspend_device(udev); | ||
322 | } | 319 | } |
323 | 320 | ||
321 | error = driver->probe(intf, id); | ||
322 | if (error) | ||
323 | goto err; | ||
324 | |||
325 | intf->condition = USB_INTERFACE_BOUND; | ||
326 | usb_autosuspend_device(udev); | ||
324 | return error; | 327 | return error; |
325 | 328 | ||
326 | err: | 329 | err: |
327 | mark_quiesced(intf); | ||
328 | intf->needs_remote_wakeup = 0; | 330 | intf->needs_remote_wakeup = 0; |
329 | intf->condition = USB_INTERFACE_UNBOUND; | 331 | intf->condition = USB_INTERFACE_UNBOUND; |
330 | usb_cancel_queued_reset(intf); | 332 | usb_cancel_queued_reset(intf); |
333 | |||
334 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ | ||
335 | pm_runtime_disable(dev); | ||
336 | pm_runtime_set_suspended(dev); | ||
337 | |||
331 | usb_autosuspend_device(udev); | 338 | usb_autosuspend_device(udev); |
332 | return error; | 339 | return error; |
333 | } | 340 | } |
@@ -377,9 +384,17 @@ static int usb_unbind_interface(struct device *dev) | |||
377 | usb_set_intfdata(intf, NULL); | 384 | usb_set_intfdata(intf, NULL); |
378 | 385 | ||
379 | intf->condition = USB_INTERFACE_UNBOUND; | 386 | intf->condition = USB_INTERFACE_UNBOUND; |
380 | mark_quiesced(intf); | ||
381 | intf->needs_remote_wakeup = 0; | 387 | intf->needs_remote_wakeup = 0; |
382 | 388 | ||
389 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ | ||
390 | pm_runtime_disable(dev); | ||
391 | pm_runtime_set_suspended(dev); | ||
392 | |||
393 | /* Undo any residual pm_autopm_get_interface_* calls */ | ||
394 | for (r = atomic_read(&intf->pm_usage_cnt); r > 0; --r) | ||
395 | usb_autopm_put_interface_no_suspend(intf); | ||
396 | atomic_set(&intf->pm_usage_cnt, 0); | ||
397 | |||
383 | if (!error) | 398 | if (!error) |
384 | usb_autosuspend_device(udev); | 399 | usb_autosuspend_device(udev); |
385 | 400 | ||
@@ -410,7 +425,6 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
410 | struct usb_interface *iface, void *priv) | 425 | struct usb_interface *iface, void *priv) |
411 | { | 426 | { |
412 | struct device *dev = &iface->dev; | 427 | struct device *dev = &iface->dev; |
413 | struct usb_device *udev = interface_to_usbdev(iface); | ||
414 | int retval = 0; | 428 | int retval = 0; |
415 | 429 | ||
416 | if (dev->driver) | 430 | if (dev->driver) |
@@ -420,11 +434,16 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
420 | usb_set_intfdata(iface, priv); | 434 | usb_set_intfdata(iface, priv); |
421 | iface->needs_binding = 0; | 435 | iface->needs_binding = 0; |
422 | 436 | ||
423 | usb_pm_lock(udev); | ||
424 | iface->condition = USB_INTERFACE_BOUND; | 437 | iface->condition = USB_INTERFACE_BOUND; |
425 | mark_active(iface); | 438 | |
426 | atomic_set(&iface->pm_usage_cnt, !driver->supports_autosuspend); | 439 | /* Bound interfaces are initially active. They are |
427 | usb_pm_unlock(udev); | 440 | * runtime-PM-enabled only if the driver has autosuspend support. |
441 | * They are sensitive to their children's power states. | ||
442 | */ | ||
443 | pm_runtime_set_active(dev); | ||
444 | pm_suspend_ignore_children(dev, false); | ||
445 | if (driver->supports_autosuspend) | ||
446 | pm_runtime_enable(dev); | ||
428 | 447 | ||
429 | /* if interface was already added, bind now; else let | 448 | /* if interface was already added, bind now; else let |
430 | * the future device_add() bind it, bypassing probe() | 449 | * the future device_add() bind it, bypassing probe() |
@@ -691,9 +710,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
691 | { | 710 | { |
692 | struct usb_device *usb_dev; | 711 | struct usb_device *usb_dev; |
693 | 712 | ||
694 | /* driver is often null here; dev_dbg() would oops */ | ||
695 | pr_debug("usb %s: uevent\n", dev_name(dev)); | ||
696 | |||
697 | if (is_usb_device(dev)) { | 713 | if (is_usb_device(dev)) { |
698 | usb_dev = to_usb_device(dev); | 714 | usb_dev = to_usb_device(dev); |
699 | } else if (is_usb_interface(dev)) { | 715 | } else if (is_usb_interface(dev)) { |
@@ -705,6 +721,7 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
705 | } | 721 | } |
706 | 722 | ||
707 | if (usb_dev->devnum < 0) { | 723 | if (usb_dev->devnum < 0) { |
724 | /* driver is often null here; dev_dbg() would oops */ | ||
708 | pr_debug("usb %s: already deleted?\n", dev_name(dev)); | 725 | pr_debug("usb %s: already deleted?\n", dev_name(dev)); |
709 | return -ENODEV; | 726 | return -ENODEV; |
710 | } | 727 | } |
@@ -983,7 +1000,6 @@ static void do_unbind_rebind(struct usb_device *udev, int action) | |||
983 | } | 1000 | } |
984 | } | 1001 | } |
985 | 1002 | ||
986 | /* Caller has locked udev's pm_mutex */ | ||
987 | static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) | 1003 | static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) |
988 | { | 1004 | { |
989 | struct usb_device_driver *udriver; | 1005 | struct usb_device_driver *udriver; |
@@ -1007,7 +1023,6 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) | |||
1007 | return status; | 1023 | return status; |
1008 | } | 1024 | } |
1009 | 1025 | ||
1010 | /* Caller has locked udev's pm_mutex */ | ||
1011 | static int usb_resume_device(struct usb_device *udev, pm_message_t msg) | 1026 | static int usb_resume_device(struct usb_device *udev, pm_message_t msg) |
1012 | { | 1027 | { |
1013 | struct usb_device_driver *udriver; | 1028 | struct usb_device_driver *udriver; |
@@ -1041,27 +1056,20 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg) | |||
1041 | return status; | 1056 | return status; |
1042 | } | 1057 | } |
1043 | 1058 | ||
1044 | /* Caller has locked intf's usb_device's pm mutex */ | ||
1045 | static int usb_suspend_interface(struct usb_device *udev, | 1059 | static int usb_suspend_interface(struct usb_device *udev, |
1046 | struct usb_interface *intf, pm_message_t msg) | 1060 | struct usb_interface *intf, pm_message_t msg) |
1047 | { | 1061 | { |
1048 | struct usb_driver *driver; | 1062 | struct usb_driver *driver; |
1049 | int status = 0; | 1063 | int status = 0; |
1050 | 1064 | ||
1051 | /* with no hardware, USB interfaces only use FREEZE and ON states */ | 1065 | if (udev->state == USB_STATE_NOTATTACHED || |
1052 | if (udev->state == USB_STATE_NOTATTACHED || !is_active(intf)) | 1066 | intf->condition == USB_INTERFACE_UNBOUND) |
1053 | goto done; | ||
1054 | |||
1055 | /* This can happen; see usb_driver_release_interface() */ | ||
1056 | if (intf->condition == USB_INTERFACE_UNBOUND) | ||
1057 | goto done; | 1067 | goto done; |
1058 | driver = to_usb_driver(intf->dev.driver); | 1068 | driver = to_usb_driver(intf->dev.driver); |
1059 | 1069 | ||
1060 | if (driver->suspend) { | 1070 | if (driver->suspend) { |
1061 | status = driver->suspend(intf, msg); | 1071 | status = driver->suspend(intf, msg); |
1062 | if (status == 0) | 1072 | if (status && !(msg.event & PM_EVENT_AUTO)) |
1063 | mark_quiesced(intf); | ||
1064 | else if (!(msg.event & PM_EVENT_AUTO)) | ||
1065 | dev_err(&intf->dev, "%s error %d\n", | 1073 | dev_err(&intf->dev, "%s error %d\n", |
1066 | "suspend", status); | 1074 | "suspend", status); |
1067 | } else { | 1075 | } else { |
@@ -1069,7 +1077,6 @@ static int usb_suspend_interface(struct usb_device *udev, | |||
1069 | intf->needs_binding = 1; | 1077 | intf->needs_binding = 1; |
1070 | dev_warn(&intf->dev, "no %s for driver %s?\n", | 1078 | dev_warn(&intf->dev, "no %s for driver %s?\n", |
1071 | "suspend", driver->name); | 1079 | "suspend", driver->name); |
1072 | mark_quiesced(intf); | ||
1073 | } | 1080 | } |
1074 | 1081 | ||
1075 | done: | 1082 | done: |
@@ -1077,14 +1084,13 @@ static int usb_suspend_interface(struct usb_device *udev, | |||
1077 | return status; | 1084 | return status; |
1078 | } | 1085 | } |
1079 | 1086 | ||
1080 | /* Caller has locked intf's usb_device's pm_mutex */ | ||
1081 | static int usb_resume_interface(struct usb_device *udev, | 1087 | static int usb_resume_interface(struct usb_device *udev, |
1082 | struct usb_interface *intf, pm_message_t msg, int reset_resume) | 1088 | struct usb_interface *intf, pm_message_t msg, int reset_resume) |
1083 | { | 1089 | { |
1084 | struct usb_driver *driver; | 1090 | struct usb_driver *driver; |
1085 | int status = 0; | 1091 | int status = 0; |
1086 | 1092 | ||
1087 | if (udev->state == USB_STATE_NOTATTACHED || is_active(intf)) | 1093 | if (udev->state == USB_STATE_NOTATTACHED) |
1088 | goto done; | 1094 | goto done; |
1089 | 1095 | ||
1090 | /* Don't let autoresume interfere with unbinding */ | 1096 | /* Don't let autoresume interfere with unbinding */ |
@@ -1135,90 +1141,11 @@ static int usb_resume_interface(struct usb_device *udev, | |||
1135 | 1141 | ||
1136 | done: | 1142 | done: |
1137 | dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); | 1143 | dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); |
1138 | if (status == 0 && intf->condition == USB_INTERFACE_BOUND) | ||
1139 | mark_active(intf); | ||
1140 | 1144 | ||
1141 | /* Later we will unbind the driver and/or reprobe, if necessary */ | 1145 | /* Later we will unbind the driver and/or reprobe, if necessary */ |
1142 | return status; | 1146 | return status; |
1143 | } | 1147 | } |
1144 | 1148 | ||
1145 | #ifdef CONFIG_USB_SUSPEND | ||
1146 | |||
1147 | /* Internal routine to check whether we may autosuspend a device. */ | ||
1148 | static int autosuspend_check(struct usb_device *udev, int reschedule) | ||
1149 | { | ||
1150 | int i; | ||
1151 | struct usb_interface *intf; | ||
1152 | unsigned long suspend_time, j; | ||
1153 | |||
1154 | /* For autosuspend, fail fast if anything is in use or autosuspend | ||
1155 | * is disabled. Also fail if any interfaces require remote wakeup | ||
1156 | * but it isn't available. | ||
1157 | */ | ||
1158 | if (udev->pm_usage_cnt > 0) | ||
1159 | return -EBUSY; | ||
1160 | if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled) | ||
1161 | return -EPERM; | ||
1162 | |||
1163 | suspend_time = udev->last_busy + udev->autosuspend_delay; | ||
1164 | if (udev->actconfig) { | ||
1165 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | ||
1166 | intf = udev->actconfig->interface[i]; | ||
1167 | if (!is_active(intf)) | ||
1168 | continue; | ||
1169 | if (atomic_read(&intf->pm_usage_cnt) > 0) | ||
1170 | return -EBUSY; | ||
1171 | if (intf->needs_remote_wakeup && | ||
1172 | !udev->do_remote_wakeup) { | ||
1173 | dev_dbg(&udev->dev, "remote wakeup needed " | ||
1174 | "for autosuspend\n"); | ||
1175 | return -EOPNOTSUPP; | ||
1176 | } | ||
1177 | |||
1178 | /* Don't allow autosuspend if the device will need | ||
1179 | * a reset-resume and any of its interface drivers | ||
1180 | * doesn't include support. | ||
1181 | */ | ||
1182 | if (udev->quirks & USB_QUIRK_RESET_RESUME) { | ||
1183 | struct usb_driver *driver; | ||
1184 | |||
1185 | driver = to_usb_driver(intf->dev.driver); | ||
1186 | if (!driver->reset_resume || | ||
1187 | intf->needs_remote_wakeup) | ||
1188 | return -EOPNOTSUPP; | ||
1189 | } | ||
1190 | } | ||
1191 | } | ||
1192 | |||
1193 | /* If everything is okay but the device hasn't been idle for long | ||
1194 | * enough, queue a delayed autosuspend request. If the device | ||
1195 | * _has_ been idle for long enough and the reschedule flag is set, | ||
1196 | * likewise queue a delayed (1 second) autosuspend request. | ||
1197 | */ | ||
1198 | j = jiffies; | ||
1199 | if (time_before(j, suspend_time)) | ||
1200 | reschedule = 1; | ||
1201 | else | ||
1202 | suspend_time = j + HZ; | ||
1203 | if (reschedule) { | ||
1204 | if (!timer_pending(&udev->autosuspend.timer)) { | ||
1205 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | ||
1206 | round_jiffies_up_relative(suspend_time - j)); | ||
1207 | } | ||
1208 | return -EAGAIN; | ||
1209 | } | ||
1210 | return 0; | ||
1211 | } | ||
1212 | |||
1213 | #else | ||
1214 | |||
1215 | static inline int autosuspend_check(struct usb_device *udev, int reschedule) | ||
1216 | { | ||
1217 | return 0; | ||
1218 | } | ||
1219 | |||
1220 | #endif /* CONFIG_USB_SUSPEND */ | ||
1221 | |||
1222 | /** | 1149 | /** |
1223 | * usb_suspend_both - suspend a USB device and its interfaces | 1150 | * usb_suspend_both - suspend a USB device and its interfaces |
1224 | * @udev: the usb_device to suspend | 1151 | * @udev: the usb_device to suspend |
@@ -1230,27 +1157,12 @@ static inline int autosuspend_check(struct usb_device *udev, int reschedule) | |||
1230 | * all the interfaces which were suspended are resumed so that they remain | 1157 | * all the interfaces which were suspended are resumed so that they remain |
1231 | * in the same state as the device. | 1158 | * in the same state as the device. |
1232 | * | 1159 | * |
1233 | * If an autosuspend is in progress the routine checks first to make sure | 1160 | * Autosuspend requests originating from a child device or an interface |
1234 | * that neither the device itself or any of its active interfaces is in use | 1161 | * driver may be made without the protection of @udev's device lock, but |
1235 | * (pm_usage_cnt is greater than 0). If they are, the autosuspend fails. | 1162 | * all other suspend calls will hold the lock. Usbcore will insure that |
1236 | * | 1163 | * method calls do not arrive during bind, unbind, or reset operations. |
1237 | * If the suspend succeeds, the routine recursively queues an autosuspend | 1164 | * However drivers must be prepared to handle suspend calls arriving at |
1238 | * request for @udev's parent device, thereby propagating the change up | 1165 | * unpredictable times. |
1239 | * the device tree. If all of the parent's children are now suspended, | ||
1240 | * the parent will autosuspend in turn. | ||
1241 | * | ||
1242 | * The suspend method calls are subject to mutual exclusion under control | ||
1243 | * of @udev's pm_mutex. Many of these calls are also under the protection | ||
1244 | * of @udev's device lock (including all requests originating outside the | ||
1245 | * USB subsystem), but autosuspend requests generated by a child device or | ||
1246 | * interface driver may not be. Usbcore will insure that the method calls | ||
1247 | * do not arrive during bind, unbind, or reset operations. However, drivers | ||
1248 | * must be prepared to handle suspend calls arriving at unpredictable times. | ||
1249 | * The only way to block such calls is to do an autoresume (preventing | ||
1250 | * autosuspends) while holding @udev's device lock (preventing outside | ||
1251 | * suspends). | ||
1252 | * | ||
1253 | * The caller must hold @udev->pm_mutex. | ||
1254 | * | 1166 | * |
1255 | * This routine can run only in process context. | 1167 | * This routine can run only in process context. |
1256 | */ | 1168 | */ |
@@ -1259,20 +1171,11 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1259 | int status = 0; | 1171 | int status = 0; |
1260 | int i = 0; | 1172 | int i = 0; |
1261 | struct usb_interface *intf; | 1173 | struct usb_interface *intf; |
1262 | struct usb_device *parent = udev->parent; | ||
1263 | 1174 | ||
1264 | if (udev->state == USB_STATE_NOTATTACHED || | 1175 | if (udev->state == USB_STATE_NOTATTACHED || |
1265 | udev->state == USB_STATE_SUSPENDED) | 1176 | udev->state == USB_STATE_SUSPENDED) |
1266 | goto done; | 1177 | goto done; |
1267 | 1178 | ||
1268 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); | ||
1269 | |||
1270 | if (msg.event & PM_EVENT_AUTO) { | ||
1271 | status = autosuspend_check(udev, 0); | ||
1272 | if (status < 0) | ||
1273 | goto done; | ||
1274 | } | ||
1275 | |||
1276 | /* Suspend all the interfaces and then udev itself */ | 1179 | /* Suspend all the interfaces and then udev itself */ |
1277 | if (udev->actconfig) { | 1180 | if (udev->actconfig) { |
1278 | for (; i < udev->actconfig->desc.bNumInterfaces; i++) { | 1181 | for (; i < udev->actconfig->desc.bNumInterfaces; i++) { |
@@ -1287,35 +1190,21 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1287 | 1190 | ||
1288 | /* If the suspend failed, resume interfaces that did get suspended */ | 1191 | /* If the suspend failed, resume interfaces that did get suspended */ |
1289 | if (status != 0) { | 1192 | if (status != 0) { |
1290 | pm_message_t msg2; | 1193 | msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); |
1291 | |||
1292 | msg2.event = msg.event ^ (PM_EVENT_SUSPEND | PM_EVENT_RESUME); | ||
1293 | while (--i >= 0) { | 1194 | while (--i >= 0) { |
1294 | intf = udev->actconfig->interface[i]; | 1195 | intf = udev->actconfig->interface[i]; |
1295 | usb_resume_interface(udev, intf, msg2, 0); | 1196 | usb_resume_interface(udev, intf, msg, 0); |
1296 | } | 1197 | } |
1297 | 1198 | ||
1298 | /* Try another autosuspend when the interfaces aren't busy */ | 1199 | /* If the suspend succeeded then prevent any more URB submissions |
1299 | if (msg.event & PM_EVENT_AUTO) | 1200 | * and flush any outstanding URBs. |
1300 | autosuspend_check(udev, status == -EBUSY); | ||
1301 | |||
1302 | /* If the suspend succeeded then prevent any more URB submissions, | ||
1303 | * flush any outstanding URBs, and propagate the suspend up the tree. | ||
1304 | */ | 1201 | */ |
1305 | } else { | 1202 | } else { |
1306 | cancel_delayed_work(&udev->autosuspend); | ||
1307 | udev->can_submit = 0; | 1203 | udev->can_submit = 0; |
1308 | for (i = 0; i < 16; ++i) { | 1204 | for (i = 0; i < 16; ++i) { |
1309 | usb_hcd_flush_endpoint(udev, udev->ep_out[i]); | 1205 | usb_hcd_flush_endpoint(udev, udev->ep_out[i]); |
1310 | usb_hcd_flush_endpoint(udev, udev->ep_in[i]); | 1206 | usb_hcd_flush_endpoint(udev, udev->ep_in[i]); |
1311 | } | 1207 | } |
1312 | |||
1313 | /* If this is just a FREEZE or a PRETHAW, udev might | ||
1314 | * not really be suspended. Only true suspends get | ||
1315 | * propagated up the device tree. | ||
1316 | */ | ||
1317 | if (parent && udev->state == USB_STATE_SUSPENDED) | ||
1318 | usb_autosuspend_device(parent); | ||
1319 | } | 1208 | } |
1320 | 1209 | ||
1321 | done: | 1210 | done: |
@@ -1332,23 +1221,12 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1332 | * the resume method for @udev and then calls the resume methods for all | 1221 | * the resume method for @udev and then calls the resume methods for all |
1333 | * the interface drivers in @udev. | 1222 | * the interface drivers in @udev. |
1334 | * | 1223 | * |
1335 | * Before starting the resume, the routine calls itself recursively for | 1224 | * Autoresume requests originating from a child device or an interface |
1336 | * the parent device of @udev, thereby propagating the change up the device | 1225 | * driver may be made without the protection of @udev's device lock, but |
1337 | * tree and assuring that @udev will be able to resume. If the parent is | 1226 | * all other resume calls will hold the lock. Usbcore will insure that |
1338 | * unable to resume successfully, the routine fails. | 1227 | * method calls do not arrive during bind, unbind, or reset operations. |
1339 | * | 1228 | * However drivers must be prepared to handle resume calls arriving at |
1340 | * The resume method calls are subject to mutual exclusion under control | 1229 | * unpredictable times. |
1341 | * of @udev's pm_mutex. Many of these calls are also under the protection | ||
1342 | * of @udev's device lock (including all requests originating outside the | ||
1343 | * USB subsystem), but autoresume requests generated by a child device or | ||
1344 | * interface driver may not be. Usbcore will insure that the method calls | ||
1345 | * do not arrive during bind, unbind, or reset operations. However, drivers | ||
1346 | * must be prepared to handle resume calls arriving at unpredictable times. | ||
1347 | * The only way to block such calls is to do an autoresume (preventing | ||
1348 | * other autoresumes) while holding @udev's device lock (preventing outside | ||
1349 | * resumes). | ||
1350 | * | ||
1351 | * The caller must hold @udev->pm_mutex. | ||
1352 | * | 1230 | * |
1353 | * This routine can run only in process context. | 1231 | * This routine can run only in process context. |
1354 | */ | 1232 | */ |
@@ -1357,48 +1235,18 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) | |||
1357 | int status = 0; | 1235 | int status = 0; |
1358 | int i; | 1236 | int i; |
1359 | struct usb_interface *intf; | 1237 | struct usb_interface *intf; |
1360 | struct usb_device *parent = udev->parent; | ||
1361 | 1238 | ||
1362 | cancel_delayed_work(&udev->autosuspend); | ||
1363 | if (udev->state == USB_STATE_NOTATTACHED) { | 1239 | if (udev->state == USB_STATE_NOTATTACHED) { |
1364 | status = -ENODEV; | 1240 | status = -ENODEV; |
1365 | goto done; | 1241 | goto done; |
1366 | } | 1242 | } |
1367 | udev->can_submit = 1; | 1243 | udev->can_submit = 1; |
1368 | 1244 | ||
1369 | /* Propagate the resume up the tree, if necessary */ | 1245 | /* Resume the device */ |
1370 | if (udev->state == USB_STATE_SUSPENDED) { | 1246 | if (udev->state == USB_STATE_SUSPENDED || udev->reset_resume) |
1371 | if (parent) { | ||
1372 | status = usb_autoresume_device(parent); | ||
1373 | if (status == 0) { | ||
1374 | status = usb_resume_device(udev, msg); | ||
1375 | if (status || udev->state == | ||
1376 | USB_STATE_NOTATTACHED) { | ||
1377 | usb_autosuspend_device(parent); | ||
1378 | |||
1379 | /* It's possible usb_resume_device() | ||
1380 | * failed after the port was | ||
1381 | * unsuspended, causing udev to be | ||
1382 | * logically disconnected. We don't | ||
1383 | * want usb_disconnect() to autosuspend | ||
1384 | * the parent again, so tell it that | ||
1385 | * udev disconnected while still | ||
1386 | * suspended. */ | ||
1387 | if (udev->state == | ||
1388 | USB_STATE_NOTATTACHED) | ||
1389 | udev->discon_suspended = 1; | ||
1390 | } | ||
1391 | } | ||
1392 | } else { | ||
1393 | |||
1394 | /* We can't progagate beyond the USB subsystem, | ||
1395 | * so if a root hub's controller is suspended | ||
1396 | * then we're stuck. */ | ||
1397 | status = usb_resume_device(udev, msg); | ||
1398 | } | ||
1399 | } else if (udev->reset_resume) | ||
1400 | status = usb_resume_device(udev, msg); | 1247 | status = usb_resume_device(udev, msg); |
1401 | 1248 | ||
1249 | /* Resume the interfaces */ | ||
1402 | if (status == 0 && udev->actconfig) { | 1250 | if (status == 0 && udev->actconfig) { |
1403 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 1251 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
1404 | intf = udev->actconfig->interface[i]; | 1252 | intf = udev->actconfig->interface[i]; |
@@ -1414,55 +1262,94 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) | |||
1414 | return status; | 1262 | return status; |
1415 | } | 1263 | } |
1416 | 1264 | ||
1417 | #ifdef CONFIG_USB_SUSPEND | 1265 | /* The device lock is held by the PM core */ |
1266 | int usb_suspend(struct device *dev, pm_message_t msg) | ||
1267 | { | ||
1268 | struct usb_device *udev = to_usb_device(dev); | ||
1418 | 1269 | ||
1419 | /* Internal routine to adjust a device's usage counter and change | 1270 | do_unbind_rebind(udev, DO_UNBIND); |
1420 | * its autosuspend state. | 1271 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); |
1421 | */ | 1272 | return usb_suspend_both(udev, msg); |
1422 | static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) | 1273 | } |
1274 | |||
1275 | /* The device lock is held by the PM core */ | ||
1276 | int usb_resume(struct device *dev, pm_message_t msg) | ||
1423 | { | 1277 | { |
1424 | int status = 0; | 1278 | struct usb_device *udev = to_usb_device(dev); |
1279 | int status; | ||
1425 | 1280 | ||
1426 | usb_pm_lock(udev); | 1281 | /* For PM complete calls, all we do is rebind interfaces */ |
1427 | udev->pm_usage_cnt += inc_usage_cnt; | 1282 | if (msg.event == PM_EVENT_ON) { |
1428 | WARN_ON(udev->pm_usage_cnt < 0); | 1283 | if (udev->state != USB_STATE_NOTATTACHED) |
1429 | if (inc_usage_cnt) | 1284 | do_unbind_rebind(udev, DO_REBIND); |
1430 | udev->last_busy = jiffies; | 1285 | status = 0; |
1431 | if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { | 1286 | |
1432 | if (udev->state == USB_STATE_SUSPENDED) | 1287 | /* For all other calls, take the device back to full power and |
1433 | status = usb_resume_both(udev, PMSG_AUTO_RESUME); | 1288 | * tell the PM core in case it was autosuspended previously. |
1434 | if (status != 0) | 1289 | */ |
1435 | udev->pm_usage_cnt -= inc_usage_cnt; | 1290 | } else { |
1436 | else if (inc_usage_cnt) | 1291 | status = usb_resume_both(udev, msg); |
1292 | if (status == 0) { | ||
1293 | pm_runtime_disable(dev); | ||
1294 | pm_runtime_set_active(dev); | ||
1295 | pm_runtime_enable(dev); | ||
1437 | udev->last_busy = jiffies; | 1296 | udev->last_busy = jiffies; |
1438 | } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { | 1297 | } |
1439 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); | ||
1440 | } | 1298 | } |
1441 | usb_pm_unlock(udev); | 1299 | |
1300 | /* Avoid PM error messages for devices disconnected while suspended | ||
1301 | * as we'll display regular disconnect messages just a bit later. | ||
1302 | */ | ||
1303 | if (status == -ENODEV) | ||
1304 | status = 0; | ||
1442 | return status; | 1305 | return status; |
1443 | } | 1306 | } |
1444 | 1307 | ||
1445 | /* usb_autosuspend_work - callback routine to autosuspend a USB device */ | 1308 | #endif /* CONFIG_PM */ |
1446 | void usb_autosuspend_work(struct work_struct *work) | 1309 | |
1447 | { | 1310 | #ifdef CONFIG_USB_SUSPEND |
1448 | struct usb_device *udev = | ||
1449 | container_of(work, struct usb_device, autosuspend.work); | ||
1450 | 1311 | ||
1451 | usb_autopm_do_device(udev, 0); | 1312 | /** |
1313 | * usb_enable_autosuspend - allow a USB device to be autosuspended | ||
1314 | * @udev: the USB device which may be autosuspended | ||
1315 | * | ||
1316 | * This routine allows @udev to be autosuspended. An autosuspend won't | ||
1317 | * take place until the autosuspend_delay has elapsed and all the other | ||
1318 | * necessary conditions are satisfied. | ||
1319 | * | ||
1320 | * The caller must hold @udev's device lock. | ||
1321 | */ | ||
1322 | int usb_enable_autosuspend(struct usb_device *udev) | ||
1323 | { | ||
1324 | if (udev->autosuspend_disabled) { | ||
1325 | udev->autosuspend_disabled = 0; | ||
1326 | usb_autosuspend_device(udev); | ||
1327 | } | ||
1328 | return 0; | ||
1452 | } | 1329 | } |
1330 | EXPORT_SYMBOL_GPL(usb_enable_autosuspend); | ||
1453 | 1331 | ||
1454 | /* usb_autoresume_work - callback routine to autoresume a USB device */ | 1332 | /** |
1455 | void usb_autoresume_work(struct work_struct *work) | 1333 | * usb_disable_autosuspend - prevent a USB device from being autosuspended |
1334 | * @udev: the USB device which may not be autosuspended | ||
1335 | * | ||
1336 | * This routine prevents @udev from being autosuspended and wakes it up | ||
1337 | * if it is already autosuspended. | ||
1338 | * | ||
1339 | * The caller must hold @udev's device lock. | ||
1340 | */ | ||
1341 | int usb_disable_autosuspend(struct usb_device *udev) | ||
1456 | { | 1342 | { |
1457 | struct usb_device *udev = | 1343 | int rc = 0; |
1458 | container_of(work, struct usb_device, autoresume); | ||
1459 | 1344 | ||
1460 | /* Wake it up, let the drivers do their thing, and then put it | 1345 | if (!udev->autosuspend_disabled) { |
1461 | * back to sleep. | 1346 | rc = usb_autoresume_device(udev); |
1462 | */ | 1347 | if (rc == 0) |
1463 | if (usb_autopm_do_device(udev, 1) == 0) | 1348 | udev->autosuspend_disabled = 1; |
1464 | usb_autopm_do_device(udev, -1); | 1349 | } |
1350 | return rc; | ||
1465 | } | 1351 | } |
1352 | EXPORT_SYMBOL_GPL(usb_disable_autosuspend); | ||
1466 | 1353 | ||
1467 | /** | 1354 | /** |
1468 | * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces | 1355 | * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces |
@@ -1472,15 +1359,11 @@ void usb_autoresume_work(struct work_struct *work) | |||
1472 | * @udev and wants to allow it to autosuspend. Examples would be when | 1359 | * @udev and wants to allow it to autosuspend. Examples would be when |
1473 | * @udev's device file in usbfs is closed or after a configuration change. | 1360 | * @udev's device file in usbfs is closed or after a configuration change. |
1474 | * | 1361 | * |
1475 | * @udev's usage counter is decremented. If it or any of the usage counters | 1362 | * @udev's usage counter is decremented; if it drops to 0 and all the |
1476 | * for an active interface is greater than 0, no autosuspend request will be | 1363 | * interfaces are inactive then a delayed autosuspend will be attempted. |
1477 | * queued. (If an interface driver does not support autosuspend then its | 1364 | * The attempt may fail (see autosuspend_check()). |
1478 | * usage counter is permanently positive.) Furthermore, if an interface | ||
1479 | * driver requires remote-wakeup capability during autosuspend but remote | ||
1480 | * wakeup is disabled, the autosuspend will fail. | ||
1481 | * | 1365 | * |
1482 | * Often the caller will hold @udev's device lock, but this is not | 1366 | * The caller must hold @udev's device lock. |
1483 | * necessary. | ||
1484 | * | 1367 | * |
1485 | * This routine can run only in process context. | 1368 | * This routine can run only in process context. |
1486 | */ | 1369 | */ |
@@ -1488,9 +1371,11 @@ void usb_autosuspend_device(struct usb_device *udev) | |||
1488 | { | 1371 | { |
1489 | int status; | 1372 | int status; |
1490 | 1373 | ||
1491 | status = usb_autopm_do_device(udev, -1); | 1374 | udev->last_busy = jiffies; |
1492 | dev_vdbg(&udev->dev, "%s: cnt %d\n", | 1375 | status = pm_runtime_put_sync(&udev->dev); |
1493 | __func__, udev->pm_usage_cnt); | 1376 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", |
1377 | __func__, atomic_read(&udev->dev.power.usage_count), | ||
1378 | status); | ||
1494 | } | 1379 | } |
1495 | 1380 | ||
1496 | /** | 1381 | /** |
@@ -1500,17 +1385,22 @@ void usb_autosuspend_device(struct usb_device *udev) | |||
1500 | * This routine should be called when a core subsystem thinks @udev may | 1385 | * This routine should be called when a core subsystem thinks @udev may |
1501 | * be ready to autosuspend. | 1386 | * be ready to autosuspend. |
1502 | * | 1387 | * |
1503 | * @udev's usage counter left unchanged. If it or any of the usage counters | 1388 | * @udev's usage counter left unchanged. If it is 0 and all the interfaces |
1504 | * for an active interface is greater than 0, or autosuspend is not allowed | 1389 | * are inactive then an autosuspend will be attempted. The attempt may |
1505 | * for any other reason, no autosuspend request will be queued. | 1390 | * fail or be delayed. |
1391 | * | ||
1392 | * The caller must hold @udev's device lock. | ||
1506 | * | 1393 | * |
1507 | * This routine can run only in process context. | 1394 | * This routine can run only in process context. |
1508 | */ | 1395 | */ |
1509 | void usb_try_autosuspend_device(struct usb_device *udev) | 1396 | void usb_try_autosuspend_device(struct usb_device *udev) |
1510 | { | 1397 | { |
1511 | usb_autopm_do_device(udev, 0); | 1398 | int status; |
1512 | dev_vdbg(&udev->dev, "%s: cnt %d\n", | 1399 | |
1513 | __func__, udev->pm_usage_cnt); | 1400 | status = pm_runtime_idle(&udev->dev); |
1401 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", | ||
1402 | __func__, atomic_read(&udev->dev.power.usage_count), | ||
1403 | status); | ||
1514 | } | 1404 | } |
1515 | 1405 | ||
1516 | /** | 1406 | /** |
@@ -1519,16 +1409,15 @@ void usb_try_autosuspend_device(struct usb_device *udev) | |||
1519 | * | 1409 | * |
1520 | * This routine should be called when a core subsystem wants to use @udev | 1410 | * This routine should be called when a core subsystem wants to use @udev |
1521 | * and needs to guarantee that it is not suspended. No autosuspend will | 1411 | * and needs to guarantee that it is not suspended. No autosuspend will |
1522 | * occur until usb_autosuspend_device is called. (Note that this will not | 1412 | * occur until usb_autosuspend_device() is called. (Note that this will |
1523 | * prevent suspend events originating in the PM core.) Examples would be | 1413 | * not prevent suspend events originating in the PM core.) Examples would |
1524 | * when @udev's device file in usbfs is opened or when a remote-wakeup | 1414 | * be when @udev's device file in usbfs is opened or when a remote-wakeup |
1525 | * request is received. | 1415 | * request is received. |
1526 | * | 1416 | * |
1527 | * @udev's usage counter is incremented to prevent subsequent autosuspends. | 1417 | * @udev's usage counter is incremented to prevent subsequent autosuspends. |
1528 | * However if the autoresume fails then the usage counter is re-decremented. | 1418 | * However if the autoresume fails then the usage counter is re-decremented. |
1529 | * | 1419 | * |
1530 | * Often the caller will hold @udev's device lock, but this is not | 1420 | * The caller must hold @udev's device lock. |
1531 | * necessary (and attempting it might cause deadlock). | ||
1532 | * | 1421 | * |
1533 | * This routine can run only in process context. | 1422 | * This routine can run only in process context. |
1534 | */ | 1423 | */ |
@@ -1536,42 +1425,14 @@ int usb_autoresume_device(struct usb_device *udev) | |||
1536 | { | 1425 | { |
1537 | int status; | 1426 | int status; |
1538 | 1427 | ||
1539 | status = usb_autopm_do_device(udev, 1); | 1428 | status = pm_runtime_get_sync(&udev->dev); |
1540 | dev_vdbg(&udev->dev, "%s: status %d cnt %d\n", | 1429 | if (status < 0) |
1541 | __func__, status, udev->pm_usage_cnt); | 1430 | pm_runtime_put_sync(&udev->dev); |
1542 | return status; | 1431 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", |
1543 | } | 1432 | __func__, atomic_read(&udev->dev.power.usage_count), |
1544 | 1433 | status); | |
1545 | /* Internal routine to adjust an interface's usage counter and change | 1434 | if (status > 0) |
1546 | * its device's autosuspend state. | 1435 | status = 0; |
1547 | */ | ||
1548 | static int usb_autopm_do_interface(struct usb_interface *intf, | ||
1549 | int inc_usage_cnt) | ||
1550 | { | ||
1551 | struct usb_device *udev = interface_to_usbdev(intf); | ||
1552 | int status = 0; | ||
1553 | |||
1554 | usb_pm_lock(udev); | ||
1555 | if (intf->condition == USB_INTERFACE_UNBOUND) | ||
1556 | status = -ENODEV; | ||
1557 | else { | ||
1558 | atomic_add(inc_usage_cnt, &intf->pm_usage_cnt); | ||
1559 | udev->last_busy = jiffies; | ||
1560 | if (inc_usage_cnt >= 0 && | ||
1561 | atomic_read(&intf->pm_usage_cnt) > 0) { | ||
1562 | if (udev->state == USB_STATE_SUSPENDED) | ||
1563 | status = usb_resume_both(udev, | ||
1564 | PMSG_AUTO_RESUME); | ||
1565 | if (status != 0) | ||
1566 | atomic_sub(inc_usage_cnt, &intf->pm_usage_cnt); | ||
1567 | else | ||
1568 | udev->last_busy = jiffies; | ||
1569 | } else if (inc_usage_cnt <= 0 && | ||
1570 | atomic_read(&intf->pm_usage_cnt) <= 0) { | ||
1571 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); | ||
1572 | } | ||
1573 | } | ||
1574 | usb_pm_unlock(udev); | ||
1575 | return status; | 1436 | return status; |
1576 | } | 1437 | } |
1577 | 1438 | ||
@@ -1585,34 +1446,25 @@ static int usb_autopm_do_interface(struct usb_interface *intf, | |||
1585 | * closed. | 1446 | * closed. |
1586 | * | 1447 | * |
1587 | * The routine decrements @intf's usage counter. When the counter reaches | 1448 | * The routine decrements @intf's usage counter. When the counter reaches |
1588 | * 0, a delayed autosuspend request for @intf's device is queued. When | 1449 | * 0, a delayed autosuspend request for @intf's device is attempted. The |
1589 | * the delay expires, if @intf->pm_usage_cnt is still <= 0 along with all | 1450 | * attempt may fail (see autosuspend_check()). |
1590 | * the other usage counters for the sibling interfaces and @intf's | ||
1591 | * usb_device, the device and all its interfaces will be autosuspended. | ||
1592 | * | ||
1593 | * Note that @intf->pm_usage_cnt is owned by the interface driver. The | ||
1594 | * core will not change its value other than the increment and decrement | ||
1595 | * in usb_autopm_get_interface and usb_autopm_put_interface. The driver | ||
1596 | * may use this simple counter-oriented discipline or may set the value | ||
1597 | * any way it likes. | ||
1598 | * | 1451 | * |
1599 | * If the driver has set @intf->needs_remote_wakeup then autosuspend will | 1452 | * If the driver has set @intf->needs_remote_wakeup then autosuspend will |
1600 | * take place only if the device's remote-wakeup facility is enabled. | 1453 | * take place only if the device's remote-wakeup facility is enabled. |
1601 | * | 1454 | * |
1602 | * Suspend method calls queued by this routine can arrive at any time | ||
1603 | * while @intf is resumed and its usage counter is equal to 0. They are | ||
1604 | * not protected by the usb_device's lock but only by its pm_mutex. | ||
1605 | * Drivers must provide their own synchronization. | ||
1606 | * | ||
1607 | * This routine can run only in process context. | 1455 | * This routine can run only in process context. |
1608 | */ | 1456 | */ |
1609 | void usb_autopm_put_interface(struct usb_interface *intf) | 1457 | void usb_autopm_put_interface(struct usb_interface *intf) |
1610 | { | 1458 | { |
1611 | int status; | 1459 | struct usb_device *udev = interface_to_usbdev(intf); |
1460 | int status; | ||
1612 | 1461 | ||
1613 | status = usb_autopm_do_interface(intf, -1); | 1462 | udev->last_busy = jiffies; |
1614 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1463 | atomic_dec(&intf->pm_usage_cnt); |
1615 | __func__, status, atomic_read(&intf->pm_usage_cnt)); | 1464 | status = pm_runtime_put_sync(&intf->dev); |
1465 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", | ||
1466 | __func__, atomic_read(&intf->dev.power.usage_count), | ||
1467 | status); | ||
1616 | } | 1468 | } |
1617 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface); | 1469 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface); |
1618 | 1470 | ||
@@ -1620,11 +1472,11 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); | |||
1620 | * usb_autopm_put_interface_async - decrement a USB interface's PM-usage counter | 1472 | * usb_autopm_put_interface_async - decrement a USB interface's PM-usage counter |
1621 | * @intf: the usb_interface whose counter should be decremented | 1473 | * @intf: the usb_interface whose counter should be decremented |
1622 | * | 1474 | * |
1623 | * This routine does essentially the same thing as | 1475 | * This routine does much the same thing as usb_autopm_put_interface(): |
1624 | * usb_autopm_put_interface(): it decrements @intf's usage counter and | 1476 | * It decrements @intf's usage counter and schedules a delayed |
1625 | * queues a delayed autosuspend request if the counter is <= 0. The | 1477 | * autosuspend request if the counter is <= 0. The difference is that it |
1626 | * difference is that it does not acquire the device's pm_mutex; | 1478 | * does not perform any synchronization; callers should hold a private |
1627 | * callers must handle all synchronization issues themselves. | 1479 | * lock and handle all synchronization issues themselves. |
1628 | * | 1480 | * |
1629 | * Typically a driver would call this routine during an URB's completion | 1481 | * Typically a driver would call this routine during an URB's completion |
1630 | * handler, if no more URBs were pending. | 1482 | * handler, if no more URBs were pending. |
@@ -1634,28 +1486,58 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); | |||
1634 | void usb_autopm_put_interface_async(struct usb_interface *intf) | 1486 | void usb_autopm_put_interface_async(struct usb_interface *intf) |
1635 | { | 1487 | { |
1636 | struct usb_device *udev = interface_to_usbdev(intf); | 1488 | struct usb_device *udev = interface_to_usbdev(intf); |
1489 | unsigned long last_busy; | ||
1637 | int status = 0; | 1490 | int status = 0; |
1638 | 1491 | ||
1639 | if (intf->condition == USB_INTERFACE_UNBOUND) { | 1492 | last_busy = udev->last_busy; |
1640 | status = -ENODEV; | 1493 | udev->last_busy = jiffies; |
1641 | } else { | 1494 | atomic_dec(&intf->pm_usage_cnt); |
1642 | udev->last_busy = jiffies; | 1495 | pm_runtime_put_noidle(&intf->dev); |
1643 | atomic_dec(&intf->pm_usage_cnt); | 1496 | |
1644 | if (udev->autosuspend_disabled || udev->autosuspend_delay < 0) | 1497 | if (!udev->autosuspend_disabled) { |
1645 | status = -EPERM; | 1498 | /* Optimization: Don't schedule a delayed autosuspend if |
1646 | else if (atomic_read(&intf->pm_usage_cnt) <= 0 && | 1499 | * the timer is already running and the expiration time |
1647 | !timer_pending(&udev->autosuspend.timer)) { | 1500 | * wouldn't change. |
1648 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | 1501 | * |
1502 | * We have to use the interface's timer. Attempts to | ||
1503 | * schedule a suspend for the device would fail because | ||
1504 | * the interface is still active. | ||
1505 | */ | ||
1506 | if (intf->dev.power.timer_expires == 0 || | ||
1507 | round_jiffies_up(last_busy) != | ||
1508 | round_jiffies_up(jiffies)) { | ||
1509 | status = pm_schedule_suspend(&intf->dev, | ||
1510 | jiffies_to_msecs( | ||
1649 | round_jiffies_up_relative( | 1511 | round_jiffies_up_relative( |
1650 | udev->autosuspend_delay)); | 1512 | udev->autosuspend_delay))); |
1651 | } | 1513 | } |
1652 | } | 1514 | } |
1653 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1515 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", |
1654 | __func__, status, atomic_read(&intf->pm_usage_cnt)); | 1516 | __func__, atomic_read(&intf->dev.power.usage_count), |
1517 | status); | ||
1655 | } | 1518 | } |
1656 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async); | 1519 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async); |
1657 | 1520 | ||
1658 | /** | 1521 | /** |
1522 | * usb_autopm_put_interface_no_suspend - decrement a USB interface's PM-usage counter | ||
1523 | * @intf: the usb_interface whose counter should be decremented | ||
1524 | * | ||
1525 | * This routine decrements @intf's usage counter but does not carry out an | ||
1526 | * autosuspend. | ||
1527 | * | ||
1528 | * This routine can run in atomic context. | ||
1529 | */ | ||
1530 | void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) | ||
1531 | { | ||
1532 | struct usb_device *udev = interface_to_usbdev(intf); | ||
1533 | |||
1534 | udev->last_busy = jiffies; | ||
1535 | atomic_dec(&intf->pm_usage_cnt); | ||
1536 | pm_runtime_put_noidle(&intf->dev); | ||
1537 | } | ||
1538 | EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend); | ||
1539 | |||
1540 | /** | ||
1659 | * usb_autopm_get_interface - increment a USB interface's PM-usage counter | 1541 | * usb_autopm_get_interface - increment a USB interface's PM-usage counter |
1660 | * @intf: the usb_interface whose counter should be incremented | 1542 | * @intf: the usb_interface whose counter should be incremented |
1661 | * | 1543 | * |
@@ -1667,25 +1549,8 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async); | |||
1667 | * or @intf is unbound. A typical example would be a character-device | 1549 | * or @intf is unbound. A typical example would be a character-device |
1668 | * driver when its device file is opened. | 1550 | * driver when its device file is opened. |
1669 | * | 1551 | * |
1670 | * | 1552 | * @intf's usage counter is incremented to prevent subsequent autosuspends. |
1671 | * The routine increments @intf's usage counter. (However if the | 1553 | * However if the autoresume fails then the counter is re-decremented. |
1672 | * autoresume fails then the counter is re-decremented.) So long as the | ||
1673 | * counter is greater than 0, autosuspend will not be allowed for @intf | ||
1674 | * or its usb_device. When the driver is finished using @intf it should | ||
1675 | * call usb_autopm_put_interface() to decrement the usage counter and | ||
1676 | * queue a delayed autosuspend request (if the counter is <= 0). | ||
1677 | * | ||
1678 | * | ||
1679 | * Note that @intf->pm_usage_cnt is owned by the interface driver. The | ||
1680 | * core will not change its value other than the increment and decrement | ||
1681 | * in usb_autopm_get_interface and usb_autopm_put_interface. The driver | ||
1682 | * may use this simple counter-oriented discipline or may set the value | ||
1683 | * any way it likes. | ||
1684 | * | ||
1685 | * Resume method calls generated by this routine can arrive at any time | ||
1686 | * while @intf is suspended. They are not protected by the usb_device's | ||
1687 | * lock but only by its pm_mutex. Drivers must provide their own | ||
1688 | * synchronization. | ||
1689 | * | 1554 | * |
1690 | * This routine can run only in process context. | 1555 | * This routine can run only in process context. |
1691 | */ | 1556 | */ |
@@ -1693,9 +1558,16 @@ int usb_autopm_get_interface(struct usb_interface *intf) | |||
1693 | { | 1558 | { |
1694 | int status; | 1559 | int status; |
1695 | 1560 | ||
1696 | status = usb_autopm_do_interface(intf, 1); | 1561 | status = pm_runtime_get_sync(&intf->dev); |
1697 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1562 | if (status < 0) |
1698 | __func__, status, atomic_read(&intf->pm_usage_cnt)); | 1563 | pm_runtime_put_sync(&intf->dev); |
1564 | else | ||
1565 | atomic_inc(&intf->pm_usage_cnt); | ||
1566 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", | ||
1567 | __func__, atomic_read(&intf->dev.power.usage_count), | ||
1568 | status); | ||
1569 | if (status > 0) | ||
1570 | status = 0; | ||
1699 | return status; | 1571 | return status; |
1700 | } | 1572 | } |
1701 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface); | 1573 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface); |
@@ -1705,149 +1577,207 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface); | |||
1705 | * @intf: the usb_interface whose counter should be incremented | 1577 | * @intf: the usb_interface whose counter should be incremented |
1706 | * | 1578 | * |
1707 | * This routine does much the same thing as | 1579 | * This routine does much the same thing as |
1708 | * usb_autopm_get_interface(): it increments @intf's usage counter and | 1580 | * usb_autopm_get_interface(): It increments @intf's usage counter and |
1709 | * queues an autoresume request if the result is > 0. The differences | 1581 | * queues an autoresume request if the device is suspended. The |
1710 | * are that it does not acquire the device's pm_mutex (callers must | 1582 | * differences are that it does not perform any synchronization (callers |
1711 | * handle all synchronization issues themselves), and it does not | 1583 | * should hold a private lock and handle all synchronization issues |
1712 | * autoresume the device directly (it only queues a request). After a | 1584 | * themselves), and it does not autoresume the device directly (it only |
1713 | * successful call, the device will generally not yet be resumed. | 1585 | * queues a request). After a successful call, the device may not yet be |
1586 | * resumed. | ||
1714 | * | 1587 | * |
1715 | * This routine can run in atomic context. | 1588 | * This routine can run in atomic context. |
1716 | */ | 1589 | */ |
1717 | int usb_autopm_get_interface_async(struct usb_interface *intf) | 1590 | int usb_autopm_get_interface_async(struct usb_interface *intf) |
1718 | { | 1591 | { |
1719 | struct usb_device *udev = interface_to_usbdev(intf); | 1592 | int status = 0; |
1720 | int status = 0; | 1593 | enum rpm_status s; |
1721 | 1594 | ||
1722 | if (intf->condition == USB_INTERFACE_UNBOUND) | 1595 | /* Don't request a resume unless the interface is already suspending |
1723 | status = -ENODEV; | 1596 | * or suspended. Doing so would force a running suspend timer to be |
1724 | else { | 1597 | * cancelled. |
1598 | */ | ||
1599 | pm_runtime_get_noresume(&intf->dev); | ||
1600 | s = ACCESS_ONCE(intf->dev.power.runtime_status); | ||
1601 | if (s == RPM_SUSPENDING || s == RPM_SUSPENDED) | ||
1602 | status = pm_request_resume(&intf->dev); | ||
1603 | |||
1604 | if (status < 0 && status != -EINPROGRESS) | ||
1605 | pm_runtime_put_noidle(&intf->dev); | ||
1606 | else | ||
1725 | atomic_inc(&intf->pm_usage_cnt); | 1607 | atomic_inc(&intf->pm_usage_cnt); |
1726 | if (atomic_read(&intf->pm_usage_cnt) > 0 && | 1608 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", |
1727 | udev->state == USB_STATE_SUSPENDED) | 1609 | __func__, atomic_read(&intf->dev.power.usage_count), |
1728 | queue_work(ksuspend_usb_wq, &udev->autoresume); | 1610 | status); |
1729 | } | 1611 | if (status > 0) |
1730 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | 1612 | status = 0; |
1731 | __func__, status, atomic_read(&intf->pm_usage_cnt)); | ||
1732 | return status; | 1613 | return status; |
1733 | } | 1614 | } |
1734 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); | 1615 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); |
1735 | 1616 | ||
1736 | #else | ||
1737 | |||
1738 | void usb_autosuspend_work(struct work_struct *work) | ||
1739 | {} | ||
1740 | |||
1741 | void usb_autoresume_work(struct work_struct *work) | ||
1742 | {} | ||
1743 | |||
1744 | #endif /* CONFIG_USB_SUSPEND */ | ||
1745 | |||
1746 | /** | 1617 | /** |
1747 | * usb_external_suspend_device - external suspend of a USB device and its interfaces | 1618 | * usb_autopm_get_interface_no_resume - increment a USB interface's PM-usage counter |
1748 | * @udev: the usb_device to suspend | 1619 | * @intf: the usb_interface whose counter should be incremented |
1749 | * @msg: Power Management message describing this state transition | ||
1750 | * | 1620 | * |
1751 | * This routine handles external suspend requests: ones not generated | 1621 | * This routine increments @intf's usage counter but does not carry out an |
1752 | * internally by a USB driver (autosuspend) but rather coming from the user | 1622 | * autoresume. |
1753 | * (via sysfs) or the PM core (system sleep). The suspend will be carried | ||
1754 | * out regardless of @udev's usage counter or those of its interfaces, | ||
1755 | * and regardless of whether or not remote wakeup is enabled. Of course, | ||
1756 | * interface drivers still have the option of failing the suspend (if | ||
1757 | * there are unsuspended children, for example). | ||
1758 | * | 1623 | * |
1759 | * The caller must hold @udev's device lock. | 1624 | * This routine can run in atomic context. |
1760 | */ | 1625 | */ |
1761 | int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg) | 1626 | void usb_autopm_get_interface_no_resume(struct usb_interface *intf) |
1762 | { | 1627 | { |
1763 | int status; | 1628 | struct usb_device *udev = interface_to_usbdev(intf); |
1764 | 1629 | ||
1765 | do_unbind_rebind(udev, DO_UNBIND); | 1630 | udev->last_busy = jiffies; |
1766 | usb_pm_lock(udev); | 1631 | atomic_inc(&intf->pm_usage_cnt); |
1767 | status = usb_suspend_both(udev, msg); | 1632 | pm_runtime_get_noresume(&intf->dev); |
1768 | usb_pm_unlock(udev); | ||
1769 | return status; | ||
1770 | } | 1633 | } |
1634 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume); | ||
1771 | 1635 | ||
1772 | /** | 1636 | /* Internal routine to check whether we may autosuspend a device. */ |
1773 | * usb_external_resume_device - external resume of a USB device and its interfaces | 1637 | static int autosuspend_check(struct usb_device *udev) |
1774 | * @udev: the usb_device to resume | ||
1775 | * @msg: Power Management message describing this state transition | ||
1776 | * | ||
1777 | * This routine handles external resume requests: ones not generated | ||
1778 | * internally by a USB driver (autoresume) but rather coming from the user | ||
1779 | * (via sysfs), the PM core (system resume), or the device itself (remote | ||
1780 | * wakeup). @udev's usage counter is unaffected. | ||
1781 | * | ||
1782 | * The caller must hold @udev's device lock. | ||
1783 | */ | ||
1784 | int usb_external_resume_device(struct usb_device *udev, pm_message_t msg) | ||
1785 | { | 1638 | { |
1786 | int status; | 1639 | int i; |
1640 | struct usb_interface *intf; | ||
1641 | unsigned long suspend_time, j; | ||
1787 | 1642 | ||
1788 | usb_pm_lock(udev); | 1643 | /* Fail if autosuspend is disabled, or any interfaces are in use, or |
1789 | status = usb_resume_both(udev, msg); | 1644 | * any interface drivers require remote wakeup but it isn't available. |
1790 | udev->last_busy = jiffies; | 1645 | */ |
1791 | usb_pm_unlock(udev); | 1646 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); |
1792 | if (status == 0) | 1647 | if (udev->actconfig) { |
1793 | do_unbind_rebind(udev, DO_REBIND); | 1648 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
1649 | intf = udev->actconfig->interface[i]; | ||
1794 | 1650 | ||
1795 | /* Now that the device is awake, we can start trying to autosuspend | 1651 | /* We don't need to check interfaces that are |
1796 | * it again. */ | 1652 | * disabled for runtime PM. Either they are unbound |
1797 | if (status == 0) | 1653 | * or else their drivers don't support autosuspend |
1798 | usb_try_autosuspend_device(udev); | 1654 | * and so they are permanently active. |
1799 | return status; | 1655 | */ |
1656 | if (intf->dev.power.disable_depth) | ||
1657 | continue; | ||
1658 | if (atomic_read(&intf->dev.power.usage_count) > 0) | ||
1659 | return -EBUSY; | ||
1660 | if (intf->needs_remote_wakeup && | ||
1661 | !udev->do_remote_wakeup) { | ||
1662 | dev_dbg(&udev->dev, "remote wakeup needed " | ||
1663 | "for autosuspend\n"); | ||
1664 | return -EOPNOTSUPP; | ||
1665 | } | ||
1666 | |||
1667 | /* Don't allow autosuspend if the device will need | ||
1668 | * a reset-resume and any of its interface drivers | ||
1669 | * doesn't include support or needs remote wakeup. | ||
1670 | */ | ||
1671 | if (udev->quirks & USB_QUIRK_RESET_RESUME) { | ||
1672 | struct usb_driver *driver; | ||
1673 | |||
1674 | driver = to_usb_driver(intf->dev.driver); | ||
1675 | if (!driver->reset_resume || | ||
1676 | intf->needs_remote_wakeup) | ||
1677 | return -EOPNOTSUPP; | ||
1678 | } | ||
1679 | } | ||
1680 | } | ||
1681 | |||
1682 | /* If everything is okay but the device hasn't been idle for long | ||
1683 | * enough, queue a delayed autosuspend request. | ||
1684 | */ | ||
1685 | j = ACCESS_ONCE(jiffies); | ||
1686 | suspend_time = udev->last_busy + udev->autosuspend_delay; | ||
1687 | if (time_before(j, suspend_time)) { | ||
1688 | pm_schedule_suspend(&udev->dev, jiffies_to_msecs( | ||
1689 | round_jiffies_up_relative(suspend_time - j))); | ||
1690 | return -EAGAIN; | ||
1691 | } | ||
1692 | return 0; | ||
1800 | } | 1693 | } |
1801 | 1694 | ||
1802 | int usb_suspend(struct device *dev, pm_message_t msg) | 1695 | static int usb_runtime_suspend(struct device *dev) |
1803 | { | 1696 | { |
1804 | struct usb_device *udev; | 1697 | int status = 0; |
1805 | |||
1806 | udev = to_usb_device(dev); | ||
1807 | 1698 | ||
1808 | /* If udev is already suspended, we can skip this suspend and | 1699 | /* A USB device can be suspended if it passes the various autosuspend |
1809 | * we should also skip the upcoming system resume. High-speed | 1700 | * checks. Runtime suspend for a USB device means suspending all the |
1810 | * root hubs are an exception; they need to resume whenever the | 1701 | * interfaces and then the device itself. |
1811 | * system wakes up in order for USB-PERSIST port handover to work | ||
1812 | * properly. | ||
1813 | */ | 1702 | */ |
1814 | if (udev->state == USB_STATE_SUSPENDED) { | 1703 | if (is_usb_device(dev)) { |
1815 | if (udev->parent || udev->speed != USB_SPEED_HIGH) | 1704 | struct usb_device *udev = to_usb_device(dev); |
1816 | udev->skip_sys_resume = 1; | 1705 | |
1817 | return 0; | 1706 | if (autosuspend_check(udev) != 0) |
1707 | return -EAGAIN; | ||
1708 | |||
1709 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); | ||
1710 | |||
1711 | /* If an interface fails the suspend, adjust the last_busy | ||
1712 | * time so that we don't get another suspend attempt right | ||
1713 | * away. | ||
1714 | */ | ||
1715 | if (status) { | ||
1716 | udev->last_busy = jiffies + | ||
1717 | (udev->autosuspend_delay == 0 ? | ||
1718 | HZ/2 : 0); | ||
1719 | } | ||
1720 | |||
1721 | /* Prevent the parent from suspending immediately after */ | ||
1722 | else if (udev->parent) { | ||
1723 | udev->parent->last_busy = jiffies; | ||
1724 | } | ||
1818 | } | 1725 | } |
1819 | 1726 | ||
1820 | udev->skip_sys_resume = 0; | 1727 | /* Runtime suspend for a USB interface doesn't mean anything. */ |
1821 | return usb_external_suspend_device(udev, msg); | 1728 | return status; |
1822 | } | 1729 | } |
1823 | 1730 | ||
1824 | int usb_resume(struct device *dev, pm_message_t msg) | 1731 | static int usb_runtime_resume(struct device *dev) |
1825 | { | 1732 | { |
1826 | struct usb_device *udev; | 1733 | /* Runtime resume for a USB device means resuming both the device |
1827 | int status; | 1734 | * and all its interfaces. |
1735 | */ | ||
1736 | if (is_usb_device(dev)) { | ||
1737 | struct usb_device *udev = to_usb_device(dev); | ||
1738 | int status; | ||
1828 | 1739 | ||
1829 | udev = to_usb_device(dev); | 1740 | status = usb_resume_both(udev, PMSG_AUTO_RESUME); |
1741 | udev->last_busy = jiffies; | ||
1742 | return status; | ||
1743 | } | ||
1830 | 1744 | ||
1831 | /* If udev->skip_sys_resume is set then udev was already suspended | 1745 | /* Runtime resume for a USB interface doesn't mean anything. */ |
1832 | * when the system sleep started, so we don't want to resume it | 1746 | return 0; |
1833 | * during this system wakeup. | 1747 | } |
1834 | */ | ||
1835 | if (udev->skip_sys_resume) | ||
1836 | return 0; | ||
1837 | status = usb_external_resume_device(udev, msg); | ||
1838 | 1748 | ||
1839 | /* Avoid PM error messages for devices disconnected while suspended | 1749 | static int usb_runtime_idle(struct device *dev) |
1840 | * as we'll display regular disconnect messages just a bit later. | 1750 | { |
1751 | /* An idle USB device can be suspended if it passes the various | ||
1752 | * autosuspend checks. An idle interface can be suspended at | ||
1753 | * any time. | ||
1841 | */ | 1754 | */ |
1842 | if (status == -ENODEV) | 1755 | if (is_usb_device(dev)) { |
1843 | return 0; | 1756 | struct usb_device *udev = to_usb_device(dev); |
1844 | return status; | 1757 | |
1758 | if (autosuspend_check(udev) != 0) | ||
1759 | return 0; | ||
1760 | } | ||
1761 | |||
1762 | pm_runtime_suspend(dev); | ||
1763 | return 0; | ||
1845 | } | 1764 | } |
1846 | 1765 | ||
1847 | #endif /* CONFIG_PM */ | 1766 | static struct dev_pm_ops usb_bus_pm_ops = { |
1767 | .runtime_suspend = usb_runtime_suspend, | ||
1768 | .runtime_resume = usb_runtime_resume, | ||
1769 | .runtime_idle = usb_runtime_idle, | ||
1770 | }; | ||
1771 | |||
1772 | #else | ||
1773 | |||
1774 | #define usb_bus_pm_ops (*(struct dev_pm_ops *) NULL) | ||
1775 | |||
1776 | #endif /* CONFIG_USB_SUSPEND */ | ||
1848 | 1777 | ||
1849 | struct bus_type usb_bus_type = { | 1778 | struct bus_type usb_bus_type = { |
1850 | .name = "usb", | 1779 | .name = "usb", |
1851 | .match = usb_device_match, | 1780 | .match = usb_device_match, |
1852 | .uevent = usb_uevent, | 1781 | .uevent = usb_uevent, |
1782 | .pm = &usb_bus_pm_ops, | ||
1853 | }; | 1783 | }; |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index bfc6c2eea647..c3536f151f02 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -34,7 +34,6 @@ static int usb_open(struct inode * inode, struct file * file) | |||
34 | int err = -ENODEV; | 34 | int err = -ENODEV; |
35 | const struct file_operations *old_fops, *new_fops = NULL; | 35 | const struct file_operations *old_fops, *new_fops = NULL; |
36 | 36 | ||
37 | lock_kernel(); | ||
38 | down_read(&minor_rwsem); | 37 | down_read(&minor_rwsem); |
39 | c = usb_minors[minor]; | 38 | c = usb_minors[minor]; |
40 | 39 | ||
@@ -53,7 +52,6 @@ static int usb_open(struct inode * inode, struct file * file) | |||
53 | fops_put(old_fops); | 52 | fops_put(old_fops); |
54 | done: | 53 | done: |
55 | up_read(&minor_rwsem); | 54 | up_read(&minor_rwsem); |
56 | unlock_kernel(); | ||
57 | return err; | 55 | return err; |
58 | } | 56 | } |
59 | 57 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 80995ef0868c..2f8cedda8007 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
41 | #include <linux/mutex.h> | 41 | #include <linux/mutex.h> |
42 | #include <linux/pm_runtime.h> | ||
42 | 43 | ||
43 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
44 | 45 | ||
@@ -141,7 +142,7 @@ static const u8 usb3_rh_dev_descriptor[18] = { | |||
141 | 0x09, /* __u8 bMaxPacketSize0; 2^9 = 512 Bytes */ | 142 | 0x09, /* __u8 bMaxPacketSize0; 2^9 = 512 Bytes */ |
142 | 143 | ||
143 | 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ | 144 | 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ |
144 | 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ | 145 | 0x03, 0x00, /* __le16 idProduct; device 0x0003 */ |
145 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ | 146 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ |
146 | 147 | ||
147 | 0x03, /* __u8 iManufacturer; */ | 148 | 0x03, /* __u8 iManufacturer; */ |
@@ -1670,11 +1671,16 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev, | |||
1670 | } | 1671 | } |
1671 | } | 1672 | } |
1672 | for (i = 0; i < num_intfs; ++i) { | 1673 | for (i = 0; i < num_intfs; ++i) { |
1674 | struct usb_host_interface *first_alt; | ||
1675 | int iface_num; | ||
1676 | |||
1677 | first_alt = &new_config->intf_cache[i]->altsetting[0]; | ||
1678 | iface_num = first_alt->desc.bInterfaceNumber; | ||
1673 | /* Set up endpoints for alternate interface setting 0 */ | 1679 | /* Set up endpoints for alternate interface setting 0 */ |
1674 | alt = usb_find_alt_setting(new_config, i, 0); | 1680 | alt = usb_find_alt_setting(new_config, iface_num, 0); |
1675 | if (!alt) | 1681 | if (!alt) |
1676 | /* No alt setting 0? Pick the first setting. */ | 1682 | /* No alt setting 0? Pick the first setting. */ |
1677 | alt = &new_config->intf_cache[i]->altsetting[0]; | 1683 | alt = first_alt; |
1678 | 1684 | ||
1679 | for (j = 0; j < alt->desc.bNumEndpoints; j++) { | 1685 | for (j = 0; j < alt->desc.bNumEndpoints; j++) { |
1680 | ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]); | 1686 | ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]); |
@@ -1853,6 +1859,10 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) | |||
1853 | return status; | 1859 | return status; |
1854 | } | 1860 | } |
1855 | 1861 | ||
1862 | #endif /* CONFIG_PM */ | ||
1863 | |||
1864 | #ifdef CONFIG_USB_SUSPEND | ||
1865 | |||
1856 | /* Workqueue routine for root-hub remote wakeup */ | 1866 | /* Workqueue routine for root-hub remote wakeup */ |
1857 | static void hcd_resume_work(struct work_struct *work) | 1867 | static void hcd_resume_work(struct work_struct *work) |
1858 | { | 1868 | { |
@@ -1860,8 +1870,7 @@ static void hcd_resume_work(struct work_struct *work) | |||
1860 | struct usb_device *udev = hcd->self.root_hub; | 1870 | struct usb_device *udev = hcd->self.root_hub; |
1861 | 1871 | ||
1862 | usb_lock_device(udev); | 1872 | usb_lock_device(udev); |
1863 | usb_mark_last_busy(udev); | 1873 | usb_remote_wakeup(udev); |
1864 | usb_external_resume_device(udev, PMSG_REMOTE_RESUME); | ||
1865 | usb_unlock_device(udev); | 1874 | usb_unlock_device(udev); |
1866 | } | 1875 | } |
1867 | 1876 | ||
@@ -1880,12 +1889,12 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd) | |||
1880 | 1889 | ||
1881 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 1890 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
1882 | if (hcd->rh_registered) | 1891 | if (hcd->rh_registered) |
1883 | queue_work(ksuspend_usb_wq, &hcd->wakeup_work); | 1892 | queue_work(pm_wq, &hcd->wakeup_work); |
1884 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); | 1893 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); |
1885 | } | 1894 | } |
1886 | EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); | 1895 | EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); |
1887 | 1896 | ||
1888 | #endif | 1897 | #endif /* CONFIG_USB_SUSPEND */ |
1889 | 1898 | ||
1890 | /*-------------------------------------------------------------------------*/ | 1899 | /*-------------------------------------------------------------------------*/ |
1891 | 1900 | ||
@@ -2030,7 +2039,7 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, | |||
2030 | init_timer(&hcd->rh_timer); | 2039 | init_timer(&hcd->rh_timer); |
2031 | hcd->rh_timer.function = rh_timer_func; | 2040 | hcd->rh_timer.function = rh_timer_func; |
2032 | hcd->rh_timer.data = (unsigned long) hcd; | 2041 | hcd->rh_timer.data = (unsigned long) hcd; |
2033 | #ifdef CONFIG_PM | 2042 | #ifdef CONFIG_USB_SUSPEND |
2034 | INIT_WORK(&hcd->wakeup_work, hcd_resume_work); | 2043 | INIT_WORK(&hcd->wakeup_work, hcd_resume_work); |
2035 | #endif | 2044 | #endif |
2036 | mutex_init(&hcd->bandwidth_mutex); | 2045 | mutex_init(&hcd->bandwidth_mutex); |
@@ -2230,7 +2239,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
2230 | hcd->rh_registered = 0; | 2239 | hcd->rh_registered = 0; |
2231 | spin_unlock_irq (&hcd_root_hub_lock); | 2240 | spin_unlock_irq (&hcd_root_hub_lock); |
2232 | 2241 | ||
2233 | #ifdef CONFIG_PM | 2242 | #ifdef CONFIG_USB_SUSPEND |
2234 | cancel_work_sync(&hcd->wakeup_work); | 2243 | cancel_work_sync(&hcd->wakeup_work); |
2235 | #endif | 2244 | #endif |
2236 | 2245 | ||
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index bbe2b924aae8..a3cdb09734ab 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -80,7 +80,7 @@ struct usb_hcd { | |||
80 | 80 | ||
81 | struct timer_list rh_timer; /* drives root-hub polling */ | 81 | struct timer_list rh_timer; /* drives root-hub polling */ |
82 | struct urb *status_urb; /* the current status urb */ | 82 | struct urb *status_urb; /* the current status urb */ |
83 | #ifdef CONFIG_PM | 83 | #ifdef CONFIG_USB_SUSPEND |
84 | struct work_struct wakeup_work; /* for remote wakeup */ | 84 | struct work_struct wakeup_work; /* for remote wakeup */ |
85 | #endif | 85 | #endif |
86 | 86 | ||
@@ -248,7 +248,7 @@ struct hc_driver { | |||
248 | /* xHCI specific functions */ | 248 | /* xHCI specific functions */ |
249 | /* Called by usb_alloc_dev to alloc HC device structures */ | 249 | /* Called by usb_alloc_dev to alloc HC device structures */ |
250 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); | 250 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); |
251 | /* Called by usb_release_dev to free HC device structures */ | 251 | /* Called by usb_disconnect to free HC device structures */ |
252 | void (*free_dev)(struct usb_hcd *, struct usb_device *); | 252 | void (*free_dev)(struct usb_hcd *, struct usb_device *); |
253 | 253 | ||
254 | /* Bandwidth computation functions */ | 254 | /* Bandwidth computation functions */ |
@@ -286,6 +286,7 @@ struct hc_driver { | |||
286 | */ | 286 | */ |
287 | int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev, | 287 | int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev, |
288 | struct usb_tt *tt, gfp_t mem_flags); | 288 | struct usb_tt *tt, gfp_t mem_flags); |
289 | int (*reset_device)(struct usb_hcd *, struct usb_device *); | ||
289 | }; | 290 | }; |
290 | 291 | ||
291 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | 292 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
@@ -463,16 +464,20 @@ extern int usb_find_interface_driver(struct usb_device *dev, | |||
463 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) | 464 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) |
464 | 465 | ||
465 | #ifdef CONFIG_PM | 466 | #ifdef CONFIG_PM |
466 | extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd); | ||
467 | extern void usb_root_hub_lost_power(struct usb_device *rhdev); | 467 | extern void usb_root_hub_lost_power(struct usb_device *rhdev); |
468 | extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg); | 468 | extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg); |
469 | extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg); | 469 | extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg); |
470 | #endif /* CONFIG_PM */ | ||
471 | |||
472 | #ifdef CONFIG_USB_SUSPEND | ||
473 | extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd); | ||
470 | #else | 474 | #else |
471 | static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) | 475 | static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) |
472 | { | 476 | { |
473 | return; | 477 | return; |
474 | } | 478 | } |
475 | #endif /* CONFIG_PM */ | 479 | #endif /* CONFIG_USB_SUSPEND */ |
480 | |||
476 | 481 | ||
477 | /* | 482 | /* |
478 | * USB device fs stuff | 483 | * USB device fs stuff |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 20ecb4cec8de..0940ccd6f4f4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kthread.h> | 22 | #include <linux/kthread.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/freezer.h> | 24 | #include <linux/freezer.h> |
25 | #include <linux/pm_runtime.h> | ||
25 | 26 | ||
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
27 | #include <asm/byteorder.h> | 28 | #include <asm/byteorder.h> |
@@ -71,7 +72,6 @@ struct usb_hub { | |||
71 | 72 | ||
72 | unsigned mA_per_port; /* current for each child */ | 73 | unsigned mA_per_port; /* current for each child */ |
73 | 74 | ||
74 | unsigned init_done:1; | ||
75 | unsigned limited_power:1; | 75 | unsigned limited_power:1; |
76 | unsigned quiescing:1; | 76 | unsigned quiescing:1; |
77 | unsigned disconnected:1; | 77 | unsigned disconnected:1; |
@@ -820,7 +820,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
820 | } | 820 | } |
821 | init3: | 821 | init3: |
822 | hub->quiescing = 0; | 822 | hub->quiescing = 0; |
823 | hub->init_done = 1; | ||
824 | 823 | ||
825 | status = usb_submit_urb(hub->urb, GFP_NOIO); | 824 | status = usb_submit_urb(hub->urb, GFP_NOIO); |
826 | if (status < 0) | 825 | if (status < 0) |
@@ -861,11 +860,6 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
861 | int i; | 860 | int i; |
862 | 861 | ||
863 | cancel_delayed_work_sync(&hub->init_work); | 862 | cancel_delayed_work_sync(&hub->init_work); |
864 | if (!hub->init_done) { | ||
865 | hub->init_done = 1; | ||
866 | usb_autopm_put_interface_no_suspend( | ||
867 | to_usb_interface(hub->intfdev)); | ||
868 | } | ||
869 | 863 | ||
870 | /* khubd and related activity won't re-trigger */ | 864 | /* khubd and related activity won't re-trigger */ |
871 | hub->quiescing = 1; | 865 | hub->quiescing = 1; |
@@ -1224,6 +1218,9 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1224 | desc = intf->cur_altsetting; | 1218 | desc = intf->cur_altsetting; |
1225 | hdev = interface_to_usbdev(intf); | 1219 | hdev = interface_to_usbdev(intf); |
1226 | 1220 | ||
1221 | /* Hubs have proper suspend/resume support */ | ||
1222 | usb_enable_autosuspend(hdev); | ||
1223 | |||
1227 | if (hdev->level == MAX_TOPO_LEVEL) { | 1224 | if (hdev->level == MAX_TOPO_LEVEL) { |
1228 | dev_err(&intf->dev, | 1225 | dev_err(&intf->dev, |
1229 | "Unsupported bus topology: hub nested too deep\n"); | 1226 | "Unsupported bus topology: hub nested too deep\n"); |
@@ -1402,10 +1399,8 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev) | |||
1402 | if (udev->children[i]) | 1399 | if (udev->children[i]) |
1403 | recursively_mark_NOTATTACHED(udev->children[i]); | 1400 | recursively_mark_NOTATTACHED(udev->children[i]); |
1404 | } | 1401 | } |
1405 | if (udev->state == USB_STATE_SUSPENDED) { | 1402 | if (udev->state == USB_STATE_SUSPENDED) |
1406 | udev->discon_suspended = 1; | ||
1407 | udev->active_duration -= jiffies; | 1403 | udev->active_duration -= jiffies; |
1408 | } | ||
1409 | udev->state = USB_STATE_NOTATTACHED; | 1404 | udev->state = USB_STATE_NOTATTACHED; |
1410 | } | 1405 | } |
1411 | 1406 | ||
@@ -1448,11 +1443,11 @@ void usb_set_device_state(struct usb_device *udev, | |||
1448 | || new_state == USB_STATE_SUSPENDED) | 1443 | || new_state == USB_STATE_SUSPENDED) |
1449 | ; /* No change to wakeup settings */ | 1444 | ; /* No change to wakeup settings */ |
1450 | else if (new_state == USB_STATE_CONFIGURED) | 1445 | else if (new_state == USB_STATE_CONFIGURED) |
1451 | device_init_wakeup(&udev->dev, | 1446 | device_set_wakeup_capable(&udev->dev, |
1452 | (udev->actconfig->desc.bmAttributes | 1447 | (udev->actconfig->desc.bmAttributes |
1453 | & USB_CONFIG_ATT_WAKEUP)); | 1448 | & USB_CONFIG_ATT_WAKEUP)); |
1454 | else | 1449 | else |
1455 | device_init_wakeup(&udev->dev, 0); | 1450 | device_set_wakeup_capable(&udev->dev, 0); |
1456 | } | 1451 | } |
1457 | if (udev->state == USB_STATE_SUSPENDED && | 1452 | if (udev->state == USB_STATE_SUSPENDED && |
1458 | new_state != USB_STATE_SUSPENDED) | 1453 | new_state != USB_STATE_SUSPENDED) |
@@ -1529,31 +1524,15 @@ static void update_address(struct usb_device *udev, int devnum) | |||
1529 | udev->devnum = devnum; | 1524 | udev->devnum = devnum; |
1530 | } | 1525 | } |
1531 | 1526 | ||
1532 | #ifdef CONFIG_USB_SUSPEND | 1527 | static void hub_free_dev(struct usb_device *udev) |
1533 | |||
1534 | static void usb_stop_pm(struct usb_device *udev) | ||
1535 | { | 1528 | { |
1536 | /* Synchronize with the ksuspend thread to prevent any more | 1529 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); |
1537 | * autosuspend requests from being submitted, and decrement | ||
1538 | * the parent's count of unsuspended children. | ||
1539 | */ | ||
1540 | usb_pm_lock(udev); | ||
1541 | if (udev->parent && !udev->discon_suspended) | ||
1542 | usb_autosuspend_device(udev->parent); | ||
1543 | usb_pm_unlock(udev); | ||
1544 | 1530 | ||
1545 | /* Stop any autosuspend or autoresume requests already submitted */ | 1531 | /* Root hubs aren't real devices, so don't free HCD resources */ |
1546 | cancel_delayed_work_sync(&udev->autosuspend); | 1532 | if (hcd->driver->free_dev && udev->parent) |
1547 | cancel_work_sync(&udev->autoresume); | 1533 | hcd->driver->free_dev(hcd, udev); |
1548 | } | 1534 | } |
1549 | 1535 | ||
1550 | #else | ||
1551 | |||
1552 | static inline void usb_stop_pm(struct usb_device *udev) | ||
1553 | { } | ||
1554 | |||
1555 | #endif | ||
1556 | |||
1557 | /** | 1536 | /** |
1558 | * usb_disconnect - disconnect a device (usbcore-internal) | 1537 | * usb_disconnect - disconnect a device (usbcore-internal) |
1559 | * @pdev: pointer to device being disconnected | 1538 | * @pdev: pointer to device being disconnected |
@@ -1622,7 +1601,7 @@ void usb_disconnect(struct usb_device **pdev) | |||
1622 | *pdev = NULL; | 1601 | *pdev = NULL; |
1623 | spin_unlock_irq(&device_state_lock); | 1602 | spin_unlock_irq(&device_state_lock); |
1624 | 1603 | ||
1625 | usb_stop_pm(udev); | 1604 | hub_free_dev(udev); |
1626 | 1605 | ||
1627 | put_device(&udev->dev); | 1606 | put_device(&udev->dev); |
1628 | } | 1607 | } |
@@ -1799,9 +1778,18 @@ int usb_new_device(struct usb_device *udev) | |||
1799 | { | 1778 | { |
1800 | int err; | 1779 | int err; |
1801 | 1780 | ||
1802 | /* Increment the parent's count of unsuspended children */ | 1781 | if (udev->parent) { |
1803 | if (udev->parent) | 1782 | /* Initialize non-root-hub device wakeup to disabled; |
1804 | usb_autoresume_device(udev->parent); | 1783 | * device (un)configuration controls wakeup capable |
1784 | * sysfs power/wakeup controls wakeup enabled/disabled | ||
1785 | */ | ||
1786 | device_init_wakeup(&udev->dev, 0); | ||
1787 | device_set_wakeup_enable(&udev->dev, 1); | ||
1788 | } | ||
1789 | |||
1790 | /* Tell the runtime-PM framework the device is active */ | ||
1791 | pm_runtime_set_active(&udev->dev); | ||
1792 | pm_runtime_enable(&udev->dev); | ||
1805 | 1793 | ||
1806 | usb_detect_quirks(udev); | 1794 | usb_detect_quirks(udev); |
1807 | err = usb_enumerate_device(udev); /* Read descriptors */ | 1795 | err = usb_enumerate_device(udev); /* Read descriptors */ |
@@ -1833,7 +1821,8 @@ int usb_new_device(struct usb_device *udev) | |||
1833 | 1821 | ||
1834 | fail: | 1822 | fail: |
1835 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1823 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
1836 | usb_stop_pm(udev); | 1824 | pm_runtime_disable(&udev->dev); |
1825 | pm_runtime_set_suspended(&udev->dev); | ||
1837 | return err; | 1826 | return err; |
1838 | } | 1827 | } |
1839 | 1828 | ||
@@ -1982,7 +1971,7 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, | |||
1982 | if (!(portstatus & USB_PORT_STAT_RESET) && | 1971 | if (!(portstatus & USB_PORT_STAT_RESET) && |
1983 | (portstatus & USB_PORT_STAT_ENABLE)) { | 1972 | (portstatus & USB_PORT_STAT_ENABLE)) { |
1984 | if (hub_is_wusb(hub)) | 1973 | if (hub_is_wusb(hub)) |
1985 | udev->speed = USB_SPEED_VARIABLE; | 1974 | udev->speed = USB_SPEED_WIRELESS; |
1986 | else if (portstatus & USB_PORT_STAT_HIGH_SPEED) | 1975 | else if (portstatus & USB_PORT_STAT_HIGH_SPEED) |
1987 | udev->speed = USB_SPEED_HIGH; | 1976 | udev->speed = USB_SPEED_HIGH; |
1988 | else if (portstatus & USB_PORT_STAT_LOW_SPEED) | 1977 | else if (portstatus & USB_PORT_STAT_LOW_SPEED) |
@@ -2008,7 +1997,9 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2008 | struct usb_device *udev, unsigned int delay) | 1997 | struct usb_device *udev, unsigned int delay) |
2009 | { | 1998 | { |
2010 | int i, status; | 1999 | int i, status; |
2000 | struct usb_hcd *hcd; | ||
2011 | 2001 | ||
2002 | hcd = bus_to_hcd(udev->bus); | ||
2012 | /* Block EHCI CF initialization during the port reset. | 2003 | /* Block EHCI CF initialization during the port reset. |
2013 | * Some companion controllers don't like it when they mix. | 2004 | * Some companion controllers don't like it when they mix. |
2014 | */ | 2005 | */ |
@@ -2036,6 +2027,14 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2036 | /* TRSTRCY = 10 ms; plus some extra */ | 2027 | /* TRSTRCY = 10 ms; plus some extra */ |
2037 | msleep(10 + 40); | 2028 | msleep(10 + 40); |
2038 | update_address(udev, 0); | 2029 | update_address(udev, 0); |
2030 | if (hcd->driver->reset_device) { | ||
2031 | status = hcd->driver->reset_device(hcd, udev); | ||
2032 | if (status < 0) { | ||
2033 | dev_err(&udev->dev, "Cannot reset " | ||
2034 | "HCD device state\n"); | ||
2035 | break; | ||
2036 | } | ||
2037 | } | ||
2039 | /* FALL THROUGH */ | 2038 | /* FALL THROUGH */ |
2040 | case -ENOTCONN: | 2039 | case -ENOTCONN: |
2041 | case -ENODEV: | 2040 | case -ENODEV: |
@@ -2381,14 +2380,17 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
2381 | } | 2380 | } |
2382 | 2381 | ||
2383 | /* caller has locked udev */ | 2382 | /* caller has locked udev */ |
2384 | static int remote_wakeup(struct usb_device *udev) | 2383 | int usb_remote_wakeup(struct usb_device *udev) |
2385 | { | 2384 | { |
2386 | int status = 0; | 2385 | int status = 0; |
2387 | 2386 | ||
2388 | if (udev->state == USB_STATE_SUSPENDED) { | 2387 | if (udev->state == USB_STATE_SUSPENDED) { |
2389 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); | 2388 | dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); |
2390 | usb_mark_last_busy(udev); | 2389 | status = usb_autoresume_device(udev); |
2391 | status = usb_external_resume_device(udev, PMSG_REMOTE_RESUME); | 2390 | if (status == 0) { |
2391 | /* Let the drivers do their thing, then... */ | ||
2392 | usb_autosuspend_device(udev); | ||
2393 | } | ||
2392 | } | 2394 | } |
2393 | return status; | 2395 | return status; |
2394 | } | 2396 | } |
@@ -2425,11 +2427,6 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
2425 | return status; | 2427 | return status; |
2426 | } | 2428 | } |
2427 | 2429 | ||
2428 | static inline int remote_wakeup(struct usb_device *udev) | ||
2429 | { | ||
2430 | return 0; | ||
2431 | } | ||
2432 | |||
2433 | #endif | 2430 | #endif |
2434 | 2431 | ||
2435 | static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | 2432 | static int hub_suspend(struct usb_interface *intf, pm_message_t msg) |
@@ -2496,11 +2493,6 @@ EXPORT_SYMBOL_GPL(usb_root_hub_lost_power); | |||
2496 | 2493 | ||
2497 | #else /* CONFIG_PM */ | 2494 | #else /* CONFIG_PM */ |
2498 | 2495 | ||
2499 | static inline int remote_wakeup(struct usb_device *udev) | ||
2500 | { | ||
2501 | return 0; | ||
2502 | } | ||
2503 | |||
2504 | #define hub_suspend NULL | 2496 | #define hub_suspend NULL |
2505 | #define hub_resume NULL | 2497 | #define hub_resume NULL |
2506 | #define hub_reset_resume NULL | 2498 | #define hub_reset_resume NULL |
@@ -2645,14 +2637,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2645 | 2637 | ||
2646 | mutex_lock(&usb_address0_mutex); | 2638 | mutex_lock(&usb_address0_mutex); |
2647 | 2639 | ||
2648 | if ((hcd->driver->flags & HCD_USB3) && udev->config) { | 2640 | if (!udev->config && oldspeed == USB_SPEED_SUPER) { |
2649 | /* FIXME this will need special handling by the xHCI driver. */ | ||
2650 | dev_dbg(&udev->dev, | ||
2651 | "xHCI reset of configured device " | ||
2652 | "not supported yet.\n"); | ||
2653 | retval = -EINVAL; | ||
2654 | goto fail; | ||
2655 | } else if (!udev->config && oldspeed == USB_SPEED_SUPER) { | ||
2656 | /* Don't reset USB 3.0 devices during an initial setup */ | 2641 | /* Don't reset USB 3.0 devices during an initial setup */ |
2657 | usb_set_device_state(udev, USB_STATE_DEFAULT); | 2642 | usb_set_device_state(udev, USB_STATE_DEFAULT); |
2658 | } else { | 2643 | } else { |
@@ -2678,7 +2663,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2678 | */ | 2663 | */ |
2679 | switch (udev->speed) { | 2664 | switch (udev->speed) { |
2680 | case USB_SPEED_SUPER: | 2665 | case USB_SPEED_SUPER: |
2681 | case USB_SPEED_VARIABLE: /* fixed at 512 */ | 2666 | case USB_SPEED_WIRELESS: /* fixed at 512 */ |
2682 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); | 2667 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); |
2683 | break; | 2668 | break; |
2684 | case USB_SPEED_HIGH: /* fixed at 64 */ | 2669 | case USB_SPEED_HIGH: /* fixed at 64 */ |
@@ -2706,7 +2691,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2706 | case USB_SPEED_SUPER: | 2691 | case USB_SPEED_SUPER: |
2707 | speed = "super"; | 2692 | speed = "super"; |
2708 | break; | 2693 | break; |
2709 | case USB_SPEED_VARIABLE: | 2694 | case USB_SPEED_WIRELESS: |
2710 | speed = "variable"; | 2695 | speed = "variable"; |
2711 | type = "Wireless "; | 2696 | type = "Wireless "; |
2712 | break; | 2697 | break; |
@@ -3006,7 +2991,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
3006 | /* For a suspended device, treat this as a | 2991 | /* For a suspended device, treat this as a |
3007 | * remote wakeup event. | 2992 | * remote wakeup event. |
3008 | */ | 2993 | */ |
3009 | status = remote_wakeup(udev); | 2994 | status = usb_remote_wakeup(udev); |
3010 | #endif | 2995 | #endif |
3011 | 2996 | ||
3012 | } else { | 2997 | } else { |
@@ -3192,6 +3177,7 @@ loop_disable: | |||
3192 | loop: | 3177 | loop: |
3193 | usb_ep0_reinit(udev); | 3178 | usb_ep0_reinit(udev); |
3194 | release_address(udev); | 3179 | release_address(udev); |
3180 | hub_free_dev(udev); | ||
3195 | usb_put_dev(udev); | 3181 | usb_put_dev(udev); |
3196 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) | 3182 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) |
3197 | break; | 3183 | break; |
@@ -3259,7 +3245,7 @@ static void hub_events(void) | |||
3259 | * disconnected while waiting for the lock to succeed. */ | 3245 | * disconnected while waiting for the lock to succeed. */ |
3260 | usb_lock_device(hdev); | 3246 | usb_lock_device(hdev); |
3261 | if (unlikely(hub->disconnected)) | 3247 | if (unlikely(hub->disconnected)) |
3262 | goto loop2; | 3248 | goto loop_disconnected; |
3263 | 3249 | ||
3264 | /* If the hub has died, clean up after it */ | 3250 | /* If the hub has died, clean up after it */ |
3265 | if (hdev->state == USB_STATE_NOTATTACHED) { | 3251 | if (hdev->state == USB_STATE_NOTATTACHED) { |
@@ -3352,7 +3338,7 @@ static void hub_events(void) | |||
3352 | msleep(10); | 3338 | msleep(10); |
3353 | 3339 | ||
3354 | usb_lock_device(udev); | 3340 | usb_lock_device(udev); |
3355 | ret = remote_wakeup(hdev-> | 3341 | ret = usb_remote_wakeup(hdev-> |
3356 | children[i-1]); | 3342 | children[i-1]); |
3357 | usb_unlock_device(udev); | 3343 | usb_unlock_device(udev); |
3358 | if (ret < 0) | 3344 | if (ret < 0) |
@@ -3419,7 +3405,7 @@ static void hub_events(void) | |||
3419 | * kick_khubd() and allow autosuspend. | 3405 | * kick_khubd() and allow autosuspend. |
3420 | */ | 3406 | */ |
3421 | usb_autopm_put_interface(intf); | 3407 | usb_autopm_put_interface(intf); |
3422 | loop2: | 3408 | loop_disconnected: |
3423 | usb_unlock_device(hdev); | 3409 | usb_unlock_device(hdev); |
3424 | kref_put(&hub->kref, hub_release); | 3410 | kref_put(&hub->kref, hub_release); |
3425 | 3411 | ||
@@ -3446,7 +3432,7 @@ static int hub_thread(void *__unused) | |||
3446 | return 0; | 3432 | return 0; |
3447 | } | 3433 | } |
3448 | 3434 | ||
3449 | static struct usb_device_id hub_id_table [] = { | 3435 | static const struct usb_device_id hub_id_table[] = { |
3450 | { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, | 3436 | { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, |
3451 | .bDeviceClass = USB_CLASS_HUB}, | 3437 | .bDeviceClass = USB_CLASS_HUB}, |
3452 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, | 3438 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index df73574a9cc9..cd220277c6c3 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1316,7 +1316,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1316 | 1316 | ||
1317 | alt = usb_altnum_to_altsetting(iface, alternate); | 1317 | alt = usb_altnum_to_altsetting(iface, alternate); |
1318 | if (!alt) { | 1318 | if (!alt) { |
1319 | dev_warn(&dev->dev, "selecting invalid altsetting %d", | 1319 | dev_warn(&dev->dev, "selecting invalid altsetting %d\n", |
1320 | alternate); | 1320 | alternate); |
1321 | return -EINVAL; | 1321 | return -EINVAL; |
1322 | } | 1322 | } |
@@ -1471,7 +1471,7 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1471 | /* If not, reinstate the old alternate settings */ | 1471 | /* If not, reinstate the old alternate settings */ |
1472 | if (retval < 0) { | 1472 | if (retval < 0) { |
1473 | reset_old_alts: | 1473 | reset_old_alts: |
1474 | for (; i >= 0; i--) { | 1474 | for (i--; i >= 0; i--) { |
1475 | struct usb_interface *intf = config->interface[i]; | 1475 | struct usb_interface *intf = config->interface[i]; |
1476 | struct usb_host_interface *alt; | 1476 | struct usb_host_interface *alt; |
1477 | 1477 | ||
@@ -1843,7 +1843,6 @@ free_interfaces: | |||
1843 | intf->dev.dma_mask = dev->dev.dma_mask; | 1843 | intf->dev.dma_mask = dev->dev.dma_mask; |
1844 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); | 1844 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); |
1845 | device_initialize(&intf->dev); | 1845 | device_initialize(&intf->dev); |
1846 | mark_quiesced(intf); | ||
1847 | dev_set_name(&intf->dev, "%d-%s:%d.%d", | 1846 | dev_set_name(&intf->dev, "%d-%s:%d.%d", |
1848 | dev->bus->busnum, dev->devpath, | 1847 | dev->bus->busnum, dev->devpath, |
1849 | configuration, alt->desc.bInterfaceNumber); | 1848 | configuration, alt->desc.bInterfaceNumber); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index ab93918d9207..f073c5cb4e7b 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -103,10 +103,19 @@ void usb_detect_quirks(struct usb_device *udev) | |||
103 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", | 103 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", |
104 | udev->quirks); | 104 | udev->quirks); |
105 | 105 | ||
106 | /* By default, disable autosuspend for all non-hubs */ | ||
107 | #ifdef CONFIG_USB_SUSPEND | 106 | #ifdef CONFIG_USB_SUSPEND |
108 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) | 107 | |
109 | udev->autosuspend_disabled = 1; | 108 | /* By default, disable autosuspend for all devices. The hub driver |
109 | * will enable it for hubs. | ||
110 | */ | ||
111 | usb_disable_autosuspend(udev); | ||
112 | |||
113 | /* Autosuspend can also be disabled if the initial autosuspend_delay | ||
114 | * is negative. | ||
115 | */ | ||
116 | if (udev->autosuspend_delay < 0) | ||
117 | usb_autoresume_device(udev); | ||
118 | |||
110 | #endif | 119 | #endif |
111 | 120 | ||
112 | /* For the present, all devices default to USB-PERSIST enabled */ | 121 | /* For the present, all devices default to USB-PERSIST enabled */ |
@@ -120,6 +129,7 @@ void usb_detect_quirks(struct usb_device *udev) | |||
120 | * for all devices. It will affect things like hub resets | 129 | * for all devices. It will affect things like hub resets |
121 | * and EMF-related port disables. | 130 | * and EMF-related port disables. |
122 | */ | 131 | */ |
123 | udev->persist_enabled = 1; | 132 | if (!(udev->quirks & USB_QUIRK_RESET_MORPHS)) |
133 | udev->persist_enabled = 1; | ||
124 | #endif /* CONFIG_PM */ | 134 | #endif /* CONFIG_PM */ |
125 | } | 135 | } |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 5f3908f6e2dc..43c002e3a9aa 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -115,7 +115,7 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf) | |||
115 | case USB_SPEED_HIGH: | 115 | case USB_SPEED_HIGH: |
116 | speed = "480"; | 116 | speed = "480"; |
117 | break; | 117 | break; |
118 | case USB_SPEED_VARIABLE: | 118 | case USB_SPEED_WIRELESS: |
119 | speed = "480"; | 119 | speed = "480"; |
120 | break; | 120 | break; |
121 | case USB_SPEED_SUPER: | 121 | case USB_SPEED_SUPER: |
@@ -191,6 +191,36 @@ show_quirks(struct device *dev, struct device_attribute *attr, char *buf) | |||
191 | static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); | 191 | static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); |
192 | 192 | ||
193 | static ssize_t | 193 | static ssize_t |
194 | show_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, char *buf) | ||
195 | { | ||
196 | struct usb_device *udev; | ||
197 | |||
198 | udev = to_usb_device(dev); | ||
199 | return sprintf(buf, "%d\n", !!(udev->quirks & USB_QUIRK_RESET_MORPHS)); | ||
200 | } | ||
201 | |||
202 | static ssize_t | ||
203 | set_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, | ||
204 | const char *buf, size_t count) | ||
205 | { | ||
206 | struct usb_device *udev = to_usb_device(dev); | ||
207 | int config; | ||
208 | |||
209 | if (sscanf(buf, "%d", &config) != 1 || config < 0 || config > 1) | ||
210 | return -EINVAL; | ||
211 | usb_lock_device(udev); | ||
212 | if (config) | ||
213 | udev->quirks |= USB_QUIRK_RESET_MORPHS; | ||
214 | else | ||
215 | udev->quirks &= ~USB_QUIRK_RESET_MORPHS; | ||
216 | usb_unlock_device(udev); | ||
217 | return count; | ||
218 | } | ||
219 | |||
220 | static DEVICE_ATTR(avoid_reset_quirk, S_IRUGO | S_IWUSR, | ||
221 | show_avoid_reset_quirk, set_avoid_reset_quirk); | ||
222 | |||
223 | static ssize_t | ||
194 | show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) | 224 | show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) |
195 | { | 225 | { |
196 | struct usb_device *udev; | 226 | struct usb_device *udev; |
@@ -226,9 +256,10 @@ set_persist(struct device *dev, struct device_attribute *attr, | |||
226 | 256 | ||
227 | if (sscanf(buf, "%d", &value) != 1) | 257 | if (sscanf(buf, "%d", &value) != 1) |
228 | return -EINVAL; | 258 | return -EINVAL; |
229 | usb_pm_lock(udev); | 259 | |
260 | usb_lock_device(udev); | ||
230 | udev->persist_enabled = !!value; | 261 | udev->persist_enabled = !!value; |
231 | usb_pm_unlock(udev); | 262 | usb_unlock_device(udev); |
232 | return count; | 263 | return count; |
233 | } | 264 | } |
234 | 265 | ||
@@ -315,20 +346,34 @@ set_autosuspend(struct device *dev, struct device_attribute *attr, | |||
315 | const char *buf, size_t count) | 346 | const char *buf, size_t count) |
316 | { | 347 | { |
317 | struct usb_device *udev = to_usb_device(dev); | 348 | struct usb_device *udev = to_usb_device(dev); |
318 | int value; | 349 | int value, old_delay; |
350 | int rc; | ||
319 | 351 | ||
320 | if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || | 352 | if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || |
321 | value <= - INT_MAX/HZ) | 353 | value <= - INT_MAX/HZ) |
322 | return -EINVAL; | 354 | return -EINVAL; |
323 | value *= HZ; | 355 | value *= HZ; |
324 | 356 | ||
357 | usb_lock_device(udev); | ||
358 | old_delay = udev->autosuspend_delay; | ||
325 | udev->autosuspend_delay = value; | 359 | udev->autosuspend_delay = value; |
326 | if (value >= 0) | 360 | |
327 | usb_try_autosuspend_device(udev); | 361 | if (old_delay < 0) { /* Autosuspend wasn't allowed */ |
328 | else { | 362 | if (value >= 0) |
329 | if (usb_autoresume_device(udev) == 0) | ||
330 | usb_autosuspend_device(udev); | 363 | usb_autosuspend_device(udev); |
364 | } else { /* Autosuspend was allowed */ | ||
365 | if (value < 0) { | ||
366 | rc = usb_autoresume_device(udev); | ||
367 | if (rc < 0) { | ||
368 | count = rc; | ||
369 | udev->autosuspend_delay = old_delay; | ||
370 | } | ||
371 | } else { | ||
372 | usb_try_autosuspend_device(udev); | ||
373 | } | ||
331 | } | 374 | } |
375 | |||
376 | usb_unlock_device(udev); | ||
332 | return count; | 377 | return count; |
333 | } | 378 | } |
334 | 379 | ||
@@ -356,34 +401,25 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
356 | struct usb_device *udev = to_usb_device(dev); | 401 | struct usb_device *udev = to_usb_device(dev); |
357 | int len = count; | 402 | int len = count; |
358 | char *cp; | 403 | char *cp; |
359 | int rc = 0; | 404 | int rc; |
360 | int old_autosuspend_disabled; | ||
361 | 405 | ||
362 | cp = memchr(buf, '\n', count); | 406 | cp = memchr(buf, '\n', count); |
363 | if (cp) | 407 | if (cp) |
364 | len = cp - buf; | 408 | len = cp - buf; |
365 | 409 | ||
366 | usb_lock_device(udev); | 410 | usb_lock_device(udev); |
367 | old_autosuspend_disabled = udev->autosuspend_disabled; | ||
368 | 411 | ||
369 | /* Setting the flags without calling usb_pm_lock is a subject to | ||
370 | * races, but who cares... | ||
371 | */ | ||
372 | if (len == sizeof on_string - 1 && | 412 | if (len == sizeof on_string - 1 && |
373 | strncmp(buf, on_string, len) == 0) { | 413 | strncmp(buf, on_string, len) == 0) |
374 | udev->autosuspend_disabled = 1; | 414 | rc = usb_disable_autosuspend(udev); |
375 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); | ||
376 | 415 | ||
377 | } else if (len == sizeof auto_string - 1 && | 416 | else if (len == sizeof auto_string - 1 && |
378 | strncmp(buf, auto_string, len) == 0) { | 417 | strncmp(buf, auto_string, len) == 0) |
379 | udev->autosuspend_disabled = 0; | 418 | rc = usb_enable_autosuspend(udev); |
380 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); | ||
381 | 419 | ||
382 | } else | 420 | else |
383 | rc = -EINVAL; | 421 | rc = -EINVAL; |
384 | 422 | ||
385 | if (rc) | ||
386 | udev->autosuspend_disabled = old_autosuspend_disabled; | ||
387 | usb_unlock_device(udev); | 423 | usb_unlock_device(udev); |
388 | return (rc < 0 ? rc : count); | 424 | return (rc < 0 ? rc : count); |
389 | } | 425 | } |
@@ -558,6 +594,7 @@ static struct attribute *dev_attrs[] = { | |||
558 | &dev_attr_version.attr, | 594 | &dev_attr_version.attr, |
559 | &dev_attr_maxchild.attr, | 595 | &dev_attr_maxchild.attr, |
560 | &dev_attr_quirks.attr, | 596 | &dev_attr_quirks.attr, |
597 | &dev_attr_avoid_reset_quirk.attr, | ||
561 | &dev_attr_authorized.attr, | 598 | &dev_attr_authorized.attr, |
562 | &dev_attr_remove.attr, | 599 | &dev_attr_remove.attr, |
563 | NULL, | 600 | NULL, |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index e7cae1334693..27080561a1c2 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -387,6 +387,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
387 | { | 387 | { |
388 | unsigned int orig_flags = urb->transfer_flags; | 388 | unsigned int orig_flags = urb->transfer_flags; |
389 | unsigned int allowed; | 389 | unsigned int allowed; |
390 | static int pipetypes[4] = { | ||
391 | PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT | ||
392 | }; | ||
393 | |||
394 | /* Check that the pipe's type matches the endpoint's type */ | ||
395 | if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) | ||
396 | return -EPIPE; /* The most suitable error code :-) */ | ||
390 | 397 | ||
391 | /* enforce simple/standard policy */ | 398 | /* enforce simple/standard policy */ |
392 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | | 399 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | |
@@ -430,7 +437,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
430 | case USB_ENDPOINT_XFER_INT: | 437 | case USB_ENDPOINT_XFER_INT: |
431 | /* too small? */ | 438 | /* too small? */ |
432 | switch (dev->speed) { | 439 | switch (dev->speed) { |
433 | case USB_SPEED_VARIABLE: | 440 | case USB_SPEED_WIRELESS: |
434 | if (urb->interval < 6) | 441 | if (urb->interval < 6) |
435 | return -EINVAL; | 442 | return -EINVAL; |
436 | break; | 443 | break; |
@@ -446,7 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
446 | if (urb->interval > (1 << 15)) | 453 | if (urb->interval > (1 << 15)) |
447 | return -EINVAL; | 454 | return -EINVAL; |
448 | max = 1 << 15; | 455 | max = 1 << 15; |
449 | case USB_SPEED_VARIABLE: | 456 | case USB_SPEED_WIRELESS: |
450 | if (urb->interval > 16) | 457 | if (urb->interval > 16) |
451 | return -EINVAL; | 458 | return -EINVAL; |
452 | break; | 459 | break; |
@@ -473,7 +480,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
473 | default: | 480 | default: |
474 | return -EINVAL; | 481 | return -EINVAL; |
475 | } | 482 | } |
476 | if (dev->speed != USB_SPEED_VARIABLE) { | 483 | if (dev->speed != USB_SPEED_WIRELESS) { |
477 | /* Round down to a power of 2, no more than max */ | 484 | /* Round down to a power of 2, no more than max */ |
478 | urb->interval = min(max, 1 << ilog2(urb->interval)); | 485 | urb->interval = min(max, 1 << ilog2(urb->interval)); |
479 | } | 486 | } |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0daff0d968ba..1297e9b16a51 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -49,9 +49,6 @@ const char *usbcore_name = "usbcore"; | |||
49 | 49 | ||
50 | static int nousb; /* Disable USB when built into kernel image */ | 50 | static int nousb; /* Disable USB when built into kernel image */ |
51 | 51 | ||
52 | /* Workqueue for autosuspend and for remote wakeup of root hubs */ | ||
53 | struct workqueue_struct *ksuspend_usb_wq; | ||
54 | |||
55 | #ifdef CONFIG_USB_SUSPEND | 52 | #ifdef CONFIG_USB_SUSPEND |
56 | static int usb_autosuspend_delay = 2; /* Default delay value, | 53 | static int usb_autosuspend_delay = 2; /* Default delay value, |
57 | * in seconds */ | 54 | * in seconds */ |
@@ -228,9 +225,6 @@ static void usb_release_dev(struct device *dev) | |||
228 | hcd = bus_to_hcd(udev->bus); | 225 | hcd = bus_to_hcd(udev->bus); |
229 | 226 | ||
230 | usb_destroy_configuration(udev); | 227 | usb_destroy_configuration(udev); |
231 | /* Root hubs aren't real devices, so don't free HCD resources */ | ||
232 | if (hcd->driver->free_dev && udev->parent) | ||
233 | hcd->driver->free_dev(hcd, udev); | ||
234 | usb_put_hcd(hcd); | 228 | usb_put_hcd(hcd); |
235 | kfree(udev->product); | 229 | kfree(udev->product); |
236 | kfree(udev->manufacturer); | 230 | kfree(udev->manufacturer); |
@@ -264,23 +258,6 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
264 | 258 | ||
265 | #ifdef CONFIG_PM | 259 | #ifdef CONFIG_PM |
266 | 260 | ||
267 | static int ksuspend_usb_init(void) | ||
268 | { | ||
269 | /* This workqueue is supposed to be both freezable and | ||
270 | * singlethreaded. Its job doesn't justify running on more | ||
271 | * than one CPU. | ||
272 | */ | ||
273 | ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd"); | ||
274 | if (!ksuspend_usb_wq) | ||
275 | return -ENOMEM; | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static void ksuspend_usb_cleanup(void) | ||
280 | { | ||
281 | destroy_workqueue(ksuspend_usb_wq); | ||
282 | } | ||
283 | |||
284 | /* USB device Power-Management thunks. | 261 | /* USB device Power-Management thunks. |
285 | * There's no need to distinguish here between quiescing a USB device | 262 | * There's no need to distinguish here between quiescing a USB device |
286 | * and powering it down; the generic_suspend() routine takes care of | 263 | * and powering it down; the generic_suspend() routine takes care of |
@@ -296,7 +273,7 @@ static int usb_dev_prepare(struct device *dev) | |||
296 | static void usb_dev_complete(struct device *dev) | 273 | static void usb_dev_complete(struct device *dev) |
297 | { | 274 | { |
298 | /* Currently used only for rebinding interfaces */ | 275 | /* Currently used only for rebinding interfaces */ |
299 | usb_resume(dev, PMSG_RESUME); /* Message event is meaningless */ | 276 | usb_resume(dev, PMSG_ON); /* FIXME: change to PMSG_COMPLETE */ |
300 | } | 277 | } |
301 | 278 | ||
302 | static int usb_dev_suspend(struct device *dev) | 279 | static int usb_dev_suspend(struct device *dev) |
@@ -342,9 +319,7 @@ static const struct dev_pm_ops usb_device_pm_ops = { | |||
342 | 319 | ||
343 | #else | 320 | #else |
344 | 321 | ||
345 | #define ksuspend_usb_init() 0 | 322 | #define usb_device_pm_ops (*(struct dev_pm_ops *) NULL) |
346 | #define ksuspend_usb_cleanup() do {} while (0) | ||
347 | #define usb_device_pm_ops (*(struct dev_pm_ops *)0) | ||
348 | 323 | ||
349 | #endif /* CONFIG_PM */ | 324 | #endif /* CONFIG_PM */ |
350 | 325 | ||
@@ -472,9 +447,6 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
472 | INIT_LIST_HEAD(&dev->filelist); | 447 | INIT_LIST_HEAD(&dev->filelist); |
473 | 448 | ||
474 | #ifdef CONFIG_PM | 449 | #ifdef CONFIG_PM |
475 | mutex_init(&dev->pm_mutex); | ||
476 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); | ||
477 | INIT_WORK(&dev->autoresume, usb_autoresume_work); | ||
478 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; | 450 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; |
479 | dev->connect_time = jiffies; | 451 | dev->connect_time = jiffies; |
480 | dev->active_duration = -jiffies; | 452 | dev->active_duration = -jiffies; |
@@ -1117,9 +1089,6 @@ static int __init usb_init(void) | |||
1117 | if (retval) | 1089 | if (retval) |
1118 | goto out; | 1090 | goto out; |
1119 | 1091 | ||
1120 | retval = ksuspend_usb_init(); | ||
1121 | if (retval) | ||
1122 | goto out; | ||
1123 | retval = bus_register(&usb_bus_type); | 1092 | retval = bus_register(&usb_bus_type); |
1124 | if (retval) | 1093 | if (retval) |
1125 | goto bus_register_failed; | 1094 | goto bus_register_failed; |
@@ -1159,7 +1128,7 @@ major_init_failed: | |||
1159 | bus_notifier_failed: | 1128 | bus_notifier_failed: |
1160 | bus_unregister(&usb_bus_type); | 1129 | bus_unregister(&usb_bus_type); |
1161 | bus_register_failed: | 1130 | bus_register_failed: |
1162 | ksuspend_usb_cleanup(); | 1131 | usb_debugfs_cleanup(); |
1163 | out: | 1132 | out: |
1164 | return retval; | 1133 | return retval; |
1165 | } | 1134 | } |
@@ -1181,7 +1150,6 @@ static void __exit usb_exit(void) | |||
1181 | usb_hub_cleanup(); | 1150 | usb_hub_cleanup(); |
1182 | bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); | 1151 | bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); |
1183 | bus_unregister(&usb_bus_type); | 1152 | bus_unregister(&usb_bus_type); |
1184 | ksuspend_usb_cleanup(); | ||
1185 | usb_debugfs_cleanup(); | 1153 | usb_debugfs_cleanup(); |
1186 | } | 1154 | } |
1187 | 1155 | ||
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 4c36c7f512a0..cd882203ad34 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -55,24 +55,8 @@ extern void usb_major_cleanup(void); | |||
55 | extern int usb_suspend(struct device *dev, pm_message_t msg); | 55 | extern int usb_suspend(struct device *dev, pm_message_t msg); |
56 | extern int usb_resume(struct device *dev, pm_message_t msg); | 56 | extern int usb_resume(struct device *dev, pm_message_t msg); |
57 | 57 | ||
58 | extern void usb_autosuspend_work(struct work_struct *work); | ||
59 | extern void usb_autoresume_work(struct work_struct *work); | ||
60 | extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg); | 58 | extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg); |
61 | extern int usb_port_resume(struct usb_device *dev, pm_message_t msg); | 59 | extern int usb_port_resume(struct usb_device *dev, pm_message_t msg); |
62 | extern int usb_external_suspend_device(struct usb_device *udev, | ||
63 | pm_message_t msg); | ||
64 | extern int usb_external_resume_device(struct usb_device *udev, | ||
65 | pm_message_t msg); | ||
66 | |||
67 | static inline void usb_pm_lock(struct usb_device *udev) | ||
68 | { | ||
69 | mutex_lock_nested(&udev->pm_mutex, udev->level); | ||
70 | } | ||
71 | |||
72 | static inline void usb_pm_unlock(struct usb_device *udev) | ||
73 | { | ||
74 | mutex_unlock(&udev->pm_mutex); | ||
75 | } | ||
76 | 60 | ||
77 | #else | 61 | #else |
78 | 62 | ||
@@ -86,9 +70,6 @@ static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
86 | return 0; | 70 | return 0; |
87 | } | 71 | } |
88 | 72 | ||
89 | static inline void usb_pm_lock(struct usb_device *udev) {} | ||
90 | static inline void usb_pm_unlock(struct usb_device *udev) {} | ||
91 | |||
92 | #endif | 73 | #endif |
93 | 74 | ||
94 | #ifdef CONFIG_USB_SUSPEND | 75 | #ifdef CONFIG_USB_SUSPEND |
@@ -96,6 +77,7 @@ static inline void usb_pm_unlock(struct usb_device *udev) {} | |||
96 | extern void usb_autosuspend_device(struct usb_device *udev); | 77 | extern void usb_autosuspend_device(struct usb_device *udev); |
97 | extern void usb_try_autosuspend_device(struct usb_device *udev); | 78 | extern void usb_try_autosuspend_device(struct usb_device *udev); |
98 | extern int usb_autoresume_device(struct usb_device *udev); | 79 | extern int usb_autoresume_device(struct usb_device *udev); |
80 | extern int usb_remote_wakeup(struct usb_device *dev); | ||
99 | 81 | ||
100 | #else | 82 | #else |
101 | 83 | ||
@@ -106,9 +88,13 @@ static inline int usb_autoresume_device(struct usb_device *udev) | |||
106 | return 0; | 88 | return 0; |
107 | } | 89 | } |
108 | 90 | ||
91 | static inline int usb_remote_wakeup(struct usb_device *udev) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
109 | #endif | 96 | #endif |
110 | 97 | ||
111 | extern struct workqueue_struct *ksuspend_usb_wq; | ||
112 | extern struct bus_type usb_bus_type; | 98 | extern struct bus_type usb_bus_type; |
113 | extern struct device_type usb_device_type; | 99 | extern struct device_type usb_device_type; |
114 | extern struct device_type usb_if_device_type; | 100 | extern struct device_type usb_if_device_type; |
@@ -138,23 +124,6 @@ static inline int is_usb_device_driver(struct device_driver *drv) | |||
138 | for_devices; | 124 | for_devices; |
139 | } | 125 | } |
140 | 126 | ||
141 | /* Interfaces and their "power state" are owned by usbcore */ | ||
142 | |||
143 | static inline void mark_active(struct usb_interface *f) | ||
144 | { | ||
145 | f->is_active = 1; | ||
146 | } | ||
147 | |||
148 | static inline void mark_quiesced(struct usb_interface *f) | ||
149 | { | ||
150 | f->is_active = 0; | ||
151 | } | ||
152 | |||
153 | static inline int is_active(const struct usb_interface *f) | ||
154 | { | ||
155 | return f->is_active; | ||
156 | } | ||
157 | |||
158 | 127 | ||
159 | /* for labeling diagnostics */ | 128 | /* for labeling diagnostics */ |
160 | extern const char *usbcore_name; | 129 | extern const char *usbcore_name; |
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 2958a1271b20..6e98a3697844 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
@@ -66,8 +66,6 @@ static struct ehci_dev ehci_dev; | |||
66 | 66 | ||
67 | #define USB_DEBUG_DEVNUM 127 | 67 | #define USB_DEBUG_DEVNUM 127 |
68 | 68 | ||
69 | #define DBGP_DATA_TOGGLE 0x8800 | ||
70 | |||
71 | #ifdef DBGP_DEBUG | 69 | #ifdef DBGP_DEBUG |
72 | #define dbgp_printk printk | 70 | #define dbgp_printk printk |
73 | static void dbgp_ehci_status(char *str) | 71 | static void dbgp_ehci_status(char *str) |
@@ -88,11 +86,6 @@ static inline void dbgp_ehci_status(char *str) { } | |||
88 | static inline void dbgp_printk(const char *fmt, ...) { } | 86 | static inline void dbgp_printk(const char *fmt, ...) { } |
89 | #endif | 87 | #endif |
90 | 88 | ||
91 | static inline u32 dbgp_pid_update(u32 x, u32 tok) | ||
92 | { | ||
93 | return ((x ^ DBGP_DATA_TOGGLE) & 0xffff00) | (tok & 0xff); | ||
94 | } | ||
95 | |||
96 | static inline u32 dbgp_len_update(u32 x, u32 len) | 89 | static inline u32 dbgp_len_update(u32 x, u32 len) |
97 | { | 90 | { |
98 | return (x & ~0x0f) | (len & 0x0f); | 91 | return (x & ~0x0f) | (len & 0x0f); |
@@ -136,6 +129,19 @@ static inline u32 dbgp_len_update(u32 x, u32 len) | |||
136 | 129 | ||
137 | #define DBGP_MAX_PACKET 8 | 130 | #define DBGP_MAX_PACKET 8 |
138 | #define DBGP_TIMEOUT (250 * 1000) | 131 | #define DBGP_TIMEOUT (250 * 1000) |
132 | #define DBGP_LOOPS 1000 | ||
133 | |||
134 | static inline u32 dbgp_pid_write_update(u32 x, u32 tok) | ||
135 | { | ||
136 | static int data0 = USB_PID_DATA1; | ||
137 | data0 ^= USB_PID_DATA_TOGGLE; | ||
138 | return (x & 0xffff0000) | (data0 << 8) | (tok & 0xff); | ||
139 | } | ||
140 | |||
141 | static inline u32 dbgp_pid_read_update(u32 x, u32 tok) | ||
142 | { | ||
143 | return (x & 0xffff0000) | (USB_PID_DATA0 << 8) | (tok & 0xff); | ||
144 | } | ||
139 | 145 | ||
140 | static int dbgp_wait_until_complete(void) | 146 | static int dbgp_wait_until_complete(void) |
141 | { | 147 | { |
@@ -180,7 +186,7 @@ static int dbgp_wait_until_done(unsigned ctrl) | |||
180 | { | 186 | { |
181 | u32 pids, lpid; | 187 | u32 pids, lpid; |
182 | int ret; | 188 | int ret; |
183 | int loop = 3; | 189 | int loop = DBGP_LOOPS; |
184 | 190 | ||
185 | retry: | 191 | retry: |
186 | writel(ctrl | DBGP_GO, &ehci_debug->control); | 192 | writel(ctrl | DBGP_GO, &ehci_debug->control); |
@@ -197,6 +203,8 @@ retry: | |||
197 | */ | 203 | */ |
198 | if (ret == -DBGP_TIMEOUT && !dbgp_not_safe) | 204 | if (ret == -DBGP_TIMEOUT && !dbgp_not_safe) |
199 | dbgp_not_safe = 1; | 205 | dbgp_not_safe = 1; |
206 | if (ret == -DBGP_ERR_BAD && --loop > 0) | ||
207 | goto retry; | ||
200 | return ret; | 208 | return ret; |
201 | } | 209 | } |
202 | 210 | ||
@@ -245,12 +253,20 @@ static inline void dbgp_get_data(void *buf, int size) | |||
245 | bytes[i] = (hi >> (8*(i - 4))) & 0xff; | 253 | bytes[i] = (hi >> (8*(i - 4))) & 0xff; |
246 | } | 254 | } |
247 | 255 | ||
248 | static int dbgp_out(u32 addr, const char *bytes, int size) | 256 | static int dbgp_bulk_write(unsigned devnum, unsigned endpoint, |
257 | const char *bytes, int size) | ||
249 | { | 258 | { |
259 | int ret; | ||
260 | u32 addr; | ||
250 | u32 pids, ctrl; | 261 | u32 pids, ctrl; |
251 | 262 | ||
263 | if (size > DBGP_MAX_PACKET) | ||
264 | return -1; | ||
265 | |||
266 | addr = DBGP_EPADDR(devnum, endpoint); | ||
267 | |||
252 | pids = readl(&ehci_debug->pids); | 268 | pids = readl(&ehci_debug->pids); |
253 | pids = dbgp_pid_update(pids, USB_PID_OUT); | 269 | pids = dbgp_pid_write_update(pids, USB_PID_OUT); |
254 | 270 | ||
255 | ctrl = readl(&ehci_debug->control); | 271 | ctrl = readl(&ehci_debug->control); |
256 | ctrl = dbgp_len_update(ctrl, size); | 272 | ctrl = dbgp_len_update(ctrl, size); |
@@ -260,34 +276,7 @@ static int dbgp_out(u32 addr, const char *bytes, int size) | |||
260 | dbgp_set_data(bytes, size); | 276 | dbgp_set_data(bytes, size); |
261 | writel(addr, &ehci_debug->address); | 277 | writel(addr, &ehci_debug->address); |
262 | writel(pids, &ehci_debug->pids); | 278 | writel(pids, &ehci_debug->pids); |
263 | return dbgp_wait_until_done(ctrl); | 279 | ret = dbgp_wait_until_done(ctrl); |
264 | } | ||
265 | |||
266 | static int dbgp_bulk_write(unsigned devnum, unsigned endpoint, | ||
267 | const char *bytes, int size) | ||
268 | { | ||
269 | int ret; | ||
270 | int loops = 5; | ||
271 | u32 addr; | ||
272 | if (size > DBGP_MAX_PACKET) | ||
273 | return -1; | ||
274 | |||
275 | addr = DBGP_EPADDR(devnum, endpoint); | ||
276 | try_again: | ||
277 | if (loops--) { | ||
278 | ret = dbgp_out(addr, bytes, size); | ||
279 | if (ret == -DBGP_ERR_BAD) { | ||
280 | int try_loops = 3; | ||
281 | do { | ||
282 | /* Emit a dummy packet to re-sync communication | ||
283 | * with the debug device */ | ||
284 | if (dbgp_out(addr, "12345678", 8) >= 0) { | ||
285 | udelay(2); | ||
286 | goto try_again; | ||
287 | } | ||
288 | } while (try_loops--); | ||
289 | } | ||
290 | } | ||
291 | 280 | ||
292 | return ret; | 281 | return ret; |
293 | } | 282 | } |
@@ -304,7 +293,7 @@ static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, | |||
304 | addr = DBGP_EPADDR(devnum, endpoint); | 293 | addr = DBGP_EPADDR(devnum, endpoint); |
305 | 294 | ||
306 | pids = readl(&ehci_debug->pids); | 295 | pids = readl(&ehci_debug->pids); |
307 | pids = dbgp_pid_update(pids, USB_PID_IN); | 296 | pids = dbgp_pid_read_update(pids, USB_PID_IN); |
308 | 297 | ||
309 | ctrl = readl(&ehci_debug->control); | 298 | ctrl = readl(&ehci_debug->control); |
310 | ctrl = dbgp_len_update(ctrl, size); | 299 | ctrl = dbgp_len_update(ctrl, size); |
@@ -362,7 +351,6 @@ static int dbgp_control_msg(unsigned devnum, int requesttype, | |||
362 | return dbgp_bulk_read(devnum, 0, data, size); | 351 | return dbgp_bulk_read(devnum, 0, data, size); |
363 | } | 352 | } |
364 | 353 | ||
365 | |||
366 | /* Find a PCI capability */ | 354 | /* Find a PCI capability */ |
367 | static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap) | 355 | static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap) |
368 | { | 356 | { |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index ee411206c699..7460cd797f45 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -812,6 +812,16 @@ config USB_CDC_COMPOSITE | |||
812 | Say "y" to link the driver statically, or "m" to build a | 812 | Say "y" to link the driver statically, or "m" to build a |
813 | dynamically linked module. | 813 | dynamically linked module. |
814 | 814 | ||
815 | config USB_G_NOKIA | ||
816 | tristate "Nokia composite gadget" | ||
817 | depends on PHONET | ||
818 | help | ||
819 | The Nokia composite gadget provides support for acm, obex | ||
820 | and phonet in only one composite gadget driver. | ||
821 | |||
822 | It's only really useful for N900 hardware. If you're building | ||
823 | a kernel for N900, say Y or M here. If unsure, say N. | ||
824 | |||
815 | config USB_G_MULTI | 825 | config USB_G_MULTI |
816 | tristate "Multifunction Composite Gadget (EXPERIMENTAL)" | 826 | tristate "Multifunction Composite Gadget (EXPERIMENTAL)" |
817 | depends on BLOCK && NET | 827 | depends on BLOCK && NET |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 2e2c047262b7..43b51da8d727 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -43,6 +43,7 @@ g_mass_storage-objs := mass_storage.o | |||
43 | g_printer-objs := printer.o | 43 | g_printer-objs := printer.o |
44 | g_cdc-objs := cdc2.o | 44 | g_cdc-objs := cdc2.o |
45 | g_multi-objs := multi.o | 45 | g_multi-objs := multi.o |
46 | g_nokia-objs := nokia.o | ||
46 | 47 | ||
47 | obj-$(CONFIG_USB_ZERO) += g_zero.o | 48 | obj-$(CONFIG_USB_ZERO) += g_zero.o |
48 | obj-$(CONFIG_USB_AUDIO) += g_audio.o | 49 | obj-$(CONFIG_USB_AUDIO) += g_audio.o |
@@ -55,4 +56,5 @@ obj-$(CONFIG_USB_G_PRINTER) += g_printer.o | |||
55 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o | 56 | obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o |
56 | obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o | 57 | obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o |
57 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o | 58 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o |
59 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o | ||
58 | 60 | ||
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 043e04db2a05..12ac9cd32a07 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1656,9 +1656,7 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1656 | if (!res) | 1656 | if (!res) |
1657 | return -ENXIO; | 1657 | return -ENXIO; |
1658 | 1658 | ||
1659 | if (!request_mem_region(res->start, | 1659 | if (!request_mem_region(res->start, resource_size(res), driver_name)) { |
1660 | res->end - res->start + 1, | ||
1661 | driver_name)) { | ||
1662 | DBG("someone's using UDC memory\n"); | 1660 | DBG("someone's using UDC memory\n"); |
1663 | return -EBUSY; | 1661 | return -EBUSY; |
1664 | } | 1662 | } |
@@ -1699,7 +1697,7 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1699 | udc->ep[3].maxpacket = 64; | 1697 | udc->ep[3].maxpacket = 64; |
1700 | } | 1698 | } |
1701 | 1699 | ||
1702 | udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); | 1700 | udc->udp_baseaddr = ioremap(res->start, resource_size(res)); |
1703 | if (!udc->udp_baseaddr) { | 1701 | if (!udc->udp_baseaddr) { |
1704 | retval = -ENOMEM; | 1702 | retval = -ENOMEM; |
1705 | goto fail0a; | 1703 | goto fail0a; |
@@ -1781,7 +1779,7 @@ fail0a: | |||
1781 | if (cpu_is_at91rm9200()) | 1779 | if (cpu_is_at91rm9200()) |
1782 | gpio_free(udc->board.pullup_pin); | 1780 | gpio_free(udc->board.pullup_pin); |
1783 | fail0: | 1781 | fail0: |
1784 | release_mem_region(res->start, res->end - res->start + 1); | 1782 | release_mem_region(res->start, resource_size(res)); |
1785 | DBG("%s probe failed, %d\n", driver_name, retval); | 1783 | DBG("%s probe failed, %d\n", driver_name, retval); |
1786 | return retval; | 1784 | return retval; |
1787 | } | 1785 | } |
@@ -1813,7 +1811,7 @@ static int __exit at91udc_remove(struct platform_device *pdev) | |||
1813 | gpio_free(udc->board.pullup_pin); | 1811 | gpio_free(udc->board.pullup_pin); |
1814 | 1812 | ||
1815 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1813 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1816 | release_mem_region(res->start, res->end - res->start + 1); | 1814 | release_mem_region(res->start, resource_size(res)); |
1817 | 1815 | ||
1818 | clk_put(udc->iclk); | 1816 | clk_put(udc->iclk); |
1819 | clk_put(udc->fclk); | 1817 | clk_put(udc->fclk); |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 4e970cf0e29a..f79bdfe4bed9 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -320,7 +320,7 @@ static inline void usba_cleanup_debugfs(struct usba_udc *udc) | |||
320 | static int vbus_is_present(struct usba_udc *udc) | 320 | static int vbus_is_present(struct usba_udc *udc) |
321 | { | 321 | { |
322 | if (gpio_is_valid(udc->vbus_pin)) | 322 | if (gpio_is_valid(udc->vbus_pin)) |
323 | return gpio_get_value(udc->vbus_pin); | 323 | return gpio_get_value(udc->vbus_pin) ^ udc->vbus_pin_inverted; |
324 | 324 | ||
325 | /* No Vbus detection: Assume always present */ | 325 | /* No Vbus detection: Assume always present */ |
326 | return 1; | 326 | return 1; |
@@ -1763,7 +1763,7 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid) | |||
1763 | if (!udc->driver) | 1763 | if (!udc->driver) |
1764 | goto out; | 1764 | goto out; |
1765 | 1765 | ||
1766 | vbus = gpio_get_value(udc->vbus_pin); | 1766 | vbus = vbus_is_present(udc); |
1767 | if (vbus != udc->vbus_prev) { | 1767 | if (vbus != udc->vbus_prev) { |
1768 | if (vbus) { | 1768 | if (vbus) { |
1769 | toggle_bias(1); | 1769 | toggle_bias(1); |
@@ -1914,14 +1914,14 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
1914 | udc->vbus_pin = -ENODEV; | 1914 | udc->vbus_pin = -ENODEV; |
1915 | 1915 | ||
1916 | ret = -ENOMEM; | 1916 | ret = -ENOMEM; |
1917 | udc->regs = ioremap(regs->start, regs->end - regs->start + 1); | 1917 | udc->regs = ioremap(regs->start, resource_size(regs)); |
1918 | if (!udc->regs) { | 1918 | if (!udc->regs) { |
1919 | dev_err(&pdev->dev, "Unable to map I/O memory, aborting.\n"); | 1919 | dev_err(&pdev->dev, "Unable to map I/O memory, aborting.\n"); |
1920 | goto err_map_regs; | 1920 | goto err_map_regs; |
1921 | } | 1921 | } |
1922 | dev_info(&pdev->dev, "MMIO registers at 0x%08lx mapped at %p\n", | 1922 | dev_info(&pdev->dev, "MMIO registers at 0x%08lx mapped at %p\n", |
1923 | (unsigned long)regs->start, udc->regs); | 1923 | (unsigned long)regs->start, udc->regs); |
1924 | udc->fifo = ioremap(fifo->start, fifo->end - fifo->start + 1); | 1924 | udc->fifo = ioremap(fifo->start, resource_size(fifo)); |
1925 | if (!udc->fifo) { | 1925 | if (!udc->fifo) { |
1926 | dev_err(&pdev->dev, "Unable to map FIFO, aborting.\n"); | 1926 | dev_err(&pdev->dev, "Unable to map FIFO, aborting.\n"); |
1927 | goto err_map_fifo; | 1927 | goto err_map_fifo; |
@@ -2000,6 +2000,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
2000 | if (gpio_is_valid(pdata->vbus_pin)) { | 2000 | if (gpio_is_valid(pdata->vbus_pin)) { |
2001 | if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { | 2001 | if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { |
2002 | udc->vbus_pin = pdata->vbus_pin; | 2002 | udc->vbus_pin = pdata->vbus_pin; |
2003 | udc->vbus_pin_inverted = pdata->vbus_pin_inverted; | ||
2003 | 2004 | ||
2004 | ret = request_irq(gpio_to_irq(udc->vbus_pin), | 2005 | ret = request_irq(gpio_to_irq(udc->vbus_pin), |
2005 | usba_vbus_irq, 0, | 2006 | usba_vbus_irq, 0, |
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h index f7baea307f0d..88a2e07a11a8 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/atmel_usba_udc.h | |||
@@ -323,6 +323,7 @@ struct usba_udc { | |||
323 | struct platform_device *pdev; | 323 | struct platform_device *pdev; |
324 | int irq; | 324 | int irq; |
325 | int vbus_pin; | 325 | int vbus_pin; |
326 | int vbus_pin_inverted; | ||
326 | struct clk *pclk; | 327 | struct clk *pclk; |
327 | struct clk *hclk; | 328 | struct clk *hclk; |
328 | 329 | ||
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index cd0914ec898e..65a5f94cbc04 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -265,16 +265,24 @@ struct usb_ep * __init usb_ep_autoconfig ( | |||
265 | return ep; | 265 | return ep; |
266 | } | 266 | } |
267 | 267 | ||
268 | } else if (gadget_is_sh (gadget) && USB_ENDPOINT_XFER_INT == type) { | 268 | #ifdef CONFIG_BLACKFIN |
269 | /* single buffering is enough; maybe 8 byte fifo is too */ | 269 | } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) { |
270 | ep = find_ep (gadget, "ep3in-bulk"); | 270 | if ((USB_ENDPOINT_XFER_BULK == type) || |
271 | if (ep && ep_matches (gadget, ep, desc)) | 271 | (USB_ENDPOINT_XFER_ISOC == type)) { |
272 | return ep; | 272 | if (USB_DIR_IN & desc->bEndpointAddress) |
273 | 273 | ep = find_ep (gadget, "ep5in"); | |
274 | } else if (gadget_is_mq11xx (gadget) && USB_ENDPOINT_XFER_INT == type) { | 274 | else |
275 | ep = find_ep (gadget, "ep1-bulk"); | 275 | ep = find_ep (gadget, "ep6out"); |
276 | } else if (USB_ENDPOINT_XFER_INT == type) { | ||
277 | if (USB_DIR_IN & desc->bEndpointAddress) | ||
278 | ep = find_ep(gadget, "ep1in"); | ||
279 | else | ||
280 | ep = find_ep(gadget, "ep2out"); | ||
281 | } else | ||
282 | ep = NULL; | ||
276 | if (ep && ep_matches (gadget, ep, desc)) | 283 | if (ep && ep_matches (gadget, ep, desc)) |
277 | return ep; | 284 | return ep; |
285 | #endif | ||
278 | } | 286 | } |
279 | 287 | ||
280 | /* Second, look at endpoints until an unclaimed one looks usable */ | 288 | /* Second, look at endpoints until an unclaimed one looks usable */ |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 141372b6e7a1..400f80372d93 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -259,7 +259,7 @@ static struct usb_configuration rndis_config_driver = { | |||
259 | 259 | ||
260 | /*-------------------------------------------------------------------------*/ | 260 | /*-------------------------------------------------------------------------*/ |
261 | 261 | ||
262 | #ifdef USB_ETH_EEM | 262 | #ifdef CONFIG_USB_ETH_EEM |
263 | static int use_eem = 1; | 263 | static int use_eem = 1; |
264 | #else | 264 | #else |
265 | static int use_eem; | 265 | static int use_eem; |
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index d10353d46b86..e49c7325dce2 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
@@ -702,14 +702,6 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) | |||
702 | /* Some controllers can't support CDC ACM ... */ | 702 | /* Some controllers can't support CDC ACM ... */ |
703 | static inline bool can_support_cdc(struct usb_configuration *c) | 703 | static inline bool can_support_cdc(struct usb_configuration *c) |
704 | { | 704 | { |
705 | /* SH3 doesn't support multiple interfaces */ | ||
706 | if (gadget_is_sh(c->cdev->gadget)) | ||
707 | return false; | ||
708 | |||
709 | /* sa1100 doesn't have a third interrupt endpoint */ | ||
710 | if (gadget_is_sa1100(c->cdev->gadget)) | ||
711 | return false; | ||
712 | |||
713 | /* everything else is *probably* fine ... */ | 705 | /* everything else is *probably* fine ... */ |
714 | return true; | 706 | return true; |
715 | } | 707 | } |
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index ecf5bdd0ae06..2fff530efc19 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c | |||
@@ -497,12 +497,9 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
497 | struct net_device *net; | 497 | struct net_device *net; |
498 | 498 | ||
499 | /* Enable zlps by default for ECM conformance; | 499 | /* Enable zlps by default for ECM conformance; |
500 | * override for musb_hdrc (avoids txdma ovhead) | 500 | * override for musb_hdrc (avoids txdma ovhead). |
501 | * and sa1100 (can't). | ||
502 | */ | 501 | */ |
503 | ecm->port.is_zlp_ok = !( | 502 | ecm->port.is_zlp_ok = !(gadget_is_musbhdrc(cdev->gadget) |
504 | gadget_is_sa1100(cdev->gadget) | ||
505 | || gadget_is_musbhdrc(cdev->gadget) | ||
506 | ); | 503 | ); |
507 | ecm->port.cdc_filter = DEFAULT_FILTER; | 504 | ecm->port.cdc_filter = DEFAULT_FILTER; |
508 | DBG(cdev, "activate ecm\n"); | 505 | DBG(cdev, "activate ecm\n"); |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index a37640eba434..b1935fe156a0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -368,7 +368,7 @@ struct fsg_common { | |||
368 | struct task_struct *thread_task; | 368 | struct task_struct *thread_task; |
369 | 369 | ||
370 | /* Callback function to call when thread exits. */ | 370 | /* Callback function to call when thread exits. */ |
371 | void (*thread_exits)(struct fsg_common *common); | 371 | int (*thread_exits)(struct fsg_common *common); |
372 | /* Gadget's private data. */ | 372 | /* Gadget's private data. */ |
373 | void *private_data; | 373 | void *private_data; |
374 | 374 | ||
@@ -392,8 +392,12 @@ struct fsg_config { | |||
392 | const char *lun_name_format; | 392 | const char *lun_name_format; |
393 | const char *thread_name; | 393 | const char *thread_name; |
394 | 394 | ||
395 | /* Callback function to call when thread exits. */ | 395 | /* Callback function to call when thread exits. If no |
396 | void (*thread_exits)(struct fsg_common *common); | 396 | * callback is set or it returns value lower then zero MSF |
397 | * will force eject all LUNs it operates on (including those | ||
398 | * marked as non-removable or with prevent_medium_removal flag | ||
399 | * set). */ | ||
400 | int (*thread_exits)(struct fsg_common *common); | ||
397 | /* Gadget's private data. */ | 401 | /* Gadget's private data. */ |
398 | void *private_data; | 402 | void *private_data; |
399 | 403 | ||
@@ -614,7 +618,12 @@ static int fsg_setup(struct usb_function *f, | |||
614 | return -EDOM; | 618 | return -EDOM; |
615 | VDBG(fsg, "get max LUN\n"); | 619 | VDBG(fsg, "get max LUN\n"); |
616 | *(u8 *) req->buf = fsg->common->nluns - 1; | 620 | *(u8 *) req->buf = fsg->common->nluns - 1; |
617 | return 1; | 621 | |
622 | /* Respond with data/status */ | ||
623 | req->length = min((u16)1, w_length); | ||
624 | fsg->common->ep0req_name = | ||
625 | ctrl->bRequestType & USB_DIR_IN ? "ep0-in" : "ep0-out"; | ||
626 | return ep0_queue(fsg->common); | ||
618 | } | 627 | } |
619 | 628 | ||
620 | VDBG(fsg, | 629 | VDBG(fsg, |
@@ -2524,14 +2533,6 @@ static void handle_exception(struct fsg_common *common) | |||
2524 | 2533 | ||
2525 | case FSG_STATE_CONFIG_CHANGE: | 2534 | case FSG_STATE_CONFIG_CHANGE: |
2526 | rc = do_set_config(common, new_config); | 2535 | rc = do_set_config(common, new_config); |
2527 | if (common->ep0_req_tag != exception_req_tag) | ||
2528 | break; | ||
2529 | if (rc != 0) { /* STALL on errors */ | ||
2530 | DBG(common, "ep0 set halt\n"); | ||
2531 | usb_ep_set_halt(common->ep0); | ||
2532 | } else { /* Complete the status stage */ | ||
2533 | ep0_queue(common); | ||
2534 | } | ||
2535 | break; | 2536 | break; |
2536 | 2537 | ||
2537 | case FSG_STATE_EXIT: | 2538 | case FSG_STATE_EXIT: |
@@ -2615,8 +2616,20 @@ static int fsg_main_thread(void *common_) | |||
2615 | common->thread_task = NULL; | 2616 | common->thread_task = NULL; |
2616 | spin_unlock_irq(&common->lock); | 2617 | spin_unlock_irq(&common->lock); |
2617 | 2618 | ||
2618 | if (common->thread_exits) | 2619 | if (!common->thread_exits || common->thread_exits(common) < 0) { |
2619 | common->thread_exits(common); | 2620 | struct fsg_lun *curlun = common->luns; |
2621 | unsigned i = common->nluns; | ||
2622 | |||
2623 | down_write(&common->filesem); | ||
2624 | for (; i--; ++curlun) { | ||
2625 | if (!fsg_lun_is_open(curlun)) | ||
2626 | continue; | ||
2627 | |||
2628 | fsg_lun_close(curlun); | ||
2629 | curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; | ||
2630 | } | ||
2631 | up_write(&common->filesem); | ||
2632 | } | ||
2620 | 2633 | ||
2621 | /* Let the unbind and cleanup routines know the thread has exited */ | 2634 | /* Let the unbind and cleanup routines know the thread has exited */ |
2622 | complete_and_exit(&common->thread_notifier, 0); | 2635 | complete_and_exit(&common->thread_notifier, 0); |
@@ -2763,10 +2776,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2763 | if (cfg->release != 0xffff) { | 2776 | if (cfg->release != 0xffff) { |
2764 | i = cfg->release; | 2777 | i = cfg->release; |
2765 | } else { | 2778 | } else { |
2766 | /* The sa1100 controller is not supported */ | 2779 | i = usb_gadget_controller_number(gadget); |
2767 | i = gadget_is_sa1100(gadget) | ||
2768 | ? -1 | ||
2769 | : usb_gadget_controller_number(gadget); | ||
2770 | if (i >= 0) { | 2780 | if (i >= 0) { |
2771 | i = 0x0300 + i; | 2781 | i = 0x0300 + i; |
2772 | } else { | 2782 | } else { |
@@ -2791,8 +2801,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2791 | * disable stalls. | 2801 | * disable stalls. |
2792 | */ | 2802 | */ |
2793 | common->can_stall = cfg->can_stall && | 2803 | common->can_stall = cfg->can_stall && |
2794 | !(gadget_is_sh(common->gadget) || | 2804 | !(gadget_is_at91(common->gadget)); |
2795 | gadget_is_at91(common->gadget)); | ||
2796 | 2805 | ||
2797 | 2806 | ||
2798 | spin_lock_init(&common->lock); | 2807 | spin_lock_init(&common->lock); |
@@ -2852,7 +2861,6 @@ error_release: | |||
2852 | /* Call fsg_common_release() directly, ref might be not | 2861 | /* Call fsg_common_release() directly, ref might be not |
2853 | * initialised */ | 2862 | * initialised */ |
2854 | fsg_common_release(&common->ref); | 2863 | fsg_common_release(&common->ref); |
2855 | complete(&common->thread_notifier); | ||
2856 | return ERR_PTR(rc); | 2864 | return ERR_PTR(rc); |
2857 | } | 2865 | } |
2858 | 2866 | ||
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 95dae4c1ea40..a30e60c7f129 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
@@ -769,10 +769,6 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f) | |||
769 | /* Some controllers can't support RNDIS ... */ | 769 | /* Some controllers can't support RNDIS ... */ |
770 | static inline bool can_support_rndis(struct usb_configuration *c) | 770 | static inline bool can_support_rndis(struct usb_configuration *c) |
771 | { | 771 | { |
772 | /* only two endpoints on sa1100 */ | ||
773 | if (gadget_is_sa1100(c->cdev->gadget)) | ||
774 | return false; | ||
775 | |||
776 | /* everything else is *presumably* fine */ | 772 | /* everything else is *presumably* fine */ |
777 | return true; | 773 | return true; |
778 | } | 774 | } |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 29dfb0277ffb..a90dd2db0488 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -3208,15 +3208,11 @@ static int __init check_parameters(struct fsg_dev *fsg) | |||
3208 | * halt bulk endpoints correctly. If one of them is present, | 3208 | * halt bulk endpoints correctly. If one of them is present, |
3209 | * disable stalls. | 3209 | * disable stalls. |
3210 | */ | 3210 | */ |
3211 | if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget)) | 3211 | if (gadget_is_at91(fsg->gadget)) |
3212 | mod_data.can_stall = 0; | 3212 | mod_data.can_stall = 0; |
3213 | 3213 | ||
3214 | if (mod_data.release == 0xffff) { // Parameter wasn't set | 3214 | if (mod_data.release == 0xffff) { // Parameter wasn't set |
3215 | /* The sa1100 controller is not supported */ | 3215 | gcnum = usb_gadget_controller_number(fsg->gadget); |
3216 | if (gadget_is_sa1100(fsg->gadget)) | ||
3217 | gcnum = -1; | ||
3218 | else | ||
3219 | gcnum = usb_gadget_controller_number(fsg->gadget); | ||
3220 | if (gcnum >= 0) | 3216 | if (gcnum >= 0) |
3221 | mod_data.release = 0x0300 + gcnum; | 3217 | mod_data.release = 0x0300 + gcnum; |
3222 | else { | 3218 | else { |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 7881f12413c4..3537d51073b2 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -2749,7 +2749,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev) | |||
2749 | } | 2749 | } |
2750 | 2750 | ||
2751 | /*-------------------------------------------------------------------------*/ | 2751 | /*-------------------------------------------------------------------------*/ |
2752 | static struct of_device_id __devinitdata qe_udc_match[] = { | 2752 | static const struct of_device_id qe_udc_match[] __devinitconst = { |
2753 | { | 2753 | { |
2754 | .compatible = "fsl,mpc8323-qe-usb", | 2754 | .compatible = "fsl,mpc8323-qe-usb", |
2755 | .data = (void *)PORT_QE, | 2755 | .data = (void *)PORT_QE, |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index f2d270b202f2..1edbc12fff18 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -45,46 +45,18 @@ | |||
45 | #define gadget_is_goku(g) 0 | 45 | #define gadget_is_goku(g) 0 |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | /* SH3 UDC -- not yet ported 2.4 --> 2.6 */ | ||
49 | #ifdef CONFIG_USB_GADGET_SUPERH | ||
50 | #define gadget_is_sh(g) !strcmp("sh_udc", (g)->name) | ||
51 | #else | ||
52 | #define gadget_is_sh(g) 0 | ||
53 | #endif | ||
54 | |||
55 | /* not yet stable on 2.6 (would help "original Zaurus") */ | ||
56 | #ifdef CONFIG_USB_GADGET_SA1100 | ||
57 | #define gadget_is_sa1100(g) !strcmp("sa1100_udc", (g)->name) | ||
58 | #else | ||
59 | #define gadget_is_sa1100(g) 0 | ||
60 | #endif | ||
61 | |||
62 | #ifdef CONFIG_USB_GADGET_LH7A40X | 48 | #ifdef CONFIG_USB_GADGET_LH7A40X |
63 | #define gadget_is_lh7a40x(g) !strcmp("lh7a40x_udc", (g)->name) | 49 | #define gadget_is_lh7a40x(g) !strcmp("lh7a40x_udc", (g)->name) |
64 | #else | 50 | #else |
65 | #define gadget_is_lh7a40x(g) 0 | 51 | #define gadget_is_lh7a40x(g) 0 |
66 | #endif | 52 | #endif |
67 | 53 | ||
68 | /* handhelds.org tree (?) */ | ||
69 | #ifdef CONFIG_USB_GADGET_MQ11XX | ||
70 | #define gadget_is_mq11xx(g) !strcmp("mq11xx_udc", (g)->name) | ||
71 | #else | ||
72 | #define gadget_is_mq11xx(g) 0 | ||
73 | #endif | ||
74 | |||
75 | #ifdef CONFIG_USB_GADGET_OMAP | 54 | #ifdef CONFIG_USB_GADGET_OMAP |
76 | #define gadget_is_omap(g) !strcmp("omap_udc", (g)->name) | 55 | #define gadget_is_omap(g) !strcmp("omap_udc", (g)->name) |
77 | #else | 56 | #else |
78 | #define gadget_is_omap(g) 0 | 57 | #define gadget_is_omap(g) 0 |
79 | #endif | 58 | #endif |
80 | 59 | ||
81 | /* not yet ported 2.4 --> 2.6 */ | ||
82 | #ifdef CONFIG_USB_GADGET_N9604 | ||
83 | #define gadget_is_n9604(g) !strcmp("n9604_udc", (g)->name) | ||
84 | #else | ||
85 | #define gadget_is_n9604(g) 0 | ||
86 | #endif | ||
87 | |||
88 | /* various unstable versions available */ | 60 | /* various unstable versions available */ |
89 | #ifdef CONFIG_USB_GADGET_PXA27X | 61 | #ifdef CONFIG_USB_GADGET_PXA27X |
90 | #define gadget_is_pxa27x(g) !strcmp("pxa27x_udc", (g)->name) | 62 | #define gadget_is_pxa27x(g) !strcmp("pxa27x_udc", (g)->name) |
@@ -122,14 +94,6 @@ | |||
122 | #define gadget_is_fsl_usb2(g) 0 | 94 | #define gadget_is_fsl_usb2(g) 0 |
123 | #endif | 95 | #endif |
124 | 96 | ||
125 | /* Mentor high speed function controller */ | ||
126 | /* from Montavista kernel (?) */ | ||
127 | #ifdef CONFIG_USB_GADGET_MUSBHSFC | ||
128 | #define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name) | ||
129 | #else | ||
130 | #define gadget_is_musbhsfc(g) 0 | ||
131 | #endif | ||
132 | |||
133 | /* Mentor high speed "dual role" controller, in peripheral role */ | 97 | /* Mentor high speed "dual role" controller, in peripheral role */ |
134 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | 98 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
135 | #define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name) | 99 | #define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name) |
@@ -143,13 +107,6 @@ | |||
143 | #define gadget_is_langwell(g) 0 | 107 | #define gadget_is_langwell(g) 0 |
144 | #endif | 108 | #endif |
145 | 109 | ||
146 | /* from Montavista kernel (?) */ | ||
147 | #ifdef CONFIG_USB_GADGET_MPC8272 | ||
148 | #define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name) | ||
149 | #else | ||
150 | #define gadget_is_mpc8272(g) 0 | ||
151 | #endif | ||
152 | |||
153 | #ifdef CONFIG_USB_GADGET_M66592 | 110 | #ifdef CONFIG_USB_GADGET_M66592 |
154 | #define gadget_is_m66592(g) !strcmp("m66592_udc", (g)->name) | 111 | #define gadget_is_m66592(g) !strcmp("m66592_udc", (g)->name) |
155 | #else | 112 | #else |
@@ -203,20 +160,12 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
203 | return 0x02; | 160 | return 0x02; |
204 | else if (gadget_is_pxa(gadget)) | 161 | else if (gadget_is_pxa(gadget)) |
205 | return 0x03; | 162 | return 0x03; |
206 | else if (gadget_is_sh(gadget)) | ||
207 | return 0x04; | ||
208 | else if (gadget_is_sa1100(gadget)) | ||
209 | return 0x05; | ||
210 | else if (gadget_is_goku(gadget)) | 163 | else if (gadget_is_goku(gadget)) |
211 | return 0x06; | 164 | return 0x06; |
212 | else if (gadget_is_mq11xx(gadget)) | ||
213 | return 0x07; | ||
214 | else if (gadget_is_omap(gadget)) | 165 | else if (gadget_is_omap(gadget)) |
215 | return 0x08; | 166 | return 0x08; |
216 | else if (gadget_is_lh7a40x(gadget)) | 167 | else if (gadget_is_lh7a40x(gadget)) |
217 | return 0x09; | 168 | return 0x09; |
218 | else if (gadget_is_n9604(gadget)) | ||
219 | return 0x10; | ||
220 | else if (gadget_is_pxa27x(gadget)) | 169 | else if (gadget_is_pxa27x(gadget)) |
221 | return 0x11; | 170 | return 0x11; |
222 | else if (gadget_is_s3c2410(gadget)) | 171 | else if (gadget_is_s3c2410(gadget)) |
@@ -225,12 +174,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
225 | return 0x13; | 174 | return 0x13; |
226 | else if (gadget_is_imx(gadget)) | 175 | else if (gadget_is_imx(gadget)) |
227 | return 0x14; | 176 | return 0x14; |
228 | else if (gadget_is_musbhsfc(gadget)) | ||
229 | return 0x15; | ||
230 | else if (gadget_is_musbhdrc(gadget)) | 177 | else if (gadget_is_musbhdrc(gadget)) |
231 | return 0x16; | 178 | return 0x16; |
232 | else if (gadget_is_mpc8272(gadget)) | ||
233 | return 0x17; | ||
234 | else if (gadget_is_atmel_usba(gadget)) | 179 | else if (gadget_is_atmel_usba(gadget)) |
235 | return 0x18; | 180 | return 0x18; |
236 | else if (gadget_is_fsl_usb2(gadget)) | 181 | else if (gadget_is_fsl_usb2(gadget)) |
@@ -265,10 +210,6 @@ static inline bool gadget_supports_altsettings(struct usb_gadget *gadget) | |||
265 | if (gadget_is_pxa27x(gadget)) | 210 | if (gadget_is_pxa27x(gadget)) |
266 | return false; | 211 | return false; |
267 | 212 | ||
268 | /* SH3 hardware just doesn't do altsettings */ | ||
269 | if (gadget_is_sh(gadget)) | ||
270 | return false; | ||
271 | |||
272 | /* Everything else is *presumably* fine ... */ | 213 | /* Everything else is *presumably* fine ... */ |
273 | return true; | 214 | return true; |
274 | } | 215 | } |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 5f6a2e0a9357..04f6224b7e06 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -618,11 +618,6 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags) | |||
618 | } | 618 | } |
619 | #endif | 619 | #endif |
620 | 620 | ||
621 | if (gadget_is_sa1100(gadget) && dev->config) { | ||
622 | /* tx fifo is full, but we can't clear it...*/ | ||
623 | ERROR(dev, "can't change configurations\n"); | ||
624 | return -ESPIPE; | ||
625 | } | ||
626 | gmidi_reset_config(dev); | 621 | gmidi_reset_config(dev); |
627 | 622 | ||
628 | switch (number) { | 623 | switch (number) { |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 112bb40a427c..e8edc640381e 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1859,7 +1859,7 @@ done: | |||
1859 | 1859 | ||
1860 | /*-------------------------------------------------------------------------*/ | 1860 | /*-------------------------------------------------------------------------*/ |
1861 | 1861 | ||
1862 | static struct pci_device_id pci_ids [] = { { | 1862 | static const struct pci_device_id pci_ids[] = { { |
1863 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | 1863 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), |
1864 | .class_mask = ~0, | 1864 | .class_mask = ~0, |
1865 | .vendor = 0x102f, /* Toshiba */ | 1865 | .vendor = 0x102f, /* Toshiba */ |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index bf0f6520c6df..de8a83803505 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -194,7 +194,7 @@ enum ep_state { | |||
194 | }; | 194 | }; |
195 | 195 | ||
196 | struct ep_data { | 196 | struct ep_data { |
197 | struct semaphore lock; | 197 | struct mutex lock; |
198 | enum ep_state state; | 198 | enum ep_state state; |
199 | atomic_t count; | 199 | atomic_t count; |
200 | struct dev_data *dev; | 200 | struct dev_data *dev; |
@@ -298,10 +298,10 @@ get_ready_ep (unsigned f_flags, struct ep_data *epdata) | |||
298 | int val; | 298 | int val; |
299 | 299 | ||
300 | if (f_flags & O_NONBLOCK) { | 300 | if (f_flags & O_NONBLOCK) { |
301 | if (down_trylock (&epdata->lock) != 0) | 301 | if (!mutex_trylock(&epdata->lock)) |
302 | goto nonblock; | 302 | goto nonblock; |
303 | if (epdata->state != STATE_EP_ENABLED) { | 303 | if (epdata->state != STATE_EP_ENABLED) { |
304 | up (&epdata->lock); | 304 | mutex_unlock(&epdata->lock); |
305 | nonblock: | 305 | nonblock: |
306 | val = -EAGAIN; | 306 | val = -EAGAIN; |
307 | } else | 307 | } else |
@@ -309,7 +309,8 @@ nonblock: | |||
309 | return val; | 309 | return val; |
310 | } | 310 | } |
311 | 311 | ||
312 | if ((val = down_interruptible (&epdata->lock)) < 0) | 312 | val = mutex_lock_interruptible(&epdata->lock); |
313 | if (val < 0) | ||
313 | return val; | 314 | return val; |
314 | 315 | ||
315 | switch (epdata->state) { | 316 | switch (epdata->state) { |
@@ -323,7 +324,7 @@ nonblock: | |||
323 | // FALLTHROUGH | 324 | // FALLTHROUGH |
324 | case STATE_EP_UNBOUND: /* clean disconnect */ | 325 | case STATE_EP_UNBOUND: /* clean disconnect */ |
325 | val = -ENODEV; | 326 | val = -ENODEV; |
326 | up (&epdata->lock); | 327 | mutex_unlock(&epdata->lock); |
327 | } | 328 | } |
328 | return val; | 329 | return val; |
329 | } | 330 | } |
@@ -393,7 +394,7 @@ ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
393 | if (likely (data->ep != NULL)) | 394 | if (likely (data->ep != NULL)) |
394 | usb_ep_set_halt (data->ep); | 395 | usb_ep_set_halt (data->ep); |
395 | spin_unlock_irq (&data->dev->lock); | 396 | spin_unlock_irq (&data->dev->lock); |
396 | up (&data->lock); | 397 | mutex_unlock(&data->lock); |
397 | return -EBADMSG; | 398 | return -EBADMSG; |
398 | } | 399 | } |
399 | 400 | ||
@@ -411,7 +412,7 @@ ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
411 | value = -EFAULT; | 412 | value = -EFAULT; |
412 | 413 | ||
413 | free1: | 414 | free1: |
414 | up (&data->lock); | 415 | mutex_unlock(&data->lock); |
415 | kfree (kbuf); | 416 | kfree (kbuf); |
416 | return value; | 417 | return value; |
417 | } | 418 | } |
@@ -436,7 +437,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
436 | if (likely (data->ep != NULL)) | 437 | if (likely (data->ep != NULL)) |
437 | usb_ep_set_halt (data->ep); | 438 | usb_ep_set_halt (data->ep); |
438 | spin_unlock_irq (&data->dev->lock); | 439 | spin_unlock_irq (&data->dev->lock); |
439 | up (&data->lock); | 440 | mutex_unlock(&data->lock); |
440 | return -EBADMSG; | 441 | return -EBADMSG; |
441 | } | 442 | } |
442 | 443 | ||
@@ -455,7 +456,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
455 | VDEBUG (data->dev, "%s write %zu IN, status %d\n", | 456 | VDEBUG (data->dev, "%s write %zu IN, status %d\n", |
456 | data->name, len, (int) value); | 457 | data->name, len, (int) value); |
457 | free1: | 458 | free1: |
458 | up (&data->lock); | 459 | mutex_unlock(&data->lock); |
459 | kfree (kbuf); | 460 | kfree (kbuf); |
460 | return value; | 461 | return value; |
461 | } | 462 | } |
@@ -466,7 +467,8 @@ ep_release (struct inode *inode, struct file *fd) | |||
466 | struct ep_data *data = fd->private_data; | 467 | struct ep_data *data = fd->private_data; |
467 | int value; | 468 | int value; |
468 | 469 | ||
469 | if ((value = down_interruptible(&data->lock)) < 0) | 470 | value = mutex_lock_interruptible(&data->lock); |
471 | if (value < 0) | ||
470 | return value; | 472 | return value; |
471 | 473 | ||
472 | /* clean up if this can be reopened */ | 474 | /* clean up if this can be reopened */ |
@@ -476,7 +478,7 @@ ep_release (struct inode *inode, struct file *fd) | |||
476 | data->hs_desc.bDescriptorType = 0; | 478 | data->hs_desc.bDescriptorType = 0; |
477 | usb_ep_disable(data->ep); | 479 | usb_ep_disable(data->ep); |
478 | } | 480 | } |
479 | up (&data->lock); | 481 | mutex_unlock(&data->lock); |
480 | put_ep (data); | 482 | put_ep (data); |
481 | return 0; | 483 | return 0; |
482 | } | 484 | } |
@@ -507,7 +509,7 @@ static long ep_ioctl(struct file *fd, unsigned code, unsigned long value) | |||
507 | } else | 509 | } else |
508 | status = -ENODEV; | 510 | status = -ENODEV; |
509 | spin_unlock_irq (&data->dev->lock); | 511 | spin_unlock_irq (&data->dev->lock); |
510 | up (&data->lock); | 512 | mutex_unlock(&data->lock); |
511 | return status; | 513 | return status; |
512 | } | 514 | } |
513 | 515 | ||
@@ -673,7 +675,7 @@ fail: | |||
673 | value = -ENODEV; | 675 | value = -ENODEV; |
674 | spin_unlock_irq(&epdata->dev->lock); | 676 | spin_unlock_irq(&epdata->dev->lock); |
675 | 677 | ||
676 | up(&epdata->lock); | 678 | mutex_unlock(&epdata->lock); |
677 | 679 | ||
678 | if (unlikely(value)) { | 680 | if (unlikely(value)) { |
679 | kfree(priv); | 681 | kfree(priv); |
@@ -765,7 +767,8 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
765 | u32 tag; | 767 | u32 tag; |
766 | int value, length = len; | 768 | int value, length = len; |
767 | 769 | ||
768 | if ((value = down_interruptible (&data->lock)) < 0) | 770 | value = mutex_lock_interruptible(&data->lock); |
771 | if (value < 0) | ||
769 | return value; | 772 | return value; |
770 | 773 | ||
771 | if (data->state != STATE_EP_READY) { | 774 | if (data->state != STATE_EP_READY) { |
@@ -854,7 +857,7 @@ fail: | |||
854 | data->desc.bDescriptorType = 0; | 857 | data->desc.bDescriptorType = 0; |
855 | data->hs_desc.bDescriptorType = 0; | 858 | data->hs_desc.bDescriptorType = 0; |
856 | } | 859 | } |
857 | up (&data->lock); | 860 | mutex_unlock(&data->lock); |
858 | return value; | 861 | return value; |
859 | fail0: | 862 | fail0: |
860 | value = -EINVAL; | 863 | value = -EINVAL; |
@@ -870,7 +873,7 @@ ep_open (struct inode *inode, struct file *fd) | |||
870 | struct ep_data *data = inode->i_private; | 873 | struct ep_data *data = inode->i_private; |
871 | int value = -EBUSY; | 874 | int value = -EBUSY; |
872 | 875 | ||
873 | if (down_interruptible (&data->lock) != 0) | 876 | if (mutex_lock_interruptible(&data->lock) != 0) |
874 | return -EINTR; | 877 | return -EINTR; |
875 | spin_lock_irq (&data->dev->lock); | 878 | spin_lock_irq (&data->dev->lock); |
876 | if (data->dev->state == STATE_DEV_UNBOUND) | 879 | if (data->dev->state == STATE_DEV_UNBOUND) |
@@ -885,7 +888,7 @@ ep_open (struct inode *inode, struct file *fd) | |||
885 | DBG (data->dev, "%s state %d\n", | 888 | DBG (data->dev, "%s state %d\n", |
886 | data->name, data->state); | 889 | data->name, data->state); |
887 | spin_unlock_irq (&data->dev->lock); | 890 | spin_unlock_irq (&data->dev->lock); |
888 | up (&data->lock); | 891 | mutex_unlock(&data->lock); |
889 | return value; | 892 | return value; |
890 | } | 893 | } |
891 | 894 | ||
@@ -1631,7 +1634,7 @@ static int activate_ep_files (struct dev_data *dev) | |||
1631 | if (!data) | 1634 | if (!data) |
1632 | goto enomem0; | 1635 | goto enomem0; |
1633 | data->state = STATE_EP_DISABLED; | 1636 | data->state = STATE_EP_DISABLED; |
1634 | init_MUTEX (&data->lock); | 1637 | mutex_init(&data->lock); |
1635 | init_waitqueue_head (&data->wait); | 1638 | init_waitqueue_head (&data->wait); |
1636 | 1639 | ||
1637 | strncpy (data->name, ep->name, sizeof (data->name) - 1); | 1640 | strncpy (data->name, ep->name, sizeof (data->name) - 1); |
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 19619fbf20ac..705cc1f76327 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c | |||
@@ -135,6 +135,12 @@ FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); | |||
135 | static unsigned long msg_registered = 0; | 135 | static unsigned long msg_registered = 0; |
136 | static void msg_cleanup(void); | 136 | static void msg_cleanup(void); |
137 | 137 | ||
138 | static int msg_thread_exits(struct fsg_common *common) | ||
139 | { | ||
140 | msg_cleanup(); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
138 | static int __init msg_do_config(struct usb_configuration *c) | 144 | static int __init msg_do_config(struct usb_configuration *c) |
139 | { | 145 | { |
140 | struct fsg_common *common; | 146 | struct fsg_common *common; |
@@ -147,7 +153,7 @@ static int __init msg_do_config(struct usb_configuration *c) | |||
147 | } | 153 | } |
148 | 154 | ||
149 | fsg_config_from_params(&config, &mod_data); | 155 | fsg_config_from_params(&config, &mod_data); |
150 | config.thread_exits = (void(*)(struct fsg_common*))&msg_cleanup; | 156 | config.thread_exits = msg_thread_exits; |
151 | common = fsg_common_init(0, c->cdev, &config); | 157 | common = fsg_common_init(0, c->cdev, &config); |
152 | if (IS_ERR(common)) | 158 | if (IS_ERR(common)) |
153 | return PTR_ERR(common); | 159 | return PTR_ERR(common); |
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c new file mode 100644 index 000000000000..7d6b66a85724 --- /dev/null +++ b/drivers/usb/gadget/nokia.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* | ||
2 | * nokia.c -- Nokia Composite Gadget Driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Nokia Corporation | ||
5 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> | ||
6 | * | ||
7 | * This gadget driver borrows from serial.c which is: | ||
8 | * | ||
9 | * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) | ||
10 | * Copyright (C) 2008 by David Brownell | ||
11 | * Copyright (C) 2008 by Nokia Corporation | ||
12 | * | ||
13 | * This software is distributed under the terms of the GNU General | ||
14 | * Public License ("GPL") as published by the Free Software Foundation, | ||
15 | * version 2 of that License. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/utsname.h> | ||
20 | #include <linux/device.h> | ||
21 | |||
22 | #include "u_serial.h" | ||
23 | #include "u_ether.h" | ||
24 | #include "u_phonet.h" | ||
25 | #include "gadget_chips.h" | ||
26 | |||
27 | /* Defines */ | ||
28 | |||
29 | #define NOKIA_VERSION_NUM 0x0211 | ||
30 | #define NOKIA_LONG_NAME "N900 (PC-Suite Mode)" | ||
31 | |||
32 | /*-------------------------------------------------------------------------*/ | ||
33 | |||
34 | /* | ||
35 | * Kbuild is not very cooperative with respect to linking separately | ||
36 | * compiled library objects into one module. So for now we won't use | ||
37 | * separate compilation ... ensuring init/exit sections work to shrink | ||
38 | * the runtime footprint, and giving us at least some parts of what | ||
39 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
40 | */ | ||
41 | #include "composite.c" | ||
42 | #include "usbstring.c" | ||
43 | #include "config.c" | ||
44 | #include "epautoconf.c" | ||
45 | |||
46 | #include "u_serial.c" | ||
47 | #include "f_acm.c" | ||
48 | #include "f_ecm.c" | ||
49 | #include "f_obex.c" | ||
50 | #include "f_serial.c" | ||
51 | #include "f_phonet.c" | ||
52 | #include "u_ether.c" | ||
53 | |||
54 | /*-------------------------------------------------------------------------*/ | ||
55 | |||
56 | #define NOKIA_VENDOR_ID 0x0421 /* Nokia */ | ||
57 | #define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */ | ||
58 | |||
59 | /* string IDs are assigned dynamically */ | ||
60 | |||
61 | #define STRING_MANUFACTURER_IDX 0 | ||
62 | #define STRING_PRODUCT_IDX 1 | ||
63 | #define STRING_DESCRIPTION_IDX 2 | ||
64 | |||
65 | static char manufacturer_nokia[] = "Nokia"; | ||
66 | static const char product_nokia[] = NOKIA_LONG_NAME; | ||
67 | static const char description_nokia[] = "PC-Suite Configuration"; | ||
68 | |||
69 | static struct usb_string strings_dev[] = { | ||
70 | [STRING_MANUFACTURER_IDX].s = manufacturer_nokia, | ||
71 | [STRING_PRODUCT_IDX].s = NOKIA_LONG_NAME, | ||
72 | [STRING_DESCRIPTION_IDX].s = description_nokia, | ||
73 | { } /* end of list */ | ||
74 | }; | ||
75 | |||
76 | static struct usb_gadget_strings stringtab_dev = { | ||
77 | .language = 0x0409, /* en-us */ | ||
78 | .strings = strings_dev, | ||
79 | }; | ||
80 | |||
81 | static struct usb_gadget_strings *dev_strings[] = { | ||
82 | &stringtab_dev, | ||
83 | NULL, | ||
84 | }; | ||
85 | |||
86 | static struct usb_device_descriptor device_desc = { | ||
87 | .bLength = USB_DT_DEVICE_SIZE, | ||
88 | .bDescriptorType = USB_DT_DEVICE, | ||
89 | .bcdUSB = __constant_cpu_to_le16(0x0200), | ||
90 | .bDeviceClass = USB_CLASS_COMM, | ||
91 | .idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID), | ||
92 | .idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID), | ||
93 | /* .iManufacturer = DYNAMIC */ | ||
94 | /* .iProduct = DYNAMIC */ | ||
95 | .bNumConfigurations = 1, | ||
96 | }; | ||
97 | |||
98 | /*-------------------------------------------------------------------------*/ | ||
99 | |||
100 | /* Module */ | ||
101 | MODULE_DESCRIPTION("Nokia composite gadget driver for N900"); | ||
102 | MODULE_AUTHOR("Felipe Balbi"); | ||
103 | MODULE_LICENSE("GPL"); | ||
104 | |||
105 | /*-------------------------------------------------------------------------*/ | ||
106 | |||
107 | static u8 hostaddr[ETH_ALEN]; | ||
108 | |||
109 | static int __init nokia_bind_config(struct usb_configuration *c) | ||
110 | { | ||
111 | int status = 0; | ||
112 | |||
113 | status = phonet_bind_config(c); | ||
114 | if (status) | ||
115 | printk(KERN_DEBUG "could not bind phonet config\n"); | ||
116 | |||
117 | status = obex_bind_config(c, 0); | ||
118 | if (status) | ||
119 | printk(KERN_DEBUG "could not bind obex config %d\n", 0); | ||
120 | |||
121 | status = obex_bind_config(c, 1); | ||
122 | if (status) | ||
123 | printk(KERN_DEBUG "could not bind obex config %d\n", 0); | ||
124 | |||
125 | status = acm_bind_config(c, 2); | ||
126 | if (status) | ||
127 | printk(KERN_DEBUG "could not bind acm config\n"); | ||
128 | |||
129 | status = ecm_bind_config(c, hostaddr); | ||
130 | if (status) | ||
131 | printk(KERN_DEBUG "could not bind ecm config\n"); | ||
132 | |||
133 | return status; | ||
134 | } | ||
135 | |||
136 | static struct usb_configuration nokia_config_500ma_driver = { | ||
137 | .label = "Bus Powered", | ||
138 | .bind = nokia_bind_config, | ||
139 | .bConfigurationValue = 1, | ||
140 | /* .iConfiguration = DYNAMIC */ | ||
141 | .bmAttributes = USB_CONFIG_ATT_ONE, | ||
142 | .bMaxPower = 250, /* 500mA */ | ||
143 | }; | ||
144 | |||
145 | static struct usb_configuration nokia_config_100ma_driver = { | ||
146 | .label = "Self Powered", | ||
147 | .bind = nokia_bind_config, | ||
148 | .bConfigurationValue = 2, | ||
149 | /* .iConfiguration = DYNAMIC */ | ||
150 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
151 | .bMaxPower = 50, /* 100 mA */ | ||
152 | }; | ||
153 | |||
154 | static int __init nokia_bind(struct usb_composite_dev *cdev) | ||
155 | { | ||
156 | int gcnum; | ||
157 | struct usb_gadget *gadget = cdev->gadget; | ||
158 | int status; | ||
159 | |||
160 | status = gphonet_setup(cdev->gadget); | ||
161 | if (status < 0) | ||
162 | goto err_phonet; | ||
163 | |||
164 | status = gserial_setup(cdev->gadget, 3); | ||
165 | if (status < 0) | ||
166 | goto err_serial; | ||
167 | |||
168 | status = gether_setup(cdev->gadget, hostaddr); | ||
169 | if (status < 0) | ||
170 | goto err_ether; | ||
171 | |||
172 | status = usb_string_id(cdev); | ||
173 | if (status < 0) | ||
174 | goto err_usb; | ||
175 | strings_dev[STRING_MANUFACTURER_IDX].id = status; | ||
176 | |||
177 | device_desc.iManufacturer = status; | ||
178 | |||
179 | status = usb_string_id(cdev); | ||
180 | if (status < 0) | ||
181 | goto err_usb; | ||
182 | strings_dev[STRING_PRODUCT_IDX].id = status; | ||
183 | |||
184 | device_desc.iProduct = status; | ||
185 | |||
186 | /* config description */ | ||
187 | status = usb_string_id(cdev); | ||
188 | if (status < 0) | ||
189 | goto err_usb; | ||
190 | strings_dev[STRING_DESCRIPTION_IDX].id = status; | ||
191 | |||
192 | nokia_config_500ma_driver.iConfiguration = status; | ||
193 | nokia_config_100ma_driver.iConfiguration = status; | ||
194 | |||
195 | /* set up other descriptors */ | ||
196 | gcnum = usb_gadget_controller_number(gadget); | ||
197 | if (gcnum >= 0) | ||
198 | device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM); | ||
199 | else { | ||
200 | /* this should only work with hw that supports altsettings | ||
201 | * and several endpoints, anything else, panic. | ||
202 | */ | ||
203 | pr_err("nokia_bind: controller '%s' not recognized\n", | ||
204 | gadget->name); | ||
205 | goto err_usb; | ||
206 | } | ||
207 | |||
208 | /* finaly register the configuration */ | ||
209 | status = usb_add_config(cdev, &nokia_config_500ma_driver); | ||
210 | if (status < 0) | ||
211 | goto err_usb; | ||
212 | |||
213 | status = usb_add_config(cdev, &nokia_config_100ma_driver); | ||
214 | if (status < 0) | ||
215 | goto err_usb; | ||
216 | |||
217 | dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME); | ||
218 | |||
219 | return 0; | ||
220 | |||
221 | err_usb: | ||
222 | gether_cleanup(); | ||
223 | err_ether: | ||
224 | gserial_cleanup(); | ||
225 | err_serial: | ||
226 | gphonet_cleanup(); | ||
227 | err_phonet: | ||
228 | return status; | ||
229 | } | ||
230 | |||
231 | static int __exit nokia_unbind(struct usb_composite_dev *cdev) | ||
232 | { | ||
233 | gphonet_cleanup(); | ||
234 | gserial_cleanup(); | ||
235 | gether_cleanup(); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static struct usb_composite_driver nokia_driver = { | ||
241 | .name = "g_nokia", | ||
242 | .dev = &device_desc, | ||
243 | .strings = dev_strings, | ||
244 | .bind = nokia_bind, | ||
245 | .unbind = __exit_p(nokia_unbind), | ||
246 | }; | ||
247 | |||
248 | static int __init nokia_init(void) | ||
249 | { | ||
250 | return usb_composite_register(&nokia_driver); | ||
251 | } | ||
252 | module_init(nokia_init); | ||
253 | |||
254 | static void __exit nokia_cleanup(void) | ||
255 | { | ||
256 | usb_composite_unregister(&nokia_driver); | ||
257 | } | ||
258 | module_exit(nokia_cleanup); | ||
259 | |||
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 2d867fd22413..6b8bf8c781c4 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -949,12 +949,6 @@ printer_set_config(struct printer_dev *dev, unsigned number) | |||
949 | int result = 0; | 949 | int result = 0; |
950 | struct usb_gadget *gadget = dev->gadget; | 950 | struct usb_gadget *gadget = dev->gadget; |
951 | 951 | ||
952 | if (gadget_is_sa1100(gadget) && dev->config) { | ||
953 | /* tx fifo is full, but we can't clear it...*/ | ||
954 | INFO(dev, "can't change configurations\n"); | ||
955 | return -ESPIPE; | ||
956 | } | ||
957 | |||
958 | switch (number) { | 952 | switch (number) { |
959 | case DEV_CONFIG_VALUE: | 953 | case DEV_CONFIG_VALUE: |
960 | result = 0; | 954 | result = 0; |
@@ -1033,12 +1027,6 @@ set_interface(struct printer_dev *dev, unsigned number) | |||
1033 | { | 1027 | { |
1034 | int result = 0; | 1028 | int result = 0; |
1035 | 1029 | ||
1036 | if (gadget_is_sa1100(dev->gadget) && dev->interface < 0) { | ||
1037 | /* tx fifo is full, but we can't clear it...*/ | ||
1038 | INFO(dev, "can't change interfaces\n"); | ||
1039 | return -ESPIPE; | ||
1040 | } | ||
1041 | |||
1042 | /* Free the current interface */ | 1030 | /* Free the current interface */ |
1043 | switch (dev->interface) { | 1031 | switch (dev->interface) { |
1044 | case PRINTER_INTERFACE: | 1032 | case PRINTER_INTERFACE: |
@@ -1392,12 +1380,6 @@ printer_bind(struct usb_gadget *gadget) | |||
1392 | goto fail; | 1380 | goto fail; |
1393 | } | 1381 | } |
1394 | 1382 | ||
1395 | if (gadget_is_sa1100(gadget)) { | ||
1396 | /* hardware can't write zero length packets. */ | ||
1397 | ERROR(dev, "SA1100 controller is unsupport by this driver\n"); | ||
1398 | goto fail; | ||
1399 | } | ||
1400 | |||
1401 | gcnum = usb_gadget_controller_number(gadget); | 1383 | gcnum = usb_gadget_controller_number(gadget); |
1402 | if (gcnum >= 0) { | 1384 | if (gcnum >= 0) { |
1403 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); | 1385 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index adda1208a1ec..05b892c3d686 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -742,13 +742,17 @@ static void ep_del_request(struct pxa_ep *ep, struct pxa27x_request *req) | |||
742 | * @ep: pxa physical endpoint | 742 | * @ep: pxa physical endpoint |
743 | * @req: pxa request | 743 | * @req: pxa request |
744 | * @status: usb request status sent to gadget API | 744 | * @status: usb request status sent to gadget API |
745 | * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held | ||
745 | * | 746 | * |
746 | * Context: ep->lock held | 747 | * Context: ep->lock held if flags not NULL, else ep->lock released |
747 | * | 748 | * |
748 | * Retire a pxa27x usb request. Endpoint must be locked. | 749 | * Retire a pxa27x usb request. Endpoint must be locked. |
749 | */ | 750 | */ |
750 | static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) | 751 | static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status, |
752 | unsigned long *pflags) | ||
751 | { | 753 | { |
754 | unsigned long flags; | ||
755 | |||
752 | ep_del_request(ep, req); | 756 | ep_del_request(ep, req); |
753 | if (likely(req->req.status == -EINPROGRESS)) | 757 | if (likely(req->req.status == -EINPROGRESS)) |
754 | req->req.status = status; | 758 | req->req.status = status; |
@@ -760,38 +764,48 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) | |||
760 | &req->req, status, | 764 | &req->req, status, |
761 | req->req.actual, req->req.length); | 765 | req->req.actual, req->req.length); |
762 | 766 | ||
767 | if (pflags) | ||
768 | spin_unlock_irqrestore(&ep->lock, *pflags); | ||
769 | local_irq_save(flags); | ||
763 | req->req.complete(&req->udc_usb_ep->usb_ep, &req->req); | 770 | req->req.complete(&req->udc_usb_ep->usb_ep, &req->req); |
771 | local_irq_restore(flags); | ||
772 | if (pflags) | ||
773 | spin_lock_irqsave(&ep->lock, *pflags); | ||
764 | } | 774 | } |
765 | 775 | ||
766 | /** | 776 | /** |
767 | * ep_end_out_req - Ends endpoint OUT request | 777 | * ep_end_out_req - Ends endpoint OUT request |
768 | * @ep: physical endpoint | 778 | * @ep: physical endpoint |
769 | * @req: pxa request | 779 | * @req: pxa request |
780 | * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held | ||
770 | * | 781 | * |
771 | * Context: ep->lock held | 782 | * Context: ep->lock held or released (see req_done()) |
772 | * | 783 | * |
773 | * Ends endpoint OUT request (completes usb request). | 784 | * Ends endpoint OUT request (completes usb request). |
774 | */ | 785 | */ |
775 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 786 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req, |
787 | unsigned long *pflags) | ||
776 | { | 788 | { |
777 | inc_ep_stats_reqs(ep, !USB_DIR_IN); | 789 | inc_ep_stats_reqs(ep, !USB_DIR_IN); |
778 | req_done(ep, req, 0); | 790 | req_done(ep, req, 0, pflags); |
779 | } | 791 | } |
780 | 792 | ||
781 | /** | 793 | /** |
782 | * ep0_end_out_req - Ends control endpoint OUT request (ends data stage) | 794 | * ep0_end_out_req - Ends control endpoint OUT request (ends data stage) |
783 | * @ep: physical endpoint | 795 | * @ep: physical endpoint |
784 | * @req: pxa request | 796 | * @req: pxa request |
797 | * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held | ||
785 | * | 798 | * |
786 | * Context: ep->lock held | 799 | * Context: ep->lock held or released (see req_done()) |
787 | * | 800 | * |
788 | * Ends control endpoint OUT request (completes usb request), and puts | 801 | * Ends control endpoint OUT request (completes usb request), and puts |
789 | * control endpoint into idle state | 802 | * control endpoint into idle state |
790 | */ | 803 | */ |
791 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 804 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req, |
805 | unsigned long *pflags) | ||
792 | { | 806 | { |
793 | set_ep0state(ep->dev, OUT_STATUS_STAGE); | 807 | set_ep0state(ep->dev, OUT_STATUS_STAGE); |
794 | ep_end_out_req(ep, req); | 808 | ep_end_out_req(ep, req, pflags); |
795 | ep0_idle(ep->dev); | 809 | ep0_idle(ep->dev); |
796 | } | 810 | } |
797 | 811 | ||
@@ -799,31 +813,35 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
799 | * ep_end_in_req - Ends endpoint IN request | 813 | * ep_end_in_req - Ends endpoint IN request |
800 | * @ep: physical endpoint | 814 | * @ep: physical endpoint |
801 | * @req: pxa request | 815 | * @req: pxa request |
816 | * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held | ||
802 | * | 817 | * |
803 | * Context: ep->lock held | 818 | * Context: ep->lock held or released (see req_done()) |
804 | * | 819 | * |
805 | * Ends endpoint IN request (completes usb request). | 820 | * Ends endpoint IN request (completes usb request). |
806 | */ | 821 | */ |
807 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 822 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req, |
823 | unsigned long *pflags) | ||
808 | { | 824 | { |
809 | inc_ep_stats_reqs(ep, USB_DIR_IN); | 825 | inc_ep_stats_reqs(ep, USB_DIR_IN); |
810 | req_done(ep, req, 0); | 826 | req_done(ep, req, 0, pflags); |
811 | } | 827 | } |
812 | 828 | ||
813 | /** | 829 | /** |
814 | * ep0_end_in_req - Ends control endpoint IN request (ends data stage) | 830 | * ep0_end_in_req - Ends control endpoint IN request (ends data stage) |
815 | * @ep: physical endpoint | 831 | * @ep: physical endpoint |
816 | * @req: pxa request | 832 | * @req: pxa request |
833 | * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held | ||
817 | * | 834 | * |
818 | * Context: ep->lock held | 835 | * Context: ep->lock held or released (see req_done()) |
819 | * | 836 | * |
820 | * Ends control endpoint IN request (completes usb request), and puts | 837 | * Ends control endpoint IN request (completes usb request), and puts |
821 | * control endpoint into status state | 838 | * control endpoint into status state |
822 | */ | 839 | */ |
823 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 840 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req, |
841 | unsigned long *pflags) | ||
824 | { | 842 | { |
825 | set_ep0state(ep->dev, IN_STATUS_STAGE); | 843 | set_ep0state(ep->dev, IN_STATUS_STAGE); |
826 | ep_end_in_req(ep, req); | 844 | ep_end_in_req(ep, req, pflags); |
827 | } | 845 | } |
828 | 846 | ||
829 | /** | 847 | /** |
@@ -831,19 +849,22 @@ static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
831 | * @ep: pxa endpoint | 849 | * @ep: pxa endpoint |
832 | * @status: usb request status | 850 | * @status: usb request status |
833 | * | 851 | * |
834 | * Context: ep->lock held | 852 | * Context: ep->lock released |
835 | * | 853 | * |
836 | * Dequeues all requests on an endpoint. As a side effect, interrupts will be | 854 | * Dequeues all requests on an endpoint. As a side effect, interrupts will be |
837 | * disabled on that endpoint (because no more requests). | 855 | * disabled on that endpoint (because no more requests). |
838 | */ | 856 | */ |
839 | static void nuke(struct pxa_ep *ep, int status) | 857 | static void nuke(struct pxa_ep *ep, int status) |
840 | { | 858 | { |
841 | struct pxa27x_request *req; | 859 | struct pxa27x_request *req; |
860 | unsigned long flags; | ||
842 | 861 | ||
862 | spin_lock_irqsave(&ep->lock, flags); | ||
843 | while (!list_empty(&ep->queue)) { | 863 | while (!list_empty(&ep->queue)) { |
844 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | 864 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); |
845 | req_done(ep, req, status); | 865 | req_done(ep, req, status, &flags); |
846 | } | 866 | } |
867 | spin_unlock_irqrestore(&ep->lock, flags); | ||
847 | } | 868 | } |
848 | 869 | ||
849 | /** | 870 | /** |
@@ -1123,6 +1144,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1123 | int rc = 0; | 1144 | int rc = 0; |
1124 | int is_first_req; | 1145 | int is_first_req; |
1125 | unsigned length; | 1146 | unsigned length; |
1147 | int recursion_detected; | ||
1126 | 1148 | ||
1127 | req = container_of(_req, struct pxa27x_request, req); | 1149 | req = container_of(_req, struct pxa27x_request, req); |
1128 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | 1150 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); |
@@ -1152,6 +1174,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1152 | return -EMSGSIZE; | 1174 | return -EMSGSIZE; |
1153 | 1175 | ||
1154 | spin_lock_irqsave(&ep->lock, flags); | 1176 | spin_lock_irqsave(&ep->lock, flags); |
1177 | recursion_detected = ep->in_handle_ep; | ||
1155 | 1178 | ||
1156 | is_first_req = list_empty(&ep->queue); | 1179 | is_first_req = list_empty(&ep->queue); |
1157 | ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n", | 1180 | ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n", |
@@ -1161,12 +1184,12 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1161 | if (!ep->enabled) { | 1184 | if (!ep->enabled) { |
1162 | _req->status = -ESHUTDOWN; | 1185 | _req->status = -ESHUTDOWN; |
1163 | rc = -ESHUTDOWN; | 1186 | rc = -ESHUTDOWN; |
1164 | goto out; | 1187 | goto out_locked; |
1165 | } | 1188 | } |
1166 | 1189 | ||
1167 | if (req->in_use) { | 1190 | if (req->in_use) { |
1168 | ep_err(ep, "refusing to queue req %p (already queued)\n", req); | 1191 | ep_err(ep, "refusing to queue req %p (already queued)\n", req); |
1169 | goto out; | 1192 | goto out_locked; |
1170 | } | 1193 | } |
1171 | 1194 | ||
1172 | length = _req->length; | 1195 | length = _req->length; |
@@ -1174,12 +1197,13 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1174 | _req->actual = 0; | 1197 | _req->actual = 0; |
1175 | 1198 | ||
1176 | ep_add_request(ep, req); | 1199 | ep_add_request(ep, req); |
1200 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1177 | 1201 | ||
1178 | if (is_ep0(ep)) { | 1202 | if (is_ep0(ep)) { |
1179 | switch (dev->ep0state) { | 1203 | switch (dev->ep0state) { |
1180 | case WAIT_ACK_SET_CONF_INTERF: | 1204 | case WAIT_ACK_SET_CONF_INTERF: |
1181 | if (length == 0) { | 1205 | if (length == 0) { |
1182 | ep_end_in_req(ep, req); | 1206 | ep_end_in_req(ep, req, NULL); |
1183 | } else { | 1207 | } else { |
1184 | ep_err(ep, "got a request of %d bytes while" | 1208 | ep_err(ep, "got a request of %d bytes while" |
1185 | "in state WAIT_ACK_SET_CONF_INTERF\n", | 1209 | "in state WAIT_ACK_SET_CONF_INTERF\n", |
@@ -1192,12 +1216,12 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1192 | case IN_DATA_STAGE: | 1216 | case IN_DATA_STAGE: |
1193 | if (!ep_is_full(ep)) | 1217 | if (!ep_is_full(ep)) |
1194 | if (write_ep0_fifo(ep, req)) | 1218 | if (write_ep0_fifo(ep, req)) |
1195 | ep0_end_in_req(ep, req); | 1219 | ep0_end_in_req(ep, req, NULL); |
1196 | break; | 1220 | break; |
1197 | case OUT_DATA_STAGE: | 1221 | case OUT_DATA_STAGE: |
1198 | if ((length == 0) || !epout_has_pkt(ep)) | 1222 | if ((length == 0) || !epout_has_pkt(ep)) |
1199 | if (read_ep0_fifo(ep, req)) | 1223 | if (read_ep0_fifo(ep, req)) |
1200 | ep0_end_out_req(ep, req); | 1224 | ep0_end_out_req(ep, req, NULL); |
1201 | break; | 1225 | break; |
1202 | default: | 1226 | default: |
1203 | ep_err(ep, "odd state %s to send me a request\n", | 1227 | ep_err(ep, "odd state %s to send me a request\n", |
@@ -1207,12 +1231,15 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1207 | break; | 1231 | break; |
1208 | } | 1232 | } |
1209 | } else { | 1233 | } else { |
1210 | handle_ep(ep); | 1234 | if (!recursion_detected) |
1235 | handle_ep(ep); | ||
1211 | } | 1236 | } |
1212 | 1237 | ||
1213 | out: | 1238 | out: |
1214 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1215 | return rc; | 1239 | return rc; |
1240 | out_locked: | ||
1241 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1242 | goto out; | ||
1216 | } | 1243 | } |
1217 | 1244 | ||
1218 | /** | 1245 | /** |
@@ -1242,13 +1269,14 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1242 | /* make sure it's actually queued on this endpoint */ | 1269 | /* make sure it's actually queued on this endpoint */ |
1243 | list_for_each_entry(req, &ep->queue, queue) { | 1270 | list_for_each_entry(req, &ep->queue, queue) { |
1244 | if (&req->req == _req) { | 1271 | if (&req->req == _req) { |
1245 | req_done(ep, req, -ECONNRESET); | ||
1246 | rc = 0; | 1272 | rc = 0; |
1247 | break; | 1273 | break; |
1248 | } | 1274 | } |
1249 | } | 1275 | } |
1250 | 1276 | ||
1251 | spin_unlock_irqrestore(&ep->lock, flags); | 1277 | spin_unlock_irqrestore(&ep->lock, flags); |
1278 | if (!rc) | ||
1279 | req_done(ep, req, -ECONNRESET, NULL); | ||
1252 | return rc; | 1280 | return rc; |
1253 | } | 1281 | } |
1254 | 1282 | ||
@@ -1445,7 +1473,6 @@ static int pxa_ep_disable(struct usb_ep *_ep) | |||
1445 | { | 1473 | { |
1446 | struct pxa_ep *ep; | 1474 | struct pxa_ep *ep; |
1447 | struct udc_usb_ep *udc_usb_ep; | 1475 | struct udc_usb_ep *udc_usb_ep; |
1448 | unsigned long flags; | ||
1449 | 1476 | ||
1450 | if (!_ep) | 1477 | if (!_ep) |
1451 | return -EINVAL; | 1478 | return -EINVAL; |
@@ -1455,10 +1482,8 @@ static int pxa_ep_disable(struct usb_ep *_ep) | |||
1455 | if (!ep || is_ep0(ep) || !list_empty(&ep->queue)) | 1482 | if (!ep || is_ep0(ep) || !list_empty(&ep->queue)) |
1456 | return -EINVAL; | 1483 | return -EINVAL; |
1457 | 1484 | ||
1458 | spin_lock_irqsave(&ep->lock, flags); | ||
1459 | ep->enabled = 0; | 1485 | ep->enabled = 0; |
1460 | nuke(ep, -ESHUTDOWN); | 1486 | nuke(ep, -ESHUTDOWN); |
1461 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1462 | 1487 | ||
1463 | pxa_ep_fifo_flush(_ep); | 1488 | pxa_ep_fifo_flush(_ep); |
1464 | udc_usb_ep->pxa_ep = NULL; | 1489 | udc_usb_ep->pxa_ep = NULL; |
@@ -1907,8 +1932,10 @@ static void handle_ep0_ctrl_req(struct pxa_udc *udc, | |||
1907 | } u; | 1932 | } u; |
1908 | int i; | 1933 | int i; |
1909 | int have_extrabytes = 0; | 1934 | int have_extrabytes = 0; |
1935 | unsigned long flags; | ||
1910 | 1936 | ||
1911 | nuke(ep, -EPROTO); | 1937 | nuke(ep, -EPROTO); |
1938 | spin_lock_irqsave(&ep->lock, flags); | ||
1912 | 1939 | ||
1913 | /* | 1940 | /* |
1914 | * In the PXA320 manual, in the section about Back-to-Back setup | 1941 | * In the PXA320 manual, in the section about Back-to-Back setup |
@@ -1947,10 +1974,13 @@ static void handle_ep0_ctrl_req(struct pxa_udc *udc, | |||
1947 | /* Tell UDC to enter Data Stage */ | 1974 | /* Tell UDC to enter Data Stage */ |
1948 | ep_write_UDCCSR(ep, UDCCSR0_SA | UDCCSR0_OPC); | 1975 | ep_write_UDCCSR(ep, UDCCSR0_SA | UDCCSR0_OPC); |
1949 | 1976 | ||
1977 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1950 | i = udc->driver->setup(&udc->gadget, &u.r); | 1978 | i = udc->driver->setup(&udc->gadget, &u.r); |
1979 | spin_lock_irqsave(&ep->lock, flags); | ||
1951 | if (i < 0) | 1980 | if (i < 0) |
1952 | goto stall; | 1981 | goto stall; |
1953 | out: | 1982 | out: |
1983 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1954 | return; | 1984 | return; |
1955 | stall: | 1985 | stall: |
1956 | ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n", | 1986 | ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n", |
@@ -2055,13 +2085,13 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) | |||
2055 | if (req && !ep_is_full(ep)) | 2085 | if (req && !ep_is_full(ep)) |
2056 | completed = write_ep0_fifo(ep, req); | 2086 | completed = write_ep0_fifo(ep, req); |
2057 | if (completed) | 2087 | if (completed) |
2058 | ep0_end_in_req(ep, req); | 2088 | ep0_end_in_req(ep, req, NULL); |
2059 | break; | 2089 | break; |
2060 | case OUT_DATA_STAGE: /* SET_DESCRIPTOR */ | 2090 | case OUT_DATA_STAGE: /* SET_DESCRIPTOR */ |
2061 | if (epout_has_pkt(ep) && req) | 2091 | if (epout_has_pkt(ep) && req) |
2062 | completed = read_ep0_fifo(ep, req); | 2092 | completed = read_ep0_fifo(ep, req); |
2063 | if (completed) | 2093 | if (completed) |
2064 | ep0_end_out_req(ep, req); | 2094 | ep0_end_out_req(ep, req, NULL); |
2065 | break; | 2095 | break; |
2066 | case STALL: | 2096 | case STALL: |
2067 | ep_write_UDCCSR(ep, UDCCSR0_FST); | 2097 | ep_write_UDCCSR(ep, UDCCSR0_FST); |
@@ -2091,7 +2121,7 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) | |||
2091 | * Tries to transfer all pending request data into the endpoint and/or | 2121 | * Tries to transfer all pending request data into the endpoint and/or |
2092 | * transfer all pending data in the endpoint into usb requests. | 2122 | * transfer all pending data in the endpoint into usb requests. |
2093 | * | 2123 | * |
2094 | * Is always called when in_interrupt() or with ep->lock held. | 2124 | * Is always called when in_interrupt() and with ep->lock released. |
2095 | */ | 2125 | */ |
2096 | static void handle_ep(struct pxa_ep *ep) | 2126 | static void handle_ep(struct pxa_ep *ep) |
2097 | { | 2127 | { |
@@ -2100,10 +2130,17 @@ static void handle_ep(struct pxa_ep *ep) | |||
2100 | u32 udccsr; | 2130 | u32 udccsr; |
2101 | int is_in = ep->dir_in; | 2131 | int is_in = ep->dir_in; |
2102 | int loop = 0; | 2132 | int loop = 0; |
2133 | unsigned long flags; | ||
2134 | |||
2135 | spin_lock_irqsave(&ep->lock, flags); | ||
2136 | if (ep->in_handle_ep) | ||
2137 | goto recursion_detected; | ||
2138 | ep->in_handle_ep = 1; | ||
2103 | 2139 | ||
2104 | do { | 2140 | do { |
2105 | completed = 0; | 2141 | completed = 0; |
2106 | udccsr = udc_ep_readl(ep, UDCCSR); | 2142 | udccsr = udc_ep_readl(ep, UDCCSR); |
2143 | |||
2107 | if (likely(!list_empty(&ep->queue))) | 2144 | if (likely(!list_empty(&ep->queue))) |
2108 | req = list_entry(ep->queue.next, | 2145 | req = list_entry(ep->queue.next, |
2109 | struct pxa27x_request, queue); | 2146 | struct pxa27x_request, queue); |
@@ -2122,15 +2159,22 @@ static void handle_ep(struct pxa_ep *ep) | |||
2122 | if (unlikely(is_in)) { | 2159 | if (unlikely(is_in)) { |
2123 | if (likely(!ep_is_full(ep))) | 2160 | if (likely(!ep_is_full(ep))) |
2124 | completed = write_fifo(ep, req); | 2161 | completed = write_fifo(ep, req); |
2125 | if (completed) | ||
2126 | ep_end_in_req(ep, req); | ||
2127 | } else { | 2162 | } else { |
2128 | if (likely(epout_has_pkt(ep))) | 2163 | if (likely(epout_has_pkt(ep))) |
2129 | completed = read_fifo(ep, req); | 2164 | completed = read_fifo(ep, req); |
2130 | if (completed) | 2165 | } |
2131 | ep_end_out_req(ep, req); | 2166 | |
2167 | if (completed) { | ||
2168 | if (is_in) | ||
2169 | ep_end_in_req(ep, req, &flags); | ||
2170 | else | ||
2171 | ep_end_out_req(ep, req, &flags); | ||
2132 | } | 2172 | } |
2133 | } while (completed); | 2173 | } while (completed); |
2174 | |||
2175 | ep->in_handle_ep = 0; | ||
2176 | recursion_detected: | ||
2177 | spin_unlock_irqrestore(&ep->lock, flags); | ||
2134 | } | 2178 | } |
2135 | 2179 | ||
2136 | /** | 2180 | /** |
@@ -2218,9 +2262,13 @@ static void irq_handle_data(int irq, struct pxa_udc *udc) | |||
2218 | continue; | 2262 | continue; |
2219 | 2263 | ||
2220 | udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK)); | 2264 | udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK)); |
2221 | ep = &udc->pxa_ep[i]; | 2265 | |
2222 | ep->stats.irqs++; | 2266 | WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep)); |
2223 | handle_ep(ep); | 2267 | if (i < ARRAY_SIZE(udc->pxa_ep)) { |
2268 | ep = &udc->pxa_ep[i]; | ||
2269 | ep->stats.irqs++; | ||
2270 | handle_ep(ep); | ||
2271 | } | ||
2224 | } | 2272 | } |
2225 | 2273 | ||
2226 | for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) { | 2274 | for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) { |
@@ -2228,9 +2276,12 @@ static void irq_handle_data(int irq, struct pxa_udc *udc) | |||
2228 | if (!(udcisr1 & UDCISR_INT_MASK)) | 2276 | if (!(udcisr1 & UDCISR_INT_MASK)) |
2229 | continue; | 2277 | continue; |
2230 | 2278 | ||
2231 | ep = &udc->pxa_ep[i]; | 2279 | WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep)); |
2232 | ep->stats.irqs++; | 2280 | if (i < ARRAY_SIZE(udc->pxa_ep)) { |
2233 | handle_ep(ep); | 2281 | ep = &udc->pxa_ep[i]; |
2282 | ep->stats.irqs++; | ||
2283 | handle_ep(ep); | ||
2284 | } | ||
2234 | } | 2285 | } |
2235 | 2286 | ||
2236 | } | 2287 | } |
@@ -2439,7 +2490,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2439 | } | 2490 | } |
2440 | 2491 | ||
2441 | retval = -ENOMEM; | 2492 | retval = -ENOMEM; |
2442 | udc->regs = ioremap(regs->start, regs->end - regs->start + 1); | 2493 | udc->regs = ioremap(regs->start, resource_size(regs)); |
2443 | if (!udc->regs) { | 2494 | if (!udc->regs) { |
2444 | dev_err(&pdev->dev, "Unable to map UDC I/O memory\n"); | 2495 | dev_err(&pdev->dev, "Unable to map UDC I/O memory\n"); |
2445 | goto err_map; | 2496 | goto err_map; |
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index e25225e26586..ff61e4866e8a 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa27x_udc.h | |||
@@ -318,6 +318,11 @@ struct udc_usb_ep { | |||
318 | * @queue: requests queue | 318 | * @queue: requests queue |
319 | * @lock: lock to pxa_ep data (queues and stats) | 319 | * @lock: lock to pxa_ep data (queues and stats) |
320 | * @enabled: true when endpoint enabled (not stopped by gadget layer) | 320 | * @enabled: true when endpoint enabled (not stopped by gadget layer) |
321 | * @in_handle_ep: number of recursions of handle_ep() function | ||
322 | * Prevents deadlocks or infinite recursions of types : | ||
323 | * irq->handle_ep()->req_done()->req.complete()->pxa_ep_queue()->handle_ep() | ||
324 | * or | ||
325 | * pxa_ep_queue()->handle_ep()->req_done()->req.complete()->pxa_ep_queue() | ||
321 | * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX) | 326 | * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX) |
322 | * @name: endpoint name (for trace/debug purpose) | 327 | * @name: endpoint name (for trace/debug purpose) |
323 | * @dir_in: 1 if IN endpoint, 0 if OUT endpoint | 328 | * @dir_in: 1 if IN endpoint, 0 if OUT endpoint |
@@ -346,6 +351,7 @@ struct pxa_ep { | |||
346 | spinlock_t lock; /* Protects this structure */ | 351 | spinlock_t lock; /* Protects this structure */ |
347 | /* (queues, stats) */ | 352 | /* (queues, stats) */ |
348 | unsigned enabled:1; | 353 | unsigned enabled:1; |
354 | unsigned in_handle_ep:1; | ||
349 | 355 | ||
350 | unsigned idx:5; | 356 | unsigned idx:5; |
351 | char *name; | 357 | char *name; |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 5fc80a104150..7e5bf593d386 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -317,7 +317,8 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) | |||
317 | * | 317 | * |
318 | * Allocate a new USB request structure appropriate for the specified endpoint | 318 | * Allocate a new USB request structure appropriate for the specified endpoint |
319 | */ | 319 | */ |
320 | struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep, gfp_t flags) | 320 | static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep, |
321 | gfp_t flags) | ||
321 | { | 322 | { |
322 | struct s3c_hsotg_req *req; | 323 | struct s3c_hsotg_req *req; |
323 | 324 | ||
@@ -373,7 +374,7 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, | |||
373 | req->dma = DMA_ADDR_INVALID; | 374 | req->dma = DMA_ADDR_INVALID; |
374 | hs_req->mapped = 0; | 375 | hs_req->mapped = 0; |
375 | } else { | 376 | } else { |
376 | dma_sync_single(hsotg->dev, req->dma, req->length, dir); | 377 | dma_sync_single_for_cpu(hsotg->dev, req->dma, req->length, dir); |
377 | } | 378 | } |
378 | } | 379 | } |
379 | 380 | ||
@@ -755,7 +756,7 @@ static int s3c_hsotg_map_dma(struct s3c_hsotg *hsotg, | |||
755 | hs_req->mapped = 1; | 756 | hs_req->mapped = 1; |
756 | req->dma = dma; | 757 | req->dma = dma; |
757 | } else { | 758 | } else { |
758 | dma_sync_single(hsotg->dev, req->dma, req->length, dir); | 759 | dma_sync_single_for_cpu(hsotg->dev, req->dma, req->length, dir); |
759 | hs_req->mapped = 0; | 760 | hs_req->mapped = 0; |
760 | } | 761 | } |
761 | 762 | ||
@@ -1460,7 +1461,7 @@ static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg) | |||
1460 | * as the actual data should be sent to the memory directly and we turn | 1461 | * as the actual data should be sent to the memory directly and we turn |
1461 | * on the completion interrupts to get notifications of transfer completion. | 1462 | * on the completion interrupts to get notifications of transfer completion. |
1462 | */ | 1463 | */ |
1463 | void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg) | 1464 | static void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg) |
1464 | { | 1465 | { |
1465 | u32 grxstsr = readl(hsotg->regs + S3C_GRXSTSP); | 1466 | u32 grxstsr = readl(hsotg->regs + S3C_GRXSTSP); |
1466 | u32 epnum, status, size; | 1467 | u32 epnum, status, size; |
@@ -3094,7 +3095,7 @@ static void s3c_hsotg_gate(struct platform_device *pdev, bool on) | |||
3094 | local_irq_restore(flags); | 3095 | local_irq_restore(flags); |
3095 | } | 3096 | } |
3096 | 3097 | ||
3097 | struct s3c_hsotg_plat s3c_hsotg_default_pdata; | 3098 | static struct s3c_hsotg_plat s3c_hsotg_default_pdata; |
3098 | 3099 | ||
3099 | static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | 3100 | static int __devinit s3c_hsotg_probe(struct platform_device *pdev) |
3100 | { | 3101 | { |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 2fc02bd95848..84ca195c2d10 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -746,6 +746,10 @@ static const struct net_device_ops eth_netdev_ops = { | |||
746 | .ndo_validate_addr = eth_validate_addr, | 746 | .ndo_validate_addr = eth_validate_addr, |
747 | }; | 747 | }; |
748 | 748 | ||
749 | static struct device_type gadget_type = { | ||
750 | .name = "gadget", | ||
751 | }; | ||
752 | |||
749 | /** | 753 | /** |
750 | * gether_setup - initialize one ethernet-over-usb link | 754 | * gether_setup - initialize one ethernet-over-usb link |
751 | * @g: gadget to associated with these links | 755 | * @g: gadget to associated with these links |
@@ -808,6 +812,7 @@ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) | |||
808 | 812 | ||
809 | dev->gadget = g; | 813 | dev->gadget = g; |
810 | SET_NETDEV_DEV(net, &g->dev); | 814 | SET_NETDEV_DEV(net, &g->dev); |
815 | SET_NETDEV_DEVTYPE(net, &gadget_type); | ||
811 | 816 | ||
812 | status = register_netdev(net); | 817 | status = register_netdev(net); |
813 | if (status < 0) { | 818 | if (status < 0) { |
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h index fd55f450bc0e..3c8c0c9f9d72 100644 --- a/drivers/usb/gadget/u_ether.h +++ b/drivers/usb/gadget/u_ether.h | |||
@@ -93,13 +93,6 @@ static inline bool can_support_ecm(struct usb_gadget *gadget) | |||
93 | if (!gadget_supports_altsettings(gadget)) | 93 | if (!gadget_supports_altsettings(gadget)) |
94 | return false; | 94 | return false; |
95 | 95 | ||
96 | /* SA1100 can do ECM, *without* status endpoint ... but we'll | ||
97 | * only use it in non-ECM mode for backwards compatibility | ||
98 | * (and since we currently require a status endpoint) | ||
99 | */ | ||
100 | if (gadget_is_sa1100(gadget)) | ||
101 | return false; | ||
102 | |||
103 | /* Everything else is *presumably* fine ... but this is a bit | 96 | /* Everything else is *presumably* fine ... but this is a bit |
104 | * chancy, so be **CERTAIN** there are no hardware issues with | 97 | * chancy, so be **CERTAIN** there are no hardware issues with |
105 | * your controller. Add it above if it can't handle CDC. | 98 | * your controller. Add it above if it can't handle CDC. |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 2d772401b7ad..fac81ee193dd 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -297,12 +297,10 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
297 | */ | 297 | */ |
298 | if (loopdefault) { | 298 | if (loopdefault) { |
299 | loopback_add(cdev, autoresume != 0); | 299 | loopback_add(cdev, autoresume != 0); |
300 | if (!gadget_is_sh(gadget)) | 300 | sourcesink_add(cdev, autoresume != 0); |
301 | sourcesink_add(cdev, autoresume != 0); | ||
302 | } else { | 301 | } else { |
303 | sourcesink_add(cdev, autoresume != 0); | 302 | sourcesink_add(cdev, autoresume != 0); |
304 | if (!gadget_is_sh(gadget)) | 303 | loopback_add(cdev, autoresume != 0); |
305 | loopback_add(cdev, autoresume != 0); | ||
306 | } | 304 | } |
307 | 305 | ||
308 | gcnum = usb_gadget_controller_number(gadget); | 306 | gcnum = usb_gadget_controller_number(gadget); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2678a1624fcc..8d3df0397de3 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -399,3 +399,14 @@ config USB_HWA_HCD | |||
399 | 399 | ||
400 | To compile this driver a module, choose M here: the module | 400 | To compile this driver a module, choose M here: the module |
401 | will be called "hwa-hc". | 401 | will be called "hwa-hc". |
402 | |||
403 | config USB_IMX21_HCD | ||
404 | tristate "iMX21 HCD support" | ||
405 | depends on USB && ARM && MACH_MX21 | ||
406 | help | ||
407 | This driver enables support for the on-chip USB host in the | ||
408 | iMX21 processor. | ||
409 | |||
410 | To compile this driver as a module, choose M here: the | ||
411 | module will be called "imx21-hcd". | ||
412 | |||
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index f58b2494c44a..4e0c67f1f51b 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -32,3 +32,5 @@ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o | |||
32 | obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o | 32 | obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o |
33 | obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o | 33 | obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o |
34 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o | 34 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o |
35 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o | ||
36 | |||
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 87c1b7c34c0e..51bd0edf544f 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c | |||
@@ -149,7 +149,7 @@ static int __init ehci_atmel_drv_probe(struct platform_device *pdev) | |||
149 | goto fail_request_resource; | 149 | goto fail_request_resource; |
150 | } | 150 | } |
151 | hcd->rsrc_start = res->start; | 151 | hcd->rsrc_start = res->start; |
152 | hcd->rsrc_len = res->end - res->start + 1; | 152 | hcd->rsrc_len = resource_size(res); |
153 | 153 | ||
154 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | 154 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, |
155 | driver->description)) { | 155 | driver->description)) { |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index dbfb482a94e3..e3a74e75e822 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -121,6 +121,7 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
121 | { | 121 | { |
122 | struct usb_hcd *hcd; | 122 | struct usb_hcd *hcd; |
123 | struct ehci_hcd *ehci; | 123 | struct ehci_hcd *ehci; |
124 | struct resource *res; | ||
124 | int ret; | 125 | int ret; |
125 | 126 | ||
126 | if (usb_disabled()) | 127 | if (usb_disabled()) |
@@ -144,8 +145,9 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
144 | if (!hcd) | 145 | if (!hcd) |
145 | return -ENOMEM; | 146 | return -ENOMEM; |
146 | 147 | ||
147 | hcd->rsrc_start = pdev->resource[0].start; | 148 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
148 | hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; | 149 | hcd->rsrc_start = res->start; |
150 | hcd->rsrc_len = resource_size(res); | ||
149 | 151 | ||
150 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 152 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
151 | pr_debug("request_mem_region failed"); | 153 | pr_debug("request_mem_region failed"); |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 991174937db3..0e26aa13f158 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 MontaVista Software | 2 | * Copyright 2005-2009 MontaVista Software, Inc. |
3 | * Copyright 2008 Freescale Semiconductor, Inc. | ||
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 5 | * 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 | 6 | * under the terms of the GNU General Public License as published by the |
@@ -17,17 +18,20 @@ | |||
17 | * | 18 | * |
18 | * Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided | 19 | * Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided |
19 | * by Hunter Wu. | 20 | * by Hunter Wu. |
21 | * Power Management support by Dave Liu <daveliu@freescale.com>, | ||
22 | * Jerry Huang <Chang-Ming.Huang@freescale.com> and | ||
23 | * Anton Vorontsov <avorontsov@ru.mvista.com>. | ||
20 | */ | 24 | */ |
21 | 25 | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/pm.h> | ||
22 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
23 | #include <linux/fsl_devices.h> | 31 | #include <linux/fsl_devices.h> |
24 | 32 | ||
25 | #include "ehci-fsl.h" | 33 | #include "ehci-fsl.h" |
26 | 34 | ||
27 | /* FIXME: Power Management is un-ported so temporarily disable it */ | ||
28 | #undef CONFIG_PM | ||
29 | |||
30 | |||
31 | /* configure so an HC device and id are always provided */ | 35 | /* configure so an HC device and id are always provided */ |
32 | /* always called with process context; sleeping is OK */ | 36 | /* always called with process context; sleeping is OK */ |
33 | 37 | ||
@@ -40,8 +44,8 @@ | |||
40 | * Allocates basic resources for this USB host controller. | 44 | * Allocates basic resources for this USB host controller. |
41 | * | 45 | * |
42 | */ | 46 | */ |
43 | int usb_hcd_fsl_probe(const struct hc_driver *driver, | 47 | static int usb_hcd_fsl_probe(const struct hc_driver *driver, |
44 | struct platform_device *pdev) | 48 | struct platform_device *pdev) |
45 | { | 49 | { |
46 | struct fsl_usb2_platform_data *pdata; | 50 | struct fsl_usb2_platform_data *pdata; |
47 | struct usb_hcd *hcd; | 51 | struct usb_hcd *hcd; |
@@ -147,7 +151,8 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
147 | * Reverses the effect of usb_hcd_fsl_probe(). | 151 | * Reverses the effect of usb_hcd_fsl_probe(). |
148 | * | 152 | * |
149 | */ | 153 | */ |
150 | void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev) | 154 | static void usb_hcd_fsl_remove(struct usb_hcd *hcd, |
155 | struct platform_device *pdev) | ||
151 | { | 156 | { |
152 | usb_remove_hcd(hcd); | 157 | usb_remove_hcd(hcd); |
153 | iounmap(hcd->regs); | 158 | iounmap(hcd->regs); |
@@ -284,10 +289,81 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
284 | return retval; | 289 | return retval; |
285 | } | 290 | } |
286 | 291 | ||
292 | struct ehci_fsl { | ||
293 | struct ehci_hcd ehci; | ||
294 | |||
295 | #ifdef CONFIG_PM | ||
296 | /* Saved USB PHY settings, need to restore after deep sleep. */ | ||
297 | u32 usb_ctrl; | ||
298 | #endif | ||
299 | }; | ||
300 | |||
301 | #ifdef CONFIG_PM | ||
302 | |||
303 | static struct ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd) | ||
304 | { | ||
305 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
306 | |||
307 | return container_of(ehci, struct ehci_fsl, ehci); | ||
308 | } | ||
309 | |||
310 | static int ehci_fsl_drv_suspend(struct device *dev) | ||
311 | { | ||
312 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
313 | struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); | ||
314 | void __iomem *non_ehci = hcd->regs; | ||
315 | |||
316 | if (!fsl_deep_sleep()) | ||
317 | return 0; | ||
318 | |||
319 | ehci_fsl->usb_ctrl = in_be32(non_ehci + FSL_SOC_USB_CTRL); | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int ehci_fsl_drv_resume(struct device *dev) | ||
324 | { | ||
325 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
326 | struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); | ||
327 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
328 | void __iomem *non_ehci = hcd->regs; | ||
329 | |||
330 | if (!fsl_deep_sleep()) | ||
331 | return 0; | ||
332 | |||
333 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
334 | |||
335 | /* Restore USB PHY settings and enable the controller. */ | ||
336 | out_be32(non_ehci + FSL_SOC_USB_CTRL, ehci_fsl->usb_ctrl); | ||
337 | |||
338 | ehci_reset(ehci); | ||
339 | ehci_fsl_reinit(ehci); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int ehci_fsl_drv_restore(struct device *dev) | ||
345 | { | ||
346 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
347 | |||
348 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static struct dev_pm_ops ehci_fsl_pm_ops = { | ||
353 | .suspend = ehci_fsl_drv_suspend, | ||
354 | .resume = ehci_fsl_drv_resume, | ||
355 | .restore = ehci_fsl_drv_restore, | ||
356 | }; | ||
357 | |||
358 | #define EHCI_FSL_PM_OPS (&ehci_fsl_pm_ops) | ||
359 | #else | ||
360 | #define EHCI_FSL_PM_OPS NULL | ||
361 | #endif /* CONFIG_PM */ | ||
362 | |||
287 | static const struct hc_driver ehci_fsl_hc_driver = { | 363 | static const struct hc_driver ehci_fsl_hc_driver = { |
288 | .description = hcd_name, | 364 | .description = hcd_name, |
289 | .product_desc = "Freescale On-Chip EHCI Host Controller", | 365 | .product_desc = "Freescale On-Chip EHCI Host Controller", |
290 | .hcd_priv_size = sizeof(struct ehci_hcd), | 366 | .hcd_priv_size = sizeof(struct ehci_fsl), |
291 | 367 | ||
292 | /* | 368 | /* |
293 | * generic hardware linkage | 369 | * generic hardware linkage |
@@ -354,6 +430,7 @@ static struct platform_driver ehci_fsl_driver = { | |||
354 | .remove = ehci_fsl_drv_remove, | 430 | .remove = ehci_fsl_drv_remove, |
355 | .shutdown = usb_hcd_platform_shutdown, | 431 | .shutdown = usb_hcd_platform_shutdown, |
356 | .driver = { | 432 | .driver = { |
357 | .name = "fsl-ehci", | 433 | .name = "fsl-ehci", |
434 | .pm = EHCI_FSL_PM_OPS, | ||
358 | }, | 435 | }, |
359 | }; | 436 | }; |
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 35c56f40bdbb..23cd917088b4 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c | |||
@@ -162,6 +162,17 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) | |||
162 | goto err_ioremap; | 162 | goto err_ioremap; |
163 | } | 163 | } |
164 | 164 | ||
165 | /* call platform specific init function */ | ||
166 | if (pdata->init) { | ||
167 | ret = pdata->init(pdev); | ||
168 | if (ret) { | ||
169 | dev_err(dev, "platform init failed\n"); | ||
170 | goto err_init; | ||
171 | } | ||
172 | /* platforms need some time to settle changed IO settings */ | ||
173 | mdelay(10); | ||
174 | } | ||
175 | |||
165 | /* enable clocks */ | 176 | /* enable clocks */ |
166 | priv->usbclk = clk_get(dev, "usb"); | 177 | priv->usbclk = clk_get(dev, "usb"); |
167 | if (IS_ERR(priv->usbclk)) { | 178 | if (IS_ERR(priv->usbclk)) { |
@@ -192,18 +203,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) | |||
192 | if (ret < 0) | 203 | if (ret < 0) |
193 | goto err_init; | 204 | goto err_init; |
194 | 205 | ||
195 | /* call platform specific init function */ | ||
196 | if (pdata->init) { | ||
197 | ret = pdata->init(pdev); | ||
198 | if (ret) { | ||
199 | dev_err(dev, "platform init failed\n"); | ||
200 | goto err_init; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /* most platforms need some time to settle changed IO settings */ | ||
205 | mdelay(10); | ||
206 | |||
207 | /* Initialize the transceiver */ | 206 | /* Initialize the transceiver */ |
208 | if (pdata->otg) { | 207 | if (pdata->otg) { |
209 | pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; | 208 | pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 74d07f4e8b7d..f0282d6bb7aa 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -26,10 +26,9 @@ | |||
26 | * along with this program; if not, write to the Free Software | 26 | * along with this program; if not, write to the Free Software |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | * | 28 | * |
29 | * TODO (last updated Feb 23rd, 2009): | 29 | * TODO (last updated Feb 12, 2010): |
30 | * - add kernel-doc | 30 | * - add kernel-doc |
31 | * - enable AUTOIDLE | 31 | * - enable AUTOIDLE |
32 | * - move DPLL5 programming to clock fw | ||
33 | * - add suspend/resume | 32 | * - add suspend/resume |
34 | * - move workarounds to board-files | 33 | * - move workarounds to board-files |
35 | */ | 34 | */ |
@@ -37,6 +36,7 @@ | |||
37 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
38 | #include <linux/clk.h> | 37 | #include <linux/clk.h> |
39 | #include <linux/gpio.h> | 38 | #include <linux/gpio.h> |
39 | #include <linux/regulator/consumer.h> | ||
40 | #include <plat/usb.h> | 40 | #include <plat/usb.h> |
41 | 41 | ||
42 | /* | 42 | /* |
@@ -178,6 +178,11 @@ struct ehci_hcd_omap { | |||
178 | void __iomem *uhh_base; | 178 | void __iomem *uhh_base; |
179 | void __iomem *tll_base; | 179 | void __iomem *tll_base; |
180 | void __iomem *ehci_base; | 180 | void __iomem *ehci_base; |
181 | |||
182 | /* Regulators for USB PHYs. | ||
183 | * Each PHY can have a seperate regulator. | ||
184 | */ | ||
185 | struct regulator *regulator[OMAP3_HS_USB_PORTS]; | ||
181 | }; | 186 | }; |
182 | 187 | ||
183 | /*-------------------------------------------------------------------------*/ | 188 | /*-------------------------------------------------------------------------*/ |
@@ -546,6 +551,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
546 | 551 | ||
547 | int irq = platform_get_irq(pdev, 0); | 552 | int irq = platform_get_irq(pdev, 0); |
548 | int ret = -ENODEV; | 553 | int ret = -ENODEV; |
554 | int i; | ||
555 | char supply[7]; | ||
549 | 556 | ||
550 | if (!pdata) { | 557 | if (!pdata) { |
551 | dev_dbg(&pdev->dev, "missing platform_data\n"); | 558 | dev_dbg(&pdev->dev, "missing platform_data\n"); |
@@ -613,6 +620,21 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
613 | goto err_tll_ioremap; | 620 | goto err_tll_ioremap; |
614 | } | 621 | } |
615 | 622 | ||
623 | /* get ehci regulator and enable */ | ||
624 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | ||
625 | if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) { | ||
626 | omap->regulator[i] = NULL; | ||
627 | continue; | ||
628 | } | ||
629 | snprintf(supply, sizeof(supply), "hsusb%d", i); | ||
630 | omap->regulator[i] = regulator_get(omap->dev, supply); | ||
631 | if (IS_ERR(omap->regulator[i])) | ||
632 | dev_dbg(&pdev->dev, | ||
633 | "failed to get ehci port%d regulator\n", i); | ||
634 | else | ||
635 | regulator_enable(omap->regulator[i]); | ||
636 | } | ||
637 | |||
616 | ret = omap_start_ehc(omap, hcd); | 638 | ret = omap_start_ehc(omap, hcd); |
617 | if (ret) { | 639 | if (ret) { |
618 | dev_dbg(&pdev->dev, "failed to start ehci\n"); | 640 | dev_dbg(&pdev->dev, "failed to start ehci\n"); |
@@ -622,13 +644,12 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
622 | omap->ehci->regs = hcd->regs | 644 | omap->ehci->regs = hcd->regs |
623 | + HC_LENGTH(readl(&omap->ehci->caps->hc_capbase)); | 645 | + HC_LENGTH(readl(&omap->ehci->caps->hc_capbase)); |
624 | 646 | ||
647 | dbg_hcs_params(omap->ehci, "reset"); | ||
648 | dbg_hcc_params(omap->ehci, "reset"); | ||
649 | |||
625 | /* cache this readonly data; minimize chip reads */ | 650 | /* cache this readonly data; minimize chip reads */ |
626 | omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params); | 651 | omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params); |
627 | 652 | ||
628 | /* SET 1 micro-frame Interrupt interval */ | ||
629 | writel(readl(&omap->ehci->regs->command) | (1 << 16), | ||
630 | &omap->ehci->regs->command); | ||
631 | |||
632 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 653 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
633 | if (ret) { | 654 | if (ret) { |
634 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); | 655 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); |
@@ -641,6 +662,12 @@ err_add_hcd: | |||
641 | omap_stop_ehc(omap, hcd); | 662 | omap_stop_ehc(omap, hcd); |
642 | 663 | ||
643 | err_start: | 664 | err_start: |
665 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | ||
666 | if (omap->regulator[i]) { | ||
667 | regulator_disable(omap->regulator[i]); | ||
668 | regulator_put(omap->regulator[i]); | ||
669 | } | ||
670 | } | ||
644 | iounmap(omap->tll_base); | 671 | iounmap(omap->tll_base); |
645 | 672 | ||
646 | err_tll_ioremap: | 673 | err_tll_ioremap: |
@@ -674,13 +701,21 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
674 | { | 701 | { |
675 | struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); | 702 | struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); |
676 | struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); | 703 | struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); |
704 | int i; | ||
677 | 705 | ||
678 | usb_remove_hcd(hcd); | 706 | usb_remove_hcd(hcd); |
679 | omap_stop_ehc(omap, hcd); | 707 | omap_stop_ehc(omap, hcd); |
680 | iounmap(hcd->regs); | 708 | iounmap(hcd->regs); |
709 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | ||
710 | if (omap->regulator[i]) { | ||
711 | regulator_disable(omap->regulator[i]); | ||
712 | regulator_put(omap->regulator[i]); | ||
713 | } | ||
714 | } | ||
681 | iounmap(omap->tll_base); | 715 | iounmap(omap->tll_base); |
682 | iounmap(omap->uhh_base); | 716 | iounmap(omap->uhh_base); |
683 | usb_put_hcd(hcd); | 717 | usb_put_hcd(hcd); |
718 | kfree(omap); | ||
684 | 719 | ||
685 | return 0; | 720 | return 0; |
686 | } | 721 | } |
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 1d283e1b2b8d..0f87dc72820a 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
@@ -222,14 +222,14 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) | |||
222 | goto err1; | 222 | goto err1; |
223 | } | 223 | } |
224 | 224 | ||
225 | if (!request_mem_region(res->start, res->end - res->start + 1, | 225 | if (!request_mem_region(res->start, resource_size(res), |
226 | ehci_orion_hc_driver.description)) { | 226 | ehci_orion_hc_driver.description)) { |
227 | dev_dbg(&pdev->dev, "controller already in use\n"); | 227 | dev_dbg(&pdev->dev, "controller already in use\n"); |
228 | err = -EBUSY; | 228 | err = -EBUSY; |
229 | goto err1; | 229 | goto err1; |
230 | } | 230 | } |
231 | 231 | ||
232 | regs = ioremap(res->start, res->end - res->start + 1); | 232 | regs = ioremap(res->start, resource_size(res)); |
233 | if (regs == NULL) { | 233 | if (regs == NULL) { |
234 | dev_dbg(&pdev->dev, "error mapping memory\n"); | 234 | dev_dbg(&pdev->dev, "error mapping memory\n"); |
235 | err = -EFAULT; | 235 | err = -EFAULT; |
@@ -244,7 +244,7 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) | |||
244 | } | 244 | } |
245 | 245 | ||
246 | hcd->rsrc_start = res->start; | 246 | hcd->rsrc_start = res->start; |
247 | hcd->rsrc_len = res->end - res->start + 1; | 247 | hcd->rsrc_len = resource_size(res); |
248 | hcd->regs = regs; | 248 | hcd->regs = regs; |
249 | 249 | ||
250 | ehci = hcd_to_ehci(hcd); | 250 | ehci = hcd_to_ehci(hcd); |
@@ -287,7 +287,7 @@ err4: | |||
287 | err3: | 287 | err3: |
288 | iounmap(regs); | 288 | iounmap(regs); |
289 | err2: | 289 | err2: |
290 | release_mem_region(res->start, res->end - res->start + 1); | 290 | release_mem_region(res->start, resource_size(res)); |
291 | err1: | 291 | err1: |
292 | dev_err(&pdev->dev, "init %s fail, %d\n", | 292 | dev_err(&pdev->dev, "init %s fail, %d\n", |
293 | dev_name(&pdev->dev), err); | 293 | dev_name(&pdev->dev), err); |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 36f96da129f5..8df33b8a634c 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -134,21 +134,21 @@ ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | |||
134 | hcd->rsrc_len = res.end - res.start + 1; | 134 | hcd->rsrc_len = res.end - res.start + 1; |
135 | 135 | ||
136 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 136 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
137 | printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); | 137 | printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); |
138 | rv = -EBUSY; | 138 | rv = -EBUSY; |
139 | goto err_rmr; | 139 | goto err_rmr; |
140 | } | 140 | } |
141 | 141 | ||
142 | irq = irq_of_parse_and_map(dn, 0); | 142 | irq = irq_of_parse_and_map(dn, 0); |
143 | if (irq == NO_IRQ) { | 143 | if (irq == NO_IRQ) { |
144 | printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); | 144 | printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); |
145 | rv = -EBUSY; | 145 | rv = -EBUSY; |
146 | goto err_irq; | 146 | goto err_irq; |
147 | } | 147 | } |
148 | 148 | ||
149 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 149 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); |
150 | if (!hcd->regs) { | 150 | if (!hcd->regs) { |
151 | printk(KERN_ERR __FILE__ ": ioremap failed\n"); | 151 | printk(KERN_ERR "%s: ioremap failed\n", __FILE__); |
152 | rv = -ENOMEM; | 152 | rv = -ENOMEM; |
153 | goto err_ioremap; | 153 | goto err_ioremap; |
154 | } | 154 | } |
@@ -161,9 +161,9 @@ ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | |||
161 | ehci->ohci_hcctrl_reg = ioremap(res.start + | 161 | ehci->ohci_hcctrl_reg = ioremap(res.start + |
162 | OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN); | 162 | OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN); |
163 | else | 163 | else |
164 | pr_debug(__FILE__ ": no ohci offset in fdt\n"); | 164 | pr_debug("%s: no ohci offset in fdt\n", __FILE__); |
165 | if (!ehci->ohci_hcctrl_reg) { | 165 | if (!ehci->ohci_hcctrl_reg) { |
166 | pr_debug(__FILE__ ": ioremap for ohci hcctrl failed\n"); | 166 | pr_debug("%s: ioremap for ohci hcctrl failed\n", __FILE__); |
167 | } else { | 167 | } else { |
168 | ehci->has_amcc_usb23 = 1; | 168 | ehci->has_amcc_usb23 = 1; |
169 | } | 169 | } |
@@ -241,7 +241,7 @@ static int ehci_hcd_ppc_of_remove(struct of_device *op) | |||
241 | else | 241 | else |
242 | release_mem_region(res.start, 0x4); | 242 | release_mem_region(res.start, 0x4); |
243 | else | 243 | else |
244 | pr_debug(__FILE__ ": no ohci offset in fdt\n"); | 244 | pr_debug("%s: no ohci offset in fdt\n", __FILE__); |
245 | of_node_put(np); | 245 | of_node_put(np); |
246 | } | 246 | } |
247 | 247 | ||
@@ -264,7 +264,7 @@ static int ehci_hcd_ppc_of_shutdown(struct of_device *op) | |||
264 | } | 264 | } |
265 | 265 | ||
266 | 266 | ||
267 | static struct of_device_id ehci_hcd_ppc_of_match[] = { | 267 | static const struct of_device_id ehci_hcd_ppc_of_match[] = { |
268 | { | 268 | { |
269 | .compatible = "usb-ehci", | 269 | .compatible = "usb-ehci", |
270 | }, | 270 | }, |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 1e391e624c8a..39340ae00ac4 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -510,6 +510,8 @@ static int disable_periodic (struct ehci_hcd *ehci) | |||
510 | ehci_writel(ehci, cmd, &ehci->regs->command); | 510 | ehci_writel(ehci, cmd, &ehci->regs->command); |
511 | /* posted write ... */ | 511 | /* posted write ... */ |
512 | 512 | ||
513 | free_cached_itd_list(ehci); | ||
514 | |||
513 | ehci->next_uframe = -1; | 515 | ehci->next_uframe = -1; |
514 | return 0; | 516 | return 0; |
515 | } | 517 | } |
@@ -2322,9 +2324,13 @@ restart: | |||
2322 | * No need to check for activity unless the | 2324 | * No need to check for activity unless the |
2323 | * frame is current. | 2325 | * frame is current. |
2324 | */ | 2326 | */ |
2325 | if (frame == clock_frame && live && | 2327 | if (((frame == clock_frame) || |
2326 | (q.sitd->hw_results & | 2328 | (((frame + 1) % ehci->periodic_size) |
2327 | SITD_ACTIVE(ehci))) { | 2329 | == clock_frame)) |
2330 | && live | ||
2331 | && (q.sitd->hw_results & | ||
2332 | SITD_ACTIVE(ehci))) { | ||
2333 | |||
2328 | incomplete = true; | 2334 | incomplete = true; |
2329 | q_p = &q.sitd->sitd_next; | 2335 | q_p = &q.sitd->sitd_next; |
2330 | hw_p = &q.sitd->hw_next; | 2336 | hw_p = &q.sitd->hw_next; |
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index a5861531ad3e..f603bb2c0a8e 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c | |||
@@ -177,21 +177,21 @@ ehci_hcd_xilinx_of_probe(struct of_device *op, const struct of_device_id *match) | |||
177 | hcd->rsrc_len = res.end - res.start + 1; | 177 | hcd->rsrc_len = res.end - res.start + 1; |
178 | 178 | ||
179 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 179 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
180 | printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); | 180 | printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); |
181 | rv = -EBUSY; | 181 | rv = -EBUSY; |
182 | goto err_rmr; | 182 | goto err_rmr; |
183 | } | 183 | } |
184 | 184 | ||
185 | irq = irq_of_parse_and_map(dn, 0); | 185 | irq = irq_of_parse_and_map(dn, 0); |
186 | if (irq == NO_IRQ) { | 186 | if (irq == NO_IRQ) { |
187 | printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); | 187 | printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); |
188 | rv = -EBUSY; | 188 | rv = -EBUSY; |
189 | goto err_irq; | 189 | goto err_irq; |
190 | } | 190 | } |
191 | 191 | ||
192 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 192 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); |
193 | if (!hcd->regs) { | 193 | if (!hcd->regs) { |
194 | printk(KERN_ERR __FILE__ ": ioremap failed\n"); | 194 | printk(KERN_ERR "%s: ioremap failed\n", __FILE__); |
195 | rv = -ENOMEM; | 195 | rv = -ENOMEM; |
196 | goto err_ioremap; | 196 | goto err_ioremap; |
197 | } | 197 | } |
@@ -281,7 +281,7 @@ static int ehci_hcd_xilinx_of_shutdown(struct of_device *op) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | 283 | ||
284 | static struct of_device_id ehci_hcd_xilinx_of_match[] = { | 284 | static const struct of_device_id ehci_hcd_xilinx_of_match[] = { |
285 | {.compatible = "xlnx,xps-usb-host-1.00.a",}, | 285 | {.compatible = "xlnx,xps-usb-host-1.00.a",}, |
286 | {}, | 286 | {}, |
287 | }; | 287 | }; |
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 78e7c3cfcb72..5dcfb3de9945 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c | |||
@@ -433,7 +433,7 @@ static int fhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
433 | return -ENOMEM; | 433 | return -ENOMEM; |
434 | 434 | ||
435 | /* allocate the private part of the URB */ | 435 | /* allocate the private part of the URB */ |
436 | urb_priv->tds = kzalloc(size * sizeof(struct td), mem_flags); | 436 | urb_priv->tds = kcalloc(size, sizeof(*urb_priv->tds), mem_flags); |
437 | if (!urb_priv->tds) { | 437 | if (!urb_priv->tds) { |
438 | kfree(urb_priv); | 438 | kfree(urb_priv); |
439 | return -ENOMEM; | 439 | return -ENOMEM; |
@@ -805,7 +805,7 @@ static int __devexit of_fhci_remove(struct of_device *ofdev) | |||
805 | return fhci_remove(&ofdev->dev); | 805 | return fhci_remove(&ofdev->dev); |
806 | } | 806 | } |
807 | 807 | ||
808 | static struct of_device_id of_fhci_match[] = { | 808 | static const struct of_device_id of_fhci_match[] = { |
809 | { .compatible = "fsl,mpc8323-qe-usb", }, | 809 | { .compatible = "fsl,mpc8323-qe-usb", }, |
810 | {}, | 810 | {}, |
811 | }; | 811 | }; |
diff --git a/drivers/usb/host/imx21-dbg.c b/drivers/usb/host/imx21-dbg.c new file mode 100644 index 000000000000..512f647448ca --- /dev/null +++ b/drivers/usb/host/imx21-dbg.c | |||
@@ -0,0 +1,527 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 by Martin Fuzzey | ||
3 | * | ||
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 | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software Foundation, | ||
16 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | /* this file is part of imx21-hcd.c */ | ||
20 | |||
21 | #ifndef DEBUG | ||
22 | |||
23 | static inline void create_debug_files(struct imx21 *imx21) { } | ||
24 | static inline void remove_debug_files(struct imx21 *imx21) { } | ||
25 | static inline void debug_urb_submitted(struct imx21 *imx21, struct urb *urb) {} | ||
26 | static inline void debug_urb_completed(struct imx21 *imx21, struct urb *urb, | ||
27 | int status) {} | ||
28 | static inline void debug_urb_unlinked(struct imx21 *imx21, struct urb *urb) {} | ||
29 | static inline void debug_urb_queued_for_etd(struct imx21 *imx21, | ||
30 | struct urb *urb) {} | ||
31 | static inline void debug_urb_queued_for_dmem(struct imx21 *imx21, | ||
32 | struct urb *urb) {} | ||
33 | static inline void debug_etd_allocated(struct imx21 *imx21) {} | ||
34 | static inline void debug_etd_freed(struct imx21 *imx21) {} | ||
35 | static inline void debug_dmem_allocated(struct imx21 *imx21, int size) {} | ||
36 | static inline void debug_dmem_freed(struct imx21 *imx21, int size) {} | ||
37 | static inline void debug_isoc_submitted(struct imx21 *imx21, | ||
38 | int frame, struct td *td) {} | ||
39 | static inline void debug_isoc_completed(struct imx21 *imx21, | ||
40 | int frame, struct td *td, int cc, int len) {} | ||
41 | |||
42 | #else | ||
43 | |||
44 | #include <linux/debugfs.h> | ||
45 | #include <linux/seq_file.h> | ||
46 | |||
47 | static const char *dir_labels[] = { | ||
48 | "TD 0", | ||
49 | "OUT", | ||
50 | "IN", | ||
51 | "TD 1" | ||
52 | }; | ||
53 | |||
54 | static const char *speed_labels[] = { | ||
55 | "Full", | ||
56 | "Low" | ||
57 | }; | ||
58 | |||
59 | static const char *format_labels[] = { | ||
60 | "Control", | ||
61 | "ISO", | ||
62 | "Bulk", | ||
63 | "Interrupt" | ||
64 | }; | ||
65 | |||
66 | static inline struct debug_stats *stats_for_urb(struct imx21 *imx21, | ||
67 | struct urb *urb) | ||
68 | { | ||
69 | return usb_pipeisoc(urb->pipe) ? | ||
70 | &imx21->isoc_stats : &imx21->nonisoc_stats; | ||
71 | } | ||
72 | |||
73 | static void debug_urb_submitted(struct imx21 *imx21, struct urb *urb) | ||
74 | { | ||
75 | stats_for_urb(imx21, urb)->submitted++; | ||
76 | } | ||
77 | |||
78 | static void debug_urb_completed(struct imx21 *imx21, struct urb *urb, int st) | ||
79 | { | ||
80 | if (st) | ||
81 | stats_for_urb(imx21, urb)->completed_failed++; | ||
82 | else | ||
83 | stats_for_urb(imx21, urb)->completed_ok++; | ||
84 | } | ||
85 | |||
86 | static void debug_urb_unlinked(struct imx21 *imx21, struct urb *urb) | ||
87 | { | ||
88 | stats_for_urb(imx21, urb)->unlinked++; | ||
89 | } | ||
90 | |||
91 | static void debug_urb_queued_for_etd(struct imx21 *imx21, struct urb *urb) | ||
92 | { | ||
93 | stats_for_urb(imx21, urb)->queue_etd++; | ||
94 | } | ||
95 | |||
96 | static void debug_urb_queued_for_dmem(struct imx21 *imx21, struct urb *urb) | ||
97 | { | ||
98 | stats_for_urb(imx21, urb)->queue_dmem++; | ||
99 | } | ||
100 | |||
101 | static inline void debug_etd_allocated(struct imx21 *imx21) | ||
102 | { | ||
103 | imx21->etd_usage.maximum = max( | ||
104 | ++(imx21->etd_usage.value), | ||
105 | imx21->etd_usage.maximum); | ||
106 | } | ||
107 | |||
108 | static inline void debug_etd_freed(struct imx21 *imx21) | ||
109 | { | ||
110 | imx21->etd_usage.value--; | ||
111 | } | ||
112 | |||
113 | static inline void debug_dmem_allocated(struct imx21 *imx21, int size) | ||
114 | { | ||
115 | imx21->dmem_usage.value += size; | ||
116 | imx21->dmem_usage.maximum = max( | ||
117 | imx21->dmem_usage.value, | ||
118 | imx21->dmem_usage.maximum); | ||
119 | } | ||
120 | |||
121 | static inline void debug_dmem_freed(struct imx21 *imx21, int size) | ||
122 | { | ||
123 | imx21->dmem_usage.value -= size; | ||
124 | } | ||
125 | |||
126 | |||
127 | static void debug_isoc_submitted(struct imx21 *imx21, | ||
128 | int frame, struct td *td) | ||
129 | { | ||
130 | struct debug_isoc_trace *trace = &imx21->isoc_trace[ | ||
131 | imx21->isoc_trace_index++]; | ||
132 | |||
133 | imx21->isoc_trace_index %= ARRAY_SIZE(imx21->isoc_trace); | ||
134 | trace->schedule_frame = td->frame; | ||
135 | trace->submit_frame = frame; | ||
136 | trace->request_len = td->len; | ||
137 | trace->td = td; | ||
138 | } | ||
139 | |||
140 | static inline void debug_isoc_completed(struct imx21 *imx21, | ||
141 | int frame, struct td *td, int cc, int len) | ||
142 | { | ||
143 | struct debug_isoc_trace *trace, *trace_failed; | ||
144 | int i; | ||
145 | int found = 0; | ||
146 | |||
147 | trace = imx21->isoc_trace; | ||
148 | for (i = 0; i < ARRAY_SIZE(imx21->isoc_trace); i++, trace++) { | ||
149 | if (trace->td == td) { | ||
150 | trace->done_frame = frame; | ||
151 | trace->done_len = len; | ||
152 | trace->cc = cc; | ||
153 | trace->td = NULL; | ||
154 | found = 1; | ||
155 | break; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | if (found && cc) { | ||
160 | trace_failed = &imx21->isoc_trace_failed[ | ||
161 | imx21->isoc_trace_index_failed++]; | ||
162 | |||
163 | imx21->isoc_trace_index_failed %= ARRAY_SIZE( | ||
164 | imx21->isoc_trace_failed); | ||
165 | *trace_failed = *trace; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | |||
170 | static char *format_ep(struct usb_host_endpoint *ep, char *buf, int bufsize) | ||
171 | { | ||
172 | if (ep) | ||
173 | snprintf(buf, bufsize, "ep_%02x (type:%02X kaddr:%p)", | ||
174 | ep->desc.bEndpointAddress, | ||
175 | usb_endpoint_type(&ep->desc), | ||
176 | ep); | ||
177 | else | ||
178 | snprintf(buf, bufsize, "none"); | ||
179 | return buf; | ||
180 | } | ||
181 | |||
182 | static char *format_etd_dword0(u32 value, char *buf, int bufsize) | ||
183 | { | ||
184 | snprintf(buf, bufsize, | ||
185 | "addr=%d ep=%d dir=%s speed=%s format=%s halted=%d", | ||
186 | value & 0x7F, | ||
187 | (value >> DW0_ENDPNT) & 0x0F, | ||
188 | dir_labels[(value >> DW0_DIRECT) & 0x03], | ||
189 | speed_labels[(value >> DW0_SPEED) & 0x01], | ||
190 | format_labels[(value >> DW0_FORMAT) & 0x03], | ||
191 | (value >> DW0_HALTED) & 0x01); | ||
192 | return buf; | ||
193 | } | ||
194 | |||
195 | static int debug_status_show(struct seq_file *s, void *v) | ||
196 | { | ||
197 | struct imx21 *imx21 = s->private; | ||
198 | int etds_allocated = 0; | ||
199 | int etds_sw_busy = 0; | ||
200 | int etds_hw_busy = 0; | ||
201 | int dmem_blocks = 0; | ||
202 | int queued_for_etd = 0; | ||
203 | int queued_for_dmem = 0; | ||
204 | unsigned int dmem_bytes = 0; | ||
205 | int i; | ||
206 | struct etd_priv *etd; | ||
207 | u32 etd_enable_mask; | ||
208 | unsigned long flags; | ||
209 | struct imx21_dmem_area *dmem; | ||
210 | struct ep_priv *ep_priv; | ||
211 | |||
212 | spin_lock_irqsave(&imx21->lock, flags); | ||
213 | |||
214 | etd_enable_mask = readl(imx21->regs + USBH_ETDENSET); | ||
215 | for (i = 0, etd = imx21->etd; i < USB_NUM_ETD; i++, etd++) { | ||
216 | if (etd->alloc) | ||
217 | etds_allocated++; | ||
218 | if (etd->urb) | ||
219 | etds_sw_busy++; | ||
220 | if (etd_enable_mask & (1<<i)) | ||
221 | etds_hw_busy++; | ||
222 | } | ||
223 | |||
224 | list_for_each_entry(dmem, &imx21->dmem_list, list) { | ||
225 | dmem_bytes += dmem->size; | ||
226 | dmem_blocks++; | ||
227 | } | ||
228 | |||
229 | list_for_each_entry(ep_priv, &imx21->queue_for_etd, queue) | ||
230 | queued_for_etd++; | ||
231 | |||
232 | list_for_each_entry(etd, &imx21->queue_for_dmem, queue) | ||
233 | queued_for_dmem++; | ||
234 | |||
235 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
236 | |||
237 | seq_printf(s, | ||
238 | "Frame: %d\n" | ||
239 | "ETDs allocated: %d/%d (max=%d)\n" | ||
240 | "ETDs in use sw: %d\n" | ||
241 | "ETDs in use hw: %d\n" | ||
242 | "DMEM alocated: %d/%d (max=%d)\n" | ||
243 | "DMEM blocks: %d\n" | ||
244 | "Queued waiting for ETD: %d\n" | ||
245 | "Queued waiting for DMEM: %d\n", | ||
246 | readl(imx21->regs + USBH_FRMNUB) & 0xFFFF, | ||
247 | etds_allocated, USB_NUM_ETD, imx21->etd_usage.maximum, | ||
248 | etds_sw_busy, | ||
249 | etds_hw_busy, | ||
250 | dmem_bytes, DMEM_SIZE, imx21->dmem_usage.maximum, | ||
251 | dmem_blocks, | ||
252 | queued_for_etd, | ||
253 | queued_for_dmem); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int debug_dmem_show(struct seq_file *s, void *v) | ||
259 | { | ||
260 | struct imx21 *imx21 = s->private; | ||
261 | struct imx21_dmem_area *dmem; | ||
262 | unsigned long flags; | ||
263 | char ep_text[40]; | ||
264 | |||
265 | spin_lock_irqsave(&imx21->lock, flags); | ||
266 | |||
267 | list_for_each_entry(dmem, &imx21->dmem_list, list) | ||
268 | seq_printf(s, | ||
269 | "%04X: size=0x%X " | ||
270 | "ep=%s\n", | ||
271 | dmem->offset, dmem->size, | ||
272 | format_ep(dmem->ep, ep_text, sizeof(ep_text))); | ||
273 | |||
274 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int debug_etd_show(struct seq_file *s, void *v) | ||
280 | { | ||
281 | struct imx21 *imx21 = s->private; | ||
282 | struct etd_priv *etd; | ||
283 | char buf[60]; | ||
284 | u32 dword; | ||
285 | int i, j; | ||
286 | unsigned long flags; | ||
287 | |||
288 | spin_lock_irqsave(&imx21->lock, flags); | ||
289 | |||
290 | for (i = 0, etd = imx21->etd; i < USB_NUM_ETD; i++, etd++) { | ||
291 | int state = -1; | ||
292 | struct urb_priv *urb_priv; | ||
293 | if (etd->urb) { | ||
294 | urb_priv = etd->urb->hcpriv; | ||
295 | if (urb_priv) | ||
296 | state = urb_priv->state; | ||
297 | } | ||
298 | |||
299 | seq_printf(s, | ||
300 | "etd_num: %d\n" | ||
301 | "ep: %s\n" | ||
302 | "alloc: %d\n" | ||
303 | "len: %d\n" | ||
304 | "busy sw: %d\n" | ||
305 | "busy hw: %d\n" | ||
306 | "urb state: %d\n" | ||
307 | "current urb: %p\n", | ||
308 | |||
309 | i, | ||
310 | format_ep(etd->ep, buf, sizeof(buf)), | ||
311 | etd->alloc, | ||
312 | etd->len, | ||
313 | etd->urb != NULL, | ||
314 | (readl(imx21->regs + USBH_ETDENSET) & (1 << i)) > 0, | ||
315 | state, | ||
316 | etd->urb); | ||
317 | |||
318 | for (j = 0; j < 4; j++) { | ||
319 | dword = etd_readl(imx21, i, j); | ||
320 | switch (j) { | ||
321 | case 0: | ||
322 | format_etd_dword0(dword, buf, sizeof(buf)); | ||
323 | break; | ||
324 | case 2: | ||
325 | snprintf(buf, sizeof(buf), | ||
326 | "cc=0X%02X", dword >> DW2_COMPCODE); | ||
327 | break; | ||
328 | default: | ||
329 | *buf = 0; | ||
330 | break; | ||
331 | } | ||
332 | seq_printf(s, | ||
333 | "dword %d: submitted=%08X cur=%08X [%s]\n", | ||
334 | j, | ||
335 | etd->submitted_dwords[j], | ||
336 | dword, | ||
337 | buf); | ||
338 | } | ||
339 | seq_printf(s, "\n"); | ||
340 | } | ||
341 | |||
342 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static void debug_statistics_show_one(struct seq_file *s, | ||
348 | const char *name, struct debug_stats *stats) | ||
349 | { | ||
350 | seq_printf(s, "%s:\n" | ||
351 | "submitted URBs: %lu\n" | ||
352 | "completed OK: %lu\n" | ||
353 | "completed failed: %lu\n" | ||
354 | "unlinked: %lu\n" | ||
355 | "queued for ETD: %lu\n" | ||
356 | "queued for DMEM: %lu\n\n", | ||
357 | name, | ||
358 | stats->submitted, | ||
359 | stats->completed_ok, | ||
360 | stats->completed_failed, | ||
361 | stats->unlinked, | ||
362 | stats->queue_etd, | ||
363 | stats->queue_dmem); | ||
364 | } | ||
365 | |||
366 | static int debug_statistics_show(struct seq_file *s, void *v) | ||
367 | { | ||
368 | struct imx21 *imx21 = s->private; | ||
369 | unsigned long flags; | ||
370 | |||
371 | spin_lock_irqsave(&imx21->lock, flags); | ||
372 | |||
373 | debug_statistics_show_one(s, "nonisoc", &imx21->nonisoc_stats); | ||
374 | debug_statistics_show_one(s, "isoc", &imx21->isoc_stats); | ||
375 | seq_printf(s, "unblock kludge triggers: %lu\n", imx21->debug_unblocks); | ||
376 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static void debug_isoc_show_one(struct seq_file *s, | ||
382 | const char *name, int index, struct debug_isoc_trace *trace) | ||
383 | { | ||
384 | seq_printf(s, "%s %d:\n" | ||
385 | "cc=0X%02X\n" | ||
386 | "scheduled frame %d (%d)\n" | ||
387 | "submittted frame %d (%d)\n" | ||
388 | "completed frame %d (%d)\n" | ||
389 | "requested length=%d\n" | ||
390 | "completed length=%d\n\n", | ||
391 | name, index, | ||
392 | trace->cc, | ||
393 | trace->schedule_frame, trace->schedule_frame & 0xFFFF, | ||
394 | trace->submit_frame, trace->submit_frame & 0xFFFF, | ||
395 | trace->done_frame, trace->done_frame & 0xFFFF, | ||
396 | trace->request_len, | ||
397 | trace->done_len); | ||
398 | } | ||
399 | |||
400 | static int debug_isoc_show(struct seq_file *s, void *v) | ||
401 | { | ||
402 | struct imx21 *imx21 = s->private; | ||
403 | struct debug_isoc_trace *trace; | ||
404 | unsigned long flags; | ||
405 | int i; | ||
406 | |||
407 | spin_lock_irqsave(&imx21->lock, flags); | ||
408 | |||
409 | trace = imx21->isoc_trace_failed; | ||
410 | for (i = 0; i < ARRAY_SIZE(imx21->isoc_trace_failed); i++, trace++) | ||
411 | debug_isoc_show_one(s, "isoc failed", i, trace); | ||
412 | |||
413 | trace = imx21->isoc_trace; | ||
414 | for (i = 0; i < ARRAY_SIZE(imx21->isoc_trace); i++, trace++) | ||
415 | debug_isoc_show_one(s, "isoc", i, trace); | ||
416 | |||
417 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static int debug_status_open(struct inode *inode, struct file *file) | ||
423 | { | ||
424 | return single_open(file, debug_status_show, inode->i_private); | ||
425 | } | ||
426 | |||
427 | static int debug_dmem_open(struct inode *inode, struct file *file) | ||
428 | { | ||
429 | return single_open(file, debug_dmem_show, inode->i_private); | ||
430 | } | ||
431 | |||
432 | static int debug_etd_open(struct inode *inode, struct file *file) | ||
433 | { | ||
434 | return single_open(file, debug_etd_show, inode->i_private); | ||
435 | } | ||
436 | |||
437 | static int debug_statistics_open(struct inode *inode, struct file *file) | ||
438 | { | ||
439 | return single_open(file, debug_statistics_show, inode->i_private); | ||
440 | } | ||
441 | |||
442 | static int debug_isoc_open(struct inode *inode, struct file *file) | ||
443 | { | ||
444 | return single_open(file, debug_isoc_show, inode->i_private); | ||
445 | } | ||
446 | |||
447 | static const struct file_operations debug_status_fops = { | ||
448 | .open = debug_status_open, | ||
449 | .read = seq_read, | ||
450 | .llseek = seq_lseek, | ||
451 | .release = single_release, | ||
452 | }; | ||
453 | |||
454 | static const struct file_operations debug_dmem_fops = { | ||
455 | .open = debug_dmem_open, | ||
456 | .read = seq_read, | ||
457 | .llseek = seq_lseek, | ||
458 | .release = single_release, | ||
459 | }; | ||
460 | |||
461 | static const struct file_operations debug_etd_fops = { | ||
462 | .open = debug_etd_open, | ||
463 | .read = seq_read, | ||
464 | .llseek = seq_lseek, | ||
465 | .release = single_release, | ||
466 | }; | ||
467 | |||
468 | static const struct file_operations debug_statistics_fops = { | ||
469 | .open = debug_statistics_open, | ||
470 | .read = seq_read, | ||
471 | .llseek = seq_lseek, | ||
472 | .release = single_release, | ||
473 | }; | ||
474 | |||
475 | static const struct file_operations debug_isoc_fops = { | ||
476 | .open = debug_isoc_open, | ||
477 | .read = seq_read, | ||
478 | .llseek = seq_lseek, | ||
479 | .release = single_release, | ||
480 | }; | ||
481 | |||
482 | static void create_debug_files(struct imx21 *imx21) | ||
483 | { | ||
484 | imx21->debug_root = debugfs_create_dir(dev_name(imx21->dev), NULL); | ||
485 | if (!imx21->debug_root) | ||
486 | goto failed_create_rootdir; | ||
487 | |||
488 | if (!debugfs_create_file("status", S_IRUGO, | ||
489 | imx21->debug_root, imx21, &debug_status_fops)) | ||
490 | goto failed_create; | ||
491 | |||
492 | if (!debugfs_create_file("dmem", S_IRUGO, | ||
493 | imx21->debug_root, imx21, &debug_dmem_fops)) | ||
494 | goto failed_create; | ||
495 | |||
496 | if (!debugfs_create_file("etd", S_IRUGO, | ||
497 | imx21->debug_root, imx21, &debug_etd_fops)) | ||
498 | goto failed_create; | ||
499 | |||
500 | if (!debugfs_create_file("statistics", S_IRUGO, | ||
501 | imx21->debug_root, imx21, &debug_statistics_fops)) | ||
502 | goto failed_create; | ||
503 | |||
504 | if (!debugfs_create_file("isoc", S_IRUGO, | ||
505 | imx21->debug_root, imx21, &debug_isoc_fops)) | ||
506 | goto failed_create; | ||
507 | |||
508 | return; | ||
509 | |||
510 | failed_create: | ||
511 | debugfs_remove_recursive(imx21->debug_root); | ||
512 | |||
513 | failed_create_rootdir: | ||
514 | imx21->debug_root = NULL; | ||
515 | } | ||
516 | |||
517 | |||
518 | static void remove_debug_files(struct imx21 *imx21) | ||
519 | { | ||
520 | if (imx21->debug_root) { | ||
521 | debugfs_remove_recursive(imx21->debug_root); | ||
522 | imx21->debug_root = NULL; | ||
523 | } | ||
524 | } | ||
525 | |||
526 | #endif | ||
527 | |||
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c new file mode 100644 index 000000000000..213e270e1c29 --- /dev/null +++ b/drivers/usb/host/imx21-hcd.c | |||
@@ -0,0 +1,1789 @@ | |||
1 | /* | ||
2 | * USB Host Controller Driver for IMX21 | ||
3 | * | ||
4 | * Copyright (C) 2006 Loping Dog Embedded Systems | ||
5 | * Copyright (C) 2009 Martin Fuzzey | ||
6 | * Originally written by Jay Monkman <jtm@lopingdog.com> | ||
7 | * Ported to 2.6.30, debugged and enhanced by Martin Fuzzey | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
17 | * for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software Foundation, | ||
21 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | |||
25 | /* | ||
26 | * The i.MX21 USB hardware contains | ||
27 | * * 32 transfer descriptors (called ETDs) | ||
28 | * * 4Kb of Data memory | ||
29 | * | ||
30 | * The data memory is shared between the host and fuction controlers | ||
31 | * (but this driver only supports the host controler) | ||
32 | * | ||
33 | * So setting up a transfer involves: | ||
34 | * * Allocating a ETD | ||
35 | * * Fill in ETD with appropriate information | ||
36 | * * Allocating data memory (and putting the offset in the ETD) | ||
37 | * * Activate the ETD | ||
38 | * * Get interrupt when done. | ||
39 | * | ||
40 | * An ETD is assigned to each active endpoint. | ||
41 | * | ||
42 | * Low resource (ETD and Data memory) situations are handled differently for | ||
43 | * isochronous and non insosynchronous transactions : | ||
44 | * | ||
45 | * Non ISOC transfers are queued if either ETDs or Data memory are unavailable | ||
46 | * | ||
47 | * ISOC transfers use 2 ETDs per endpoint to achieve double buffering. | ||
48 | * They allocate both ETDs and Data memory during URB submission | ||
49 | * (and fail if unavailable). | ||
50 | */ | ||
51 | |||
52 | #include <linux/clk.h> | ||
53 | #include <linux/io.h> | ||
54 | #include <linux/kernel.h> | ||
55 | #include <linux/list.h> | ||
56 | #include <linux/platform_device.h> | ||
57 | #include <linux/usb.h> | ||
58 | |||
59 | #include "../core/hcd.h" | ||
60 | #include "imx21-hcd.h" | ||
61 | |||
62 | #ifdef DEBUG | ||
63 | #define DEBUG_LOG_FRAME(imx21, etd, event) \ | ||
64 | (etd)->event##_frame = readl((imx21)->regs + USBH_FRMNUB) | ||
65 | #else | ||
66 | #define DEBUG_LOG_FRAME(imx21, etd, event) do { } while (0) | ||
67 | #endif | ||
68 | |||
69 | static const char hcd_name[] = "imx21-hcd"; | ||
70 | |||
71 | static inline struct imx21 *hcd_to_imx21(struct usb_hcd *hcd) | ||
72 | { | ||
73 | return (struct imx21 *)hcd->hcd_priv; | ||
74 | } | ||
75 | |||
76 | |||
77 | /* =========================================== */ | ||
78 | /* Hardware access helpers */ | ||
79 | /* =========================================== */ | ||
80 | |||
81 | static inline void set_register_bits(struct imx21 *imx21, u32 offset, u32 mask) | ||
82 | { | ||
83 | void __iomem *reg = imx21->regs + offset; | ||
84 | writel(readl(reg) | mask, reg); | ||
85 | } | ||
86 | |||
87 | static inline void clear_register_bits(struct imx21 *imx21, | ||
88 | u32 offset, u32 mask) | ||
89 | { | ||
90 | void __iomem *reg = imx21->regs + offset; | ||
91 | writel(readl(reg) & ~mask, reg); | ||
92 | } | ||
93 | |||
94 | static inline void clear_toggle_bit(struct imx21 *imx21, u32 offset, u32 mask) | ||
95 | { | ||
96 | void __iomem *reg = imx21->regs + offset; | ||
97 | |||
98 | if (readl(reg) & mask) | ||
99 | writel(mask, reg); | ||
100 | } | ||
101 | |||
102 | static inline void set_toggle_bit(struct imx21 *imx21, u32 offset, u32 mask) | ||
103 | { | ||
104 | void __iomem *reg = imx21->regs + offset; | ||
105 | |||
106 | if (!(readl(reg) & mask)) | ||
107 | writel(mask, reg); | ||
108 | } | ||
109 | |||
110 | static void etd_writel(struct imx21 *imx21, int etd_num, int dword, u32 value) | ||
111 | { | ||
112 | writel(value, imx21->regs + USB_ETD_DWORD(etd_num, dword)); | ||
113 | } | ||
114 | |||
115 | static u32 etd_readl(struct imx21 *imx21, int etd_num, int dword) | ||
116 | { | ||
117 | return readl(imx21->regs + USB_ETD_DWORD(etd_num, dword)); | ||
118 | } | ||
119 | |||
120 | static inline int wrap_frame(int counter) | ||
121 | { | ||
122 | return counter & 0xFFFF; | ||
123 | } | ||
124 | |||
125 | static inline int frame_after(int frame, int after) | ||
126 | { | ||
127 | /* handle wrapping like jiffies time_afer */ | ||
128 | return (s16)((s16)after - (s16)frame) < 0; | ||
129 | } | ||
130 | |||
131 | static int imx21_hc_get_frame(struct usb_hcd *hcd) | ||
132 | { | ||
133 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
134 | |||
135 | return wrap_frame(readl(imx21->regs + USBH_FRMNUB)); | ||
136 | } | ||
137 | |||
138 | |||
139 | #include "imx21-dbg.c" | ||
140 | |||
141 | /* =========================================== */ | ||
142 | /* ETD management */ | ||
143 | /* =========================================== */ | ||
144 | |||
145 | static int alloc_etd(struct imx21 *imx21) | ||
146 | { | ||
147 | int i; | ||
148 | struct etd_priv *etd = imx21->etd; | ||
149 | |||
150 | for (i = 0; i < USB_NUM_ETD; i++, etd++) { | ||
151 | if (etd->alloc == 0) { | ||
152 | memset(etd, 0, sizeof(imx21->etd[0])); | ||
153 | etd->alloc = 1; | ||
154 | debug_etd_allocated(imx21); | ||
155 | return i; | ||
156 | } | ||
157 | } | ||
158 | return -1; | ||
159 | } | ||
160 | |||
161 | static void disactivate_etd(struct imx21 *imx21, int num) | ||
162 | { | ||
163 | int etd_mask = (1 << num); | ||
164 | struct etd_priv *etd = &imx21->etd[num]; | ||
165 | |||
166 | writel(etd_mask, imx21->regs + USBH_ETDENCLR); | ||
167 | clear_register_bits(imx21, USBH_ETDDONEEN, etd_mask); | ||
168 | writel(etd_mask, imx21->regs + USB_ETDDMACHANLCLR); | ||
169 | clear_toggle_bit(imx21, USBH_ETDDONESTAT, etd_mask); | ||
170 | |||
171 | etd->active_count = 0; | ||
172 | |||
173 | DEBUG_LOG_FRAME(imx21, etd, disactivated); | ||
174 | } | ||
175 | |||
176 | static void reset_etd(struct imx21 *imx21, int num) | ||
177 | { | ||
178 | struct etd_priv *etd = imx21->etd + num; | ||
179 | int i; | ||
180 | |||
181 | disactivate_etd(imx21, num); | ||
182 | |||
183 | for (i = 0; i < 4; i++) | ||
184 | etd_writel(imx21, num, i, 0); | ||
185 | etd->urb = NULL; | ||
186 | etd->ep = NULL; | ||
187 | etd->td = NULL;; | ||
188 | } | ||
189 | |||
190 | static void free_etd(struct imx21 *imx21, int num) | ||
191 | { | ||
192 | if (num < 0) | ||
193 | return; | ||
194 | |||
195 | if (num >= USB_NUM_ETD) { | ||
196 | dev_err(imx21->dev, "BAD etd=%d!\n", num); | ||
197 | return; | ||
198 | } | ||
199 | if (imx21->etd[num].alloc == 0) { | ||
200 | dev_err(imx21->dev, "ETD %d already free!\n", num); | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | debug_etd_freed(imx21); | ||
205 | reset_etd(imx21, num); | ||
206 | memset(&imx21->etd[num], 0, sizeof(imx21->etd[0])); | ||
207 | } | ||
208 | |||
209 | |||
210 | static void setup_etd_dword0(struct imx21 *imx21, | ||
211 | int etd_num, struct urb *urb, u8 dir, u16 maxpacket) | ||
212 | { | ||
213 | etd_writel(imx21, etd_num, 0, | ||
214 | ((u32) usb_pipedevice(urb->pipe)) << DW0_ADDRESS | | ||
215 | ((u32) usb_pipeendpoint(urb->pipe) << DW0_ENDPNT) | | ||
216 | ((u32) dir << DW0_DIRECT) | | ||
217 | ((u32) ((urb->dev->speed == USB_SPEED_LOW) ? | ||
218 | 1 : 0) << DW0_SPEED) | | ||
219 | ((u32) fmt_urb_to_etd[usb_pipetype(urb->pipe)] << DW0_FORMAT) | | ||
220 | ((u32) maxpacket << DW0_MAXPKTSIZ)); | ||
221 | } | ||
222 | |||
223 | static void activate_etd(struct imx21 *imx21, | ||
224 | int etd_num, dma_addr_t dma, u8 dir) | ||
225 | { | ||
226 | u32 etd_mask = 1 << etd_num; | ||
227 | struct etd_priv *etd = &imx21->etd[etd_num]; | ||
228 | |||
229 | clear_toggle_bit(imx21, USBH_ETDDONESTAT, etd_mask); | ||
230 | set_register_bits(imx21, USBH_ETDDONEEN, etd_mask); | ||
231 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | ||
232 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); | ||
233 | |||
234 | if (dma) { | ||
235 | set_register_bits(imx21, USB_ETDDMACHANLCLR, etd_mask); | ||
236 | clear_toggle_bit(imx21, USBH_XBUFSTAT, etd_mask); | ||
237 | clear_toggle_bit(imx21, USBH_YBUFSTAT, etd_mask); | ||
238 | writel(dma, imx21->regs + USB_ETDSMSA(etd_num)); | ||
239 | set_register_bits(imx21, USB_ETDDMAEN, etd_mask); | ||
240 | } else { | ||
241 | if (dir != TD_DIR_IN) { | ||
242 | /* need to set for ZLP */ | ||
243 | set_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | ||
244 | set_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | DEBUG_LOG_FRAME(imx21, etd, activated); | ||
249 | |||
250 | #ifdef DEBUG | ||
251 | if (!etd->active_count) { | ||
252 | int i; | ||
253 | etd->activated_frame = readl(imx21->regs + USBH_FRMNUB); | ||
254 | etd->disactivated_frame = -1; | ||
255 | etd->last_int_frame = -1; | ||
256 | etd->last_req_frame = -1; | ||
257 | |||
258 | for (i = 0; i < 4; i++) | ||
259 | etd->submitted_dwords[i] = etd_readl(imx21, etd_num, i); | ||
260 | } | ||
261 | #endif | ||
262 | |||
263 | etd->active_count = 1; | ||
264 | writel(etd_mask, imx21->regs + USBH_ETDENSET); | ||
265 | } | ||
266 | |||
267 | /* =========================================== */ | ||
268 | /* Data memory management */ | ||
269 | /* =========================================== */ | ||
270 | |||
271 | static int alloc_dmem(struct imx21 *imx21, unsigned int size, | ||
272 | struct usb_host_endpoint *ep) | ||
273 | { | ||
274 | unsigned int offset = 0; | ||
275 | struct imx21_dmem_area *area; | ||
276 | struct imx21_dmem_area *tmp; | ||
277 | |||
278 | size += (~size + 1) & 0x3; /* Round to 4 byte multiple */ | ||
279 | |||
280 | if (size > DMEM_SIZE) { | ||
281 | dev_err(imx21->dev, "size=%d > DMEM_SIZE(%d)\n", | ||
282 | size, DMEM_SIZE); | ||
283 | return -EINVAL; | ||
284 | } | ||
285 | |||
286 | list_for_each_entry(tmp, &imx21->dmem_list, list) { | ||
287 | if ((size + offset) < offset) | ||
288 | goto fail; | ||
289 | if ((size + offset) <= tmp->offset) | ||
290 | break; | ||
291 | offset = tmp->size + tmp->offset; | ||
292 | if ((offset + size) > DMEM_SIZE) | ||
293 | goto fail; | ||
294 | } | ||
295 | |||
296 | area = kmalloc(sizeof(struct imx21_dmem_area), GFP_ATOMIC); | ||
297 | if (area == NULL) | ||
298 | return -ENOMEM; | ||
299 | |||
300 | area->ep = ep; | ||
301 | area->offset = offset; | ||
302 | area->size = size; | ||
303 | list_add_tail(&area->list, &tmp->list); | ||
304 | debug_dmem_allocated(imx21, size); | ||
305 | return offset; | ||
306 | |||
307 | fail: | ||
308 | return -ENOMEM; | ||
309 | } | ||
310 | |||
311 | /* Memory now available for a queued ETD - activate it */ | ||
312 | static void activate_queued_etd(struct imx21 *imx21, | ||
313 | struct etd_priv *etd, u32 dmem_offset) | ||
314 | { | ||
315 | struct urb_priv *urb_priv = etd->urb->hcpriv; | ||
316 | int etd_num = etd - &imx21->etd[0]; | ||
317 | u32 maxpacket = etd_readl(imx21, etd_num, 1) >> DW1_YBUFSRTAD; | ||
318 | u8 dir = (etd_readl(imx21, etd_num, 2) >> DW2_DIRPID) & 0x03; | ||
319 | |||
320 | dev_dbg(imx21->dev, "activating queued ETD %d now DMEM available\n", | ||
321 | etd_num); | ||
322 | etd_writel(imx21, etd_num, 1, | ||
323 | ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset); | ||
324 | |||
325 | urb_priv->active = 1; | ||
326 | activate_etd(imx21, etd_num, etd->dma_handle, dir); | ||
327 | } | ||
328 | |||
329 | static void free_dmem(struct imx21 *imx21, int offset) | ||
330 | { | ||
331 | struct imx21_dmem_area *area; | ||
332 | struct etd_priv *etd, *tmp; | ||
333 | int found = 0; | ||
334 | |||
335 | list_for_each_entry(area, &imx21->dmem_list, list) { | ||
336 | if (area->offset == offset) { | ||
337 | debug_dmem_freed(imx21, area->size); | ||
338 | list_del(&area->list); | ||
339 | kfree(area); | ||
340 | found = 1; | ||
341 | break; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | if (!found) { | ||
346 | dev_err(imx21->dev, | ||
347 | "Trying to free unallocated DMEM %d\n", offset); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | /* Try again to allocate memory for anything we've queued */ | ||
352 | list_for_each_entry_safe(etd, tmp, &imx21->queue_for_dmem, queue) { | ||
353 | offset = alloc_dmem(imx21, etd->dmem_size, etd->ep); | ||
354 | if (offset >= 0) { | ||
355 | list_del(&etd->queue); | ||
356 | activate_queued_etd(imx21, etd, (u32)offset); | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | |||
361 | static void free_epdmem(struct imx21 *imx21, struct usb_host_endpoint *ep) | ||
362 | { | ||
363 | struct imx21_dmem_area *area, *tmp; | ||
364 | |||
365 | list_for_each_entry_safe(area, tmp, &imx21->dmem_list, list) { | ||
366 | if (area->ep == ep) { | ||
367 | dev_err(imx21->dev, | ||
368 | "Active DMEM %d for disabled ep=%p\n", | ||
369 | area->offset, ep); | ||
370 | list_del(&area->list); | ||
371 | kfree(area); | ||
372 | } | ||
373 | } | ||
374 | } | ||
375 | |||
376 | |||
377 | /* =========================================== */ | ||
378 | /* End handling */ | ||
379 | /* =========================================== */ | ||
380 | static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb); | ||
381 | |||
382 | /* Endpoint now idle - release it's ETD(s) or asssign to queued request */ | ||
383 | static void ep_idle(struct imx21 *imx21, struct ep_priv *ep_priv) | ||
384 | { | ||
385 | int etd_num; | ||
386 | int i; | ||
387 | |||
388 | for (i = 0; i < NUM_ISO_ETDS; i++) { | ||
389 | etd_num = ep_priv->etd[i]; | ||
390 | if (etd_num < 0) | ||
391 | continue; | ||
392 | |||
393 | ep_priv->etd[i] = -1; | ||
394 | if (list_empty(&imx21->queue_for_etd)) { | ||
395 | free_etd(imx21, etd_num); | ||
396 | continue; | ||
397 | } | ||
398 | |||
399 | dev_dbg(imx21->dev, | ||
400 | "assigning idle etd %d for queued request\n", etd_num); | ||
401 | ep_priv = list_first_entry(&imx21->queue_for_etd, | ||
402 | struct ep_priv, queue); | ||
403 | list_del(&ep_priv->queue); | ||
404 | reset_etd(imx21, etd_num); | ||
405 | ep_priv->waiting_etd = 0; | ||
406 | ep_priv->etd[i] = etd_num; | ||
407 | |||
408 | if (list_empty(&ep_priv->ep->urb_list)) { | ||
409 | dev_err(imx21->dev, "No urb for queued ep!\n"); | ||
410 | continue; | ||
411 | } | ||
412 | schedule_nonisoc_etd(imx21, list_first_entry( | ||
413 | &ep_priv->ep->urb_list, struct urb, urb_list)); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void urb_done(struct usb_hcd *hcd, struct urb *urb, int status) | ||
418 | __releases(imx21->lock) | ||
419 | __acquires(imx21->lock) | ||
420 | { | ||
421 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
422 | struct ep_priv *ep_priv = urb->ep->hcpriv; | ||
423 | struct urb_priv *urb_priv = urb->hcpriv; | ||
424 | |||
425 | debug_urb_completed(imx21, urb, status); | ||
426 | dev_vdbg(imx21->dev, "urb %p done %d\n", urb, status); | ||
427 | |||
428 | kfree(urb_priv->isoc_td); | ||
429 | kfree(urb->hcpriv); | ||
430 | urb->hcpriv = NULL; | ||
431 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
432 | spin_unlock(&imx21->lock); | ||
433 | usb_hcd_giveback_urb(hcd, urb, status); | ||
434 | spin_lock(&imx21->lock); | ||
435 | if (list_empty(&ep_priv->ep->urb_list)) | ||
436 | ep_idle(imx21, ep_priv); | ||
437 | } | ||
438 | |||
439 | /* =========================================== */ | ||
440 | /* ISOC Handling ... */ | ||
441 | /* =========================================== */ | ||
442 | |||
443 | static void schedule_isoc_etds(struct usb_hcd *hcd, | ||
444 | struct usb_host_endpoint *ep) | ||
445 | { | ||
446 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
447 | struct ep_priv *ep_priv = ep->hcpriv; | ||
448 | struct etd_priv *etd; | ||
449 | struct urb_priv *urb_priv; | ||
450 | struct td *td; | ||
451 | int etd_num; | ||
452 | int i; | ||
453 | int cur_frame; | ||
454 | u8 dir; | ||
455 | |||
456 | for (i = 0; i < NUM_ISO_ETDS; i++) { | ||
457 | too_late: | ||
458 | if (list_empty(&ep_priv->td_list)) | ||
459 | break; | ||
460 | |||
461 | etd_num = ep_priv->etd[i]; | ||
462 | if (etd_num < 0) | ||
463 | break; | ||
464 | |||
465 | etd = &imx21->etd[etd_num]; | ||
466 | if (etd->urb) | ||
467 | continue; | ||
468 | |||
469 | td = list_entry(ep_priv->td_list.next, struct td, list); | ||
470 | list_del(&td->list); | ||
471 | urb_priv = td->urb->hcpriv; | ||
472 | |||
473 | cur_frame = imx21_hc_get_frame(hcd); | ||
474 | if (frame_after(cur_frame, td->frame)) { | ||
475 | dev_dbg(imx21->dev, "isoc too late frame %d > %d\n", | ||
476 | cur_frame, td->frame); | ||
477 | urb_priv->isoc_status = -EXDEV; | ||
478 | td->urb->iso_frame_desc[ | ||
479 | td->isoc_index].actual_length = 0; | ||
480 | td->urb->iso_frame_desc[td->isoc_index].status = -EXDEV; | ||
481 | if (--urb_priv->isoc_remaining == 0) | ||
482 | urb_done(hcd, td->urb, urb_priv->isoc_status); | ||
483 | goto too_late; | ||
484 | } | ||
485 | |||
486 | urb_priv->active = 1; | ||
487 | etd->td = td; | ||
488 | etd->ep = td->ep; | ||
489 | etd->urb = td->urb; | ||
490 | etd->len = td->len; | ||
491 | |||
492 | debug_isoc_submitted(imx21, cur_frame, td); | ||
493 | |||
494 | dir = usb_pipeout(td->urb->pipe) ? TD_DIR_OUT : TD_DIR_IN; | ||
495 | setup_etd_dword0(imx21, etd_num, td->urb, dir, etd->dmem_size); | ||
496 | etd_writel(imx21, etd_num, 1, etd->dmem_offset); | ||
497 | etd_writel(imx21, etd_num, 2, | ||
498 | (TD_NOTACCESSED << DW2_COMPCODE) | | ||
499 | ((td->frame & 0xFFFF) << DW2_STARTFRM)); | ||
500 | etd_writel(imx21, etd_num, 3, | ||
501 | (TD_NOTACCESSED << DW3_COMPCODE0) | | ||
502 | (td->len << DW3_PKTLEN0)); | ||
503 | |||
504 | activate_etd(imx21, etd_num, td->data, dir); | ||
505 | } | ||
506 | } | ||
507 | |||
508 | static void isoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | ||
509 | { | ||
510 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
511 | int etd_mask = 1 << etd_num; | ||
512 | struct urb_priv *urb_priv = urb->hcpriv; | ||
513 | struct etd_priv *etd = imx21->etd + etd_num; | ||
514 | struct td *td = etd->td; | ||
515 | struct usb_host_endpoint *ep = etd->ep; | ||
516 | int isoc_index = td->isoc_index; | ||
517 | unsigned int pipe = urb->pipe; | ||
518 | int dir_in = usb_pipein(pipe); | ||
519 | int cc; | ||
520 | int bytes_xfrd; | ||
521 | |||
522 | disactivate_etd(imx21, etd_num); | ||
523 | |||
524 | cc = (etd_readl(imx21, etd_num, 3) >> DW3_COMPCODE0) & 0xf; | ||
525 | bytes_xfrd = etd_readl(imx21, etd_num, 3) & 0x3ff; | ||
526 | |||
527 | /* Input doesn't always fill the buffer, don't generate an error | ||
528 | * when this happens. | ||
529 | */ | ||
530 | if (dir_in && (cc == TD_DATAUNDERRUN)) | ||
531 | cc = TD_CC_NOERROR; | ||
532 | |||
533 | if (cc == TD_NOTACCESSED) | ||
534 | bytes_xfrd = 0; | ||
535 | |||
536 | debug_isoc_completed(imx21, | ||
537 | imx21_hc_get_frame(hcd), td, cc, bytes_xfrd); | ||
538 | if (cc) { | ||
539 | urb_priv->isoc_status = -EXDEV; | ||
540 | dev_dbg(imx21->dev, | ||
541 | "bad iso cc=0x%X frame=%d sched frame=%d " | ||
542 | "cnt=%d len=%d urb=%p etd=%d index=%d\n", | ||
543 | cc, imx21_hc_get_frame(hcd), td->frame, | ||
544 | bytes_xfrd, td->len, urb, etd_num, isoc_index); | ||
545 | } | ||
546 | |||
547 | if (dir_in) | ||
548 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | ||
549 | |||
550 | urb->actual_length += bytes_xfrd; | ||
551 | urb->iso_frame_desc[isoc_index].actual_length = bytes_xfrd; | ||
552 | urb->iso_frame_desc[isoc_index].status = cc_to_error[cc]; | ||
553 | |||
554 | etd->td = NULL; | ||
555 | etd->urb = NULL; | ||
556 | etd->ep = NULL; | ||
557 | |||
558 | if (--urb_priv->isoc_remaining == 0) | ||
559 | urb_done(hcd, urb, urb_priv->isoc_status); | ||
560 | |||
561 | schedule_isoc_etds(hcd, ep); | ||
562 | } | ||
563 | |||
564 | static struct ep_priv *alloc_isoc_ep( | ||
565 | struct imx21 *imx21, struct usb_host_endpoint *ep) | ||
566 | { | ||
567 | struct ep_priv *ep_priv; | ||
568 | int i; | ||
569 | |||
570 | ep_priv = kzalloc(sizeof(struct ep_priv), GFP_ATOMIC); | ||
571 | if (ep_priv == NULL) | ||
572 | return NULL; | ||
573 | |||
574 | /* Allocate the ETDs */ | ||
575 | for (i = 0; i < NUM_ISO_ETDS; i++) { | ||
576 | ep_priv->etd[i] = alloc_etd(imx21); | ||
577 | if (ep_priv->etd[i] < 0) { | ||
578 | int j; | ||
579 | dev_err(imx21->dev, "isoc: Couldn't allocate etd\n"); | ||
580 | for (j = 0; j < i; j++) | ||
581 | free_etd(imx21, ep_priv->etd[j]); | ||
582 | goto alloc_etd_failed; | ||
583 | } | ||
584 | imx21->etd[ep_priv->etd[i]].ep = ep; | ||
585 | } | ||
586 | |||
587 | INIT_LIST_HEAD(&ep_priv->td_list); | ||
588 | ep_priv->ep = ep; | ||
589 | ep->hcpriv = ep_priv; | ||
590 | return ep_priv; | ||
591 | |||
592 | alloc_etd_failed: | ||
593 | kfree(ep_priv); | ||
594 | return NULL; | ||
595 | } | ||
596 | |||
597 | static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, | ||
598 | struct usb_host_endpoint *ep, | ||
599 | struct urb *urb, gfp_t mem_flags) | ||
600 | { | ||
601 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
602 | struct urb_priv *urb_priv; | ||
603 | unsigned long flags; | ||
604 | struct ep_priv *ep_priv; | ||
605 | struct td *td = NULL; | ||
606 | int i; | ||
607 | int ret; | ||
608 | int cur_frame; | ||
609 | u16 maxpacket; | ||
610 | |||
611 | urb_priv = kzalloc(sizeof(struct urb_priv), mem_flags); | ||
612 | if (urb_priv == NULL) | ||
613 | return -ENOMEM; | ||
614 | |||
615 | urb_priv->isoc_td = kzalloc( | ||
616 | sizeof(struct td) * urb->number_of_packets, mem_flags); | ||
617 | if (urb_priv->isoc_td == NULL) { | ||
618 | ret = -ENOMEM; | ||
619 | goto alloc_td_failed; | ||
620 | } | ||
621 | |||
622 | spin_lock_irqsave(&imx21->lock, flags); | ||
623 | |||
624 | if (ep->hcpriv == NULL) { | ||
625 | ep_priv = alloc_isoc_ep(imx21, ep); | ||
626 | if (ep_priv == NULL) { | ||
627 | ret = -ENOMEM; | ||
628 | goto alloc_ep_failed; | ||
629 | } | ||
630 | } else { | ||
631 | ep_priv = ep->hcpriv; | ||
632 | } | ||
633 | |||
634 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
635 | if (ret) | ||
636 | goto link_failed; | ||
637 | |||
638 | urb->status = -EINPROGRESS; | ||
639 | urb->actual_length = 0; | ||
640 | urb->error_count = 0; | ||
641 | urb->hcpriv = urb_priv; | ||
642 | urb_priv->ep = ep; | ||
643 | |||
644 | /* allocate data memory for largest packets if not already done */ | ||
645 | maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); | ||
646 | for (i = 0; i < NUM_ISO_ETDS; i++) { | ||
647 | struct etd_priv *etd = &imx21->etd[ep_priv->etd[i]]; | ||
648 | |||
649 | if (etd->dmem_size > 0 && etd->dmem_size < maxpacket) { | ||
650 | /* not sure if this can really occur.... */ | ||
651 | dev_err(imx21->dev, "increasing isoc buffer %d->%d\n", | ||
652 | etd->dmem_size, maxpacket); | ||
653 | ret = -EMSGSIZE; | ||
654 | goto alloc_dmem_failed; | ||
655 | } | ||
656 | |||
657 | if (etd->dmem_size == 0) { | ||
658 | etd->dmem_offset = alloc_dmem(imx21, maxpacket, ep); | ||
659 | if (etd->dmem_offset < 0) { | ||
660 | dev_dbg(imx21->dev, "failed alloc isoc dmem\n"); | ||
661 | ret = -EAGAIN; | ||
662 | goto alloc_dmem_failed; | ||
663 | } | ||
664 | etd->dmem_size = maxpacket; | ||
665 | } | ||
666 | } | ||
667 | |||
668 | /* calculate frame */ | ||
669 | cur_frame = imx21_hc_get_frame(hcd); | ||
670 | if (urb->transfer_flags & URB_ISO_ASAP) { | ||
671 | if (list_empty(&ep_priv->td_list)) | ||
672 | urb->start_frame = cur_frame + 5; | ||
673 | else | ||
674 | urb->start_frame = list_entry( | ||
675 | ep_priv->td_list.prev, | ||
676 | struct td, list)->frame + urb->interval; | ||
677 | } | ||
678 | urb->start_frame = wrap_frame(urb->start_frame); | ||
679 | if (frame_after(cur_frame, urb->start_frame)) { | ||
680 | dev_dbg(imx21->dev, | ||
681 | "enqueue: adjusting iso start %d (cur=%d) asap=%d\n", | ||
682 | urb->start_frame, cur_frame, | ||
683 | (urb->transfer_flags & URB_ISO_ASAP) != 0); | ||
684 | urb->start_frame = wrap_frame(cur_frame + 1); | ||
685 | } | ||
686 | |||
687 | /* set up transfers */ | ||
688 | td = urb_priv->isoc_td; | ||
689 | for (i = 0; i < urb->number_of_packets; i++, td++) { | ||
690 | td->ep = ep; | ||
691 | td->urb = urb; | ||
692 | td->len = urb->iso_frame_desc[i].length; | ||
693 | td->isoc_index = i; | ||
694 | td->frame = wrap_frame(urb->start_frame + urb->interval * i); | ||
695 | td->data = urb->transfer_dma + urb->iso_frame_desc[i].offset; | ||
696 | list_add_tail(&td->list, &ep_priv->td_list); | ||
697 | } | ||
698 | |||
699 | urb_priv->isoc_remaining = urb->number_of_packets; | ||
700 | dev_vdbg(imx21->dev, "setup %d packets for iso frame %d->%d\n", | ||
701 | urb->number_of_packets, urb->start_frame, td->frame); | ||
702 | |||
703 | debug_urb_submitted(imx21, urb); | ||
704 | schedule_isoc_etds(hcd, ep); | ||
705 | |||
706 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
707 | return 0; | ||
708 | |||
709 | alloc_dmem_failed: | ||
710 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
711 | |||
712 | link_failed: | ||
713 | alloc_ep_failed: | ||
714 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
715 | kfree(urb_priv->isoc_td); | ||
716 | |||
717 | alloc_td_failed: | ||
718 | kfree(urb_priv); | ||
719 | return ret; | ||
720 | } | ||
721 | |||
722 | static void dequeue_isoc_urb(struct imx21 *imx21, | ||
723 | struct urb *urb, struct ep_priv *ep_priv) | ||
724 | { | ||
725 | struct urb_priv *urb_priv = urb->hcpriv; | ||
726 | struct td *td, *tmp; | ||
727 | int i; | ||
728 | |||
729 | if (urb_priv->active) { | ||
730 | for (i = 0; i < NUM_ISO_ETDS; i++) { | ||
731 | int etd_num = ep_priv->etd[i]; | ||
732 | if (etd_num != -1 && imx21->etd[etd_num].urb == urb) { | ||
733 | struct etd_priv *etd = imx21->etd + etd_num; | ||
734 | |||
735 | reset_etd(imx21, etd_num); | ||
736 | if (etd->dmem_size) | ||
737 | free_dmem(imx21, etd->dmem_offset); | ||
738 | etd->dmem_size = 0; | ||
739 | } | ||
740 | } | ||
741 | } | ||
742 | |||
743 | list_for_each_entry_safe(td, tmp, &ep_priv->td_list, list) { | ||
744 | if (td->urb == urb) { | ||
745 | dev_vdbg(imx21->dev, "removing td %p\n", td); | ||
746 | list_del(&td->list); | ||
747 | } | ||
748 | } | ||
749 | } | ||
750 | |||
751 | /* =========================================== */ | ||
752 | /* NON ISOC Handling ... */ | ||
753 | /* =========================================== */ | ||
754 | |||
755 | static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | ||
756 | { | ||
757 | unsigned int pipe = urb->pipe; | ||
758 | struct urb_priv *urb_priv = urb->hcpriv; | ||
759 | struct ep_priv *ep_priv = urb_priv->ep->hcpriv; | ||
760 | int state = urb_priv->state; | ||
761 | int etd_num = ep_priv->etd[0]; | ||
762 | struct etd_priv *etd; | ||
763 | int dmem_offset; | ||
764 | u32 count; | ||
765 | u16 etd_buf_size; | ||
766 | u16 maxpacket; | ||
767 | u8 dir; | ||
768 | u8 bufround; | ||
769 | u8 datatoggle; | ||
770 | u8 interval = 0; | ||
771 | u8 relpolpos = 0; | ||
772 | |||
773 | if (etd_num < 0) { | ||
774 | dev_err(imx21->dev, "No valid ETD\n"); | ||
775 | return; | ||
776 | } | ||
777 | if (readl(imx21->regs + USBH_ETDENSET) & (1 << etd_num)) | ||
778 | dev_err(imx21->dev, "submitting to active ETD %d\n", etd_num); | ||
779 | |||
780 | etd = &imx21->etd[etd_num]; | ||
781 | maxpacket = usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe)); | ||
782 | if (!maxpacket) | ||
783 | maxpacket = 8; | ||
784 | |||
785 | if (usb_pipecontrol(pipe) && (state != US_CTRL_DATA)) { | ||
786 | if (state == US_CTRL_SETUP) { | ||
787 | dir = TD_DIR_SETUP; | ||
788 | etd->dma_handle = urb->setup_dma; | ||
789 | bufround = 0; | ||
790 | count = 8; | ||
791 | datatoggle = TD_TOGGLE_DATA0; | ||
792 | } else { /* US_CTRL_ACK */ | ||
793 | dir = usb_pipeout(pipe) ? TD_DIR_IN : TD_DIR_OUT; | ||
794 | etd->dma_handle = urb->transfer_dma; | ||
795 | bufround = 0; | ||
796 | count = 0; | ||
797 | datatoggle = TD_TOGGLE_DATA1; | ||
798 | } | ||
799 | } else { | ||
800 | dir = usb_pipeout(pipe) ? TD_DIR_OUT : TD_DIR_IN; | ||
801 | bufround = (dir == TD_DIR_IN) ? 1 : 0; | ||
802 | etd->dma_handle = urb->transfer_dma; | ||
803 | if (usb_pipebulk(pipe) && (state == US_BULK0)) | ||
804 | count = 0; | ||
805 | else | ||
806 | count = urb->transfer_buffer_length; | ||
807 | |||
808 | if (usb_pipecontrol(pipe)) { | ||
809 | datatoggle = TD_TOGGLE_DATA1; | ||
810 | } else { | ||
811 | if (usb_gettoggle( | ||
812 | urb->dev, | ||
813 | usb_pipeendpoint(urb->pipe), | ||
814 | usb_pipeout(urb->pipe))) | ||
815 | datatoggle = TD_TOGGLE_DATA1; | ||
816 | else | ||
817 | datatoggle = TD_TOGGLE_DATA0; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | etd->urb = urb; | ||
822 | etd->ep = urb_priv->ep; | ||
823 | etd->len = count; | ||
824 | |||
825 | if (usb_pipeint(pipe)) { | ||
826 | interval = urb->interval; | ||
827 | relpolpos = (readl(imx21->regs + USBH_FRMNUB) + 1) & 0xff; | ||
828 | } | ||
829 | |||
830 | /* Write ETD to device memory */ | ||
831 | setup_etd_dword0(imx21, etd_num, urb, dir, maxpacket); | ||
832 | |||
833 | etd_writel(imx21, etd_num, 2, | ||
834 | (u32) interval << DW2_POLINTERV | | ||
835 | ((u32) relpolpos << DW2_RELPOLPOS) | | ||
836 | ((u32) dir << DW2_DIRPID) | | ||
837 | ((u32) bufround << DW2_BUFROUND) | | ||
838 | ((u32) datatoggle << DW2_DATATOG) | | ||
839 | ((u32) TD_NOTACCESSED << DW2_COMPCODE)); | ||
840 | |||
841 | /* DMA will always transfer buffer size even if TOBYCNT in DWORD3 | ||
842 | is smaller. Make sure we don't overrun the buffer! | ||
843 | */ | ||
844 | if (count && count < maxpacket) | ||
845 | etd_buf_size = count; | ||
846 | else | ||
847 | etd_buf_size = maxpacket; | ||
848 | |||
849 | etd_writel(imx21, etd_num, 3, | ||
850 | ((u32) (etd_buf_size - 1) << DW3_BUFSIZE) | (u32) count); | ||
851 | |||
852 | if (!count) | ||
853 | etd->dma_handle = 0; | ||
854 | |||
855 | /* allocate x and y buffer space at once */ | ||
856 | etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket; | ||
857 | dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep); | ||
858 | if (dmem_offset < 0) { | ||
859 | /* Setup everything we can in HW and update when we get DMEM */ | ||
860 | etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16); | ||
861 | |||
862 | dev_dbg(imx21->dev, "Queuing etd %d for DMEM\n", etd_num); | ||
863 | debug_urb_queued_for_dmem(imx21, urb); | ||
864 | list_add_tail(&etd->queue, &imx21->queue_for_dmem); | ||
865 | return; | ||
866 | } | ||
867 | |||
868 | etd_writel(imx21, etd_num, 1, | ||
869 | (((u32) dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) | | ||
870 | (u32) dmem_offset); | ||
871 | |||
872 | urb_priv->active = 1; | ||
873 | |||
874 | /* enable the ETD to kick off transfer */ | ||
875 | dev_vdbg(imx21->dev, "Activating etd %d for %d bytes %s\n", | ||
876 | etd_num, count, dir != TD_DIR_IN ? "out" : "in"); | ||
877 | activate_etd(imx21, etd_num, etd->dma_handle, dir); | ||
878 | |||
879 | } | ||
880 | |||
881 | static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | ||
882 | { | ||
883 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
884 | struct etd_priv *etd = &imx21->etd[etd_num]; | ||
885 | u32 etd_mask = 1 << etd_num; | ||
886 | struct urb_priv *urb_priv = urb->hcpriv; | ||
887 | int dir; | ||
888 | u16 xbufaddr; | ||
889 | int cc; | ||
890 | u32 bytes_xfrd; | ||
891 | int etd_done; | ||
892 | |||
893 | disactivate_etd(imx21, etd_num); | ||
894 | |||
895 | dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3; | ||
896 | xbufaddr = etd_readl(imx21, etd_num, 1) & 0xffff; | ||
897 | cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf; | ||
898 | bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff); | ||
899 | |||
900 | /* save toggle carry */ | ||
901 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
902 | usb_pipeout(urb->pipe), | ||
903 | (etd_readl(imx21, etd_num, 0) >> DW0_TOGCRY) & 0x1); | ||
904 | |||
905 | if (dir == TD_DIR_IN) { | ||
906 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | ||
907 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); | ||
908 | } | ||
909 | free_dmem(imx21, xbufaddr); | ||
910 | |||
911 | urb->error_count = 0; | ||
912 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK) | ||
913 | && (cc == TD_DATAUNDERRUN)) | ||
914 | cc = TD_CC_NOERROR; | ||
915 | |||
916 | if (cc != 0) | ||
917 | dev_vdbg(imx21->dev, "cc is 0x%x\n", cc); | ||
918 | |||
919 | etd_done = (cc_to_error[cc] != 0); /* stop if error */ | ||
920 | |||
921 | switch (usb_pipetype(urb->pipe)) { | ||
922 | case PIPE_CONTROL: | ||
923 | switch (urb_priv->state) { | ||
924 | case US_CTRL_SETUP: | ||
925 | if (urb->transfer_buffer_length > 0) | ||
926 | urb_priv->state = US_CTRL_DATA; | ||
927 | else | ||
928 | urb_priv->state = US_CTRL_ACK; | ||
929 | break; | ||
930 | case US_CTRL_DATA: | ||
931 | urb->actual_length += bytes_xfrd; | ||
932 | urb_priv->state = US_CTRL_ACK; | ||
933 | break; | ||
934 | case US_CTRL_ACK: | ||
935 | etd_done = 1; | ||
936 | break; | ||
937 | default: | ||
938 | dev_err(imx21->dev, | ||
939 | "Invalid pipe state %d\n", urb_priv->state); | ||
940 | etd_done = 1; | ||
941 | break; | ||
942 | } | ||
943 | break; | ||
944 | |||
945 | case PIPE_BULK: | ||
946 | urb->actual_length += bytes_xfrd; | ||
947 | if ((urb_priv->state == US_BULK) | ||
948 | && (urb->transfer_flags & URB_ZERO_PACKET) | ||
949 | && urb->transfer_buffer_length > 0 | ||
950 | && ((urb->transfer_buffer_length % | ||
951 | usb_maxpacket(urb->dev, urb->pipe, | ||
952 | usb_pipeout(urb->pipe))) == 0)) { | ||
953 | /* need a 0-packet */ | ||
954 | urb_priv->state = US_BULK0; | ||
955 | } else { | ||
956 | etd_done = 1; | ||
957 | } | ||
958 | break; | ||
959 | |||
960 | case PIPE_INTERRUPT: | ||
961 | urb->actual_length += bytes_xfrd; | ||
962 | etd_done = 1; | ||
963 | break; | ||
964 | } | ||
965 | |||
966 | if (!etd_done) { | ||
967 | dev_vdbg(imx21->dev, "next state=%d\n", urb_priv->state); | ||
968 | schedule_nonisoc_etd(imx21, urb); | ||
969 | } else { | ||
970 | struct usb_host_endpoint *ep = urb->ep; | ||
971 | |||
972 | urb_done(hcd, urb, cc_to_error[cc]); | ||
973 | etd->urb = NULL; | ||
974 | |||
975 | if (!list_empty(&ep->urb_list)) { | ||
976 | urb = list_first_entry(&ep->urb_list, | ||
977 | struct urb, urb_list); | ||
978 | dev_vdbg(imx21->dev, "next URB %p\n", urb); | ||
979 | schedule_nonisoc_etd(imx21, urb); | ||
980 | } | ||
981 | } | ||
982 | } | ||
983 | |||
984 | static struct ep_priv *alloc_ep(void) | ||
985 | { | ||
986 | int i; | ||
987 | struct ep_priv *ep_priv; | ||
988 | |||
989 | ep_priv = kzalloc(sizeof(struct ep_priv), GFP_ATOMIC); | ||
990 | if (!ep_priv) | ||
991 | return NULL; | ||
992 | |||
993 | for (i = 0; i < NUM_ISO_ETDS; ++i) | ||
994 | ep_priv->etd[i] = -1; | ||
995 | |||
996 | return ep_priv; | ||
997 | } | ||
998 | |||
999 | static int imx21_hc_urb_enqueue(struct usb_hcd *hcd, | ||
1000 | struct urb *urb, gfp_t mem_flags) | ||
1001 | { | ||
1002 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1003 | struct usb_host_endpoint *ep = urb->ep; | ||
1004 | struct urb_priv *urb_priv; | ||
1005 | struct ep_priv *ep_priv; | ||
1006 | struct etd_priv *etd; | ||
1007 | int ret; | ||
1008 | unsigned long flags; | ||
1009 | int new_ep = 0; | ||
1010 | |||
1011 | dev_vdbg(imx21->dev, | ||
1012 | "enqueue urb=%p ep=%p len=%d " | ||
1013 | "buffer=%p dma=%08X setupBuf=%p setupDma=%08X\n", | ||
1014 | urb, ep, | ||
1015 | urb->transfer_buffer_length, | ||
1016 | urb->transfer_buffer, urb->transfer_dma, | ||
1017 | urb->setup_packet, urb->setup_dma); | ||
1018 | |||
1019 | if (usb_pipeisoc(urb->pipe)) | ||
1020 | return imx21_hc_urb_enqueue_isoc(hcd, ep, urb, mem_flags); | ||
1021 | |||
1022 | urb_priv = kzalloc(sizeof(struct urb_priv), mem_flags); | ||
1023 | if (!urb_priv) | ||
1024 | return -ENOMEM; | ||
1025 | |||
1026 | spin_lock_irqsave(&imx21->lock, flags); | ||
1027 | |||
1028 | ep_priv = ep->hcpriv; | ||
1029 | if (ep_priv == NULL) { | ||
1030 | ep_priv = alloc_ep(); | ||
1031 | if (!ep_priv) { | ||
1032 | ret = -ENOMEM; | ||
1033 | goto failed_alloc_ep; | ||
1034 | } | ||
1035 | ep->hcpriv = ep_priv; | ||
1036 | ep_priv->ep = ep; | ||
1037 | new_ep = 1; | ||
1038 | } | ||
1039 | |||
1040 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
1041 | if (ret) | ||
1042 | goto failed_link; | ||
1043 | |||
1044 | urb->status = -EINPROGRESS; | ||
1045 | urb->actual_length = 0; | ||
1046 | urb->error_count = 0; | ||
1047 | urb->hcpriv = urb_priv; | ||
1048 | urb_priv->ep = ep; | ||
1049 | |||
1050 | switch (usb_pipetype(urb->pipe)) { | ||
1051 | case PIPE_CONTROL: | ||
1052 | urb_priv->state = US_CTRL_SETUP; | ||
1053 | break; | ||
1054 | case PIPE_BULK: | ||
1055 | urb_priv->state = US_BULK; | ||
1056 | break; | ||
1057 | } | ||
1058 | |||
1059 | debug_urb_submitted(imx21, urb); | ||
1060 | if (ep_priv->etd[0] < 0) { | ||
1061 | if (ep_priv->waiting_etd) { | ||
1062 | dev_dbg(imx21->dev, | ||
1063 | "no ETD available already queued %p\n", | ||
1064 | ep_priv); | ||
1065 | debug_urb_queued_for_etd(imx21, urb); | ||
1066 | goto out; | ||
1067 | } | ||
1068 | ep_priv->etd[0] = alloc_etd(imx21); | ||
1069 | if (ep_priv->etd[0] < 0) { | ||
1070 | dev_dbg(imx21->dev, | ||
1071 | "no ETD available queueing %p\n", ep_priv); | ||
1072 | debug_urb_queued_for_etd(imx21, urb); | ||
1073 | list_add_tail(&ep_priv->queue, &imx21->queue_for_etd); | ||
1074 | ep_priv->waiting_etd = 1; | ||
1075 | goto out; | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1079 | /* Schedule if no URB already active for this endpoint */ | ||
1080 | etd = &imx21->etd[ep_priv->etd[0]]; | ||
1081 | if (etd->urb == NULL) { | ||
1082 | DEBUG_LOG_FRAME(imx21, etd, last_req); | ||
1083 | schedule_nonisoc_etd(imx21, urb); | ||
1084 | } | ||
1085 | |||
1086 | out: | ||
1087 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1088 | return 0; | ||
1089 | |||
1090 | failed_link: | ||
1091 | failed_alloc_ep: | ||
1092 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1093 | kfree(urb_priv); | ||
1094 | return ret; | ||
1095 | } | ||
1096 | |||
1097 | static int imx21_hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | ||
1098 | int status) | ||
1099 | { | ||
1100 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1101 | unsigned long flags; | ||
1102 | struct usb_host_endpoint *ep; | ||
1103 | struct ep_priv *ep_priv; | ||
1104 | struct urb_priv *urb_priv = urb->hcpriv; | ||
1105 | int ret = -EINVAL; | ||
1106 | |||
1107 | dev_vdbg(imx21->dev, "dequeue urb=%p iso=%d status=%d\n", | ||
1108 | urb, usb_pipeisoc(urb->pipe), status); | ||
1109 | |||
1110 | spin_lock_irqsave(&imx21->lock, flags); | ||
1111 | |||
1112 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
1113 | if (ret) | ||
1114 | goto fail; | ||
1115 | ep = urb_priv->ep; | ||
1116 | ep_priv = ep->hcpriv; | ||
1117 | |||
1118 | debug_urb_unlinked(imx21, urb); | ||
1119 | |||
1120 | if (usb_pipeisoc(urb->pipe)) { | ||
1121 | dequeue_isoc_urb(imx21, urb, ep_priv); | ||
1122 | schedule_isoc_etds(hcd, ep); | ||
1123 | } else if (urb_priv->active) { | ||
1124 | int etd_num = ep_priv->etd[0]; | ||
1125 | if (etd_num != -1) { | ||
1126 | disactivate_etd(imx21, etd_num); | ||
1127 | free_dmem(imx21, etd_readl(imx21, etd_num, 1) & 0xffff); | ||
1128 | imx21->etd[etd_num].urb = NULL; | ||
1129 | } | ||
1130 | } | ||
1131 | |||
1132 | urb_done(hcd, urb, status); | ||
1133 | |||
1134 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1135 | return 0; | ||
1136 | |||
1137 | fail: | ||
1138 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1139 | return ret; | ||
1140 | } | ||
1141 | |||
1142 | /* =========================================== */ | ||
1143 | /* Interrupt dispatch */ | ||
1144 | /* =========================================== */ | ||
1145 | |||
1146 | static void process_etds(struct usb_hcd *hcd, struct imx21 *imx21, int sof) | ||
1147 | { | ||
1148 | int etd_num; | ||
1149 | int enable_sof_int = 0; | ||
1150 | unsigned long flags; | ||
1151 | |||
1152 | spin_lock_irqsave(&imx21->lock, flags); | ||
1153 | |||
1154 | for (etd_num = 0; etd_num < USB_NUM_ETD; etd_num++) { | ||
1155 | u32 etd_mask = 1 << etd_num; | ||
1156 | u32 enabled = readl(imx21->regs + USBH_ETDENSET) & etd_mask; | ||
1157 | u32 done = readl(imx21->regs + USBH_ETDDONESTAT) & etd_mask; | ||
1158 | struct etd_priv *etd = &imx21->etd[etd_num]; | ||
1159 | |||
1160 | |||
1161 | if (done) { | ||
1162 | DEBUG_LOG_FRAME(imx21, etd, last_int); | ||
1163 | } else { | ||
1164 | /* | ||
1165 | * Kludge warning! | ||
1166 | * | ||
1167 | * When multiple transfers are using the bus we sometimes get into a state | ||
1168 | * where the transfer has completed (the CC field of the ETD is != 0x0F), | ||
1169 | * the ETD has self disabled but the ETDDONESTAT flag is not set | ||
1170 | * (and hence no interrupt occurs). | ||
1171 | * This causes the transfer in question to hang. | ||
1172 | * The kludge below checks for this condition at each SOF and processes any | ||
1173 | * blocked ETDs (after an arbitary 10 frame wait) | ||
1174 | * | ||
1175 | * With a single active transfer the usbtest test suite will run for days | ||
1176 | * without the kludge. | ||
1177 | * With other bus activity (eg mass storage) even just test1 will hang without | ||
1178 | * the kludge. | ||
1179 | */ | ||
1180 | u32 dword0; | ||
1181 | int cc; | ||
1182 | |||
1183 | if (etd->active_count && !enabled) /* suspicious... */ | ||
1184 | enable_sof_int = 1; | ||
1185 | |||
1186 | if (!sof || enabled || !etd->active_count) | ||
1187 | continue; | ||
1188 | |||
1189 | cc = etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE; | ||
1190 | if (cc == TD_NOTACCESSED) | ||
1191 | continue; | ||
1192 | |||
1193 | if (++etd->active_count < 10) | ||
1194 | continue; | ||
1195 | |||
1196 | dword0 = etd_readl(imx21, etd_num, 0); | ||
1197 | dev_dbg(imx21->dev, | ||
1198 | "unblock ETD %d dev=0x%X ep=0x%X cc=0x%02X!\n", | ||
1199 | etd_num, dword0 & 0x7F, | ||
1200 | (dword0 >> DW0_ENDPNT) & 0x0F, | ||
1201 | cc); | ||
1202 | |||
1203 | #ifdef DEBUG | ||
1204 | dev_dbg(imx21->dev, | ||
1205 | "frame: act=%d disact=%d" | ||
1206 | " int=%d req=%d cur=%d\n", | ||
1207 | etd->activated_frame, | ||
1208 | etd->disactivated_frame, | ||
1209 | etd->last_int_frame, | ||
1210 | etd->last_req_frame, | ||
1211 | readl(imx21->regs + USBH_FRMNUB)); | ||
1212 | imx21->debug_unblocks++; | ||
1213 | #endif | ||
1214 | etd->active_count = 0; | ||
1215 | /* End of kludge */ | ||
1216 | } | ||
1217 | |||
1218 | if (etd->ep == NULL || etd->urb == NULL) { | ||
1219 | dev_dbg(imx21->dev, | ||
1220 | "Interrupt for unexpected etd %d" | ||
1221 | " ep=%p urb=%p\n", | ||
1222 | etd_num, etd->ep, etd->urb); | ||
1223 | disactivate_etd(imx21, etd_num); | ||
1224 | continue; | ||
1225 | } | ||
1226 | |||
1227 | if (usb_pipeisoc(etd->urb->pipe)) | ||
1228 | isoc_etd_done(hcd, etd->urb, etd_num); | ||
1229 | else | ||
1230 | nonisoc_etd_done(hcd, etd->urb, etd_num); | ||
1231 | } | ||
1232 | |||
1233 | /* only enable SOF interrupt if it may be needed for the kludge */ | ||
1234 | if (enable_sof_int) | ||
1235 | set_register_bits(imx21, USBH_SYSIEN, USBH_SYSIEN_SOFINT); | ||
1236 | else | ||
1237 | clear_register_bits(imx21, USBH_SYSIEN, USBH_SYSIEN_SOFINT); | ||
1238 | |||
1239 | |||
1240 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1241 | } | ||
1242 | |||
1243 | static irqreturn_t imx21_irq(struct usb_hcd *hcd) | ||
1244 | { | ||
1245 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1246 | u32 ints = readl(imx21->regs + USBH_SYSISR); | ||
1247 | |||
1248 | if (ints & USBH_SYSIEN_HERRINT) | ||
1249 | dev_dbg(imx21->dev, "Scheduling error\n"); | ||
1250 | |||
1251 | if (ints & USBH_SYSIEN_SORINT) | ||
1252 | dev_dbg(imx21->dev, "Scheduling overrun\n"); | ||
1253 | |||
1254 | if (ints & (USBH_SYSISR_DONEINT | USBH_SYSISR_SOFINT)) | ||
1255 | process_etds(hcd, imx21, ints & USBH_SYSISR_SOFINT); | ||
1256 | |||
1257 | writel(ints, imx21->regs + USBH_SYSISR); | ||
1258 | return IRQ_HANDLED; | ||
1259 | } | ||
1260 | |||
1261 | static void imx21_hc_endpoint_disable(struct usb_hcd *hcd, | ||
1262 | struct usb_host_endpoint *ep) | ||
1263 | { | ||
1264 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1265 | unsigned long flags; | ||
1266 | struct ep_priv *ep_priv; | ||
1267 | int i; | ||
1268 | |||
1269 | if (ep == NULL) | ||
1270 | return; | ||
1271 | |||
1272 | spin_lock_irqsave(&imx21->lock, flags); | ||
1273 | ep_priv = ep->hcpriv; | ||
1274 | dev_vdbg(imx21->dev, "disable ep=%p, ep->hcpriv=%p\n", ep, ep_priv); | ||
1275 | |||
1276 | if (!list_empty(&ep->urb_list)) | ||
1277 | dev_dbg(imx21->dev, "ep's URB list is not empty\n"); | ||
1278 | |||
1279 | if (ep_priv != NULL) { | ||
1280 | for (i = 0; i < NUM_ISO_ETDS; i++) { | ||
1281 | if (ep_priv->etd[i] > -1) | ||
1282 | dev_dbg(imx21->dev, "free etd %d for disable\n", | ||
1283 | ep_priv->etd[i]); | ||
1284 | |||
1285 | free_etd(imx21, ep_priv->etd[i]); | ||
1286 | } | ||
1287 | kfree(ep_priv); | ||
1288 | ep->hcpriv = NULL; | ||
1289 | } | ||
1290 | |||
1291 | for (i = 0; i < USB_NUM_ETD; i++) { | ||
1292 | if (imx21->etd[i].alloc && imx21->etd[i].ep == ep) { | ||
1293 | dev_err(imx21->dev, | ||
1294 | "Active etd %d for disabled ep=%p!\n", i, ep); | ||
1295 | free_etd(imx21, i); | ||
1296 | } | ||
1297 | } | ||
1298 | free_epdmem(imx21, ep); | ||
1299 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1300 | } | ||
1301 | |||
1302 | /* =========================================== */ | ||
1303 | /* Hub handling */ | ||
1304 | /* =========================================== */ | ||
1305 | |||
1306 | static int get_hub_descriptor(struct usb_hcd *hcd, | ||
1307 | struct usb_hub_descriptor *desc) | ||
1308 | { | ||
1309 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1310 | desc->bDescriptorType = 0x29; /* HUB descriptor */ | ||
1311 | desc->bHubContrCurrent = 0; | ||
1312 | |||
1313 | desc->bNbrPorts = readl(imx21->regs + USBH_ROOTHUBA) | ||
1314 | & USBH_ROOTHUBA_NDNSTMPRT_MASK; | ||
1315 | desc->bDescLength = 9; | ||
1316 | desc->bPwrOn2PwrGood = 0; | ||
1317 | desc->wHubCharacteristics = (__force __u16) cpu_to_le16( | ||
1318 | 0x0002 | /* No power switching */ | ||
1319 | 0x0010 | /* No over current protection */ | ||
1320 | 0); | ||
1321 | |||
1322 | desc->bitmap[0] = 1 << 1; | ||
1323 | desc->bitmap[1] = ~0; | ||
1324 | return 0; | ||
1325 | } | ||
1326 | |||
1327 | static int imx21_hc_hub_status_data(struct usb_hcd *hcd, char *buf) | ||
1328 | { | ||
1329 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1330 | int ports; | ||
1331 | int changed = 0; | ||
1332 | int i; | ||
1333 | unsigned long flags; | ||
1334 | |||
1335 | spin_lock_irqsave(&imx21->lock, flags); | ||
1336 | ports = readl(imx21->regs + USBH_ROOTHUBA) | ||
1337 | & USBH_ROOTHUBA_NDNSTMPRT_MASK; | ||
1338 | if (ports > 7) { | ||
1339 | ports = 7; | ||
1340 | dev_err(imx21->dev, "ports %d > 7\n", ports); | ||
1341 | } | ||
1342 | for (i = 0; i < ports; i++) { | ||
1343 | if (readl(imx21->regs + USBH_PORTSTAT(i)) & | ||
1344 | (USBH_PORTSTAT_CONNECTSC | | ||
1345 | USBH_PORTSTAT_PRTENBLSC | | ||
1346 | USBH_PORTSTAT_PRTSTATSC | | ||
1347 | USBH_PORTSTAT_OVRCURIC | | ||
1348 | USBH_PORTSTAT_PRTRSTSC)) { | ||
1349 | |||
1350 | changed = 1; | ||
1351 | buf[0] |= 1 << (i + 1); | ||
1352 | } | ||
1353 | } | ||
1354 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1355 | |||
1356 | if (changed) | ||
1357 | dev_info(imx21->dev, "Hub status changed\n"); | ||
1358 | return changed; | ||
1359 | } | ||
1360 | |||
1361 | static int imx21_hc_hub_control(struct usb_hcd *hcd, | ||
1362 | u16 typeReq, | ||
1363 | u16 wValue, u16 wIndex, char *buf, u16 wLength) | ||
1364 | { | ||
1365 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1366 | int rc = 0; | ||
1367 | u32 status_write = 0; | ||
1368 | |||
1369 | switch (typeReq) { | ||
1370 | case ClearHubFeature: | ||
1371 | dev_dbg(imx21->dev, "ClearHubFeature\n"); | ||
1372 | switch (wValue) { | ||
1373 | case C_HUB_OVER_CURRENT: | ||
1374 | dev_dbg(imx21->dev, " OVER_CURRENT\n"); | ||
1375 | break; | ||
1376 | case C_HUB_LOCAL_POWER: | ||
1377 | dev_dbg(imx21->dev, " LOCAL_POWER\n"); | ||
1378 | break; | ||
1379 | default: | ||
1380 | dev_dbg(imx21->dev, " unknown\n"); | ||
1381 | rc = -EINVAL; | ||
1382 | break; | ||
1383 | } | ||
1384 | break; | ||
1385 | |||
1386 | case ClearPortFeature: | ||
1387 | dev_dbg(imx21->dev, "ClearPortFeature\n"); | ||
1388 | switch (wValue) { | ||
1389 | case USB_PORT_FEAT_ENABLE: | ||
1390 | dev_dbg(imx21->dev, " ENABLE\n"); | ||
1391 | status_write = USBH_PORTSTAT_CURCONST; | ||
1392 | break; | ||
1393 | case USB_PORT_FEAT_SUSPEND: | ||
1394 | dev_dbg(imx21->dev, " SUSPEND\n"); | ||
1395 | status_write = USBH_PORTSTAT_PRTOVRCURI; | ||
1396 | break; | ||
1397 | case USB_PORT_FEAT_POWER: | ||
1398 | dev_dbg(imx21->dev, " POWER\n"); | ||
1399 | status_write = USBH_PORTSTAT_LSDEVCON; | ||
1400 | break; | ||
1401 | case USB_PORT_FEAT_C_ENABLE: | ||
1402 | dev_dbg(imx21->dev, " C_ENABLE\n"); | ||
1403 | status_write = USBH_PORTSTAT_PRTENBLSC; | ||
1404 | break; | ||
1405 | case USB_PORT_FEAT_C_SUSPEND: | ||
1406 | dev_dbg(imx21->dev, " C_SUSPEND\n"); | ||
1407 | status_write = USBH_PORTSTAT_PRTSTATSC; | ||
1408 | break; | ||
1409 | case USB_PORT_FEAT_C_CONNECTION: | ||
1410 | dev_dbg(imx21->dev, " C_CONNECTION\n"); | ||
1411 | status_write = USBH_PORTSTAT_CONNECTSC; | ||
1412 | break; | ||
1413 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
1414 | dev_dbg(imx21->dev, " C_OVER_CURRENT\n"); | ||
1415 | status_write = USBH_PORTSTAT_OVRCURIC; | ||
1416 | break; | ||
1417 | case USB_PORT_FEAT_C_RESET: | ||
1418 | dev_dbg(imx21->dev, " C_RESET\n"); | ||
1419 | status_write = USBH_PORTSTAT_PRTRSTSC; | ||
1420 | break; | ||
1421 | default: | ||
1422 | dev_dbg(imx21->dev, " unknown\n"); | ||
1423 | rc = -EINVAL; | ||
1424 | break; | ||
1425 | } | ||
1426 | |||
1427 | break; | ||
1428 | |||
1429 | case GetHubDescriptor: | ||
1430 | dev_dbg(imx21->dev, "GetHubDescriptor\n"); | ||
1431 | rc = get_hub_descriptor(hcd, (void *)buf); | ||
1432 | break; | ||
1433 | |||
1434 | case GetHubStatus: | ||
1435 | dev_dbg(imx21->dev, " GetHubStatus\n"); | ||
1436 | *(__le32 *) buf = 0; | ||
1437 | break; | ||
1438 | |||
1439 | case GetPortStatus: | ||
1440 | dev_dbg(imx21->dev, "GetPortStatus: port: %d, 0x%x\n", | ||
1441 | wIndex, USBH_PORTSTAT(wIndex - 1)); | ||
1442 | *(__le32 *) buf = readl(imx21->regs + | ||
1443 | USBH_PORTSTAT(wIndex - 1)); | ||
1444 | break; | ||
1445 | |||
1446 | case SetHubFeature: | ||
1447 | dev_dbg(imx21->dev, "SetHubFeature\n"); | ||
1448 | switch (wValue) { | ||
1449 | case C_HUB_OVER_CURRENT: | ||
1450 | dev_dbg(imx21->dev, " OVER_CURRENT\n"); | ||
1451 | break; | ||
1452 | |||
1453 | case C_HUB_LOCAL_POWER: | ||
1454 | dev_dbg(imx21->dev, " LOCAL_POWER\n"); | ||
1455 | break; | ||
1456 | default: | ||
1457 | dev_dbg(imx21->dev, " unknown\n"); | ||
1458 | rc = -EINVAL; | ||
1459 | break; | ||
1460 | } | ||
1461 | |||
1462 | break; | ||
1463 | |||
1464 | case SetPortFeature: | ||
1465 | dev_dbg(imx21->dev, "SetPortFeature\n"); | ||
1466 | switch (wValue) { | ||
1467 | case USB_PORT_FEAT_SUSPEND: | ||
1468 | dev_dbg(imx21->dev, " SUSPEND\n"); | ||
1469 | status_write = USBH_PORTSTAT_PRTSUSPST; | ||
1470 | break; | ||
1471 | case USB_PORT_FEAT_POWER: | ||
1472 | dev_dbg(imx21->dev, " POWER\n"); | ||
1473 | status_write = USBH_PORTSTAT_PRTPWRST; | ||
1474 | break; | ||
1475 | case USB_PORT_FEAT_RESET: | ||
1476 | dev_dbg(imx21->dev, " RESET\n"); | ||
1477 | status_write = USBH_PORTSTAT_PRTRSTST; | ||
1478 | break; | ||
1479 | default: | ||
1480 | dev_dbg(imx21->dev, " unknown\n"); | ||
1481 | rc = -EINVAL; | ||
1482 | break; | ||
1483 | } | ||
1484 | break; | ||
1485 | |||
1486 | default: | ||
1487 | dev_dbg(imx21->dev, " unknown\n"); | ||
1488 | rc = -EINVAL; | ||
1489 | break; | ||
1490 | } | ||
1491 | |||
1492 | if (status_write) | ||
1493 | writel(status_write, imx21->regs + USBH_PORTSTAT(wIndex - 1)); | ||
1494 | return rc; | ||
1495 | } | ||
1496 | |||
1497 | /* =========================================== */ | ||
1498 | /* Host controller management */ | ||
1499 | /* =========================================== */ | ||
1500 | |||
1501 | static int imx21_hc_reset(struct usb_hcd *hcd) | ||
1502 | { | ||
1503 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1504 | unsigned long timeout; | ||
1505 | unsigned long flags; | ||
1506 | |||
1507 | spin_lock_irqsave(&imx21->lock, flags); | ||
1508 | |||
1509 | /* Reset the Host controler modules */ | ||
1510 | writel(USBOTG_RST_RSTCTRL | USBOTG_RST_RSTRH | | ||
1511 | USBOTG_RST_RSTHSIE | USBOTG_RST_RSTHC, | ||
1512 | imx21->regs + USBOTG_RST_CTRL); | ||
1513 | |||
1514 | /* Wait for reset to finish */ | ||
1515 | timeout = jiffies + HZ; | ||
1516 | while (readl(imx21->regs + USBOTG_RST_CTRL) != 0) { | ||
1517 | if (time_after(jiffies, timeout)) { | ||
1518 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1519 | dev_err(imx21->dev, "timeout waiting for reset\n"); | ||
1520 | return -ETIMEDOUT; | ||
1521 | } | ||
1522 | spin_unlock_irq(&imx21->lock); | ||
1523 | schedule_timeout(1); | ||
1524 | spin_lock_irq(&imx21->lock); | ||
1525 | } | ||
1526 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1527 | return 0; | ||
1528 | } | ||
1529 | |||
1530 | static int __devinit imx21_hc_start(struct usb_hcd *hcd) | ||
1531 | { | ||
1532 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1533 | unsigned long flags; | ||
1534 | int i, j; | ||
1535 | u32 hw_mode = USBOTG_HWMODE_CRECFG_HOST; | ||
1536 | u32 usb_control = 0; | ||
1537 | |||
1538 | hw_mode |= ((imx21->pdata->host_xcvr << USBOTG_HWMODE_HOSTXCVR_SHIFT) & | ||
1539 | USBOTG_HWMODE_HOSTXCVR_MASK); | ||
1540 | hw_mode |= ((imx21->pdata->otg_xcvr << USBOTG_HWMODE_OTGXCVR_SHIFT) & | ||
1541 | USBOTG_HWMODE_OTGXCVR_MASK); | ||
1542 | |||
1543 | if (imx21->pdata->host1_txenoe) | ||
1544 | usb_control |= USBCTRL_HOST1_TXEN_OE; | ||
1545 | |||
1546 | if (!imx21->pdata->host1_xcverless) | ||
1547 | usb_control |= USBCTRL_HOST1_BYP_TLL; | ||
1548 | |||
1549 | if (imx21->pdata->otg_ext_xcvr) | ||
1550 | usb_control |= USBCTRL_OTC_RCV_RXDP; | ||
1551 | |||
1552 | |||
1553 | spin_lock_irqsave(&imx21->lock, flags); | ||
1554 | |||
1555 | writel((USBOTG_CLK_CTRL_HST | USBOTG_CLK_CTRL_MAIN), | ||
1556 | imx21->regs + USBOTG_CLK_CTRL); | ||
1557 | writel(hw_mode, imx21->regs + USBOTG_HWMODE); | ||
1558 | writel(usb_control, imx21->regs + USBCTRL); | ||
1559 | writel(USB_MISCCONTROL_SKPRTRY | USB_MISCCONTROL_ARBMODE, | ||
1560 | imx21->regs + USB_MISCCONTROL); | ||
1561 | |||
1562 | /* Clear the ETDs */ | ||
1563 | for (i = 0; i < USB_NUM_ETD; i++) | ||
1564 | for (j = 0; j < 4; j++) | ||
1565 | etd_writel(imx21, i, j, 0); | ||
1566 | |||
1567 | /* Take the HC out of reset */ | ||
1568 | writel(USBH_HOST_CTRL_HCUSBSTE_OPERATIONAL | USBH_HOST_CTRL_CTLBLKSR_1, | ||
1569 | imx21->regs + USBH_HOST_CTRL); | ||
1570 | |||
1571 | /* Enable ports */ | ||
1572 | if (imx21->pdata->enable_otg_host) | ||
1573 | writel(USBH_PORTSTAT_PRTPWRST | USBH_PORTSTAT_PRTENABST, | ||
1574 | imx21->regs + USBH_PORTSTAT(0)); | ||
1575 | |||
1576 | if (imx21->pdata->enable_host1) | ||
1577 | writel(USBH_PORTSTAT_PRTPWRST | USBH_PORTSTAT_PRTENABST, | ||
1578 | imx21->regs + USBH_PORTSTAT(1)); | ||
1579 | |||
1580 | if (imx21->pdata->enable_host2) | ||
1581 | writel(USBH_PORTSTAT_PRTPWRST | USBH_PORTSTAT_PRTENABST, | ||
1582 | imx21->regs + USBH_PORTSTAT(2)); | ||
1583 | |||
1584 | |||
1585 | hcd->state = HC_STATE_RUNNING; | ||
1586 | |||
1587 | /* Enable host controller interrupts */ | ||
1588 | set_register_bits(imx21, USBH_SYSIEN, | ||
1589 | USBH_SYSIEN_HERRINT | | ||
1590 | USBH_SYSIEN_DONEINT | USBH_SYSIEN_SORINT); | ||
1591 | set_register_bits(imx21, USBOTG_CINT_STEN, USBOTG_HCINT); | ||
1592 | |||
1593 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1594 | |||
1595 | return 0; | ||
1596 | } | ||
1597 | |||
1598 | static void imx21_hc_stop(struct usb_hcd *hcd) | ||
1599 | { | ||
1600 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1601 | unsigned long flags; | ||
1602 | |||
1603 | spin_lock_irqsave(&imx21->lock, flags); | ||
1604 | |||
1605 | writel(0, imx21->regs + USBH_SYSIEN); | ||
1606 | clear_register_bits(imx21, USBOTG_CINT_STEN, USBOTG_HCINT); | ||
1607 | clear_register_bits(imx21, USBOTG_CLK_CTRL_HST | USBOTG_CLK_CTRL_MAIN, | ||
1608 | USBOTG_CLK_CTRL); | ||
1609 | spin_unlock_irqrestore(&imx21->lock, flags); | ||
1610 | } | ||
1611 | |||
1612 | /* =========================================== */ | ||
1613 | /* Driver glue */ | ||
1614 | /* =========================================== */ | ||
1615 | |||
1616 | static struct hc_driver imx21_hc_driver = { | ||
1617 | .description = hcd_name, | ||
1618 | .product_desc = "IMX21 USB Host Controller", | ||
1619 | .hcd_priv_size = sizeof(struct imx21), | ||
1620 | |||
1621 | .flags = HCD_USB11, | ||
1622 | .irq = imx21_irq, | ||
1623 | |||
1624 | .reset = imx21_hc_reset, | ||
1625 | .start = imx21_hc_start, | ||
1626 | .stop = imx21_hc_stop, | ||
1627 | |||
1628 | /* I/O requests */ | ||
1629 | .urb_enqueue = imx21_hc_urb_enqueue, | ||
1630 | .urb_dequeue = imx21_hc_urb_dequeue, | ||
1631 | .endpoint_disable = imx21_hc_endpoint_disable, | ||
1632 | |||
1633 | /* scheduling support */ | ||
1634 | .get_frame_number = imx21_hc_get_frame, | ||
1635 | |||
1636 | /* Root hub support */ | ||
1637 | .hub_status_data = imx21_hc_hub_status_data, | ||
1638 | .hub_control = imx21_hc_hub_control, | ||
1639 | |||
1640 | }; | ||
1641 | |||
1642 | static struct mx21_usbh_platform_data default_pdata = { | ||
1643 | .host_xcvr = MX21_USBXCVR_TXDIF_RXDIF, | ||
1644 | .otg_xcvr = MX21_USBXCVR_TXDIF_RXDIF, | ||
1645 | .enable_host1 = 1, | ||
1646 | .enable_host2 = 1, | ||
1647 | .enable_otg_host = 1, | ||
1648 | |||
1649 | }; | ||
1650 | |||
1651 | static int imx21_remove(struct platform_device *pdev) | ||
1652 | { | ||
1653 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
1654 | struct imx21 *imx21 = hcd_to_imx21(hcd); | ||
1655 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1656 | |||
1657 | remove_debug_files(imx21); | ||
1658 | usb_remove_hcd(hcd); | ||
1659 | |||
1660 | if (res != NULL) { | ||
1661 | clk_disable(imx21->clk); | ||
1662 | clk_put(imx21->clk); | ||
1663 | iounmap(imx21->regs); | ||
1664 | release_mem_region(res->start, resource_size(res)); | ||
1665 | } | ||
1666 | |||
1667 | kfree(hcd); | ||
1668 | return 0; | ||
1669 | } | ||
1670 | |||
1671 | |||
1672 | static int imx21_probe(struct platform_device *pdev) | ||
1673 | { | ||
1674 | struct usb_hcd *hcd; | ||
1675 | struct imx21 *imx21; | ||
1676 | struct resource *res; | ||
1677 | int ret; | ||
1678 | int irq; | ||
1679 | |||
1680 | printk(KERN_INFO "%s\n", imx21_hc_driver.product_desc); | ||
1681 | |||
1682 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1683 | if (!res) | ||
1684 | return -ENODEV; | ||
1685 | irq = platform_get_irq(pdev, 0); | ||
1686 | if (irq < 0) | ||
1687 | return -ENXIO; | ||
1688 | |||
1689 | hcd = usb_create_hcd(&imx21_hc_driver, | ||
1690 | &pdev->dev, dev_name(&pdev->dev)); | ||
1691 | if (hcd == NULL) { | ||
1692 | dev_err(&pdev->dev, "Cannot create hcd (%s)\n", | ||
1693 | dev_name(&pdev->dev)); | ||
1694 | return -ENOMEM; | ||
1695 | } | ||
1696 | |||
1697 | imx21 = hcd_to_imx21(hcd); | ||
1698 | imx21->dev = &pdev->dev; | ||
1699 | imx21->pdata = pdev->dev.platform_data; | ||
1700 | if (!imx21->pdata) | ||
1701 | imx21->pdata = &default_pdata; | ||
1702 | |||
1703 | spin_lock_init(&imx21->lock); | ||
1704 | INIT_LIST_HEAD(&imx21->dmem_list); | ||
1705 | INIT_LIST_HEAD(&imx21->queue_for_etd); | ||
1706 | INIT_LIST_HEAD(&imx21->queue_for_dmem); | ||
1707 | create_debug_files(imx21); | ||
1708 | |||
1709 | res = request_mem_region(res->start, resource_size(res), hcd_name); | ||
1710 | if (!res) { | ||
1711 | ret = -EBUSY; | ||
1712 | goto failed_request_mem; | ||
1713 | } | ||
1714 | |||
1715 | imx21->regs = ioremap(res->start, resource_size(res)); | ||
1716 | if (imx21->regs == NULL) { | ||
1717 | dev_err(imx21->dev, "Cannot map registers\n"); | ||
1718 | ret = -ENOMEM; | ||
1719 | goto failed_ioremap; | ||
1720 | } | ||
1721 | |||
1722 | /* Enable clocks source */ | ||
1723 | imx21->clk = clk_get(imx21->dev, NULL); | ||
1724 | if (IS_ERR(imx21->clk)) { | ||
1725 | dev_err(imx21->dev, "no clock found\n"); | ||
1726 | ret = PTR_ERR(imx21->clk); | ||
1727 | goto failed_clock_get; | ||
1728 | } | ||
1729 | |||
1730 | ret = clk_set_rate(imx21->clk, clk_round_rate(imx21->clk, 48000000)); | ||
1731 | if (ret) | ||
1732 | goto failed_clock_set; | ||
1733 | ret = clk_enable(imx21->clk); | ||
1734 | if (ret) | ||
1735 | goto failed_clock_enable; | ||
1736 | |||
1737 | dev_info(imx21->dev, "Hardware HC revision: 0x%02X\n", | ||
1738 | (readl(imx21->regs + USBOTG_HWMODE) >> 16) & 0xFF); | ||
1739 | |||
1740 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | ||
1741 | if (ret != 0) { | ||
1742 | dev_err(imx21->dev, "usb_add_hcd() returned %d\n", ret); | ||
1743 | goto failed_add_hcd; | ||
1744 | } | ||
1745 | |||
1746 | return 0; | ||
1747 | |||
1748 | failed_add_hcd: | ||
1749 | clk_disable(imx21->clk); | ||
1750 | failed_clock_enable: | ||
1751 | failed_clock_set: | ||
1752 | clk_put(imx21->clk); | ||
1753 | failed_clock_get: | ||
1754 | iounmap(imx21->regs); | ||
1755 | failed_ioremap: | ||
1756 | release_mem_region(res->start, res->end - res->start); | ||
1757 | failed_request_mem: | ||
1758 | remove_debug_files(imx21); | ||
1759 | usb_put_hcd(hcd); | ||
1760 | return ret; | ||
1761 | } | ||
1762 | |||
1763 | static struct platform_driver imx21_hcd_driver = { | ||
1764 | .driver = { | ||
1765 | .name = (char *)hcd_name, | ||
1766 | }, | ||
1767 | .probe = imx21_probe, | ||
1768 | .remove = imx21_remove, | ||
1769 | .suspend = NULL, | ||
1770 | .resume = NULL, | ||
1771 | }; | ||
1772 | |||
1773 | static int __init imx21_hcd_init(void) | ||
1774 | { | ||
1775 | return platform_driver_register(&imx21_hcd_driver); | ||
1776 | } | ||
1777 | |||
1778 | static void __exit imx21_hcd_cleanup(void) | ||
1779 | { | ||
1780 | platform_driver_unregister(&imx21_hcd_driver); | ||
1781 | } | ||
1782 | |||
1783 | module_init(imx21_hcd_init); | ||
1784 | module_exit(imx21_hcd_cleanup); | ||
1785 | |||
1786 | MODULE_DESCRIPTION("i.MX21 USB Host controller"); | ||
1787 | MODULE_AUTHOR("Martin Fuzzey"); | ||
1788 | MODULE_LICENSE("GPL"); | ||
1789 | MODULE_ALIAS("platform:imx21-hcd"); | ||
diff --git a/drivers/usb/host/imx21-hcd.h b/drivers/usb/host/imx21-hcd.h new file mode 100644 index 000000000000..1b0d913780a5 --- /dev/null +++ b/drivers/usb/host/imx21-hcd.h | |||
@@ -0,0 +1,436 @@ | |||
1 | /* | ||
2 | * Macros and prototypes for i.MX21 | ||
3 | * | ||
4 | * Copyright (C) 2006 Loping Dog Embedded Systems | ||
5 | * Copyright (C) 2009 Martin Fuzzey | ||
6 | * Originally written by Jay Monkman <jtm@lopingdog.com> | ||
7 | * Ported to 2.6.30, debugged and enhanced by Martin Fuzzey | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
17 | * for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software Foundation, | ||
21 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef __LINUX_IMX21_HCD_H__ | ||
25 | #define __LINUX_IMX21_HCD_H__ | ||
26 | |||
27 | #include <mach/mx21-usbhost.h> | ||
28 | |||
29 | #define NUM_ISO_ETDS 2 | ||
30 | #define USB_NUM_ETD 32 | ||
31 | #define DMEM_SIZE 4096 | ||
32 | |||
33 | /* Register definitions */ | ||
34 | #define USBOTG_HWMODE 0x00 | ||
35 | #define USBOTG_HWMODE_ANASDBEN (1 << 14) | ||
36 | #define USBOTG_HWMODE_OTGXCVR_SHIFT 6 | ||
37 | #define USBOTG_HWMODE_OTGXCVR_MASK (3 << 6) | ||
38 | #define USBOTG_HWMODE_OTGXCVR_TD_RD (0 << 6) | ||
39 | #define USBOTG_HWMODE_OTGXCVR_TS_RD (2 << 6) | ||
40 | #define USBOTG_HWMODE_OTGXCVR_TD_RS (1 << 6) | ||
41 | #define USBOTG_HWMODE_OTGXCVR_TS_RS (3 << 6) | ||
42 | #define USBOTG_HWMODE_HOSTXCVR_SHIFT 4 | ||
43 | #define USBOTG_HWMODE_HOSTXCVR_MASK (3 << 4) | ||
44 | #define USBOTG_HWMODE_HOSTXCVR_TD_RD (0 << 4) | ||
45 | #define USBOTG_HWMODE_HOSTXCVR_TS_RD (2 << 4) | ||
46 | #define USBOTG_HWMODE_HOSTXCVR_TD_RS (1 << 4) | ||
47 | #define USBOTG_HWMODE_HOSTXCVR_TS_RS (3 << 4) | ||
48 | #define USBOTG_HWMODE_CRECFG_MASK (3 << 0) | ||
49 | #define USBOTG_HWMODE_CRECFG_HOST (1 << 0) | ||
50 | #define USBOTG_HWMODE_CRECFG_FUNC (2 << 0) | ||
51 | #define USBOTG_HWMODE_CRECFG_HNP (3 << 0) | ||
52 | |||
53 | #define USBOTG_CINT_STAT 0x04 | ||
54 | #define USBOTG_CINT_STEN 0x08 | ||
55 | #define USBOTG_ASHNPINT (1 << 5) | ||
56 | #define USBOTG_ASFCINT (1 << 4) | ||
57 | #define USBOTG_ASHCINT (1 << 3) | ||
58 | #define USBOTG_SHNPINT (1 << 2) | ||
59 | #define USBOTG_FCINT (1 << 1) | ||
60 | #define USBOTG_HCINT (1 << 0) | ||
61 | |||
62 | #define USBOTG_CLK_CTRL 0x0c | ||
63 | #define USBOTG_CLK_CTRL_FUNC (1 << 2) | ||
64 | #define USBOTG_CLK_CTRL_HST (1 << 1) | ||
65 | #define USBOTG_CLK_CTRL_MAIN (1 << 0) | ||
66 | |||
67 | #define USBOTG_RST_CTRL 0x10 | ||
68 | #define USBOTG_RST_RSTI2C (1 << 15) | ||
69 | #define USBOTG_RST_RSTCTRL (1 << 5) | ||
70 | #define USBOTG_RST_RSTFC (1 << 4) | ||
71 | #define USBOTG_RST_RSTFSKE (1 << 3) | ||
72 | #define USBOTG_RST_RSTRH (1 << 2) | ||
73 | #define USBOTG_RST_RSTHSIE (1 << 1) | ||
74 | #define USBOTG_RST_RSTHC (1 << 0) | ||
75 | |||
76 | #define USBOTG_FRM_INTVL 0x14 | ||
77 | #define USBOTG_FRM_REMAIN 0x18 | ||
78 | #define USBOTG_HNP_CSR 0x1c | ||
79 | #define USBOTG_HNP_ISR 0x2c | ||
80 | #define USBOTG_HNP_IEN 0x30 | ||
81 | |||
82 | #define USBOTG_I2C_TXCVR_REG(x) (0x100 + (x)) | ||
83 | #define USBOTG_I2C_XCVR_DEVAD 0x118 | ||
84 | #define USBOTG_I2C_SEQ_OP_REG 0x119 | ||
85 | #define USBOTG_I2C_SEQ_RD_STARTAD 0x11a | ||
86 | #define USBOTG_I2C_OP_CTRL_REG 0x11b | ||
87 | #define USBOTG_I2C_SCLK_TO_SCK_HPER 0x11e | ||
88 | #define USBOTG_I2C_MASTER_INT_REG 0x11f | ||
89 | |||
90 | #define USBH_HOST_CTRL 0x80 | ||
91 | #define USBH_HOST_CTRL_HCRESET (1 << 31) | ||
92 | #define USBH_HOST_CTRL_SCHDOVR(x) ((x) << 16) | ||
93 | #define USBH_HOST_CTRL_RMTWUEN (1 << 4) | ||
94 | #define USBH_HOST_CTRL_HCUSBSTE_RESET (0 << 2) | ||
95 | #define USBH_HOST_CTRL_HCUSBSTE_RESUME (1 << 2) | ||
96 | #define USBH_HOST_CTRL_HCUSBSTE_OPERATIONAL (2 << 2) | ||
97 | #define USBH_HOST_CTRL_HCUSBSTE_SUSPEND (3 << 2) | ||
98 | #define USBH_HOST_CTRL_CTLBLKSR_1 (0 << 0) | ||
99 | #define USBH_HOST_CTRL_CTLBLKSR_2 (1 << 0) | ||
100 | #define USBH_HOST_CTRL_CTLBLKSR_3 (2 << 0) | ||
101 | #define USBH_HOST_CTRL_CTLBLKSR_4 (3 << 0) | ||
102 | |||
103 | #define USBH_SYSISR 0x88 | ||
104 | #define USBH_SYSISR_PSCINT (1 << 6) | ||
105 | #define USBH_SYSISR_FMOFINT (1 << 5) | ||
106 | #define USBH_SYSISR_HERRINT (1 << 4) | ||
107 | #define USBH_SYSISR_RESDETINT (1 << 3) | ||
108 | #define USBH_SYSISR_SOFINT (1 << 2) | ||
109 | #define USBH_SYSISR_DONEINT (1 << 1) | ||
110 | #define USBH_SYSISR_SORINT (1 << 0) | ||
111 | |||
112 | #define USBH_SYSIEN 0x8c | ||
113 | #define USBH_SYSIEN_PSCINT (1 << 6) | ||
114 | #define USBH_SYSIEN_FMOFINT (1 << 5) | ||
115 | #define USBH_SYSIEN_HERRINT (1 << 4) | ||
116 | #define USBH_SYSIEN_RESDETINT (1 << 3) | ||
117 | #define USBH_SYSIEN_SOFINT (1 << 2) | ||
118 | #define USBH_SYSIEN_DONEINT (1 << 1) | ||
119 | #define USBH_SYSIEN_SORINT (1 << 0) | ||
120 | |||
121 | #define USBH_XBUFSTAT 0x98 | ||
122 | #define USBH_YBUFSTAT 0x9c | ||
123 | #define USBH_XYINTEN 0xa0 | ||
124 | #define USBH_XFILLSTAT 0xa8 | ||
125 | #define USBH_YFILLSTAT 0xac | ||
126 | #define USBH_ETDENSET 0xc0 | ||
127 | #define USBH_ETDENCLR 0xc4 | ||
128 | #define USBH_IMMEDINT 0xcc | ||
129 | #define USBH_ETDDONESTAT 0xd0 | ||
130 | #define USBH_ETDDONEEN 0xd4 | ||
131 | #define USBH_FRMNUB 0xe0 | ||
132 | #define USBH_LSTHRESH 0xe4 | ||
133 | |||
134 | #define USBH_ROOTHUBA 0xe8 | ||
135 | #define USBH_ROOTHUBA_PWRTOGOOD_MASK (0xff) | ||
136 | #define USBH_ROOTHUBA_PWRTOGOOD_SHIFT (24) | ||
137 | #define USBH_ROOTHUBA_NOOVRCURP (1 << 12) | ||
138 | #define USBH_ROOTHUBA_OVRCURPM (1 << 11) | ||
139 | #define USBH_ROOTHUBA_DEVTYPE (1 << 10) | ||
140 | #define USBH_ROOTHUBA_PWRSWTMD (1 << 9) | ||
141 | #define USBH_ROOTHUBA_NOPWRSWT (1 << 8) | ||
142 | #define USBH_ROOTHUBA_NDNSTMPRT_MASK (0xff) | ||
143 | |||
144 | #define USBH_ROOTHUBB 0xec | ||
145 | #define USBH_ROOTHUBB_PRTPWRCM(x) (1 << ((x) + 16)) | ||
146 | #define USBH_ROOTHUBB_DEVREMOVE(x) (1 << (x)) | ||
147 | |||
148 | #define USBH_ROOTSTAT 0xf0 | ||
149 | #define USBH_ROOTSTAT_CLRRMTWUE (1 << 31) | ||
150 | #define USBH_ROOTSTAT_OVRCURCHG (1 << 17) | ||
151 | #define USBH_ROOTSTAT_DEVCONWUE (1 << 15) | ||
152 | #define USBH_ROOTSTAT_OVRCURI (1 << 1) | ||
153 | #define USBH_ROOTSTAT_LOCPWRS (1 << 0) | ||
154 | |||
155 | #define USBH_PORTSTAT(x) (0xf4 + ((x) * 4)) | ||
156 | #define USBH_PORTSTAT_PRTRSTSC (1 << 20) | ||
157 | #define USBH_PORTSTAT_OVRCURIC (1 << 19) | ||
158 | #define USBH_PORTSTAT_PRTSTATSC (1 << 18) | ||
159 | #define USBH_PORTSTAT_PRTENBLSC (1 << 17) | ||
160 | #define USBH_PORTSTAT_CONNECTSC (1 << 16) | ||
161 | #define USBH_PORTSTAT_LSDEVCON (1 << 9) | ||
162 | #define USBH_PORTSTAT_PRTPWRST (1 << 8) | ||
163 | #define USBH_PORTSTAT_PRTRSTST (1 << 4) | ||
164 | #define USBH_PORTSTAT_PRTOVRCURI (1 << 3) | ||
165 | #define USBH_PORTSTAT_PRTSUSPST (1 << 2) | ||
166 | #define USBH_PORTSTAT_PRTENABST (1 << 1) | ||
167 | #define USBH_PORTSTAT_CURCONST (1 << 0) | ||
168 | |||
169 | #define USB_DMAREV 0x800 | ||
170 | #define USB_DMAINTSTAT 0x804 | ||
171 | #define USB_DMAINTSTAT_EPERR (1 << 1) | ||
172 | #define USB_DMAINTSTAT_ETDERR (1 << 0) | ||
173 | |||
174 | #define USB_DMAINTEN 0x808 | ||
175 | #define USB_DMAINTEN_EPERRINTEN (1 << 1) | ||
176 | #define USB_DMAINTEN_ETDERRINTEN (1 << 0) | ||
177 | |||
178 | #define USB_ETDDMAERSTAT 0x80c | ||
179 | #define USB_EPDMAERSTAT 0x810 | ||
180 | #define USB_ETDDMAEN 0x820 | ||
181 | #define USB_EPDMAEN 0x824 | ||
182 | #define USB_ETDDMAXTEN 0x828 | ||
183 | #define USB_EPDMAXTEN 0x82c | ||
184 | #define USB_ETDDMAENXYT 0x830 | ||
185 | #define USB_EPDMAENXYT 0x834 | ||
186 | #define USB_ETDDMABST4EN 0x838 | ||
187 | #define USB_EPDMABST4EN 0x83c | ||
188 | |||
189 | #define USB_MISCCONTROL 0x840 | ||
190 | #define USB_MISCCONTROL_ISOPREVFRM (1 << 3) | ||
191 | #define USB_MISCCONTROL_SKPRTRY (1 << 2) | ||
192 | #define USB_MISCCONTROL_ARBMODE (1 << 1) | ||
193 | #define USB_MISCCONTROL_FILTCC (1 << 0) | ||
194 | |||
195 | #define USB_ETDDMACHANLCLR 0x848 | ||
196 | #define USB_EPDMACHANLCLR 0x84c | ||
197 | #define USB_ETDSMSA(x) (0x900 + ((x) * 4)) | ||
198 | #define USB_EPSMSA(x) (0x980 + ((x) * 4)) | ||
199 | #define USB_ETDDMABUFPTR(x) (0xa00 + ((x) * 4)) | ||
200 | #define USB_EPDMABUFPTR(x) (0xa80 + ((x) * 4)) | ||
201 | |||
202 | #define USB_ETD_DWORD(x, w) (0x200 + ((x) * 16) + ((w) * 4)) | ||
203 | #define DW0_ADDRESS 0 | ||
204 | #define DW0_ENDPNT 7 | ||
205 | #define DW0_DIRECT 11 | ||
206 | #define DW0_SPEED 13 | ||
207 | #define DW0_FORMAT 14 | ||
208 | #define DW0_MAXPKTSIZ 16 | ||
209 | #define DW0_HALTED 27 | ||
210 | #define DW0_TOGCRY 28 | ||
211 | #define DW0_SNDNAK 30 | ||
212 | |||
213 | #define DW1_XBUFSRTAD 0 | ||
214 | #define DW1_YBUFSRTAD 16 | ||
215 | |||
216 | #define DW2_RTRYDELAY 0 | ||
217 | #define DW2_POLINTERV 0 | ||
218 | #define DW2_STARTFRM 0 | ||
219 | #define DW2_RELPOLPOS 8 | ||
220 | #define DW2_DIRPID 16 | ||
221 | #define DW2_BUFROUND 18 | ||
222 | #define DW2_DELAYINT 19 | ||
223 | #define DW2_DATATOG 22 | ||
224 | #define DW2_ERRORCNT 24 | ||
225 | #define DW2_COMPCODE 28 | ||
226 | |||
227 | #define DW3_TOTBYECNT 0 | ||
228 | #define DW3_PKTLEN0 0 | ||
229 | #define DW3_COMPCODE0 12 | ||
230 | #define DW3_PKTLEN1 16 | ||
231 | #define DW3_BUFSIZE 21 | ||
232 | #define DW3_COMPCODE1 28 | ||
233 | |||
234 | #define USBCTRL 0x600 | ||
235 | #define USBCTRL_I2C_WU_INT_STAT (1 << 27) | ||
236 | #define USBCTRL_OTG_WU_INT_STAT (1 << 26) | ||
237 | #define USBCTRL_HOST_WU_INT_STAT (1 << 25) | ||
238 | #define USBCTRL_FNT_WU_INT_STAT (1 << 24) | ||
239 | #define USBCTRL_I2C_WU_INT_EN (1 << 19) | ||
240 | #define USBCTRL_OTG_WU_INT_EN (1 << 18) | ||
241 | #define USBCTRL_HOST_WU_INT_EN (1 << 17) | ||
242 | #define USBCTRL_FNT_WU_INT_EN (1 << 16) | ||
243 | #define USBCTRL_OTC_RCV_RXDP (1 << 13) | ||
244 | #define USBCTRL_HOST1_BYP_TLL (1 << 12) | ||
245 | #define USBCTRL_OTG_BYP_VAL(x) ((x) << 10) | ||
246 | #define USBCTRL_HOST1_BYP_VAL(x) ((x) << 8) | ||
247 | #define USBCTRL_OTG_PWR_MASK (1 << 6) | ||
248 | #define USBCTRL_HOST1_PWR_MASK (1 << 5) | ||
249 | #define USBCTRL_HOST2_PWR_MASK (1 << 4) | ||
250 | #define USBCTRL_USB_BYP (1 << 2) | ||
251 | #define USBCTRL_HOST1_TXEN_OE (1 << 1) | ||
252 | |||
253 | |||
254 | /* Values in TD blocks */ | ||
255 | #define TD_DIR_SETUP 0 | ||
256 | #define TD_DIR_OUT 1 | ||
257 | #define TD_DIR_IN 2 | ||
258 | #define TD_FORMAT_CONTROL 0 | ||
259 | #define TD_FORMAT_ISO 1 | ||
260 | #define TD_FORMAT_BULK 2 | ||
261 | #define TD_FORMAT_INT 3 | ||
262 | #define TD_TOGGLE_CARRY 0 | ||
263 | #define TD_TOGGLE_DATA0 2 | ||
264 | #define TD_TOGGLE_DATA1 3 | ||
265 | |||
266 | /* control transfer states */ | ||
267 | #define US_CTRL_SETUP 2 | ||
268 | #define US_CTRL_DATA 1 | ||
269 | #define US_CTRL_ACK 0 | ||
270 | |||
271 | /* bulk transfer main state and 0-length packet */ | ||
272 | #define US_BULK 1 | ||
273 | #define US_BULK0 0 | ||
274 | |||
275 | /*ETD format description*/ | ||
276 | #define IMX_FMT_CTRL 0x0 | ||
277 | #define IMX_FMT_ISO 0x1 | ||
278 | #define IMX_FMT_BULK 0x2 | ||
279 | #define IMX_FMT_INT 0x3 | ||
280 | |||
281 | static char fmt_urb_to_etd[4] = { | ||
282 | /*PIPE_ISOCHRONOUS*/ IMX_FMT_ISO, | ||
283 | /*PIPE_INTERRUPT*/ IMX_FMT_INT, | ||
284 | /*PIPE_CONTROL*/ IMX_FMT_CTRL, | ||
285 | /*PIPE_BULK*/ IMX_FMT_BULK | ||
286 | }; | ||
287 | |||
288 | /* condition (error) CC codes and mapping (OHCI like) */ | ||
289 | |||
290 | #define TD_CC_NOERROR 0x00 | ||
291 | #define TD_CC_CRC 0x01 | ||
292 | #define TD_CC_BITSTUFFING 0x02 | ||
293 | #define TD_CC_DATATOGGLEM 0x03 | ||
294 | #define TD_CC_STALL 0x04 | ||
295 | #define TD_DEVNOTRESP 0x05 | ||
296 | #define TD_PIDCHECKFAIL 0x06 | ||
297 | /*#define TD_UNEXPECTEDPID 0x07 - reserved, not active on MX2*/ | ||
298 | #define TD_DATAOVERRUN 0x08 | ||
299 | #define TD_DATAUNDERRUN 0x09 | ||
300 | #define TD_BUFFEROVERRUN 0x0C | ||
301 | #define TD_BUFFERUNDERRUN 0x0D | ||
302 | #define TD_SCHEDULEOVERRUN 0x0E | ||
303 | #define TD_NOTACCESSED 0x0F | ||
304 | |||
305 | static const int cc_to_error[16] = { | ||
306 | /* No Error */ 0, | ||
307 | /* CRC Error */ -EILSEQ, | ||
308 | /* Bit Stuff */ -EPROTO, | ||
309 | /* Data Togg */ -EILSEQ, | ||
310 | /* Stall */ -EPIPE, | ||
311 | /* DevNotResp */ -ETIMEDOUT, | ||
312 | /* PIDCheck */ -EPROTO, | ||
313 | /* UnExpPID */ -EPROTO, | ||
314 | /* DataOver */ -EOVERFLOW, | ||
315 | /* DataUnder */ -EREMOTEIO, | ||
316 | /* (for hw) */ -EIO, | ||
317 | /* (for hw) */ -EIO, | ||
318 | /* BufferOver */ -ECOMM, | ||
319 | /* BuffUnder */ -ENOSR, | ||
320 | /* (for HCD) */ -ENOSPC, | ||
321 | /* (for HCD) */ -EALREADY | ||
322 | }; | ||
323 | |||
324 | /* HCD data associated with a usb core URB */ | ||
325 | struct urb_priv { | ||
326 | struct urb *urb; | ||
327 | struct usb_host_endpoint *ep; | ||
328 | int active; | ||
329 | int state; | ||
330 | struct td *isoc_td; | ||
331 | int isoc_remaining; | ||
332 | int isoc_status; | ||
333 | }; | ||
334 | |||
335 | /* HCD data associated with a usb core endpoint */ | ||
336 | struct ep_priv { | ||
337 | struct usb_host_endpoint *ep; | ||
338 | struct list_head td_list; | ||
339 | struct list_head queue; | ||
340 | int etd[NUM_ISO_ETDS]; | ||
341 | int waiting_etd; | ||
342 | }; | ||
343 | |||
344 | /* isoc packet */ | ||
345 | struct td { | ||
346 | struct list_head list; | ||
347 | struct urb *urb; | ||
348 | struct usb_host_endpoint *ep; | ||
349 | dma_addr_t data; | ||
350 | unsigned long buf_addr; | ||
351 | int len; | ||
352 | int frame; | ||
353 | int isoc_index; | ||
354 | }; | ||
355 | |||
356 | /* HCD data associated with a hardware ETD */ | ||
357 | struct etd_priv { | ||
358 | struct usb_host_endpoint *ep; | ||
359 | struct urb *urb; | ||
360 | struct td *td; | ||
361 | struct list_head queue; | ||
362 | dma_addr_t dma_handle; | ||
363 | int alloc; | ||
364 | int len; | ||
365 | int dmem_size; | ||
366 | int dmem_offset; | ||
367 | int active_count; | ||
368 | #ifdef DEBUG | ||
369 | int activated_frame; | ||
370 | int disactivated_frame; | ||
371 | int last_int_frame; | ||
372 | int last_req_frame; | ||
373 | u32 submitted_dwords[4]; | ||
374 | #endif | ||
375 | }; | ||
376 | |||
377 | /* Hardware data memory info */ | ||
378 | struct imx21_dmem_area { | ||
379 | struct usb_host_endpoint *ep; | ||
380 | unsigned int offset; | ||
381 | unsigned int size; | ||
382 | struct list_head list; | ||
383 | }; | ||
384 | |||
385 | #ifdef DEBUG | ||
386 | struct debug_usage_stats { | ||
387 | unsigned int value; | ||
388 | unsigned int maximum; | ||
389 | }; | ||
390 | |||
391 | struct debug_stats { | ||
392 | unsigned long submitted; | ||
393 | unsigned long completed_ok; | ||
394 | unsigned long completed_failed; | ||
395 | unsigned long unlinked; | ||
396 | unsigned long queue_etd; | ||
397 | unsigned long queue_dmem; | ||
398 | }; | ||
399 | |||
400 | struct debug_isoc_trace { | ||
401 | int schedule_frame; | ||
402 | int submit_frame; | ||
403 | int request_len; | ||
404 | int done_frame; | ||
405 | int done_len; | ||
406 | int cc; | ||
407 | struct td *td; | ||
408 | }; | ||
409 | #endif | ||
410 | |||
411 | /* HCD data structure */ | ||
412 | struct imx21 { | ||
413 | spinlock_t lock; | ||
414 | struct device *dev; | ||
415 | struct mx21_usbh_platform_data *pdata; | ||
416 | struct list_head dmem_list; | ||
417 | struct list_head queue_for_etd; /* eps queued due to etd shortage */ | ||
418 | struct list_head queue_for_dmem; /* etds queued due to dmem shortage */ | ||
419 | struct etd_priv etd[USB_NUM_ETD]; | ||
420 | struct clk *clk; | ||
421 | void __iomem *regs; | ||
422 | #ifdef DEBUG | ||
423 | struct dentry *debug_root; | ||
424 | struct debug_stats nonisoc_stats; | ||
425 | struct debug_stats isoc_stats; | ||
426 | struct debug_usage_stats etd_usage; | ||
427 | struct debug_usage_stats dmem_usage; | ||
428 | struct debug_isoc_trace isoc_trace[20]; | ||
429 | struct debug_isoc_trace isoc_trace_failed[20]; | ||
430 | unsigned long debug_unblocks; | ||
431 | int isoc_trace_index; | ||
432 | int isoc_trace_index_failed; | ||
433 | #endif | ||
434 | }; | ||
435 | |||
436 | #endif | ||
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 42971657fde2..217fb5170200 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
@@ -1257,7 +1257,7 @@ static int isp1362_urb_enqueue(struct usb_hcd *hcd, | |||
1257 | 1257 | ||
1258 | /* avoid all allocations within spinlocks: request or endpoint */ | 1258 | /* avoid all allocations within spinlocks: request or endpoint */ |
1259 | if (!hep->hcpriv) { | 1259 | if (!hep->hcpriv) { |
1260 | ep = kcalloc(1, sizeof *ep, mem_flags); | 1260 | ep = kzalloc(sizeof *ep, mem_flags); |
1261 | if (!ep) | 1261 | if (!ep) |
1262 | return -ENOMEM; | 1262 | return -ENOMEM; |
1263 | } | 1263 | } |
@@ -2719,24 +2719,11 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
2719 | } | 2719 | } |
2720 | irq = irq_res->start; | 2720 | irq = irq_res->start; |
2721 | 2721 | ||
2722 | #ifdef CONFIG_USB_HCD_DMA | ||
2723 | if (pdev->dev.dma_mask) { | ||
2724 | struct resource *dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
2725 | |||
2726 | if (!dma_res) { | ||
2727 | retval = -ENODEV; | ||
2728 | goto err1; | ||
2729 | } | ||
2730 | isp1362_hcd->data_dma = dma_res->start; | ||
2731 | isp1362_hcd->max_dma_size = resource_len(dma_res); | ||
2732 | } | ||
2733 | #else | ||
2734 | if (pdev->dev.dma_mask) { | 2722 | if (pdev->dev.dma_mask) { |
2735 | DBG(1, "won't do DMA"); | 2723 | DBG(1, "won't do DMA"); |
2736 | retval = -ENODEV; | 2724 | retval = -ENODEV; |
2737 | goto err1; | 2725 | goto err1; |
2738 | } | 2726 | } |
2739 | #endif | ||
2740 | 2727 | ||
2741 | if (!request_mem_region(addr->start, resource_len(addr), hcd_name)) { | 2728 | if (!request_mem_region(addr->start, resource_len(addr), hcd_name)) { |
2742 | retval = -EBUSY; | 2729 | retval = -EBUSY; |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 27b8f7cb4471..9f01293600b0 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -17,7 +17,9 @@ | |||
17 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
18 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/mm.h> | ||
20 | #include <asm/unaligned.h> | 21 | #include <asm/unaligned.h> |
22 | #include <asm/cacheflush.h> | ||
21 | 23 | ||
22 | #include "../core/hcd.h" | 24 | #include "../core/hcd.h" |
23 | #include "isp1760-hcd.h" | 25 | #include "isp1760-hcd.h" |
@@ -904,6 +906,14 @@ __acquires(priv->lock) | |||
904 | status = 0; | 906 | status = 0; |
905 | } | 907 | } |
906 | 908 | ||
909 | if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) { | ||
910 | void *ptr; | ||
911 | for (ptr = urb->transfer_buffer; | ||
912 | ptr < urb->transfer_buffer + urb->transfer_buffer_length; | ||
913 | ptr += PAGE_SIZE) | ||
914 | flush_dcache_page(virt_to_page(ptr)); | ||
915 | } | ||
916 | |||
907 | /* complete() can reenter this HCD */ | 917 | /* complete() can reenter this HCD */ |
908 | usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); | 918 | usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); |
909 | spin_unlock(&priv->lock); | 919 | spin_unlock(&priv->lock); |
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 1c9f977a5c9c..4293cfd28d61 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -109,7 +109,7 @@ static int of_isp1760_remove(struct of_device *dev) | |||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static struct of_device_id of_isp1760_match[] = { | 112 | static const struct of_device_id of_isp1760_match[] = { |
113 | { | 113 | { |
114 | .compatible = "nxp,usb-isp1760", | 114 | .compatible = "nxp,usb-isp1760", |
115 | }, | 115 | }, |
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c new file mode 100644 index 000000000000..4aa08d36d077 --- /dev/null +++ b/drivers/usb/host/ohci-da8xx.c | |||
@@ -0,0 +1,456 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * TI DA8xx (OMAP-L1x) Bus Glue | ||
5 | * | ||
6 | * Derived from: ohci-omap.c and ohci-s3c2410.c | ||
7 | * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public License | ||
10 | * version 2. This program is licensed "as is" without any warranty of any | ||
11 | * kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/jiffies.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/clk.h> | ||
18 | |||
19 | #include <mach/da8xx.h> | ||
20 | #include <mach/usb.h> | ||
21 | |||
22 | #ifndef CONFIG_ARCH_DAVINCI_DA8XX | ||
23 | #error "This file is DA8xx bus glue. Define CONFIG_ARCH_DAVINCI_DA8XX." | ||
24 | #endif | ||
25 | |||
26 | #define CFGCHIP2 DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG) | ||
27 | |||
28 | static struct clk *usb11_clk; | ||
29 | static struct clk *usb20_clk; | ||
30 | |||
31 | /* Over-current indicator change bitmask */ | ||
32 | static volatile u16 ocic_mask; | ||
33 | |||
34 | static void ohci_da8xx_clock(int on) | ||
35 | { | ||
36 | u32 cfgchip2; | ||
37 | |||
38 | cfgchip2 = __raw_readl(CFGCHIP2); | ||
39 | if (on) { | ||
40 | clk_enable(usb11_clk); | ||
41 | |||
42 | /* | ||
43 | * If USB 1.1 reference clock is sourced from USB 2.0 PHY, we | ||
44 | * need to enable the USB 2.0 module clocking, start its PHY, | ||
45 | * and not allow it to stop the clock during USB 2.0 suspend. | ||
46 | */ | ||
47 | if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX)) { | ||
48 | clk_enable(usb20_clk); | ||
49 | |||
50 | cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN); | ||
51 | cfgchip2 |= CFGCHIP2_PHY_PLLON; | ||
52 | __raw_writel(cfgchip2, CFGCHIP2); | ||
53 | |||
54 | pr_info("Waiting for USB PHY clock good...\n"); | ||
55 | while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD)) | ||
56 | cpu_relax(); | ||
57 | } | ||
58 | |||
59 | /* Enable USB 1.1 PHY */ | ||
60 | cfgchip2 |= CFGCHIP2_USB1SUSPENDM; | ||
61 | } else { | ||
62 | clk_disable(usb11_clk); | ||
63 | if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX)) | ||
64 | clk_disable(usb20_clk); | ||
65 | |||
66 | /* Disable USB 1.1 PHY */ | ||
67 | cfgchip2 &= ~CFGCHIP2_USB1SUSPENDM; | ||
68 | } | ||
69 | __raw_writel(cfgchip2, CFGCHIP2); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * Handle the port over-current indicator change. | ||
74 | */ | ||
75 | static void ohci_da8xx_ocic_handler(struct da8xx_ohci_root_hub *hub, | ||
76 | unsigned port) | ||
77 | { | ||
78 | ocic_mask |= 1 << port; | ||
79 | |||
80 | /* Once over-current is detected, the port needs to be powered down */ | ||
81 | if (hub->get_oci(port) > 0) | ||
82 | hub->set_power(port, 0); | ||
83 | } | ||
84 | |||
85 | static int ohci_da8xx_init(struct usb_hcd *hcd) | ||
86 | { | ||
87 | struct device *dev = hcd->self.controller; | ||
88 | struct da8xx_ohci_root_hub *hub = dev->platform_data; | ||
89 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
90 | int result; | ||
91 | u32 rh_a; | ||
92 | |||
93 | dev_dbg(dev, "starting USB controller\n"); | ||
94 | |||
95 | ohci_da8xx_clock(1); | ||
96 | |||
97 | /* | ||
98 | * DA8xx only have 1 port connected to the pins but the HC root hub | ||
99 | * register A reports 2 ports, thus we'll have to override it... | ||
100 | */ | ||
101 | ohci->num_ports = 1; | ||
102 | |||
103 | result = ohci_init(ohci); | ||
104 | if (result < 0) | ||
105 | return result; | ||
106 | |||
107 | /* | ||
108 | * Since we're providing a board-specific root hub port power control | ||
109 | * and over-current reporting, we have to override the HC root hub A | ||
110 | * register's default value, so that ohci_hub_control() could return | ||
111 | * the correct hub descriptor... | ||
112 | */ | ||
113 | rh_a = ohci_readl(ohci, &ohci->regs->roothub.a); | ||
114 | if (hub->set_power) { | ||
115 | rh_a &= ~RH_A_NPS; | ||
116 | rh_a |= RH_A_PSM; | ||
117 | } | ||
118 | if (hub->get_oci) { | ||
119 | rh_a &= ~RH_A_NOCP; | ||
120 | rh_a |= RH_A_OCPM; | ||
121 | } | ||
122 | rh_a &= ~RH_A_POTPGT; | ||
123 | rh_a |= hub->potpgt << 24; | ||
124 | ohci_writel(ohci, rh_a, &ohci->regs->roothub.a); | ||
125 | |||
126 | return result; | ||
127 | } | ||
128 | |||
129 | static void ohci_da8xx_stop(struct usb_hcd *hcd) | ||
130 | { | ||
131 | ohci_stop(hcd); | ||
132 | ohci_da8xx_clock(0); | ||
133 | } | ||
134 | |||
135 | static int ohci_da8xx_start(struct usb_hcd *hcd) | ||
136 | { | ||
137 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
138 | int result; | ||
139 | |||
140 | result = ohci_run(ohci); | ||
141 | if (result < 0) | ||
142 | ohci_da8xx_stop(hcd); | ||
143 | |||
144 | return result; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Update the status data from the hub with the over-current indicator change. | ||
149 | */ | ||
150 | static int ohci_da8xx_hub_status_data(struct usb_hcd *hcd, char *buf) | ||
151 | { | ||
152 | int length = ohci_hub_status_data(hcd, buf); | ||
153 | |||
154 | /* See if we have OCIC bit set on port 1 */ | ||
155 | if (ocic_mask & (1 << 1)) { | ||
156 | dev_dbg(hcd->self.controller, "over-current indicator change " | ||
157 | "on port 1\n"); | ||
158 | |||
159 | if (!length) | ||
160 | length = 1; | ||
161 | |||
162 | buf[0] |= 1 << 1; | ||
163 | } | ||
164 | return length; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * Look at the control requests to the root hub and see if we need to override. | ||
169 | */ | ||
170 | static int ohci_da8xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
171 | u16 wIndex, char *buf, u16 wLength) | ||
172 | { | ||
173 | struct device *dev = hcd->self.controller; | ||
174 | struct da8xx_ohci_root_hub *hub = dev->platform_data; | ||
175 | int temp; | ||
176 | |||
177 | switch (typeReq) { | ||
178 | case GetPortStatus: | ||
179 | /* Check the port number */ | ||
180 | if (wIndex != 1) | ||
181 | break; | ||
182 | |||
183 | dev_dbg(dev, "GetPortStatus(%u)\n", wIndex); | ||
184 | |||
185 | temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1); | ||
186 | |||
187 | /* The port power status (PPS) bit defaults to 1 */ | ||
188 | if (hub->get_power && hub->get_power(wIndex) == 0) | ||
189 | temp &= ~RH_PS_PPS; | ||
190 | |||
191 | /* The port over-current indicator (POCI) bit is always 0 */ | ||
192 | if (hub->get_oci && hub->get_oci(wIndex) > 0) | ||
193 | temp |= RH_PS_POCI; | ||
194 | |||
195 | /* The over-current indicator change (OCIC) bit is 0 too */ | ||
196 | if (ocic_mask & (1 << wIndex)) | ||
197 | temp |= RH_PS_OCIC; | ||
198 | |||
199 | put_unaligned(cpu_to_le32(temp), (__le32 *)buf); | ||
200 | return 0; | ||
201 | case SetPortFeature: | ||
202 | temp = 1; | ||
203 | goto check_port; | ||
204 | case ClearPortFeature: | ||
205 | temp = 0; | ||
206 | |||
207 | check_port: | ||
208 | /* Check the port number */ | ||
209 | if (wIndex != 1) | ||
210 | break; | ||
211 | |||
212 | switch (wValue) { | ||
213 | case USB_PORT_FEAT_POWER: | ||
214 | dev_dbg(dev, "%sPortFeature(%u): %s\n", | ||
215 | temp ? "Set" : "Clear", wIndex, "POWER"); | ||
216 | |||
217 | if (!hub->set_power) | ||
218 | return -EPIPE; | ||
219 | |||
220 | return hub->set_power(wIndex, temp) ? -EPIPE : 0; | ||
221 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
222 | dev_dbg(dev, "%sPortFeature(%u): %s\n", | ||
223 | temp ? "Set" : "Clear", wIndex, | ||
224 | "C_OVER_CURRENT"); | ||
225 | |||
226 | if (temp) | ||
227 | ocic_mask |= 1 << wIndex; | ||
228 | else | ||
229 | ocic_mask &= ~(1 << wIndex); | ||
230 | return 0; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | return ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); | ||
235 | } | ||
236 | |||
237 | static const struct hc_driver ohci_da8xx_hc_driver = { | ||
238 | .description = hcd_name, | ||
239 | .product_desc = "DA8xx OHCI", | ||
240 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
241 | |||
242 | /* | ||
243 | * generic hardware linkage | ||
244 | */ | ||
245 | .irq = ohci_irq, | ||
246 | .flags = HCD_USB11 | HCD_MEMORY, | ||
247 | |||
248 | /* | ||
249 | * basic lifecycle operations | ||
250 | */ | ||
251 | .reset = ohci_da8xx_init, | ||
252 | .start = ohci_da8xx_start, | ||
253 | .stop = ohci_da8xx_stop, | ||
254 | .shutdown = ohci_shutdown, | ||
255 | |||
256 | /* | ||
257 | * managing i/o requests and associated device resources | ||
258 | */ | ||
259 | .urb_enqueue = ohci_urb_enqueue, | ||
260 | .urb_dequeue = ohci_urb_dequeue, | ||
261 | .endpoint_disable = ohci_endpoint_disable, | ||
262 | |||
263 | /* | ||
264 | * scheduling support | ||
265 | */ | ||
266 | .get_frame_number = ohci_get_frame, | ||
267 | |||
268 | /* | ||
269 | * root hub support | ||
270 | */ | ||
271 | .hub_status_data = ohci_da8xx_hub_status_data, | ||
272 | .hub_control = ohci_da8xx_hub_control, | ||
273 | |||
274 | #ifdef CONFIG_PM | ||
275 | .bus_suspend = ohci_bus_suspend, | ||
276 | .bus_resume = ohci_bus_resume, | ||
277 | #endif | ||
278 | .start_port_reset = ohci_start_port_reset, | ||
279 | }; | ||
280 | |||
281 | /*-------------------------------------------------------------------------*/ | ||
282 | |||
283 | |||
284 | /** | ||
285 | * usb_hcd_da8xx_probe - initialize DA8xx-based HCDs | ||
286 | * Context: !in_interrupt() | ||
287 | * | ||
288 | * Allocates basic resources for this USB host controller, and | ||
289 | * then invokes the start() method for the HCD associated with it | ||
290 | * through the hotplug entry's driver_data. | ||
291 | */ | ||
292 | static int usb_hcd_da8xx_probe(const struct hc_driver *driver, | ||
293 | struct platform_device *pdev) | ||
294 | { | ||
295 | struct da8xx_ohci_root_hub *hub = pdev->dev.platform_data; | ||
296 | struct usb_hcd *hcd; | ||
297 | struct resource *mem; | ||
298 | int error, irq; | ||
299 | |||
300 | if (hub == NULL) | ||
301 | return -ENODEV; | ||
302 | |||
303 | usb11_clk = clk_get(&pdev->dev, "usb11"); | ||
304 | if (IS_ERR(usb11_clk)) | ||
305 | return PTR_ERR(usb11_clk); | ||
306 | |||
307 | usb20_clk = clk_get(&pdev->dev, "usb20"); | ||
308 | if (IS_ERR(usb20_clk)) { | ||
309 | error = PTR_ERR(usb20_clk); | ||
310 | goto err0; | ||
311 | } | ||
312 | |||
313 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | ||
314 | if (!hcd) { | ||
315 | error = -ENOMEM; | ||
316 | goto err1; | ||
317 | } | ||
318 | |||
319 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
320 | if (!mem) { | ||
321 | error = -ENODEV; | ||
322 | goto err2; | ||
323 | } | ||
324 | hcd->rsrc_start = mem->start; | ||
325 | hcd->rsrc_len = mem->end - mem->start + 1; | ||
326 | |||
327 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
328 | dev_dbg(&pdev->dev, "request_mem_region failed\n"); | ||
329 | error = -EBUSY; | ||
330 | goto err2; | ||
331 | } | ||
332 | |||
333 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
334 | if (!hcd->regs) { | ||
335 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
336 | error = -ENOMEM; | ||
337 | goto err3; | ||
338 | } | ||
339 | |||
340 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
341 | |||
342 | irq = platform_get_irq(pdev, 0); | ||
343 | if (irq < 0) { | ||
344 | error = -ENODEV; | ||
345 | goto err4; | ||
346 | } | ||
347 | error = usb_add_hcd(hcd, irq, IRQF_DISABLED); | ||
348 | if (error) | ||
349 | goto err4; | ||
350 | |||
351 | if (hub->ocic_notify) { | ||
352 | error = hub->ocic_notify(ohci_da8xx_ocic_handler); | ||
353 | if (!error) | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | usb_remove_hcd(hcd); | ||
358 | err4: | ||
359 | iounmap(hcd->regs); | ||
360 | err3: | ||
361 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
362 | err2: | ||
363 | usb_put_hcd(hcd); | ||
364 | err1: | ||
365 | clk_put(usb20_clk); | ||
366 | err0: | ||
367 | clk_put(usb11_clk); | ||
368 | return error; | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * usb_hcd_da8xx_remove - shutdown processing for DA8xx-based HCDs | ||
373 | * @dev: USB Host Controller being removed | ||
374 | * Context: !in_interrupt() | ||
375 | * | ||
376 | * Reverses the effect of usb_hcd_da8xx_probe(), first invoking | ||
377 | * the HCD's stop() method. It is always called from a thread | ||
378 | * context, normally "rmmod", "apmd", or something similar. | ||
379 | */ | ||
380 | static inline void | ||
381 | usb_hcd_da8xx_remove(struct usb_hcd *hcd, struct platform_device *pdev) | ||
382 | { | ||
383 | struct da8xx_ohci_root_hub *hub = pdev->dev.platform_data; | ||
384 | |||
385 | hub->ocic_notify(NULL); | ||
386 | usb_remove_hcd(hcd); | ||
387 | iounmap(hcd->regs); | ||
388 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
389 | usb_put_hcd(hcd); | ||
390 | clk_put(usb20_clk); | ||
391 | clk_put(usb11_clk); | ||
392 | } | ||
393 | |||
394 | static int ohci_hcd_da8xx_drv_probe(struct platform_device *dev) | ||
395 | { | ||
396 | return usb_hcd_da8xx_probe(&ohci_da8xx_hc_driver, dev); | ||
397 | } | ||
398 | |||
399 | static int ohci_hcd_da8xx_drv_remove(struct platform_device *dev) | ||
400 | { | ||
401 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
402 | |||
403 | usb_hcd_da8xx_remove(hcd, dev); | ||
404 | platform_set_drvdata(dev, NULL); | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | #ifdef CONFIG_PM | ||
410 | static int ohci_da8xx_suspend(struct platform_device *dev, pm_message_t message) | ||
411 | { | ||
412 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
413 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
414 | |||
415 | if (time_before(jiffies, ohci->next_statechange)) | ||
416 | msleep(5); | ||
417 | ohci->next_statechange = jiffies; | ||
418 | |||
419 | ohci_da8xx_clock(0); | ||
420 | hcd->state = HC_STATE_SUSPENDED; | ||
421 | dev->dev.power.power_state = PMSG_SUSPEND; | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static int ohci_da8xx_resume(struct platform_device *dev) | ||
426 | { | ||
427 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
428 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
429 | |||
430 | if (time_before(jiffies, ohci->next_statechange)) | ||
431 | msleep(5); | ||
432 | ohci->next_statechange = jiffies; | ||
433 | |||
434 | ohci_da8xx_clock(1); | ||
435 | dev->dev.power.power_state = PMSG_ON; | ||
436 | usb_hcd_resume_root_hub(hcd); | ||
437 | return 0; | ||
438 | } | ||
439 | #endif | ||
440 | |||
441 | /* | ||
442 | * Driver definition to register with platform structure. | ||
443 | */ | ||
444 | static struct platform_driver ohci_hcd_da8xx_driver = { | ||
445 | .probe = ohci_hcd_da8xx_drv_probe, | ||
446 | .remove = ohci_hcd_da8xx_drv_remove, | ||
447 | .shutdown = usb_hcd_platform_shutdown, | ||
448 | #ifdef CONFIG_PM | ||
449 | .suspend = ohci_da8xx_suspend, | ||
450 | .resume = ohci_da8xx_resume, | ||
451 | #endif | ||
452 | .driver = { | ||
453 | .owner = THIS_MODULE, | ||
454 | .name = "ohci", | ||
455 | }, | ||
456 | }; | ||
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 811f5dfdc582..8ad2441b0284 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -53,13 +53,13 @@ urb_print(struct urb * urb, char * str, int small, int status) | |||
53 | int i, len; | 53 | int i, len; |
54 | 54 | ||
55 | if (usb_pipecontrol (pipe)) { | 55 | if (usb_pipecontrol (pipe)) { |
56 | printk (KERN_DEBUG __FILE__ ": setup(8):"); | 56 | printk (KERN_DEBUG "%s: setup(8):", __FILE__); |
57 | for (i = 0; i < 8 ; i++) | 57 | for (i = 0; i < 8 ; i++) |
58 | printk (" %02x", ((__u8 *) urb->setup_packet) [i]); | 58 | printk (" %02x", ((__u8 *) urb->setup_packet) [i]); |
59 | printk ("\n"); | 59 | printk ("\n"); |
60 | } | 60 | } |
61 | if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { | 61 | if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { |
62 | printk (KERN_DEBUG __FILE__ ": data(%d/%d):", | 62 | printk (KERN_DEBUG "%s: data(%d/%d):", __FILE__, |
63 | urb->actual_length, | 63 | urb->actual_length, |
64 | urb->transfer_buffer_length); | 64 | urb->transfer_buffer_length); |
65 | len = usb_pipeout (pipe)? | 65 | len = usb_pipeout (pipe)? |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 24eb74781919..afe59be23645 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -1051,6 +1051,11 @@ MODULE_LICENSE ("GPL"); | |||
1051 | #define PLATFORM_DRIVER usb_hcd_pnx4008_driver | 1051 | #define PLATFORM_DRIVER usb_hcd_pnx4008_driver |
1052 | #endif | 1052 | #endif |
1053 | 1053 | ||
1054 | #ifdef CONFIG_ARCH_DAVINCI_DA8XX | ||
1055 | #include "ohci-da8xx.c" | ||
1056 | #define PLATFORM_DRIVER ohci_hcd_da8xx_driver | ||
1057 | #endif | ||
1058 | |||
1054 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 1059 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
1055 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 1060 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
1056 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | 1061 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index de42283149c7..18d39f0463ee 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -28,8 +28,8 @@ extern int usb_disabled(void); | |||
28 | 28 | ||
29 | static void lh7a404_start_hc(struct platform_device *dev) | 29 | static void lh7a404_start_hc(struct platform_device *dev) |
30 | { | 30 | { |
31 | printk(KERN_DEBUG __FILE__ | 31 | printk(KERN_DEBUG "%s: starting LH7A404 OHCI USB Controller\n", |
32 | ": starting LH7A404 OHCI USB Controller\n"); | 32 | __FILE__); |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Now, carefully enable the USB clock, and take | 35 | * Now, carefully enable the USB clock, and take |
@@ -39,14 +39,13 @@ static void lh7a404_start_hc(struct platform_device *dev) | |||
39 | udelay(1000); | 39 | udelay(1000); |
40 | USBH_CMDSTATUS = OHCI_HCR; | 40 | USBH_CMDSTATUS = OHCI_HCR; |
41 | 41 | ||
42 | printk(KERN_DEBUG __FILE__ | 42 | printk(KERN_DEBUG "%s: Clock to USB host has been enabled \n", __FILE__); |
43 | ": Clock to USB host has been enabled \n"); | ||
44 | } | 43 | } |
45 | 44 | ||
46 | static void lh7a404_stop_hc(struct platform_device *dev) | 45 | static void lh7a404_stop_hc(struct platform_device *dev) |
47 | { | 46 | { |
48 | printk(KERN_DEBUG __FILE__ | 47 | printk(KERN_DEBUG "%s: stopping LH7A404 OHCI USB Controller\n", |
49 | ": stopping LH7A404 OHCI USB Controller\n"); | 48 | __FILE__); |
50 | 49 | ||
51 | CSC_PWRCNT &= ~CSC_PWRCNT_USBH_EN; /* Disable clock */ | 50 | CSC_PWRCNT &= ~CSC_PWRCNT_USBH_EN; /* Disable clock */ |
52 | } | 51 | } |
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 2769326da42e..cd74bbdd007c 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -327,7 +327,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | |||
327 | } | 327 | } |
328 | i2c_adap = i2c_get_adapter(2); | 328 | i2c_adap = i2c_get_adapter(2); |
329 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); | 329 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); |
330 | strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); | 330 | strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); |
331 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, | 331 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, |
332 | normal_i2c); | 332 | normal_i2c); |
333 | i2c_put_adapter(i2c_adap); | 333 | i2c_put_adapter(i2c_adap); |
@@ -411,7 +411,7 @@ out3: | |||
411 | out2: | 411 | out2: |
412 | clk_put(usb_clk); | 412 | clk_put(usb_clk); |
413 | out1: | 413 | out1: |
414 | i2c_unregister_client(isp1301_i2c_client); | 414 | i2c_unregister_device(isp1301_i2c_client); |
415 | isp1301_i2c_client = NULL; | 415 | isp1301_i2c_client = NULL; |
416 | out_i2c_driver: | 416 | out_i2c_driver: |
417 | i2c_del_driver(&isp1301_driver); | 417 | i2c_del_driver(&isp1301_driver); |
@@ -430,7 +430,7 @@ static int usb_hcd_pnx4008_remove(struct platform_device *pdev) | |||
430 | pnx4008_unset_usb_bits(); | 430 | pnx4008_unset_usb_bits(); |
431 | clk_disable(usb_clk); | 431 | clk_disable(usb_clk); |
432 | clk_put(usb_clk); | 432 | clk_put(usb_clk); |
433 | i2c_unregister_client(isp1301_i2c_client); | 433 | i2c_unregister_device(isp1301_i2c_client); |
434 | isp1301_i2c_client = NULL; | 434 | isp1301_i2c_client = NULL; |
435 | i2c_del_driver(&isp1301_driver); | 435 | i2c_del_driver(&isp1301_driver); |
436 | 436 | ||
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 68a301710297..103263c230cf 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -114,21 +114,21 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | |||
114 | hcd->rsrc_len = res.end - res.start + 1; | 114 | hcd->rsrc_len = res.end - res.start + 1; |
115 | 115 | ||
116 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 116 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
117 | printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); | 117 | printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); |
118 | rv = -EBUSY; | 118 | rv = -EBUSY; |
119 | goto err_rmr; | 119 | goto err_rmr; |
120 | } | 120 | } |
121 | 121 | ||
122 | irq = irq_of_parse_and_map(dn, 0); | 122 | irq = irq_of_parse_and_map(dn, 0); |
123 | if (irq == NO_IRQ) { | 123 | if (irq == NO_IRQ) { |
124 | printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); | 124 | printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); |
125 | rv = -EBUSY; | 125 | rv = -EBUSY; |
126 | goto err_irq; | 126 | goto err_irq; |
127 | } | 127 | } |
128 | 128 | ||
129 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 129 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); |
130 | if (!hcd->regs) { | 130 | if (!hcd->regs) { |
131 | printk(KERN_ERR __FILE__ ": ioremap failed\n"); | 131 | printk(KERN_ERR "%s: ioremap failed\n", __FILE__); |
132 | rv = -ENOMEM; | 132 | rv = -ENOMEM; |
133 | goto err_ioremap; | 133 | goto err_ioremap; |
134 | } | 134 | } |
@@ -169,7 +169,7 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | |||
169 | } else | 169 | } else |
170 | release_mem_region(res.start, 0x4); | 170 | release_mem_region(res.start, 0x4); |
171 | } else | 171 | } else |
172 | pr_debug(__FILE__ ": cannot get ehci offset from fdt\n"); | 172 | pr_debug("%s: cannot get ehci offset from fdt\n", __FILE__); |
173 | } | 173 | } |
174 | 174 | ||
175 | iounmap(hcd->regs); | 175 | iounmap(hcd->regs); |
@@ -212,7 +212,7 @@ static int ohci_hcd_ppc_of_shutdown(struct of_device *op) | |||
212 | } | 212 | } |
213 | 213 | ||
214 | 214 | ||
215 | static struct of_device_id ohci_hcd_ppc_of_match[] = { | 215 | static const struct of_device_id ohci_hcd_ppc_of_match[] = { |
216 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE | 216 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE |
217 | { | 217 | { |
218 | .name = "usb", | 218 | .name = "usb", |
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index cd3398b675b2..89e670e38c10 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -41,14 +41,14 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
41 | 41 | ||
42 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 42 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
43 | if (!res) { | 43 | if (!res) { |
44 | pr_debug(__FILE__ ": no irq\n"); | 44 | pr_debug("%s: no irq\n", __FILE__); |
45 | return -ENODEV; | 45 | return -ENODEV; |
46 | } | 46 | } |
47 | irq = res->start; | 47 | irq = res->start; |
48 | 48 | ||
49 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 49 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
50 | if (!res) { | 50 | if (!res) { |
51 | pr_debug(__FILE__ ": no reg addr\n"); | 51 | pr_debug("%s: no reg addr\n", __FILE__); |
52 | return -ENODEV; | 52 | return -ENODEV; |
53 | } | 53 | } |
54 | 54 | ||
@@ -59,14 +59,14 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
59 | hcd->rsrc_len = res->end - res->start + 1; | 59 | hcd->rsrc_len = res->end - res->start + 1; |
60 | 60 | ||
61 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 61 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
62 | pr_debug(__FILE__ ": request_mem_region failed\n"); | 62 | pr_debug("%s: request_mem_region failed\n", __FILE__); |
63 | retval = -EBUSY; | 63 | retval = -EBUSY; |
64 | goto err1; | 64 | goto err1; |
65 | } | 65 | } |
66 | 66 | ||
67 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 67 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); |
68 | if (!hcd->regs) { | 68 | if (!hcd->regs) { |
69 | pr_debug(__FILE__ ": ioremap failed\n"); | 69 | pr_debug("%s: ioremap failed\n", __FILE__); |
70 | retval = -ENOMEM; | 70 | retval = -ENOMEM; |
71 | goto err2; | 71 | goto err2; |
72 | } | 72 | } |
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index e4bbe8e188e4..d8eb3bdafabb 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -31,8 +31,8 @@ static void sa1111_start_hc(struct sa1111_dev *dev) | |||
31 | { | 31 | { |
32 | unsigned int usb_rst = 0; | 32 | unsigned int usb_rst = 0; |
33 | 33 | ||
34 | printk(KERN_DEBUG __FILE__ | 34 | printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", |
35 | ": starting SA-1111 OHCI USB Controller\n"); | 35 | __FILE__); |
36 | 36 | ||
37 | #ifdef CONFIG_SA1100_BADGE4 | 37 | #ifdef CONFIG_SA1100_BADGE4 |
38 | if (machine_is_badge4()) { | 38 | if (machine_is_badge4()) { |
@@ -65,8 +65,8 @@ static void sa1111_start_hc(struct sa1111_dev *dev) | |||
65 | static void sa1111_stop_hc(struct sa1111_dev *dev) | 65 | static void sa1111_stop_hc(struct sa1111_dev *dev) |
66 | { | 66 | { |
67 | unsigned int usb_rst; | 67 | unsigned int usb_rst; |
68 | printk(KERN_DEBUG __FILE__ | 68 | printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n", |
69 | ": stopping SA-1111 OHCI USB Controller\n"); | 69 | __FILE__); |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Put the USB host controller into reset. | 72 | * Put the USB host controller into reset. |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 5b22a4d1c9e4..e11cc3aa4b82 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/irq.h> | 51 | #include <asm/irq.h> |
52 | #include <asm/system.h> | 52 | #include <asm/system.h> |
53 | #include <asm/byteorder.h> | 53 | #include <asm/byteorder.h> |
54 | #include <asm/unaligned.h> | ||
54 | 55 | ||
55 | #include "../core/hcd.h" | 56 | #include "../core/hcd.h" |
56 | #include "sl811.h" | 57 | #include "sl811.h" |
@@ -1272,12 +1273,12 @@ sl811h_hub_control( | |||
1272 | sl811h_hub_descriptor(sl811, (struct usb_hub_descriptor *) buf); | 1273 | sl811h_hub_descriptor(sl811, (struct usb_hub_descriptor *) buf); |
1273 | break; | 1274 | break; |
1274 | case GetHubStatus: | 1275 | case GetHubStatus: |
1275 | *(__le32 *) buf = cpu_to_le32(0); | 1276 | put_unaligned_le32(0, buf); |
1276 | break; | 1277 | break; |
1277 | case GetPortStatus: | 1278 | case GetPortStatus: |
1278 | if (wIndex != 1) | 1279 | if (wIndex != 1) |
1279 | goto error; | 1280 | goto error; |
1280 | *(__le32 *) buf = cpu_to_le32(sl811->port1); | 1281 | put_unaligned_le32(sl811->port1, buf); |
1281 | 1282 | ||
1282 | #ifndef VERBOSE | 1283 | #ifndef VERBOSE |
1283 | if (*(u16*)(buf+2)) /* only if wPortChange is interesting */ | 1284 | if (*(u16*)(buf+2)) /* only if wPortChange is interesting */ |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 99cd00fd3514..09197067fe6b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -735,6 +735,7 @@ static void uhci_stop(struct usb_hcd *hcd) | |||
735 | uhci_hc_died(uhci); | 735 | uhci_hc_died(uhci); |
736 | uhci_scan_schedule(uhci); | 736 | uhci_scan_schedule(uhci); |
737 | spin_unlock_irq(&uhci->lock); | 737 | spin_unlock_irq(&uhci->lock); |
738 | synchronize_irq(hcd->irq); | ||
738 | 739 | ||
739 | del_timer_sync(&uhci->fsbr_timer); | 740 | del_timer_sync(&uhci->fsbr_timer); |
740 | release_uhci(uhci); | 741 | release_uhci(uhci); |
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 33128d52f212..105fa8b025bb 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -406,6 +406,25 @@ static void dbg_rsvd64(struct xhci_hcd *xhci, u64 *ctx, dma_addr_t dma) | |||
406 | } | 406 | } |
407 | } | 407 | } |
408 | 408 | ||
409 | char *xhci_get_slot_state(struct xhci_hcd *xhci, | ||
410 | struct xhci_container_ctx *ctx) | ||
411 | { | ||
412 | struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx); | ||
413 | |||
414 | switch (GET_SLOT_STATE(slot_ctx->dev_state)) { | ||
415 | case 0: | ||
416 | return "enabled/disabled"; | ||
417 | case 1: | ||
418 | return "default"; | ||
419 | case 2: | ||
420 | return "addressed"; | ||
421 | case 3: | ||
422 | return "configured"; | ||
423 | default: | ||
424 | return "reserved"; | ||
425 | } | ||
426 | } | ||
427 | |||
409 | void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx) | 428 | void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx) |
410 | { | 429 | { |
411 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | 430 | /* Fields are 32 bits wide, DMA addresses are in bytes */ |
diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index ecc131c3fe33..78c4edac1db1 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h | |||
@@ -101,12 +101,15 @@ static inline int xhci_find_next_cap_offset(void __iomem *base, int ext_offset) | |||
101 | 101 | ||
102 | next = readl(base + ext_offset); | 102 | next = readl(base + ext_offset); |
103 | 103 | ||
104 | if (ext_offset == XHCI_HCC_PARAMS_OFFSET) | 104 | if (ext_offset == XHCI_HCC_PARAMS_OFFSET) { |
105 | /* Find the first extended capability */ | 105 | /* Find the first extended capability */ |
106 | next = XHCI_HCC_EXT_CAPS(next); | 106 | next = XHCI_HCC_EXT_CAPS(next); |
107 | else | 107 | ext_offset = 0; |
108 | } else { | ||
108 | /* Find the next extended capability */ | 109 | /* Find the next extended capability */ |
109 | next = XHCI_EXT_CAPS_NEXT(next); | 110 | next = XHCI_EXT_CAPS_NEXT(next); |
111 | } | ||
112 | |||
110 | if (!next) | 113 | if (!next) |
111 | return 0; | 114 | return 0; |
112 | /* | 115 | /* |
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index 5e92c72df642..4cb69e0af834 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c | |||
@@ -1007,7 +1007,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1007 | * for usb_set_interface() and usb_set_configuration() claim). | 1007 | * for usb_set_interface() and usb_set_configuration() claim). |
1008 | */ | 1008 | */ |
1009 | if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], | 1009 | if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], |
1010 | udev, ep, GFP_KERNEL) < 0) { | 1010 | udev, ep, GFP_NOIO) < 0) { |
1011 | dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", | 1011 | dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", |
1012 | __func__, ep->desc.bEndpointAddress); | 1012 | __func__, ep->desc.bEndpointAddress); |
1013 | return -ENOMEM; | 1013 | return -ENOMEM; |
@@ -1181,6 +1181,8 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1181 | ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, | 1181 | ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, |
1182 | udev->slot_id); | 1182 | udev->slot_id); |
1183 | if (ret < 0) { | 1183 | if (ret < 0) { |
1184 | if (command) | ||
1185 | list_del(&command->cmd_list); | ||
1184 | spin_unlock_irqrestore(&xhci->lock, flags); | 1186 | spin_unlock_irqrestore(&xhci->lock, flags); |
1185 | xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); | 1187 | xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); |
1186 | return -ENOMEM; | 1188 | return -ENOMEM; |
@@ -1264,30 +1266,13 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1264 | xhci_zero_in_ctx(xhci, virt_dev); | 1266 | xhci_zero_in_ctx(xhci, virt_dev); |
1265 | /* Install new rings and free or cache any old rings */ | 1267 | /* Install new rings and free or cache any old rings */ |
1266 | for (i = 1; i < 31; ++i) { | 1268 | for (i = 1; i < 31; ++i) { |
1267 | int rings_cached; | ||
1268 | |||
1269 | if (!virt_dev->eps[i].new_ring) | 1269 | if (!virt_dev->eps[i].new_ring) |
1270 | continue; | 1270 | continue; |
1271 | /* Only cache or free the old ring if it exists. | 1271 | /* Only cache or free the old ring if it exists. |
1272 | * It may not if this is the first add of an endpoint. | 1272 | * It may not if this is the first add of an endpoint. |
1273 | */ | 1273 | */ |
1274 | if (virt_dev->eps[i].ring) { | 1274 | if (virt_dev->eps[i].ring) { |
1275 | rings_cached = virt_dev->num_rings_cached; | 1275 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
1276 | if (rings_cached < XHCI_MAX_RINGS_CACHED) { | ||
1277 | virt_dev->num_rings_cached++; | ||
1278 | rings_cached = virt_dev->num_rings_cached; | ||
1279 | virt_dev->ring_cache[rings_cached] = | ||
1280 | virt_dev->eps[i].ring; | ||
1281 | xhci_dbg(xhci, "Cached old ring, " | ||
1282 | "%d ring%s cached\n", | ||
1283 | rings_cached, | ||
1284 | (rings_cached > 1) ? "s" : ""); | ||
1285 | } else { | ||
1286 | xhci_ring_free(xhci, virt_dev->eps[i].ring); | ||
1287 | xhci_dbg(xhci, "Ring cache full (%d rings), " | ||
1288 | "freeing ring\n", | ||
1289 | virt_dev->num_rings_cached); | ||
1290 | } | ||
1291 | } | 1276 | } |
1292 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; | 1277 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; |
1293 | virt_dev->eps[i].new_ring = NULL; | 1278 | virt_dev->eps[i].new_ring = NULL; |
@@ -1458,6 +1443,131 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, | |||
1458 | } | 1443 | } |
1459 | 1444 | ||
1460 | /* | 1445 | /* |
1446 | * This submits a Reset Device Command, which will set the device state to 0, | ||
1447 | * set the device address to 0, and disable all the endpoints except the default | ||
1448 | * control endpoint. The USB core should come back and call | ||
1449 | * xhci_address_device(), and then re-set up the configuration. If this is | ||
1450 | * called because of a usb_reset_and_verify_device(), then the old alternate | ||
1451 | * settings will be re-installed through the normal bandwidth allocation | ||
1452 | * functions. | ||
1453 | * | ||
1454 | * Wait for the Reset Device command to finish. Remove all structures | ||
1455 | * associated with the endpoints that were disabled. Clear the input device | ||
1456 | * structure? Cache the rings? Reset the control endpoint 0 max packet size? | ||
1457 | */ | ||
1458 | int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | ||
1459 | { | ||
1460 | int ret, i; | ||
1461 | unsigned long flags; | ||
1462 | struct xhci_hcd *xhci; | ||
1463 | unsigned int slot_id; | ||
1464 | struct xhci_virt_device *virt_dev; | ||
1465 | struct xhci_command *reset_device_cmd; | ||
1466 | int timeleft; | ||
1467 | int last_freed_endpoint; | ||
1468 | |||
1469 | ret = xhci_check_args(hcd, udev, NULL, 0, __func__); | ||
1470 | if (ret <= 0) | ||
1471 | return ret; | ||
1472 | xhci = hcd_to_xhci(hcd); | ||
1473 | slot_id = udev->slot_id; | ||
1474 | virt_dev = xhci->devs[slot_id]; | ||
1475 | if (!virt_dev) { | ||
1476 | xhci_dbg(xhci, "%s called with invalid slot ID %u\n", | ||
1477 | __func__, slot_id); | ||
1478 | return -EINVAL; | ||
1479 | } | ||
1480 | |||
1481 | xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); | ||
1482 | /* Allocate the command structure that holds the struct completion. | ||
1483 | * Assume we're in process context, since the normal device reset | ||
1484 | * process has to wait for the device anyway. Storage devices are | ||
1485 | * reset as part of error handling, so use GFP_NOIO instead of | ||
1486 | * GFP_KERNEL. | ||
1487 | */ | ||
1488 | reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); | ||
1489 | if (!reset_device_cmd) { | ||
1490 | xhci_dbg(xhci, "Couldn't allocate command structure.\n"); | ||
1491 | return -ENOMEM; | ||
1492 | } | ||
1493 | |||
1494 | /* Attempt to submit the Reset Device command to the command ring */ | ||
1495 | spin_lock_irqsave(&xhci->lock, flags); | ||
1496 | reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; | ||
1497 | list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); | ||
1498 | ret = xhci_queue_reset_device(xhci, slot_id); | ||
1499 | if (ret) { | ||
1500 | xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); | ||
1501 | list_del(&reset_device_cmd->cmd_list); | ||
1502 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1503 | goto command_cleanup; | ||
1504 | } | ||
1505 | xhci_ring_cmd_db(xhci); | ||
1506 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1507 | |||
1508 | /* Wait for the Reset Device command to finish */ | ||
1509 | timeleft = wait_for_completion_interruptible_timeout( | ||
1510 | reset_device_cmd->completion, | ||
1511 | USB_CTRL_SET_TIMEOUT); | ||
1512 | if (timeleft <= 0) { | ||
1513 | xhci_warn(xhci, "%s while waiting for reset device command\n", | ||
1514 | timeleft == 0 ? "Timeout" : "Signal"); | ||
1515 | spin_lock_irqsave(&xhci->lock, flags); | ||
1516 | /* The timeout might have raced with the event ring handler, so | ||
1517 | * only delete from the list if the item isn't poisoned. | ||
1518 | */ | ||
1519 | if (reset_device_cmd->cmd_list.next != LIST_POISON1) | ||
1520 | list_del(&reset_device_cmd->cmd_list); | ||
1521 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1522 | ret = -ETIME; | ||
1523 | goto command_cleanup; | ||
1524 | } | ||
1525 | |||
1526 | /* The Reset Device command can't fail, according to the 0.95/0.96 spec, | ||
1527 | * unless we tried to reset a slot ID that wasn't enabled, | ||
1528 | * or the device wasn't in the addressed or configured state. | ||
1529 | */ | ||
1530 | ret = reset_device_cmd->status; | ||
1531 | switch (ret) { | ||
1532 | case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ | ||
1533 | case COMP_CTX_STATE: /* 0.96 completion code for same thing */ | ||
1534 | xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n", | ||
1535 | slot_id, | ||
1536 | xhci_get_slot_state(xhci, virt_dev->out_ctx)); | ||
1537 | xhci_info(xhci, "Not freeing device rings.\n"); | ||
1538 | /* Don't treat this as an error. May change my mind later. */ | ||
1539 | ret = 0; | ||
1540 | goto command_cleanup; | ||
1541 | case COMP_SUCCESS: | ||
1542 | xhci_dbg(xhci, "Successful reset device command.\n"); | ||
1543 | break; | ||
1544 | default: | ||
1545 | if (xhci_is_vendor_info_code(xhci, ret)) | ||
1546 | break; | ||
1547 | xhci_warn(xhci, "Unknown completion code %u for " | ||
1548 | "reset device command.\n", ret); | ||
1549 | ret = -EINVAL; | ||
1550 | goto command_cleanup; | ||
1551 | } | ||
1552 | |||
1553 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ | ||
1554 | last_freed_endpoint = 1; | ||
1555 | for (i = 1; i < 31; ++i) { | ||
1556 | if (!virt_dev->eps[i].ring) | ||
1557 | continue; | ||
1558 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | ||
1559 | last_freed_endpoint = i; | ||
1560 | } | ||
1561 | xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); | ||
1562 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); | ||
1563 | ret = 0; | ||
1564 | |||
1565 | command_cleanup: | ||
1566 | xhci_free_command(xhci, reset_device_cmd); | ||
1567 | return ret; | ||
1568 | } | ||
1569 | |||
1570 | /* | ||
1461 | * At this point, the struct usb_device is about to go away, the device has | 1571 | * At this point, the struct usb_device is about to go away, the device has |
1462 | * disconnected, and all traffic has been stopped and the endpoints have been | 1572 | * disconnected, and all traffic has been stopped and the endpoints have been |
1463 | * disabled. Free any HC data structures associated with that device. | 1573 | * disabled. Free any HC data structures associated with that device. |
@@ -1694,7 +1804,7 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, | |||
1694 | xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); | 1804 | xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); |
1695 | return -EINVAL; | 1805 | return -EINVAL; |
1696 | } | 1806 | } |
1697 | config_cmd = xhci_alloc_command(xhci, true, mem_flags); | 1807 | config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); |
1698 | if (!config_cmd) { | 1808 | if (!config_cmd) { |
1699 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); | 1809 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); |
1700 | return -ENOMEM; | 1810 | return -ENOMEM; |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index eac5b53aa9e7..208b805b80eb 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -129,6 +129,50 @@ static u32 xhci_port_state_to_neutral(u32 state) | |||
129 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); | 129 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); |
130 | } | 130 | } |
131 | 131 | ||
132 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, | ||
133 | u32 __iomem *addr, u32 port_status) | ||
134 | { | ||
135 | /* Write 1 to disable the port */ | ||
136 | xhci_writel(xhci, port_status | PORT_PE, addr); | ||
137 | port_status = xhci_readl(xhci, addr); | ||
138 | xhci_dbg(xhci, "disable port, actual port %d status = 0x%x\n", | ||
139 | wIndex, port_status); | ||
140 | } | ||
141 | |||
142 | static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, | ||
143 | u16 wIndex, u32 __iomem *addr, u32 port_status) | ||
144 | { | ||
145 | char *port_change_bit; | ||
146 | u32 status; | ||
147 | |||
148 | switch (wValue) { | ||
149 | case USB_PORT_FEAT_C_RESET: | ||
150 | status = PORT_RC; | ||
151 | port_change_bit = "reset"; | ||
152 | break; | ||
153 | case USB_PORT_FEAT_C_CONNECTION: | ||
154 | status = PORT_CSC; | ||
155 | port_change_bit = "connect"; | ||
156 | break; | ||
157 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
158 | status = PORT_OCC; | ||
159 | port_change_bit = "over-current"; | ||
160 | break; | ||
161 | case USB_PORT_FEAT_C_ENABLE: | ||
162 | status = PORT_PEC; | ||
163 | port_change_bit = "enable/disable"; | ||
164 | break; | ||
165 | default: | ||
166 | /* Should never happen */ | ||
167 | return; | ||
168 | } | ||
169 | /* Change bits are all write 1 to clear */ | ||
170 | xhci_writel(xhci, port_status | status, addr); | ||
171 | port_status = xhci_readl(xhci, addr); | ||
172 | xhci_dbg(xhci, "clear port %s change, actual port %d status = 0x%x\n", | ||
173 | port_change_bit, wIndex, port_status); | ||
174 | } | ||
175 | |||
132 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 176 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
133 | u16 wIndex, char *buf, u16 wLength) | 177 | u16 wIndex, char *buf, u16 wLength) |
134 | { | 178 | { |
@@ -138,7 +182,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
138 | u32 temp, status; | 182 | u32 temp, status; |
139 | int retval = 0; | 183 | int retval = 0; |
140 | u32 __iomem *addr; | 184 | u32 __iomem *addr; |
141 | char *port_change_bit; | ||
142 | 185 | ||
143 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 186 | ports = HCS_MAX_PORTS(xhci->hcs_params1); |
144 | 187 | ||
@@ -229,26 +272,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
229 | temp = xhci_port_state_to_neutral(temp); | 272 | temp = xhci_port_state_to_neutral(temp); |
230 | switch (wValue) { | 273 | switch (wValue) { |
231 | case USB_PORT_FEAT_C_RESET: | 274 | case USB_PORT_FEAT_C_RESET: |
232 | status = PORT_RC; | ||
233 | port_change_bit = "reset"; | ||
234 | break; | ||
235 | case USB_PORT_FEAT_C_CONNECTION: | 275 | case USB_PORT_FEAT_C_CONNECTION: |
236 | status = PORT_CSC; | ||
237 | port_change_bit = "connect"; | ||
238 | break; | ||
239 | case USB_PORT_FEAT_C_OVER_CURRENT: | 276 | case USB_PORT_FEAT_C_OVER_CURRENT: |
240 | status = PORT_OCC; | 277 | case USB_PORT_FEAT_C_ENABLE: |
241 | port_change_bit = "over-current"; | 278 | xhci_clear_port_change_bit(xhci, wValue, wIndex, |
279 | addr, temp); | ||
280 | break; | ||
281 | case USB_PORT_FEAT_ENABLE: | ||
282 | xhci_disable_port(xhci, wIndex, addr, temp); | ||
242 | break; | 283 | break; |
243 | default: | 284 | default: |
244 | goto error; | 285 | goto error; |
245 | } | 286 | } |
246 | /* Change bits are all write 1 to clear */ | ||
247 | xhci_writel(xhci, temp | status, addr); | ||
248 | temp = xhci_readl(xhci, addr); | ||
249 | xhci_dbg(xhci, "clear port %s change, actual port %d status = 0x%x\n", | ||
250 | port_change_bit, wIndex, temp); | ||
251 | temp = xhci_readl(xhci, addr); /* unblock any posted writes */ | ||
252 | break; | 287 | break; |
253 | default: | 288 | default: |
254 | error: | 289 | error: |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index bffcef7a5545..49f7d72f8b1b 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -198,6 +198,31 @@ fail: | |||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
200 | 200 | ||
201 | void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, | ||
202 | struct xhci_virt_device *virt_dev, | ||
203 | unsigned int ep_index) | ||
204 | { | ||
205 | int rings_cached; | ||
206 | |||
207 | rings_cached = virt_dev->num_rings_cached; | ||
208 | if (rings_cached < XHCI_MAX_RINGS_CACHED) { | ||
209 | virt_dev->num_rings_cached++; | ||
210 | rings_cached = virt_dev->num_rings_cached; | ||
211 | virt_dev->ring_cache[rings_cached] = | ||
212 | virt_dev->eps[ep_index].ring; | ||
213 | xhci_dbg(xhci, "Cached old ring, " | ||
214 | "%d ring%s cached\n", | ||
215 | rings_cached, | ||
216 | (rings_cached > 1) ? "s" : ""); | ||
217 | } else { | ||
218 | xhci_ring_free(xhci, virt_dev->eps[ep_index].ring); | ||
219 | xhci_dbg(xhci, "Ring cache full (%d rings), " | ||
220 | "freeing ring\n", | ||
221 | virt_dev->num_rings_cached); | ||
222 | } | ||
223 | virt_dev->eps[ep_index].ring = NULL; | ||
224 | } | ||
225 | |||
201 | /* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue | 226 | /* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue |
202 | * pointers to the beginning of the ring. | 227 | * pointers to the beginning of the ring. |
203 | */ | 228 | */ |
@@ -242,6 +267,8 @@ struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci, | |||
242 | void xhci_free_container_ctx(struct xhci_hcd *xhci, | 267 | void xhci_free_container_ctx(struct xhci_hcd *xhci, |
243 | struct xhci_container_ctx *ctx) | 268 | struct xhci_container_ctx *ctx) |
244 | { | 269 | { |
270 | if (!ctx) | ||
271 | return; | ||
245 | dma_pool_free(xhci->device_pool, ctx->bytes, ctx->dma); | 272 | dma_pool_free(xhci->device_pool, ctx->bytes, ctx->dma); |
246 | kfree(ctx); | 273 | kfree(ctx); |
247 | } | 274 | } |
@@ -427,7 +454,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
427 | case USB_SPEED_LOW: | 454 | case USB_SPEED_LOW: |
428 | slot_ctx->dev_info |= (u32) SLOT_SPEED_LS; | 455 | slot_ctx->dev_info |= (u32) SLOT_SPEED_LS; |
429 | break; | 456 | break; |
430 | case USB_SPEED_VARIABLE: | 457 | case USB_SPEED_WIRELESS: |
431 | xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); | 458 | xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); |
432 | return -EINVAL; | 459 | return -EINVAL; |
433 | break; | 460 | break; |
@@ -471,7 +498,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
471 | case USB_SPEED_LOW: | 498 | case USB_SPEED_LOW: |
472 | ep0_ctx->ep_info2 |= MAX_PACKET(8); | 499 | ep0_ctx->ep_info2 |= MAX_PACKET(8); |
473 | break; | 500 | break; |
474 | case USB_SPEED_VARIABLE: | 501 | case USB_SPEED_WIRELESS: |
475 | xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); | 502 | xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); |
476 | return -EINVAL; | 503 | return -EINVAL; |
477 | break; | 504 | break; |
@@ -819,7 +846,8 @@ static void scratchpad_free(struct xhci_hcd *xhci) | |||
819 | } | 846 | } |
820 | 847 | ||
821 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, | 848 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, |
822 | bool allocate_completion, gfp_t mem_flags) | 849 | bool allocate_in_ctx, bool allocate_completion, |
850 | gfp_t mem_flags) | ||
823 | { | 851 | { |
824 | struct xhci_command *command; | 852 | struct xhci_command *command; |
825 | 853 | ||
@@ -827,11 +855,14 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, | |||
827 | if (!command) | 855 | if (!command) |
828 | return NULL; | 856 | return NULL; |
829 | 857 | ||
830 | command->in_ctx = | 858 | if (allocate_in_ctx) { |
831 | xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, mem_flags); | 859 | command->in_ctx = |
832 | if (!command->in_ctx) { | 860 | xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, |
833 | kfree(command); | 861 | mem_flags); |
834 | return NULL; | 862 | if (!command->in_ctx) { |
863 | kfree(command); | ||
864 | return NULL; | ||
865 | } | ||
835 | } | 866 | } |
836 | 867 | ||
837 | if (allocate_completion) { | 868 | if (allocate_completion) { |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index e097008d6fb1..417d37aff8d7 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -139,6 +139,7 @@ static const struct hc_driver xhci_pci_hc_driver = { | |||
139 | .reset_bandwidth = xhci_reset_bandwidth, | 139 | .reset_bandwidth = xhci_reset_bandwidth, |
140 | .address_device = xhci_address_device, | 140 | .address_device = xhci_address_device, |
141 | .update_hub_device = xhci_update_hub_device, | 141 | .update_hub_device = xhci_update_hub_device, |
142 | .reset_device = xhci_reset_device, | ||
142 | 143 | ||
143 | /* | 144 | /* |
144 | * scheduling support | 145 | * scheduling support |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index ee7bc7ecbc59..6ba841bca4a2 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -953,6 +953,17 @@ bandwidth_change: | |||
953 | case TRB_TYPE(TRB_RESET_EP): | 953 | case TRB_TYPE(TRB_RESET_EP): |
954 | handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue); | 954 | handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue); |
955 | break; | 955 | break; |
956 | case TRB_TYPE(TRB_RESET_DEV): | ||
957 | xhci_dbg(xhci, "Completed reset device command.\n"); | ||
958 | slot_id = TRB_TO_SLOT_ID( | ||
959 | xhci->cmd_ring->dequeue->generic.field[3]); | ||
960 | virt_dev = xhci->devs[slot_id]; | ||
961 | if (virt_dev) | ||
962 | handle_cmd_in_cmd_wait_list(xhci, virt_dev, event); | ||
963 | else | ||
964 | xhci_warn(xhci, "Reset device command completion " | ||
965 | "for disabled slot %u\n", slot_id); | ||
966 | break; | ||
956 | default: | 967 | default: |
957 | /* Skip over unknown commands on the event ring */ | 968 | /* Skip over unknown commands on the event ring */ |
958 | xhci->error_bitmask |= 1 << 6; | 969 | xhci->error_bitmask |= 1 << 6; |
@@ -1080,6 +1091,20 @@ static int xhci_requires_manual_halt_cleanup(struct xhci_hcd *xhci, | |||
1080 | return 0; | 1091 | return 0; |
1081 | } | 1092 | } |
1082 | 1093 | ||
1094 | int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code) | ||
1095 | { | ||
1096 | if (trb_comp_code >= 224 && trb_comp_code <= 255) { | ||
1097 | /* Vendor defined "informational" completion code, | ||
1098 | * treat as not-an-error. | ||
1099 | */ | ||
1100 | xhci_dbg(xhci, "Vendor defined info completion code %u\n", | ||
1101 | trb_comp_code); | ||
1102 | xhci_dbg(xhci, "Treating code as success.\n"); | ||
1103 | return 1; | ||
1104 | } | ||
1105 | return 0; | ||
1106 | } | ||
1107 | |||
1083 | /* | 1108 | /* |
1084 | * If this function returns an error condition, it means it got a Transfer | 1109 | * If this function returns an error condition, it means it got a Transfer |
1085 | * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. | 1110 | * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. |
@@ -1196,13 +1221,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1196 | status = -ENOSR; | 1221 | status = -ENOSR; |
1197 | break; | 1222 | break; |
1198 | default: | 1223 | default: |
1199 | if (trb_comp_code >= 224 && trb_comp_code <= 255) { | 1224 | if (xhci_is_vendor_info_code(xhci, trb_comp_code)) { |
1200 | /* Vendor defined "informational" completion code, | ||
1201 | * treat as not-an-error. | ||
1202 | */ | ||
1203 | xhci_dbg(xhci, "Vendor defined info completion code %u\n", | ||
1204 | trb_comp_code); | ||
1205 | xhci_dbg(xhci, "Treating code as success.\n"); | ||
1206 | status = 0; | 1225 | status = 0; |
1207 | break; | 1226 | break; |
1208 | } | 1227 | } |
@@ -2181,6 +2200,14 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
2181 | false); | 2200 | false); |
2182 | } | 2201 | } |
2183 | 2202 | ||
2203 | /* Queue a reset device command TRB */ | ||
2204 | int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id) | ||
2205 | { | ||
2206 | return queue_command(xhci, 0, 0, 0, | ||
2207 | TRB_TYPE(TRB_RESET_DEV) | SLOT_ID_FOR_TRB(slot_id), | ||
2208 | false); | ||
2209 | } | ||
2210 | |||
2184 | /* Queue a configure endpoint command TRB */ | 2211 | /* Queue a configure endpoint command TRB */ |
2185 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 2212 | int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
2186 | u32 slot_id, bool command_must_succeed) | 2213 | u32 slot_id, bool command_must_succeed) |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 877813505ef2..e5eb09b2f38e 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1210,6 +1210,8 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); | |||
1210 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); | 1210 | void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); |
1211 | void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); | 1211 | void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); |
1212 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep); | 1212 | void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep); |
1213 | char *xhci_get_slot_state(struct xhci_hcd *xhci, | ||
1214 | struct xhci_container_ctx *ctx); | ||
1213 | 1215 | ||
1214 | /* xHCI memory management */ | 1216 | /* xHCI memory management */ |
1215 | void xhci_mem_cleanup(struct xhci_hcd *xhci); | 1217 | void xhci_mem_cleanup(struct xhci_hcd *xhci); |
@@ -1233,8 +1235,12 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, | |||
1233 | struct usb_device *udev, struct usb_host_endpoint *ep, | 1235 | struct usb_device *udev, struct usb_host_endpoint *ep, |
1234 | gfp_t mem_flags); | 1236 | gfp_t mem_flags); |
1235 | void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); | 1237 | void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); |
1238 | void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, | ||
1239 | struct xhci_virt_device *virt_dev, | ||
1240 | unsigned int ep_index); | ||
1236 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, | 1241 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, |
1237 | bool allocate_completion, gfp_t mem_flags); | 1242 | bool allocate_in_ctx, bool allocate_completion, |
1243 | gfp_t mem_flags); | ||
1238 | void xhci_free_command(struct xhci_hcd *xhci, | 1244 | void xhci_free_command(struct xhci_hcd *xhci, |
1239 | struct xhci_command *command); | 1245 | struct xhci_command *command); |
1240 | 1246 | ||
@@ -1264,6 +1270,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); | |||
1264 | int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); | 1270 | int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); |
1265 | int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); | 1271 | int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); |
1266 | void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); | 1272 | void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); |
1273 | int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev); | ||
1267 | int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); | 1274 | int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
1268 | void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); | 1275 | void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
1269 | 1276 | ||
@@ -1272,6 +1279,7 @@ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb); | |||
1272 | struct xhci_segment *trb_in_td(struct xhci_segment *start_seg, | 1279 | struct xhci_segment *trb_in_td(struct xhci_segment *start_seg, |
1273 | union xhci_trb *start_trb, union xhci_trb *end_trb, | 1280 | union xhci_trb *start_trb, union xhci_trb *end_trb, |
1274 | dma_addr_t suspect_dma); | 1281 | dma_addr_t suspect_dma); |
1282 | int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code); | ||
1275 | void xhci_ring_cmd_db(struct xhci_hcd *xhci); | 1283 | void xhci_ring_cmd_db(struct xhci_hcd *xhci); |
1276 | void *xhci_setup_one_noop(struct xhci_hcd *xhci); | 1284 | void *xhci_setup_one_noop(struct xhci_hcd *xhci); |
1277 | void xhci_handle_event(struct xhci_hcd *xhci); | 1285 | void xhci_handle_event(struct xhci_hcd *xhci); |
@@ -1293,6 +1301,7 @@ int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
1293 | u32 slot_id); | 1301 | u32 slot_id); |
1294 | int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, | 1302 | int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, |
1295 | unsigned int ep_index); | 1303 | unsigned int ep_index); |
1304 | int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id); | ||
1296 | void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | 1305 | void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, |
1297 | unsigned int slot_id, unsigned int ep_index, | 1306 | unsigned int slot_id, unsigned int ep_index, |
1298 | struct xhci_td *cur_td, struct xhci_dequeue_state *state); | 1307 | struct xhci_td *cur_td, struct xhci_dequeue_state *state); |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index eca355dccf65..e192e8f7c560 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -967,7 +967,7 @@ static const struct file_operations mdc800_device_ops = | |||
967 | 967 | ||
968 | 968 | ||
969 | 969 | ||
970 | static struct usb_device_id mdc800_table [] = { | 970 | static const struct usb_device_id mdc800_table[] = { |
971 | { USB_DEVICE(MDC800_VENDOR_ID, MDC800_PRODUCT_ID) }, | 971 | { USB_DEVICE(MDC800_VENDOR_ID, MDC800_PRODUCT_ID) }, |
972 | { } /* Terminating entry */ | 972 | { } /* Terminating entry */ |
973 | }; | 973 | }; |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 459a7287fe01..3a6bcd5fee09 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -155,7 +155,7 @@ static int mts_usb_probe(struct usb_interface *intf, | |||
155 | const struct usb_device_id *id); | 155 | const struct usb_device_id *id); |
156 | static void mts_usb_disconnect(struct usb_interface *intf); | 156 | static void mts_usb_disconnect(struct usb_interface *intf); |
157 | 157 | ||
158 | static struct usb_device_id mts_usb_ids []; | 158 | static const struct usb_device_id mts_usb_ids[]; |
159 | 159 | ||
160 | static struct usb_driver mts_usb_driver = { | 160 | static struct usb_driver mts_usb_driver = { |
161 | .name = "microtekX6", | 161 | .name = "microtekX6", |
@@ -656,7 +656,7 @@ static struct scsi_host_template mts_scsi_host_template = { | |||
656 | /* The entries of microtek_table must correspond, line-by-line to | 656 | /* The entries of microtek_table must correspond, line-by-line to |
657 | the entries of mts_supported_products[]. */ | 657 | the entries of mts_supported_products[]. */ |
658 | 658 | ||
659 | static struct usb_device_id mts_usb_ids [] = | 659 | static const struct usb_device_id mts_usb_ids[] = |
660 | { | 660 | { |
661 | { USB_DEVICE(0x4ce, 0x0300) }, | 661 | { USB_DEVICE(0x4ce, 0x0300) }, |
662 | { USB_DEVICE(0x5da, 0x0094) }, | 662 | { USB_DEVICE(0x5da, 0x0094) }, |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index abe3aa67ed00..55660eaf947c 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -87,17 +87,6 @@ config USB_LCD | |||
87 | To compile this driver as a module, choose M here: the | 87 | To compile this driver as a module, choose M here: the |
88 | module will be called usblcd. | 88 | module will be called usblcd. |
89 | 89 | ||
90 | config USB_BERRY_CHARGE | ||
91 | tristate "USB BlackBerry recharge support" | ||
92 | depends on USB | ||
93 | help | ||
94 | Say Y here if you want to connect a BlackBerry device to your | ||
95 | computer's USB port and have it automatically switch to "recharge" | ||
96 | mode. | ||
97 | |||
98 | To compile this driver as a module, choose M here: the | ||
99 | module will be called berry_charge. | ||
100 | |||
101 | config USB_LED | 90 | config USB_LED |
102 | tristate "USB LED driver support" | 91 | tristate "USB LED driver support" |
103 | depends on USB | 92 | depends on USB |
@@ -242,17 +231,3 @@ config USB_ISIGHTFW | |||
242 | driver beforehand. Tools for doing so are available at | 231 | driver beforehand. Tools for doing so are available at |
243 | http://bersace03.free.fr | 232 | http://bersace03.free.fr |
244 | 233 | ||
245 | config USB_VST | ||
246 | tristate "USB VST driver" | ||
247 | depends on USB | ||
248 | help | ||
249 | This driver is intended for Vernier Software Technologies | ||
250 | bulk usb devices such as their Ocean-Optics spectrometers or | ||
251 | Labquest. | ||
252 | It is a bulk channel driver with configurable read and write | ||
253 | timeouts. | ||
254 | |||
255 | To compile this driver as a module, choose M here: the | ||
256 | module will be called vstusb. | ||
257 | |||
258 | |||
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 0826aab8303f..717703e81425 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -5,7 +5,6 @@ | |||
5 | 5 | ||
6 | obj-$(CONFIG_USB_ADUTUX) += adutux.o | 6 | obj-$(CONFIG_USB_ADUTUX) += adutux.o |
7 | obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o | 7 | obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o |
8 | obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o | ||
9 | obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o | 8 | obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o |
10 | obj-$(CONFIG_USB_CYTHERM) += cytherm.o | 9 | obj-$(CONFIG_USB_CYTHERM) += cytherm.o |
11 | obj-$(CONFIG_USB_EMI26) += emi26.o | 10 | obj-$(CONFIG_USB_EMI26) += emi26.o |
@@ -23,7 +22,6 @@ obj-$(CONFIG_USB_TEST) += usbtest.o | |||
23 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o | 22 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o |
24 | obj-$(CONFIG_USB_USS720) += uss720.o | 23 | obj-$(CONFIG_USB_USS720) += uss720.o |
25 | obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o | 24 | obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o |
26 | obj-$(CONFIG_USB_VST) += vstusb.o | ||
27 | 25 | ||
28 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ | 26 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ |
29 | 27 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 203526542013..d240de097c62 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -38,7 +38,7 @@ static int debug = 1; | |||
38 | #define dbg(lvl, format, arg...) \ | 38 | #define dbg(lvl, format, arg...) \ |
39 | do { \ | 39 | do { \ |
40 | if (debug >= lvl) \ | 40 | if (debug >= lvl) \ |
41 | printk(KERN_DEBUG __FILE__ " : " format " \n", ## arg); \ | 41 | printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ |
42 | } while (0) | 42 | } while (0) |
43 | 43 | ||
44 | 44 | ||
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "Debug enabled or not"); | |||
56 | #define ADU_PRODUCT_ID 0x0064 | 56 | #define ADU_PRODUCT_ID 0x0064 |
57 | 57 | ||
58 | /* table of devices that work with this driver */ | 58 | /* table of devices that work with this driver */ |
59 | static struct usb_device_id device_table [] = { | 59 | static const struct usb_device_id device_table[] = { |
60 | { USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID) }, /* ADU100 */ | 60 | { USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID) }, /* ADU100 */ |
61 | { USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+20) }, /* ADU120 */ | 61 | { USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+20) }, /* ADU120 */ |
62 | { USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+30) }, /* ADU130 */ | 62 | { USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+30) }, /* ADU130 */ |
@@ -132,8 +132,8 @@ static void adu_debug_data(int level, const char *function, int size, | |||
132 | if (debug < level) | 132 | if (debug < level) |
133 | return; | 133 | return; |
134 | 134 | ||
135 | printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", | 135 | printk(KERN_DEBUG "%s: %s - length = %d, data = ", |
136 | function, size); | 136 | __FILE__, function, size); |
137 | for (i = 0; i < size; ++i) | 137 | for (i = 0; i < size; ++i) |
138 | printk("%.2x ", data[i]); | 138 | printk("%.2x ", data[i]); |
139 | printk("\n"); | 139 | printk("\n"); |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 1eb9e4162cc6..4d2952f1fb13 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -57,7 +57,7 @@ | |||
57 | .bInterfaceProtocol = 0x00 | 57 | .bInterfaceProtocol = 0x00 |
58 | 58 | ||
59 | /* table of devices that work with this driver */ | 59 | /* table of devices that work with this driver */ |
60 | static struct usb_device_id appledisplay_table [] = { | 60 | static const struct usb_device_id appledisplay_table[] = { |
61 | { APPLEDISPLAY_DEVICE(0x9218) }, | 61 | { APPLEDISPLAY_DEVICE(0x9218) }, |
62 | { APPLEDISPLAY_DEVICE(0x9219) }, | 62 | { APPLEDISPLAY_DEVICE(0x9219) }, |
63 | { APPLEDISPLAY_DEVICE(0x921c) }, | 63 | { APPLEDISPLAY_DEVICE(0x921c) }, |
@@ -179,7 +179,7 @@ static int appledisplay_bl_get_brightness(struct backlight_device *bd) | |||
179 | return pdata->msgdata[1]; | 179 | return pdata->msgdata[1]; |
180 | } | 180 | } |
181 | 181 | ||
182 | static struct backlight_ops appledisplay_bl_data = { | 182 | static const struct backlight_ops appledisplay_bl_data = { |
183 | .get_brightness = appledisplay_bl_get_brightness, | 183 | .get_brightness = appledisplay_bl_get_brightness, |
184 | .update_status = appledisplay_bl_update_status, | 184 | .update_status = appledisplay_bl_update_status, |
185 | }; | 185 | }; |
@@ -283,6 +283,7 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
283 | &appledisplay_bl_data); | 283 | &appledisplay_bl_data); |
284 | if (IS_ERR(pdata->bd)) { | 284 | if (IS_ERR(pdata->bd)) { |
285 | dev_err(&iface->dev, "Backlight registration failed\n"); | 285 | dev_err(&iface->dev, "Backlight registration failed\n"); |
286 | retval = PTR_ERR(pdata->bd); | ||
286 | goto error; | 287 | goto error; |
287 | } | 288 | } |
288 | 289 | ||
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c deleted file mode 100644 index c05a85bc5925..000000000000 --- a/drivers/usb/misc/berry_charge.c +++ /dev/null | |||
@@ -1,183 +0,0 @@ | |||
1 | /* | ||
2 | * USB BlackBerry charging module | ||
3 | * | ||
4 | * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | * Information on how to switch configs was taken by the bcharge.cc file | ||
11 | * created by the barry.sf.net project. | ||
12 | * | ||
13 | * bcharge.cc has the following copyright: | ||
14 | * Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/) | ||
15 | * and is released under the GPLv2. | ||
16 | * | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/usb.h> | ||
26 | |||
27 | #define RIM_VENDOR 0x0fca | ||
28 | #define BLACKBERRY 0x0001 | ||
29 | #define BLACKBERRY_PEARL_DUAL 0x0004 | ||
30 | #define BLACKBERRY_PEARL 0x0006 | ||
31 | |||
32 | static int debug; | ||
33 | static int pearl_dual_mode = 1; | ||
34 | |||
35 | #ifdef dbg | ||
36 | #undef dbg | ||
37 | #endif | ||
38 | #define dbg(dev, format, arg...) \ | ||
39 | if (debug) \ | ||
40 | dev_printk(KERN_DEBUG , dev , format , ## arg) | ||
41 | |||
42 | static struct usb_device_id id_table [] = { | ||
43 | { USB_DEVICE(RIM_VENDOR, BLACKBERRY) }, | ||
44 | { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL) }, | ||
45 | { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL_DUAL) }, | ||
46 | { }, /* Terminating entry */ | ||
47 | }; | ||
48 | MODULE_DEVICE_TABLE(usb, id_table); | ||
49 | |||
50 | static int magic_charge(struct usb_device *udev) | ||
51 | { | ||
52 | char *dummy_buffer = kzalloc(2, GFP_KERNEL); | ||
53 | int retval; | ||
54 | |||
55 | if (!dummy_buffer) | ||
56 | return -ENOMEM; | ||
57 | |||
58 | /* send two magic commands and then set the configuration. The device | ||
59 | * will then reset itself with the new power usage and should start | ||
60 | * charging. */ | ||
61 | |||
62 | /* Note, with testing, it only seems that the first message is really | ||
63 | * needed (at least for the 8700c), but to be safe, we emulate what | ||
64 | * other operating systems seem to be sending to their device. We | ||
65 | * really need to get some specs for this device to be sure about what | ||
66 | * is going on here. | ||
67 | */ | ||
68 | dbg(&udev->dev, "Sending first magic command\n"); | ||
69 | retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
70 | 0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100); | ||
71 | if (retval != 2) { | ||
72 | dev_err(&udev->dev, "First magic command failed: %d.\n", | ||
73 | retval); | ||
74 | goto exit; | ||
75 | } | ||
76 | |||
77 | dbg(&udev->dev, "Sending second magic command\n"); | ||
78 | retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
79 | 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100); | ||
80 | if (retval != 0) { | ||
81 | dev_err(&udev->dev, "Second magic command failed: %d.\n", | ||
82 | retval); | ||
83 | goto exit; | ||
84 | } | ||
85 | |||
86 | dbg(&udev->dev, "Calling set_configuration\n"); | ||
87 | retval = usb_driver_set_configuration(udev, 1); | ||
88 | if (retval) | ||
89 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); | ||
90 | |||
91 | exit: | ||
92 | kfree(dummy_buffer); | ||
93 | return retval; | ||
94 | } | ||
95 | |||
96 | static int magic_dual_mode(struct usb_device *udev) | ||
97 | { | ||
98 | char *dummy_buffer = kzalloc(2, GFP_KERNEL); | ||
99 | int retval; | ||
100 | |||
101 | if (!dummy_buffer) | ||
102 | return -ENOMEM; | ||
103 | |||
104 | /* send magic command so that the Blackberry Pearl device exposes | ||
105 | * two interfaces: both the USB mass-storage one and one which can | ||
106 | * be used for database access. */ | ||
107 | dbg(&udev->dev, "Sending magic pearl command\n"); | ||
108 | retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
109 | 0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100); | ||
110 | dbg(&udev->dev, "Magic pearl command returned %d\n", retval); | ||
111 | |||
112 | dbg(&udev->dev, "Calling set_configuration\n"); | ||
113 | retval = usb_driver_set_configuration(udev, 1); | ||
114 | if (retval) | ||
115 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); | ||
116 | |||
117 | kfree(dummy_buffer); | ||
118 | return retval; | ||
119 | } | ||
120 | |||
121 | static int berry_probe(struct usb_interface *intf, | ||
122 | const struct usb_device_id *id) | ||
123 | { | ||
124 | struct usb_device *udev = interface_to_usbdev(intf); | ||
125 | |||
126 | if (udev->bus_mA < 500) { | ||
127 | dbg(&udev->dev, "Not enough power to charge available\n"); | ||
128 | return -ENODEV; | ||
129 | } | ||
130 | |||
131 | dbg(&udev->dev, "Power is set to %dmA\n", | ||
132 | udev->actconfig->desc.bMaxPower * 2); | ||
133 | |||
134 | /* check the power usage so we don't try to enable something that is | ||
135 | * already enabled */ | ||
136 | if ((udev->actconfig->desc.bMaxPower * 2) == 500) { | ||
137 | dbg(&udev->dev, "device is already charging, power is " | ||
138 | "set to %dmA\n", udev->actconfig->desc.bMaxPower * 2); | ||
139 | return -ENODEV; | ||
140 | } | ||
141 | |||
142 | /* turn the power on */ | ||
143 | magic_charge(udev); | ||
144 | |||
145 | if ((le16_to_cpu(udev->descriptor.idProduct) == BLACKBERRY_PEARL) && | ||
146 | (pearl_dual_mode)) | ||
147 | magic_dual_mode(udev); | ||
148 | |||
149 | /* we don't really want to bind to the device, userspace programs can | ||
150 | * handle the syncing just fine, so get outta here. */ | ||
151 | return -ENODEV; | ||
152 | } | ||
153 | |||
154 | static void berry_disconnect(struct usb_interface *intf) | ||
155 | { | ||
156 | } | ||
157 | |||
158 | static struct usb_driver berry_driver = { | ||
159 | .name = "berry_charge", | ||
160 | .probe = berry_probe, | ||
161 | .disconnect = berry_disconnect, | ||
162 | .id_table = id_table, | ||
163 | }; | ||
164 | |||
165 | static int __init berry_init(void) | ||
166 | { | ||
167 | return usb_register(&berry_driver); | ||
168 | } | ||
169 | |||
170 | static void __exit berry_exit(void) | ||
171 | { | ||
172 | usb_deregister(&berry_driver); | ||
173 | } | ||
174 | |||
175 | module_init(berry_init); | ||
176 | module_exit(berry_exit); | ||
177 | |||
178 | MODULE_LICENSE("GPL"); | ||
179 | MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>"); | ||
180 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
181 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
182 | module_param(pearl_dual_mode, bool, S_IRUGO | S_IWUSR); | ||
183 | MODULE_PARM_DESC(pearl_dual_mode, "Change Blackberry Pearl to run in dual mode"); | ||
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 5720bfef6a38..1547d8cac5fb 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c | |||
@@ -56,7 +56,7 @@ | |||
56 | 56 | ||
57 | 57 | ||
58 | /* table of devices that work with this driver */ | 58 | /* table of devices that work with this driver */ |
59 | static struct usb_device_id cypress_table [] = { | 59 | static const struct usb_device_id cypress_table[] = { |
60 | { USB_DEVICE(CYPRESS_VENDOR_ID, CYPRESS_PRODUCT_ID) }, | 60 | { USB_DEVICE(CYPRESS_VENDOR_ID, CYPRESS_PRODUCT_ID) }, |
61 | { } | 61 | { } |
62 | }; | 62 | }; |
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 4fb3c38b924b..b9cbbbda8245 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #define USB_SKEL_VENDOR_ID 0x04b4 | 27 | #define USB_SKEL_VENDOR_ID 0x04b4 |
28 | #define USB_SKEL_PRODUCT_ID 0x0002 | 28 | #define USB_SKEL_PRODUCT_ID 0x0002 |
29 | 29 | ||
30 | static struct usb_device_id id_table [] = { | 30 | static const struct usb_device_id id_table[] = { |
31 | { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, | 31 | { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, |
32 | { } | 32 | { } |
33 | }; | 33 | }; |
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 879a980ca8c4..a6521c95f683 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c | |||
@@ -245,7 +245,7 @@ wraperr: | |||
245 | return err; | 245 | return err; |
246 | } | 246 | } |
247 | 247 | ||
248 | static struct usb_device_id id_table [] = { | 248 | static const struct usb_device_id id_table[] = { |
249 | { USB_DEVICE(EMI26_VENDOR_ID, EMI26_PRODUCT_ID) }, | 249 | { USB_DEVICE(EMI26_VENDOR_ID, EMI26_PRODUCT_ID) }, |
250 | { USB_DEVICE(EMI26_VENDOR_ID, EMI26B_PRODUCT_ID) }, | 250 | { USB_DEVICE(EMI26_VENDOR_ID, EMI26B_PRODUCT_ID) }, |
251 | { } /* Terminating entry */ | 251 | { } /* Terminating entry */ |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 59860b328534..fc15ad4c3139 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
@@ -259,7 +259,7 @@ wraperr: | |||
259 | return err; | 259 | return err; |
260 | } | 260 | } |
261 | 261 | ||
262 | static __devinitdata struct usb_device_id id_table [] = { | 262 | static const struct usb_device_id id_table[] __devinitconst = { |
263 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, | 263 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, |
264 | { } /* Terminating entry */ | 264 | { } /* Terminating entry */ |
265 | }; | 265 | }; |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 9d0675ed0d4c..1edb6d361896 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -86,7 +86,7 @@ static struct list_head ftdi_static_list; | |||
86 | #define USB_FTDI_ELAN_VENDOR_ID 0x0403 | 86 | #define USB_FTDI_ELAN_VENDOR_ID 0x0403 |
87 | #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea | 87 | #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea |
88 | /* table of devices that work with this driver*/ | 88 | /* table of devices that work with this driver*/ |
89 | static struct usb_device_id ftdi_elan_table[] = { | 89 | static const struct usb_device_id ftdi_elan_table[] = { |
90 | {USB_DEVICE(USB_FTDI_ELAN_VENDOR_ID, USB_FTDI_ELAN_PRODUCT_ID)}, | 90 | {USB_DEVICE(USB_FTDI_ELAN_VENDOR_ID, USB_FTDI_ELAN_PRODUCT_ID)}, |
91 | { /* Terminating entry */ } | 91 | { /* Terminating entry */ } |
92 | }; | 92 | }; |
@@ -623,9 +623,12 @@ static void ftdi_elan_status_work(struct work_struct *work) | |||
623 | */ | 623 | */ |
624 | static int ftdi_elan_open(struct inode *inode, struct file *file) | 624 | static int ftdi_elan_open(struct inode *inode, struct file *file) |
625 | { | 625 | { |
626 | int subminor = iminor(inode); | 626 | int subminor; |
627 | struct usb_interface *interface = usb_find_interface(&ftdi_elan_driver, | 627 | struct usb_interface *interface; |
628 | subminor); | 628 | |
629 | subminor = iminor(inode); | ||
630 | interface = usb_find_interface(&ftdi_elan_driver, subminor); | ||
631 | |||
629 | if (!interface) { | 632 | if (!interface) { |
630 | printk(KERN_ERR "can't find device for minor %d\n", subminor); | 633 | printk(KERN_ERR "can't find device for minor %d\n", subminor); |
631 | return -ENODEV; | 634 | return -ENODEV; |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 1337a9ce80b9..a54c3cb804ce 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #define ID_CHERRY 0x0010 | 48 | #define ID_CHERRY 0x0010 |
49 | 49 | ||
50 | /* device ID table */ | 50 | /* device ID table */ |
51 | static struct usb_device_id idmouse_table[] = { | 51 | static const struct usb_device_id idmouse_table[] = { |
52 | {USB_DEVICE(ID_SIEMENS, ID_IDMOUSE)}, /* Siemens ID Mouse (Professional) */ | 52 | {USB_DEVICE(ID_SIEMENS, ID_IDMOUSE)}, /* Siemens ID Mouse (Professional) */ |
53 | {USB_DEVICE(ID_SIEMENS, ID_CHERRY )}, /* Cherry FingerTIP ID Board */ | 53 | {USB_DEVICE(ID_SIEMENS, ID_CHERRY )}, /* Cherry FingerTIP ID Board */ |
54 | {} /* terminating null entry */ | 54 | {} /* terminating null entry */ |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index e75bb87ee92b..d3c852363883 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -139,7 +139,7 @@ static int usb_set_report(struct usb_interface *intf, unsigned char type, | |||
139 | /* driver registration */ | 139 | /* driver registration */ |
140 | /*---------------------*/ | 140 | /*---------------------*/ |
141 | /* table of devices that work with this driver */ | 141 | /* table of devices that work with this driver */ |
142 | static struct usb_device_id iowarrior_ids[] = { | 142 | static const struct usb_device_id iowarrior_ids[] = { |
143 | {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)}, | 143 | {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)}, |
144 | {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)}, | 144 | {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)}, |
145 | {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)}, | 145 | {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)}, |
@@ -602,10 +602,12 @@ static int iowarrior_open(struct inode *inode, struct file *file) | |||
602 | 602 | ||
603 | dbg("%s", __func__); | 603 | dbg("%s", __func__); |
604 | 604 | ||
605 | lock_kernel(); | ||
605 | subminor = iminor(inode); | 606 | subminor = iminor(inode); |
606 | 607 | ||
607 | interface = usb_find_interface(&iowarrior_driver, subminor); | 608 | interface = usb_find_interface(&iowarrior_driver, subminor); |
608 | if (!interface) { | 609 | if (!interface) { |
610 | unlock_kernel(); | ||
609 | err("%s - error, can't find device for minor %d", __func__, | 611 | err("%s - error, can't find device for minor %d", __func__, |
610 | subminor); | 612 | subminor); |
611 | return -ENODEV; | 613 | return -ENODEV; |
@@ -615,6 +617,7 @@ static int iowarrior_open(struct inode *inode, struct file *file) | |||
615 | dev = usb_get_intfdata(interface); | 617 | dev = usb_get_intfdata(interface); |
616 | if (!dev) { | 618 | if (!dev) { |
617 | mutex_unlock(&iowarrior_open_disc_lock); | 619 | mutex_unlock(&iowarrior_open_disc_lock); |
620 | unlock_kernel(); | ||
618 | return -ENODEV; | 621 | return -ENODEV; |
619 | } | 622 | } |
620 | 623 | ||
@@ -641,6 +644,7 @@ static int iowarrior_open(struct inode *inode, struct file *file) | |||
641 | 644 | ||
642 | out: | 645 | out: |
643 | mutex_unlock(&dev->mutex); | 646 | mutex_unlock(&dev->mutex); |
647 | unlock_kernel(); | ||
644 | return retval; | 648 | return retval; |
645 | } | 649 | } |
646 | 650 | ||
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index b897f6554ecd..06e990adc6cd 100644 --- a/drivers/usb/misc/isight_firmware.c +++ b/drivers/usb/misc/isight_firmware.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | 28 | ||
29 | static struct usb_device_id id_table[] = { | 29 | static const struct usb_device_id id_table[] = { |
30 | {USB_DEVICE(0x05ac, 0x8300)}, | 30 | {USB_DEVICE(0x05ac, 0x8300)}, |
31 | {}, | 31 | {}, |
32 | }; | 32 | }; |
@@ -112,6 +112,8 @@ out: | |||
112 | return ret; | 112 | return ret; |
113 | } | 113 | } |
114 | 114 | ||
115 | MODULE_FIRMWARE("isight.fw"); | ||
116 | |||
115 | static void isight_firmware_disconnect(struct usb_interface *intf) | 117 | static void isight_firmware_disconnect(struct usb_interface *intf) |
116 | { | 118 | { |
117 | } | 119 | } |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 90f130126c10..dd41d8710043 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -69,7 +69,7 @@ | |||
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | /* table of devices that work with this driver */ | 71 | /* table of devices that work with this driver */ |
72 | static struct usb_device_id ld_usb_table [] = { | 72 | static const struct usb_device_id ld_usb_table[] = { |
73 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, | 73 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, |
74 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, | 74 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, |
75 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, | 75 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, |
@@ -798,7 +798,7 @@ static int __init ld_usb_init(void) | |||
798 | /* register this driver with the USB subsystem */ | 798 | /* register this driver with the USB subsystem */ |
799 | retval = usb_register(&ld_usb_driver); | 799 | retval = usb_register(&ld_usb_driver); |
800 | if (retval) | 800 | if (retval) |
801 | err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval); | 801 | err("usb_register failed for the %s driver. Error number %d\n", __FILE__, retval); |
802 | 802 | ||
803 | return retval; | 803 | return retval; |
804 | } | 804 | } |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index faa6d623de78..8547bf9e3175 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -95,8 +95,11 @@ | |||
95 | 95 | ||
96 | /* Use our own dbg macro */ | 96 | /* Use our own dbg macro */ |
97 | #undef dbg | 97 | #undef dbg |
98 | #define dbg(lvl, format, arg...) do { if (debug >= lvl) printk(KERN_DEBUG __FILE__ ": " format "\n", ## arg); } while (0) | 98 | #define dbg(lvl, format, arg...) \ |
99 | 99 | do { \ | |
100 | if (debug >= lvl) \ | ||
101 | printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ | ||
102 | } while (0) | ||
100 | 103 | ||
101 | /* Version Information */ | 104 | /* Version Information */ |
102 | #define DRIVER_VERSION "v0.96" | 105 | #define DRIVER_VERSION "v0.96" |
@@ -192,7 +195,7 @@ struct tower_get_version_reply { | |||
192 | 195 | ||
193 | 196 | ||
194 | /* table of devices that work with this driver */ | 197 | /* table of devices that work with this driver */ |
195 | static struct usb_device_id tower_table [] = { | 198 | static const struct usb_device_id tower_table[] = { |
196 | { USB_DEVICE(LEGO_USB_TOWER_VENDOR_ID, LEGO_USB_TOWER_PRODUCT_ID) }, | 199 | { USB_DEVICE(LEGO_USB_TOWER_VENDOR_ID, LEGO_USB_TOWER_PRODUCT_ID) }, |
197 | { } /* Terminating entry */ | 200 | { } /* Terminating entry */ |
198 | }; | 201 | }; |
@@ -302,7 +305,7 @@ static inline void lego_usb_tower_debug_data (int level, const char *function, i | |||
302 | if (debug < level) | 305 | if (debug < level) |
303 | return; | 306 | return; |
304 | 307 | ||
305 | printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size); | 308 | printk (KERN_DEBUG "%s: %s - length = %d, data = ", __FILE__, function, size); |
306 | for (i = 0; i < size; ++i) { | 309 | for (i = 0; i < size; ++i) { |
307 | printk ("%.2x ", data[i]); | 310 | printk ("%.2x ", data[i]); |
308 | } | 311 | } |
@@ -1055,7 +1058,7 @@ static int __init lego_usb_tower_init(void) | |||
1055 | /* register this driver with the USB subsystem */ | 1058 | /* register this driver with the USB subsystem */ |
1056 | result = usb_register(&tower_driver); | 1059 | result = usb_register(&tower_driver); |
1057 | if (result < 0) { | 1060 | if (result < 0) { |
1058 | err("usb_register failed for the "__FILE__" driver. Error number %d", result); | 1061 | err("usb_register failed for the %s driver. Error number %d", __FILE__, result); |
1059 | retval = -1; | 1062 | retval = -1; |
1060 | goto exit; | 1063 | goto exit; |
1061 | } | 1064 | } |
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 32d0199d0c32..a85771b1563d 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -78,10 +78,13 @@ static int open_rio(struct inode *inode, struct file *file) | |||
78 | { | 78 | { |
79 | struct rio_usb_data *rio = &rio_instance; | 79 | struct rio_usb_data *rio = &rio_instance; |
80 | 80 | ||
81 | /* against disconnect() */ | ||
82 | lock_kernel(); | ||
81 | mutex_lock(&(rio->lock)); | 83 | mutex_lock(&(rio->lock)); |
82 | 84 | ||
83 | if (rio->isopen || !rio->present) { | 85 | if (rio->isopen || !rio->present) { |
84 | mutex_unlock(&(rio->lock)); | 86 | mutex_unlock(&(rio->lock)); |
87 | unlock_kernel(); | ||
85 | return -EBUSY; | 88 | return -EBUSY; |
86 | } | 89 | } |
87 | rio->isopen = 1; | 90 | rio->isopen = 1; |
@@ -91,6 +94,7 @@ static int open_rio(struct inode *inode, struct file *file) | |||
91 | mutex_unlock(&(rio->lock)); | 94 | mutex_unlock(&(rio->lock)); |
92 | 95 | ||
93 | dev_info(&rio->rio_dev->dev, "Rio opened.\n"); | 96 | dev_info(&rio->rio_dev->dev, "Rio opened.\n"); |
97 | unlock_kernel(); | ||
94 | 98 | ||
95 | return 0; | 99 | return 0; |
96 | } | 100 | } |
@@ -115,7 +119,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) | |||
115 | int retries; | 119 | int retries; |
116 | int retval=0; | 120 | int retval=0; |
117 | 121 | ||
118 | lock_kernel(); | ||
119 | mutex_lock(&(rio->lock)); | 122 | mutex_lock(&(rio->lock)); |
120 | /* Sanity check to make sure rio is connected, powered, etc */ | 123 | /* Sanity check to make sure rio is connected, powered, etc */ |
121 | if (rio->present == 0 || rio->rio_dev == NULL) { | 124 | if (rio->present == 0 || rio->rio_dev == NULL) { |
@@ -254,7 +257,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) | |||
254 | 257 | ||
255 | err_out: | 258 | err_out: |
256 | mutex_unlock(&(rio->lock)); | 259 | mutex_unlock(&(rio->lock)); |
257 | unlock_kernel(); | ||
258 | return retval; | 260 | return retval; |
259 | } | 261 | } |
260 | 262 | ||
@@ -489,6 +491,7 @@ static void disconnect_rio(struct usb_interface *intf) | |||
489 | struct rio_usb_data *rio = usb_get_intfdata (intf); | 491 | struct rio_usb_data *rio = usb_get_intfdata (intf); |
490 | 492 | ||
491 | usb_set_intfdata (intf, NULL); | 493 | usb_set_intfdata (intf, NULL); |
494 | lock_kernel(); | ||
492 | if (rio) { | 495 | if (rio) { |
493 | usb_deregister_dev(intf, &usb_rio_class); | 496 | usb_deregister_dev(intf, &usb_rio_class); |
494 | 497 | ||
@@ -498,6 +501,7 @@ static void disconnect_rio(struct usb_interface *intf) | |||
498 | /* better let it finish - the release will do whats needed */ | 501 | /* better let it finish - the release will do whats needed */ |
499 | rio->rio_dev = NULL; | 502 | rio->rio_dev = NULL; |
500 | mutex_unlock(&(rio->lock)); | 503 | mutex_unlock(&(rio->lock)); |
504 | unlock_kernel(); | ||
501 | return; | 505 | return; |
502 | } | 506 | } |
503 | kfree(rio->ibuf); | 507 | kfree(rio->ibuf); |
@@ -508,9 +512,10 @@ static void disconnect_rio(struct usb_interface *intf) | |||
508 | rio->present = 0; | 512 | rio->present = 0; |
509 | mutex_unlock(&(rio->lock)); | 513 | mutex_unlock(&(rio->lock)); |
510 | } | 514 | } |
515 | unlock_kernel(); | ||
511 | } | 516 | } |
512 | 517 | ||
513 | static struct usb_device_id rio_table [] = { | 518 | static const struct usb_device_id rio_table[] = { |
514 | { USB_DEVICE(0x0841, 1) }, /* Rio 500 */ | 519 | { USB_DEVICE(0x0841, 1) }, /* Rio 500 */ |
515 | { } /* Terminating entry */ | 520 | { } /* Terminating entry */ |
516 | }; | 521 | }; |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 8b37a4b9839e..aae95a009bd5 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -250,7 +250,7 @@ sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, unsigned int pipe, | |||
250 | sisusb->urbstatus[index] |= SU_URB_BUSY; | 250 | sisusb->urbstatus[index] |= SU_URB_BUSY; |
251 | 251 | ||
252 | /* Submit URB */ | 252 | /* Submit URB */ |
253 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 253 | retval = usb_submit_urb(urb, GFP_KERNEL); |
254 | 254 | ||
255 | /* If OK, and if timeout > 0, wait for completion */ | 255 | /* If OK, and if timeout > 0, wait for completion */ |
256 | if ((retval == 0) && timeout) { | 256 | if ((retval == 0) && timeout) { |
@@ -306,7 +306,7 @@ sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, unsigned int pipe, void *data, | |||
306 | urb->actual_length = 0; | 306 | urb->actual_length = 0; |
307 | 307 | ||
308 | sisusb->completein = 0; | 308 | sisusb->completein = 0; |
309 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 309 | retval = usb_submit_urb(urb, GFP_KERNEL); |
310 | if (retval == 0) { | 310 | if (retval == 0) { |
311 | wait_event_timeout(sisusb->wait_q, sisusb->completein, timeout); | 311 | wait_event_timeout(sisusb->wait_q, sisusb->completein, timeout); |
312 | if (!sisusb->completein) { | 312 | if (!sisusb->completein) { |
@@ -2416,21 +2416,28 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2416 | struct usb_interface *interface; | 2416 | struct usb_interface *interface; |
2417 | int subminor = iminor(inode); | 2417 | int subminor = iminor(inode); |
2418 | 2418 | ||
2419 | if (!(interface = usb_find_interface(&sisusb_driver, subminor))) | 2419 | lock_kernel(); |
2420 | if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { | ||
2421 | unlock_kernel(); | ||
2420 | return -ENODEV; | 2422 | return -ENODEV; |
2423 | } | ||
2421 | 2424 | ||
2422 | if (!(sisusb = usb_get_intfdata(interface))) | 2425 | if (!(sisusb = usb_get_intfdata(interface))) { |
2426 | unlock_kernel(); | ||
2423 | return -ENODEV; | 2427 | return -ENODEV; |
2428 | } | ||
2424 | 2429 | ||
2425 | mutex_lock(&sisusb->lock); | 2430 | mutex_lock(&sisusb->lock); |
2426 | 2431 | ||
2427 | if (!sisusb->present || !sisusb->ready) { | 2432 | if (!sisusb->present || !sisusb->ready) { |
2428 | mutex_unlock(&sisusb->lock); | 2433 | mutex_unlock(&sisusb->lock); |
2434 | unlock_kernel(); | ||
2429 | return -ENODEV; | 2435 | return -ENODEV; |
2430 | } | 2436 | } |
2431 | 2437 | ||
2432 | if (sisusb->isopen) { | 2438 | if (sisusb->isopen) { |
2433 | mutex_unlock(&sisusb->lock); | 2439 | mutex_unlock(&sisusb->lock); |
2440 | unlock_kernel(); | ||
2434 | return -EBUSY; | 2441 | return -EBUSY; |
2435 | } | 2442 | } |
2436 | 2443 | ||
@@ -2439,11 +2446,13 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2439 | if (sisusb_init_gfxdevice(sisusb, 0)) { | 2446 | if (sisusb_init_gfxdevice(sisusb, 0)) { |
2440 | mutex_unlock(&sisusb->lock); | 2447 | mutex_unlock(&sisusb->lock); |
2441 | dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n"); | 2448 | dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n"); |
2449 | unlock_kernel(); | ||
2442 | return -EIO; | 2450 | return -EIO; |
2443 | } | 2451 | } |
2444 | } else { | 2452 | } else { |
2445 | mutex_unlock(&sisusb->lock); | 2453 | mutex_unlock(&sisusb->lock); |
2446 | dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n"); | 2454 | dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n"); |
2455 | unlock_kernel(); | ||
2447 | return -EIO; | 2456 | return -EIO; |
2448 | } | 2457 | } |
2449 | } | 2458 | } |
@@ -2456,6 +2465,7 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2456 | file->private_data = sisusb; | 2465 | file->private_data = sisusb; |
2457 | 2466 | ||
2458 | mutex_unlock(&sisusb->lock); | 2467 | mutex_unlock(&sisusb->lock); |
2468 | unlock_kernel(); | ||
2459 | 2469 | ||
2460 | return 0; | 2470 | return 0; |
2461 | } | 2471 | } |
@@ -3238,7 +3248,7 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3238 | kref_put(&sisusb->kref, sisusb_delete); | 3248 | kref_put(&sisusb->kref, sisusb_delete); |
3239 | } | 3249 | } |
3240 | 3250 | ||
3241 | static struct usb_device_id sisusb_table [] = { | 3251 | static const struct usb_device_id sisusb_table[] = { |
3242 | { USB_DEVICE(0x0711, 0x0550) }, | 3252 | { USB_DEVICE(0x0711, 0x0550) }, |
3243 | { USB_DEVICE(0x0711, 0x0900) }, | 3253 | { USB_DEVICE(0x0711, 0x0900) }, |
3244 | { USB_DEVICE(0x0711, 0x0901) }, | 3254 | { USB_DEVICE(0x0711, 0x0901) }, |
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 2e14102955c5..5da28eaee314 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #define TRANCEVIBRATOR_VENDOR_ID 0x0b49 /* ASCII Corporation */ | 33 | #define TRANCEVIBRATOR_VENDOR_ID 0x0b49 /* ASCII Corporation */ |
34 | #define TRANCEVIBRATOR_PRODUCT_ID 0x064f /* Trance Vibrator */ | 34 | #define TRANCEVIBRATOR_PRODUCT_ID 0x064f /* Trance Vibrator */ |
35 | 35 | ||
36 | static struct usb_device_id id_table [] = { | 36 | static const struct usb_device_id id_table[] = { |
37 | { USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) }, | 37 | { USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) }, |
38 | { }, | 38 | { }, |
39 | }; | 39 | }; |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 4fb120357c55..90aede90553e 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #define IOCTL_GET_DRV_VERSION 2 | 30 | #define IOCTL_GET_DRV_VERSION 2 |
31 | 31 | ||
32 | 32 | ||
33 | static struct usb_device_id id_table [] = { | 33 | static const struct usb_device_id id_table[] = { |
34 | { .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, }, | 34 | { .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, }, |
35 | { }, | 35 | { }, |
36 | }; | 36 | }; |
@@ -74,10 +74,12 @@ static int lcd_open(struct inode *inode, struct file *file) | |||
74 | struct usb_interface *interface; | 74 | struct usb_interface *interface; |
75 | int subminor, r; | 75 | int subminor, r; |
76 | 76 | ||
77 | lock_kernel(); | ||
77 | subminor = iminor(inode); | 78 | subminor = iminor(inode); |
78 | 79 | ||
79 | interface = usb_find_interface(&lcd_driver, subminor); | 80 | interface = usb_find_interface(&lcd_driver, subminor); |
80 | if (!interface) { | 81 | if (!interface) { |
82 | unlock_kernel(); | ||
81 | err ("USBLCD: %s - error, can't find device for minor %d", | 83 | err ("USBLCD: %s - error, can't find device for minor %d", |
82 | __func__, subminor); | 84 | __func__, subminor); |
83 | return -ENODEV; | 85 | return -ENODEV; |
@@ -87,6 +89,7 @@ static int lcd_open(struct inode *inode, struct file *file) | |||
87 | dev = usb_get_intfdata(interface); | 89 | dev = usb_get_intfdata(interface); |
88 | if (!dev) { | 90 | if (!dev) { |
89 | mutex_unlock(&open_disc_mutex); | 91 | mutex_unlock(&open_disc_mutex); |
92 | unlock_kernel(); | ||
90 | return -ENODEV; | 93 | return -ENODEV; |
91 | } | 94 | } |
92 | 95 | ||
@@ -98,11 +101,13 @@ static int lcd_open(struct inode *inode, struct file *file) | |||
98 | r = usb_autopm_get_interface(interface); | 101 | r = usb_autopm_get_interface(interface); |
99 | if (r < 0) { | 102 | if (r < 0) { |
100 | kref_put(&dev->kref, lcd_delete); | 103 | kref_put(&dev->kref, lcd_delete); |
104 | unlock_kernel(); | ||
101 | return r; | 105 | return r; |
102 | } | 106 | } |
103 | 107 | ||
104 | /* save our object in the file's private structure */ | 108 | /* save our object in the file's private structure */ |
105 | file->private_data = dev; | 109 | file->private_data = dev; |
110 | unlock_kernel(); | ||
106 | 111 | ||
107 | return 0; | 112 | return 0; |
108 | } | 113 | } |
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 06cb71942dc7..63da2c3c838f 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #define PRODUCT_ID 0x1223 | 24 | #define PRODUCT_ID 0x1223 |
25 | 25 | ||
26 | /* table of devices that work with this driver */ | 26 | /* table of devices that work with this driver */ |
27 | static struct usb_device_id id_table [] = { | 27 | static const struct usb_device_id id_table[] = { |
28 | { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, | 28 | { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, |
29 | { }, | 29 | { }, |
30 | }; | 30 | }; |
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 3db255537e79..a9555cb901a1 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #define MAXLEN 6 | 27 | #define MAXLEN 6 |
28 | 28 | ||
29 | /* table of devices that work with this driver */ | 29 | /* table of devices that work with this driver */ |
30 | static struct usb_device_id id_table[] = { | 30 | static const struct usb_device_id id_table[] = { |
31 | { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, | 31 | { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, |
32 | { }, | 32 | { }, |
33 | }; | 33 | }; |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 3dab0c0b196f..a21cce6f7403 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -1580,10 +1580,6 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1580 | return -ERESTARTSYS; | 1580 | return -ERESTARTSYS; |
1581 | 1581 | ||
1582 | /* FIXME: What if a system sleep starts while a test is running? */ | 1582 | /* FIXME: What if a system sleep starts while a test is running? */ |
1583 | if (!intf->is_active) { | ||
1584 | mutex_unlock(&dev->lock); | ||
1585 | return -EHOSTUNREACH; | ||
1586 | } | ||
1587 | 1583 | ||
1588 | /* some devices, like ez-usb default devices, need a non-default | 1584 | /* some devices, like ez-usb default devices, need a non-default |
1589 | * altsetting to have any active endpoints. some tests change | 1585 | * altsetting to have any active endpoints. some tests change |
@@ -2101,7 +2097,7 @@ static struct usbtest_info generic_info = { | |||
2101 | #endif | 2097 | #endif |
2102 | 2098 | ||
2103 | 2099 | ||
2104 | static struct usb_device_id id_table [] = { | 2100 | static const struct usb_device_id id_table[] = { |
2105 | 2101 | ||
2106 | /*-------------------------------------------------------------*/ | 2102 | /*-------------------------------------------------------------*/ |
2107 | 2103 | ||
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 9a6c27a01793..f56fed53f2dd 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -770,7 +770,7 @@ static void uss720_disconnect(struct usb_interface *intf) | |||
770 | } | 770 | } |
771 | 771 | ||
772 | /* table of cables that work through this driver */ | 772 | /* table of cables that work through this driver */ |
773 | static struct usb_device_id uss720_table [] = { | 773 | static const struct usb_device_id uss720_table[] = { |
774 | { USB_DEVICE(0x047e, 0x1001) }, | 774 | { USB_DEVICE(0x047e, 0x1001) }, |
775 | { USB_DEVICE(0x0557, 0x2001) }, | 775 | { USB_DEVICE(0x0557, 0x2001) }, |
776 | { USB_DEVICE(0x0729, 0x1284) }, | 776 | { USB_DEVICE(0x0729, 0x1284) }, |
diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c deleted file mode 100644 index f26ea8dc1577..000000000000 --- a/drivers/usb/misc/vstusb.c +++ /dev/null | |||
@@ -1,783 +0,0 @@ | |||
1 | /***************************************************************************** | ||
2 | * File: drivers/usb/misc/vstusb.c | ||
3 | * | ||
4 | * Purpose: Support for the bulk USB Vernier Spectrophotometers | ||
5 | * | ||
6 | * Author: Johnnie Peters | ||
7 | * Axian Consulting | ||
8 | * Beaverton, OR, USA 97005 | ||
9 | * | ||
10 | * Modified by: EQware Engineering, Inc. | ||
11 | * Oregon City, OR, USA 97045 | ||
12 | * | ||
13 | * Copyright: 2007, 2008 | ||
14 | * Vernier Software & Technology | ||
15 | * Beaverton, OR, USA 97005 | ||
16 | * | ||
17 | * Web: www.vernier.com | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify | ||
20 | * it under the terms of the GNU General Public License version 2 as | ||
21 | * published by the Free Software Foundation. | ||
22 | * | ||
23 | *****************************************************************************/ | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/mutex.h> | ||
30 | #include <linux/uaccess.h> | ||
31 | #include <linux/usb.h> | ||
32 | |||
33 | #include <linux/usb/vstusb.h> | ||
34 | |||
35 | #define DRIVER_VERSION "VST USB Driver Version 1.5" | ||
36 | #define DRIVER_DESC "Vernier Software Technology Bulk USB Driver" | ||
37 | |||
38 | #ifdef CONFIG_USB_DYNAMIC_MINORS | ||
39 | #define VSTUSB_MINOR_BASE 0 | ||
40 | #else | ||
41 | #define VSTUSB_MINOR_BASE 199 | ||
42 | #endif | ||
43 | |||
44 | #define USB_VENDOR_OCEANOPTICS 0x2457 | ||
45 | #define USB_VENDOR_VERNIER 0x08F7 /* Vernier Software & Technology */ | ||
46 | |||
47 | #define USB_PRODUCT_USB2000 0x1002 | ||
48 | #define USB_PRODUCT_ADC1000_FW 0x1003 /* firmware download (renumerates) */ | ||
49 | #define USB_PRODUCT_ADC1000 0x1004 | ||
50 | #define USB_PRODUCT_HR2000_FW 0x1009 /* firmware download (renumerates) */ | ||
51 | #define USB_PRODUCT_HR2000 0x100A | ||
52 | #define USB_PRODUCT_HR4000_FW 0x1011 /* firmware download (renumerates) */ | ||
53 | #define USB_PRODUCT_HR4000 0x1012 | ||
54 | #define USB_PRODUCT_USB650 0x1014 /* "Red Tide" */ | ||
55 | #define USB_PRODUCT_QE65000 0x1018 | ||
56 | #define USB_PRODUCT_USB4000 0x1022 | ||
57 | #define USB_PRODUCT_USB325 0x1024 /* "Vernier Spectrometer" */ | ||
58 | |||
59 | #define USB_PRODUCT_LABPRO 0x0001 | ||
60 | #define USB_PRODUCT_LABQUEST 0x0005 | ||
61 | |||
62 | #define VST_MAXBUFFER (64*1024) | ||
63 | |||
64 | static struct usb_device_id id_table[] = { | ||
65 | { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)}, | ||
66 | { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)}, | ||
67 | { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB650)}, | ||
68 | { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB4000)}, | ||
69 | { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB325)}, | ||
70 | { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABQUEST)}, | ||
71 | { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABPRO)}, | ||
72 | {}, | ||
73 | }; | ||
74 | |||
75 | MODULE_DEVICE_TABLE(usb, id_table); | ||
76 | |||
77 | struct vstusb_device { | ||
78 | struct kref kref; | ||
79 | struct mutex lock; | ||
80 | struct usb_device *usb_dev; | ||
81 | char present; | ||
82 | char isopen; | ||
83 | struct usb_anchor submitted; | ||
84 | int rd_pipe; | ||
85 | int rd_timeout_ms; | ||
86 | int wr_pipe; | ||
87 | int wr_timeout_ms; | ||
88 | }; | ||
89 | #define to_vst_dev(d) container_of(d, struct vstusb_device, kref) | ||
90 | |||
91 | static struct usb_driver vstusb_driver; | ||
92 | |||
93 | static void vstusb_delete(struct kref *kref) | ||
94 | { | ||
95 | struct vstusb_device *vstdev = to_vst_dev(kref); | ||
96 | |||
97 | usb_put_dev(vstdev->usb_dev); | ||
98 | kfree(vstdev); | ||
99 | } | ||
100 | |||
101 | static int vstusb_open(struct inode *inode, struct file *file) | ||
102 | { | ||
103 | struct vstusb_device *vstdev; | ||
104 | struct usb_interface *interface; | ||
105 | |||
106 | interface = usb_find_interface(&vstusb_driver, iminor(inode)); | ||
107 | |||
108 | if (!interface) { | ||
109 | printk(KERN_ERR KBUILD_MODNAME | ||
110 | ": %s - error, can't find device for minor %d\n", | ||
111 | __func__, iminor(inode)); | ||
112 | return -ENODEV; | ||
113 | } | ||
114 | |||
115 | vstdev = usb_get_intfdata(interface); | ||
116 | |||
117 | if (!vstdev) | ||
118 | return -ENODEV; | ||
119 | |||
120 | /* lock this device */ | ||
121 | mutex_lock(&vstdev->lock); | ||
122 | |||
123 | /* can only open one time */ | ||
124 | if ((!vstdev->present) || (vstdev->isopen)) { | ||
125 | mutex_unlock(&vstdev->lock); | ||
126 | return -EBUSY; | ||
127 | } | ||
128 | |||
129 | /* increment our usage count */ | ||
130 | kref_get(&vstdev->kref); | ||
131 | |||
132 | vstdev->isopen = 1; | ||
133 | |||
134 | /* save device in the file's private structure */ | ||
135 | file->private_data = vstdev; | ||
136 | |||
137 | dev_dbg(&vstdev->usb_dev->dev, "%s: opened\n", __func__); | ||
138 | |||
139 | mutex_unlock(&vstdev->lock); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int vstusb_release(struct inode *inode, struct file *file) | ||
145 | { | ||
146 | struct vstusb_device *vstdev; | ||
147 | |||
148 | vstdev = file->private_data; | ||
149 | |||
150 | if (vstdev == NULL) | ||
151 | return -ENODEV; | ||
152 | |||
153 | mutex_lock(&vstdev->lock); | ||
154 | |||
155 | vstdev->isopen = 0; | ||
156 | |||
157 | dev_dbg(&vstdev->usb_dev->dev, "%s: released\n", __func__); | ||
158 | |||
159 | mutex_unlock(&vstdev->lock); | ||
160 | |||
161 | kref_put(&vstdev->kref, vstusb_delete); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static void usb_api_blocking_completion(struct urb *urb) | ||
167 | { | ||
168 | struct completion *completeit = urb->context; | ||
169 | |||
170 | complete(completeit); | ||
171 | } | ||
172 | |||
173 | static int vstusb_fill_and_send_urb(struct urb *urb, | ||
174 | struct usb_device *usb_dev, | ||
175 | unsigned int pipe, void *data, | ||
176 | unsigned int len, struct completion *done) | ||
177 | { | ||
178 | struct usb_host_endpoint *ep; | ||
179 | struct usb_host_endpoint **hostep; | ||
180 | unsigned int pipend; | ||
181 | |||
182 | int status; | ||
183 | |||
184 | hostep = usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out; | ||
185 | pipend = usb_pipeendpoint(pipe); | ||
186 | ep = hostep[pipend]; | ||
187 | |||
188 | if (!ep || (len == 0)) | ||
189 | return -EINVAL; | ||
190 | |||
191 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
192 | == USB_ENDPOINT_XFER_INT) { | ||
193 | pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); | ||
194 | usb_fill_int_urb(urb, usb_dev, pipe, data, len, | ||
195 | (usb_complete_t)usb_api_blocking_completion, | ||
196 | NULL, ep->desc.bInterval); | ||
197 | } else | ||
198 | usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, | ||
199 | (usb_complete_t)usb_api_blocking_completion, | ||
200 | NULL); | ||
201 | |||
202 | init_completion(done); | ||
203 | urb->context = done; | ||
204 | urb->actual_length = 0; | ||
205 | status = usb_submit_urb(urb, GFP_KERNEL); | ||
206 | |||
207 | return status; | ||
208 | } | ||
209 | |||
210 | static int vstusb_complete_urb(struct urb *urb, struct completion *done, | ||
211 | int timeout, int *actual_length) | ||
212 | { | ||
213 | unsigned long expire; | ||
214 | int status; | ||
215 | |||
216 | expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; | ||
217 | if (!wait_for_completion_interruptible_timeout(done, expire)) { | ||
218 | usb_kill_urb(urb); | ||
219 | status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; | ||
220 | |||
221 | dev_dbg(&urb->dev->dev, | ||
222 | "%s timed out on ep%d%s len=%d/%d, urb status = %d\n", | ||
223 | current->comm, | ||
224 | usb_pipeendpoint(urb->pipe), | ||
225 | usb_pipein(urb->pipe) ? "in" : "out", | ||
226 | urb->actual_length, | ||
227 | urb->transfer_buffer_length, | ||
228 | urb->status); | ||
229 | |||
230 | } else { | ||
231 | if (signal_pending(current)) { | ||
232 | /* if really an error */ | ||
233 | if (urb->status && !((urb->status == -ENOENT) || | ||
234 | (urb->status == -ECONNRESET) || | ||
235 | (urb->status == -ESHUTDOWN))) { | ||
236 | status = -EINTR; | ||
237 | usb_kill_urb(urb); | ||
238 | } else { | ||
239 | status = 0; | ||
240 | } | ||
241 | |||
242 | dev_dbg(&urb->dev->dev, | ||
243 | "%s: signal pending on ep%d%s len=%d/%d," | ||
244 | "urb status = %d\n", | ||
245 | current->comm, | ||
246 | usb_pipeendpoint(urb->pipe), | ||
247 | usb_pipein(urb->pipe) ? "in" : "out", | ||
248 | urb->actual_length, | ||
249 | urb->transfer_buffer_length, | ||
250 | urb->status); | ||
251 | |||
252 | } else { | ||
253 | status = urb->status; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | if (actual_length) | ||
258 | *actual_length = urb->actual_length; | ||
259 | |||
260 | return status; | ||
261 | } | ||
262 | |||
263 | static ssize_t vstusb_read(struct file *file, char __user *buffer, | ||
264 | size_t count, loff_t *ppos) | ||
265 | { | ||
266 | struct vstusb_device *vstdev; | ||
267 | int cnt = -1; | ||
268 | void *buf; | ||
269 | int retval = 0; | ||
270 | |||
271 | struct urb *urb; | ||
272 | struct usb_device *dev; | ||
273 | unsigned int pipe; | ||
274 | int timeout; | ||
275 | |||
276 | DECLARE_COMPLETION_ONSTACK(done); | ||
277 | |||
278 | vstdev = file->private_data; | ||
279 | |||
280 | if (vstdev == NULL) | ||
281 | return -ENODEV; | ||
282 | |||
283 | /* verify that we actually want to read some data */ | ||
284 | if ((count == 0) || (count > VST_MAXBUFFER)) | ||
285 | return -EINVAL; | ||
286 | |||
287 | /* lock this object */ | ||
288 | if (mutex_lock_interruptible(&vstdev->lock)) | ||
289 | return -ERESTARTSYS; | ||
290 | |||
291 | /* anyone home */ | ||
292 | if (!vstdev->present) { | ||
293 | mutex_unlock(&vstdev->lock); | ||
294 | printk(KERN_ERR KBUILD_MODNAME | ||
295 | ": %s: device not present\n", __func__); | ||
296 | return -ENODEV; | ||
297 | } | ||
298 | |||
299 | /* pull out the necessary data */ | ||
300 | dev = vstdev->usb_dev; | ||
301 | pipe = usb_rcvbulkpipe(dev, vstdev->rd_pipe); | ||
302 | timeout = vstdev->rd_timeout_ms; | ||
303 | |||
304 | buf = kmalloc(count, GFP_KERNEL); | ||
305 | if (buf == NULL) { | ||
306 | mutex_unlock(&vstdev->lock); | ||
307 | return -ENOMEM; | ||
308 | } | ||
309 | |||
310 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
311 | if (!urb) { | ||
312 | kfree(buf); | ||
313 | mutex_unlock(&vstdev->lock); | ||
314 | return -ENOMEM; | ||
315 | } | ||
316 | |||
317 | usb_anchor_urb(urb, &vstdev->submitted); | ||
318 | retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done); | ||
319 | mutex_unlock(&vstdev->lock); | ||
320 | if (retval) { | ||
321 | usb_unanchor_urb(urb); | ||
322 | dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n", | ||
323 | __func__, retval, pipe); | ||
324 | goto exit; | ||
325 | } | ||
326 | |||
327 | retval = vstusb_complete_urb(urb, &done, timeout, &cnt); | ||
328 | if (retval) { | ||
329 | dev_err(&dev->dev, "%s: error %d completing urb %d\n", | ||
330 | __func__, retval, pipe); | ||
331 | goto exit; | ||
332 | } | ||
333 | |||
334 | if (copy_to_user(buffer, buf, cnt)) { | ||
335 | dev_err(&dev->dev, "%s: can't copy_to_user\n", __func__); | ||
336 | retval = -EFAULT; | ||
337 | } else { | ||
338 | retval = cnt; | ||
339 | dev_dbg(&dev->dev, "%s: read %d bytes from pipe %d\n", | ||
340 | __func__, cnt, pipe); | ||
341 | } | ||
342 | |||
343 | exit: | ||
344 | usb_free_urb(urb); | ||
345 | kfree(buf); | ||
346 | return retval; | ||
347 | } | ||
348 | |||
349 | static ssize_t vstusb_write(struct file *file, const char __user *buffer, | ||
350 | size_t count, loff_t *ppos) | ||
351 | { | ||
352 | struct vstusb_device *vstdev; | ||
353 | int cnt = -1; | ||
354 | void *buf; | ||
355 | int retval = 0; | ||
356 | |||
357 | struct urb *urb; | ||
358 | struct usb_device *dev; | ||
359 | unsigned int pipe; | ||
360 | int timeout; | ||
361 | |||
362 | DECLARE_COMPLETION_ONSTACK(done); | ||
363 | |||
364 | vstdev = file->private_data; | ||
365 | |||
366 | if (vstdev == NULL) | ||
367 | return -ENODEV; | ||
368 | |||
369 | /* verify that we actually have some data to write */ | ||
370 | if ((count == 0) || (count > VST_MAXBUFFER)) | ||
371 | return retval; | ||
372 | |||
373 | /* lock this object */ | ||
374 | if (mutex_lock_interruptible(&vstdev->lock)) | ||
375 | return -ERESTARTSYS; | ||
376 | |||
377 | /* anyone home */ | ||
378 | if (!vstdev->present) { | ||
379 | mutex_unlock(&vstdev->lock); | ||
380 | printk(KERN_ERR KBUILD_MODNAME | ||
381 | ": %s: device not present\n", __func__); | ||
382 | return -ENODEV; | ||
383 | } | ||
384 | |||
385 | /* pull out the necessary data */ | ||
386 | dev = vstdev->usb_dev; | ||
387 | pipe = usb_sndbulkpipe(dev, vstdev->wr_pipe); | ||
388 | timeout = vstdev->wr_timeout_ms; | ||
389 | |||
390 | buf = kmalloc(count, GFP_KERNEL); | ||
391 | if (buf == NULL) { | ||
392 | mutex_unlock(&vstdev->lock); | ||
393 | return -ENOMEM; | ||
394 | } | ||
395 | |||
396 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
397 | if (!urb) { | ||
398 | kfree(buf); | ||
399 | mutex_unlock(&vstdev->lock); | ||
400 | return -ENOMEM; | ||
401 | } | ||
402 | |||
403 | if (copy_from_user(buf, buffer, count)) { | ||
404 | mutex_unlock(&vstdev->lock); | ||
405 | dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__); | ||
406 | retval = -EFAULT; | ||
407 | goto exit; | ||
408 | } | ||
409 | |||
410 | usb_anchor_urb(urb, &vstdev->submitted); | ||
411 | retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done); | ||
412 | mutex_unlock(&vstdev->lock); | ||
413 | if (retval) { | ||
414 | usb_unanchor_urb(urb); | ||
415 | dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n", | ||
416 | __func__, retval, pipe); | ||
417 | goto exit; | ||
418 | } | ||
419 | |||
420 | retval = vstusb_complete_urb(urb, &done, timeout, &cnt); | ||
421 | if (retval) { | ||
422 | dev_err(&dev->dev, "%s: error %d completing urb %d\n", | ||
423 | __func__, retval, pipe); | ||
424 | goto exit; | ||
425 | } else { | ||
426 | retval = cnt; | ||
427 | dev_dbg(&dev->dev, "%s: sent %d bytes to pipe %d\n", | ||
428 | __func__, cnt, pipe); | ||
429 | } | ||
430 | |||
431 | exit: | ||
432 | usb_free_urb(urb); | ||
433 | kfree(buf); | ||
434 | return retval; | ||
435 | } | ||
436 | |||
437 | static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
438 | { | ||
439 | int retval = 0; | ||
440 | int cnt = -1; | ||
441 | void __user *data = (void __user *)arg; | ||
442 | struct vstusb_args usb_data; | ||
443 | |||
444 | struct vstusb_device *vstdev; | ||
445 | void *buffer = NULL; /* must be initialized. buffer is | ||
446 | * referenced on exit but not all | ||
447 | * ioctls allocate it */ | ||
448 | |||
449 | struct urb *urb = NULL; /* must be initialized. urb is | ||
450 | * referenced on exit but not all | ||
451 | * ioctls allocate it */ | ||
452 | struct usb_device *dev; | ||
453 | unsigned int pipe; | ||
454 | int timeout; | ||
455 | |||
456 | DECLARE_COMPLETION_ONSTACK(done); | ||
457 | |||
458 | vstdev = file->private_data; | ||
459 | |||
460 | if (_IOC_TYPE(cmd) != VST_IOC_MAGIC) { | ||
461 | dev_warn(&vstdev->usb_dev->dev, | ||
462 | "%s: ioctl command %x, bad ioctl magic %x, " | ||
463 | "expected %x\n", __func__, cmd, | ||
464 | _IOC_TYPE(cmd), VST_IOC_MAGIC); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | |||
468 | if (vstdev == NULL) | ||
469 | return -ENODEV; | ||
470 | |||
471 | if (copy_from_user(&usb_data, data, sizeof(struct vstusb_args))) { | ||
472 | dev_err(&vstdev->usb_dev->dev, "%s: can't copy_from_user\n", | ||
473 | __func__); | ||
474 | return -EFAULT; | ||
475 | } | ||
476 | |||
477 | /* lock this object */ | ||
478 | if (mutex_lock_interruptible(&vstdev->lock)) { | ||
479 | retval = -ERESTARTSYS; | ||
480 | goto exit; | ||
481 | } | ||
482 | |||
483 | /* anyone home */ | ||
484 | if (!vstdev->present) { | ||
485 | mutex_unlock(&vstdev->lock); | ||
486 | dev_err(&vstdev->usb_dev->dev, "%s: device not present\n", | ||
487 | __func__); | ||
488 | retval = -ENODEV; | ||
489 | goto exit; | ||
490 | } | ||
491 | |||
492 | /* pull out the necessary data */ | ||
493 | dev = vstdev->usb_dev; | ||
494 | |||
495 | switch (cmd) { | ||
496 | |||
497 | case IOCTL_VSTUSB_CONFIG_RW: | ||
498 | |||
499 | vstdev->rd_pipe = usb_data.rd_pipe; | ||
500 | vstdev->rd_timeout_ms = usb_data.rd_timeout_ms; | ||
501 | vstdev->wr_pipe = usb_data.wr_pipe; | ||
502 | vstdev->wr_timeout_ms = usb_data.wr_timeout_ms; | ||
503 | |||
504 | mutex_unlock(&vstdev->lock); | ||
505 | |||
506 | dev_dbg(&dev->dev, "%s: setting pipes/timeouts, " | ||
507 | "rdpipe = %d, rdtimeout = %d, " | ||
508 | "wrpipe = %d, wrtimeout = %d\n", __func__, | ||
509 | vstdev->rd_pipe, vstdev->rd_timeout_ms, | ||
510 | vstdev->wr_pipe, vstdev->wr_timeout_ms); | ||
511 | break; | ||
512 | |||
513 | case IOCTL_VSTUSB_SEND_PIPE: | ||
514 | |||
515 | if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) { | ||
516 | mutex_unlock(&vstdev->lock); | ||
517 | retval = -EINVAL; | ||
518 | goto exit; | ||
519 | } | ||
520 | |||
521 | buffer = kmalloc(usb_data.count, GFP_KERNEL); | ||
522 | if (buffer == NULL) { | ||
523 | mutex_unlock(&vstdev->lock); | ||
524 | retval = -ENOMEM; | ||
525 | goto exit; | ||
526 | } | ||
527 | |||
528 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
529 | if (!urb) { | ||
530 | mutex_unlock(&vstdev->lock); | ||
531 | retval = -ENOMEM; | ||
532 | goto exit; | ||
533 | } | ||
534 | |||
535 | timeout = usb_data.timeout_ms; | ||
536 | |||
537 | pipe = usb_sndbulkpipe(dev, usb_data.pipe); | ||
538 | |||
539 | if (copy_from_user(buffer, usb_data.buffer, usb_data.count)) { | ||
540 | dev_err(&dev->dev, "%s: can't copy_from_user\n", | ||
541 | __func__); | ||
542 | mutex_unlock(&vstdev->lock); | ||
543 | retval = -EFAULT; | ||
544 | goto exit; | ||
545 | } | ||
546 | |||
547 | usb_anchor_urb(urb, &vstdev->submitted); | ||
548 | retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer, | ||
549 | usb_data.count, &done); | ||
550 | mutex_unlock(&vstdev->lock); | ||
551 | if (retval) { | ||
552 | usb_unanchor_urb(urb); | ||
553 | dev_err(&dev->dev, | ||
554 | "%s: error %d filling and sending urb %d\n", | ||
555 | __func__, retval, pipe); | ||
556 | goto exit; | ||
557 | } | ||
558 | |||
559 | retval = vstusb_complete_urb(urb, &done, timeout, &cnt); | ||
560 | if (retval) { | ||
561 | dev_err(&dev->dev, "%s: error %d completing urb %d\n", | ||
562 | __func__, retval, pipe); | ||
563 | } | ||
564 | |||
565 | break; | ||
566 | case IOCTL_VSTUSB_RECV_PIPE: | ||
567 | |||
568 | if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) { | ||
569 | mutex_unlock(&vstdev->lock); | ||
570 | retval = -EINVAL; | ||
571 | goto exit; | ||
572 | } | ||
573 | |||
574 | buffer = kmalloc(usb_data.count, GFP_KERNEL); | ||
575 | if (buffer == NULL) { | ||
576 | mutex_unlock(&vstdev->lock); | ||
577 | retval = -ENOMEM; | ||
578 | goto exit; | ||
579 | } | ||
580 | |||
581 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
582 | if (!urb) { | ||
583 | mutex_unlock(&vstdev->lock); | ||
584 | retval = -ENOMEM; | ||
585 | goto exit; | ||
586 | } | ||
587 | |||
588 | timeout = usb_data.timeout_ms; | ||
589 | |||
590 | pipe = usb_rcvbulkpipe(dev, usb_data.pipe); | ||
591 | |||
592 | usb_anchor_urb(urb, &vstdev->submitted); | ||
593 | retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer, | ||
594 | usb_data.count, &done); | ||
595 | mutex_unlock(&vstdev->lock); | ||
596 | if (retval) { | ||
597 | usb_unanchor_urb(urb); | ||
598 | dev_err(&dev->dev, | ||
599 | "%s: error %d filling and sending urb %d\n", | ||
600 | __func__, retval, pipe); | ||
601 | goto exit; | ||
602 | } | ||
603 | |||
604 | retval = vstusb_complete_urb(urb, &done, timeout, &cnt); | ||
605 | if (retval) { | ||
606 | dev_err(&dev->dev, "%s: error %d completing urb %d\n", | ||
607 | __func__, retval, pipe); | ||
608 | goto exit; | ||
609 | } | ||
610 | |||
611 | if (copy_to_user(usb_data.buffer, buffer, cnt)) { | ||
612 | dev_err(&dev->dev, "%s: can't copy_to_user\n", | ||
613 | __func__); | ||
614 | retval = -EFAULT; | ||
615 | goto exit; | ||
616 | } | ||
617 | |||
618 | usb_data.count = cnt; | ||
619 | if (copy_to_user(data, &usb_data, sizeof(struct vstusb_args))) { | ||
620 | dev_err(&dev->dev, "%s: can't copy_to_user\n", | ||
621 | __func__); | ||
622 | retval = -EFAULT; | ||
623 | } else { | ||
624 | dev_dbg(&dev->dev, "%s: recv %zd bytes from pipe %d\n", | ||
625 | __func__, usb_data.count, usb_data.pipe); | ||
626 | } | ||
627 | |||
628 | break; | ||
629 | |||
630 | default: | ||
631 | mutex_unlock(&vstdev->lock); | ||
632 | dev_warn(&dev->dev, "ioctl_vstusb: invalid ioctl cmd %x\n", | ||
633 | cmd); | ||
634 | return -EINVAL; | ||
635 | break; | ||
636 | } | ||
637 | exit: | ||
638 | usb_free_urb(urb); | ||
639 | kfree(buffer); | ||
640 | return retval; | ||
641 | } | ||
642 | |||
643 | static const struct file_operations vstusb_fops = { | ||
644 | .owner = THIS_MODULE, | ||
645 | .read = vstusb_read, | ||
646 | .write = vstusb_write, | ||
647 | .unlocked_ioctl = vstusb_ioctl, | ||
648 | .compat_ioctl = vstusb_ioctl, | ||
649 | .open = vstusb_open, | ||
650 | .release = vstusb_release, | ||
651 | }; | ||
652 | |||
653 | static struct usb_class_driver usb_vstusb_class = { | ||
654 | .name = "usb/vstusb%d", | ||
655 | .fops = &vstusb_fops, | ||
656 | .minor_base = VSTUSB_MINOR_BASE, | ||
657 | }; | ||
658 | |||
659 | static int vstusb_probe(struct usb_interface *intf, | ||
660 | const struct usb_device_id *id) | ||
661 | { | ||
662 | struct usb_device *dev = interface_to_usbdev(intf); | ||
663 | struct vstusb_device *vstdev; | ||
664 | int i; | ||
665 | int retval = 0; | ||
666 | |||
667 | /* allocate memory for our device state and intialize it */ | ||
668 | |||
669 | vstdev = kzalloc(sizeof(*vstdev), GFP_KERNEL); | ||
670 | if (vstdev == NULL) | ||
671 | return -ENOMEM; | ||
672 | |||
673 | /* must do usb_get_dev() prior to kref_init() since the kref_put() | ||
674 | * release function will do a usb_put_dev() */ | ||
675 | usb_get_dev(dev); | ||
676 | kref_init(&vstdev->kref); | ||
677 | mutex_init(&vstdev->lock); | ||
678 | |||
679 | i = dev->descriptor.bcdDevice; | ||
680 | |||
681 | dev_dbg(&intf->dev, "Version %1d%1d.%1d%1d found at address %d\n", | ||
682 | (i & 0xF000) >> 12, (i & 0xF00) >> 8, | ||
683 | (i & 0xF0) >> 4, (i & 0xF), dev->devnum); | ||
684 | |||
685 | vstdev->present = 1; | ||
686 | vstdev->isopen = 0; | ||
687 | vstdev->usb_dev = dev; | ||
688 | init_usb_anchor(&vstdev->submitted); | ||
689 | |||
690 | usb_set_intfdata(intf, vstdev); | ||
691 | retval = usb_register_dev(intf, &usb_vstusb_class); | ||
692 | if (retval) { | ||
693 | dev_err(&intf->dev, | ||
694 | "%s: Not able to get a minor for this device.\n", | ||
695 | __func__); | ||
696 | usb_set_intfdata(intf, NULL); | ||
697 | kref_put(&vstdev->kref, vstusb_delete); | ||
698 | return retval; | ||
699 | } | ||
700 | |||
701 | /* let the user know what node this device is now attached to */ | ||
702 | dev_info(&intf->dev, | ||
703 | "VST USB Device #%d now attached to major %d minor %d\n", | ||
704 | (intf->minor - VSTUSB_MINOR_BASE), USB_MAJOR, intf->minor); | ||
705 | |||
706 | dev_info(&intf->dev, "%s, %s\n", DRIVER_DESC, DRIVER_VERSION); | ||
707 | |||
708 | return retval; | ||
709 | } | ||
710 | |||
711 | static void vstusb_disconnect(struct usb_interface *intf) | ||
712 | { | ||
713 | struct vstusb_device *vstdev = usb_get_intfdata(intf); | ||
714 | |||
715 | usb_deregister_dev(intf, &usb_vstusb_class); | ||
716 | usb_set_intfdata(intf, NULL); | ||
717 | |||
718 | if (vstdev) { | ||
719 | |||
720 | mutex_lock(&vstdev->lock); | ||
721 | vstdev->present = 0; | ||
722 | |||
723 | usb_kill_anchored_urbs(&vstdev->submitted); | ||
724 | |||
725 | mutex_unlock(&vstdev->lock); | ||
726 | |||
727 | kref_put(&vstdev->kref, vstusb_delete); | ||
728 | } | ||
729 | |||
730 | } | ||
731 | |||
732 | static int vstusb_suspend(struct usb_interface *intf, pm_message_t message) | ||
733 | { | ||
734 | struct vstusb_device *vstdev = usb_get_intfdata(intf); | ||
735 | int time; | ||
736 | if (!vstdev) | ||
737 | return 0; | ||
738 | |||
739 | mutex_lock(&vstdev->lock); | ||
740 | time = usb_wait_anchor_empty_timeout(&vstdev->submitted, 1000); | ||
741 | if (!time) | ||
742 | usb_kill_anchored_urbs(&vstdev->submitted); | ||
743 | mutex_unlock(&vstdev->lock); | ||
744 | |||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | static int vstusb_resume(struct usb_interface *intf) | ||
749 | { | ||
750 | return 0; | ||
751 | } | ||
752 | |||
753 | static struct usb_driver vstusb_driver = { | ||
754 | .name = "vstusb", | ||
755 | .probe = vstusb_probe, | ||
756 | .disconnect = vstusb_disconnect, | ||
757 | .suspend = vstusb_suspend, | ||
758 | .resume = vstusb_resume, | ||
759 | .id_table = id_table, | ||
760 | }; | ||
761 | |||
762 | static int __init vstusb_init(void) | ||
763 | { | ||
764 | int rc; | ||
765 | |||
766 | rc = usb_register(&vstusb_driver); | ||
767 | if (rc) | ||
768 | printk(KERN_ERR "%s: failed to register (%d)", __func__, rc); | ||
769 | |||
770 | return rc; | ||
771 | } | ||
772 | |||
773 | static void __exit vstusb_exit(void) | ||
774 | { | ||
775 | usb_deregister(&vstusb_driver); | ||
776 | } | ||
777 | |||
778 | module_init(vstusb_init); | ||
779 | module_exit(vstusb_exit); | ||
780 | |||
781 | MODULE_AUTHOR("Dennis O'Brien/Stephen Ware"); | ||
782 | MODULE_DESCRIPTION(DRIVER_VERSION); | ||
783 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 385ec0520167..6dd44bc1f5ff 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -460,8 +460,8 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
460 | char ev_type, int status) | 460 | char ev_type, int status) |
461 | { | 461 | { |
462 | const struct usb_endpoint_descriptor *epd = &urb->ep->desc; | 462 | const struct usb_endpoint_descriptor *epd = &urb->ep->desc; |
463 | unsigned long flags; | ||
464 | struct timeval ts; | 463 | struct timeval ts; |
464 | unsigned long flags; | ||
465 | unsigned int urb_length; | 465 | unsigned int urb_length; |
466 | unsigned int offset; | 466 | unsigned int offset; |
467 | unsigned int length; | 467 | unsigned int length; |
@@ -600,10 +600,13 @@ static void mon_bin_complete(void *data, struct urb *urb, int status) | |||
600 | static void mon_bin_error(void *data, struct urb *urb, int error) | 600 | static void mon_bin_error(void *data, struct urb *urb, int error) |
601 | { | 601 | { |
602 | struct mon_reader_bin *rp = data; | 602 | struct mon_reader_bin *rp = data; |
603 | struct timeval ts; | ||
603 | unsigned long flags; | 604 | unsigned long flags; |
604 | unsigned int offset; | 605 | unsigned int offset; |
605 | struct mon_bin_hdr *ep; | 606 | struct mon_bin_hdr *ep; |
606 | 607 | ||
608 | do_gettimeofday(&ts); | ||
609 | |||
607 | spin_lock_irqsave(&rp->b_lock, flags); | 610 | spin_lock_irqsave(&rp->b_lock, flags); |
608 | 611 | ||
609 | offset = mon_buff_area_alloc(rp, PKT_SIZE); | 612 | offset = mon_buff_area_alloc(rp, PKT_SIZE); |
@@ -623,6 +626,8 @@ static void mon_bin_error(void *data, struct urb *urb, int error) | |||
623 | ep->devnum = urb->dev->devnum; | 626 | ep->devnum = urb->dev->devnum; |
624 | ep->busnum = urb->dev->bus->busnum; | 627 | ep->busnum = urb->dev->bus->busnum; |
625 | ep->id = (unsigned long) urb; | 628 | ep->id = (unsigned long) urb; |
629 | ep->ts_sec = ts.tv_sec; | ||
630 | ep->ts_usec = ts.tv_usec; | ||
626 | ep->status = error; | 631 | ep->status = error; |
627 | 632 | ||
628 | ep->flag_setup = '-'; | 633 | ep->flag_setup = '-'; |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 047568ff223d..31c11888ec6a 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -180,7 +180,7 @@ static inline unsigned int mon_get_timestamp(void) | |||
180 | unsigned int stamp; | 180 | unsigned int stamp; |
181 | 181 | ||
182 | do_gettimeofday(&tval); | 182 | do_gettimeofday(&tval); |
183 | stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s. */ | 183 | stamp = tval.tv_sec & 0xFFF; /* 2^32 = 4294967296. Limit to 4096s. */ |
184 | stamp = stamp * 1000000 + tval.tv_usec; | 184 | stamp = stamp * 1000000 + tval.tv_usec; |
185 | return stamp; | 185 | return stamp; |
186 | } | 186 | } |
@@ -273,12 +273,12 @@ static void mon_text_error(void *data, struct urb *urb, int error) | |||
273 | 273 | ||
274 | ep->type = 'E'; | 274 | ep->type = 'E'; |
275 | ep->id = (unsigned long) urb; | 275 | ep->id = (unsigned long) urb; |
276 | ep->busnum = 0; | 276 | ep->busnum = urb->dev->bus->busnum; |
277 | ep->devnum = urb->dev->devnum; | 277 | ep->devnum = urb->dev->devnum; |
278 | ep->epnum = usb_endpoint_num(&urb->ep->desc); | 278 | ep->epnum = usb_endpoint_num(&urb->ep->desc); |
279 | ep->xfertype = usb_endpoint_type(&urb->ep->desc); | 279 | ep->xfertype = usb_endpoint_type(&urb->ep->desc); |
280 | ep->is_in = usb_urb_dir_in(urb); | 280 | ep->is_in = usb_urb_dir_in(urb); |
281 | ep->tstamp = 0; | 281 | ep->tstamp = mon_get_timestamp(); |
282 | ep->length = 0; | 282 | ep->length = 0; |
283 | ep->status = error; | 283 | ep->status = error; |
284 | 284 | ||
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index ad26e6569665..bcee1339d4fd 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -30,7 +30,6 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
30 | void __iomem *fifo = hw_ep->fifo; | 30 | void __iomem *fifo = hw_ep->fifo; |
31 | void __iomem *epio = hw_ep->regs; | 31 | void __iomem *epio = hw_ep->regs; |
32 | u8 epnum = hw_ep->epnum; | 32 | u8 epnum = hw_ep->epnum; |
33 | u16 dma_reg = 0; | ||
34 | 33 | ||
35 | prefetch((u8 *)src); | 34 | prefetch((u8 *)src); |
36 | 35 | ||
@@ -42,15 +41,17 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
42 | dump_fifo_data(src, len); | 41 | dump_fifo_data(src, len); |
43 | 42 | ||
44 | if (!ANOMALY_05000380 && epnum != 0) { | 43 | if (!ANOMALY_05000380 && epnum != 0) { |
45 | flush_dcache_range((unsigned int)src, | 44 | u16 dma_reg; |
46 | (unsigned int)(src + len)); | 45 | |
46 | flush_dcache_range((unsigned long)src, | ||
47 | (unsigned long)(src + len)); | ||
47 | 48 | ||
48 | /* Setup DMA address register */ | 49 | /* Setup DMA address register */ |
49 | dma_reg = (u16) ((u32) src & 0xFFFF); | 50 | dma_reg = (u32)src; |
50 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); | 51 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); |
51 | SSYNC(); | 52 | SSYNC(); |
52 | 53 | ||
53 | dma_reg = (u16) (((u32) src >> 16) & 0xFFFF); | 54 | dma_reg = (u32)src >> 16; |
54 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | 55 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); |
55 | SSYNC(); | 56 | SSYNC(); |
56 | 57 | ||
@@ -79,12 +80,9 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
79 | SSYNC(); | 80 | SSYNC(); |
80 | 81 | ||
81 | if (unlikely((unsigned long)src & 0x01)) | 82 | if (unlikely((unsigned long)src & 0x01)) |
82 | outsw_8((unsigned long)fifo, src, | 83 | outsw_8((unsigned long)fifo, src, (len + 1) >> 1); |
83 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
84 | else | 84 | else |
85 | outsw((unsigned long)fifo, src, | 85 | outsw((unsigned long)fifo, src, (len + 1) >> 1); |
86 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
87 | |||
88 | } | 86 | } |
89 | } | 87 | } |
90 | /* | 88 | /* |
@@ -94,19 +92,19 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
94 | { | 92 | { |
95 | void __iomem *fifo = hw_ep->fifo; | 93 | void __iomem *fifo = hw_ep->fifo; |
96 | u8 epnum = hw_ep->epnum; | 94 | u8 epnum = hw_ep->epnum; |
97 | u16 dma_reg = 0; | ||
98 | 95 | ||
99 | if (ANOMALY_05000467 && epnum != 0) { | 96 | if (ANOMALY_05000467 && epnum != 0) { |
97 | u16 dma_reg; | ||
100 | 98 | ||
101 | invalidate_dcache_range((unsigned int)dst, | 99 | invalidate_dcache_range((unsigned long)dst, |
102 | (unsigned int)(dst + len)); | 100 | (unsigned long)(dst + len)); |
103 | 101 | ||
104 | /* Setup DMA address register */ | 102 | /* Setup DMA address register */ |
105 | dma_reg = (u16) ((u32) dst & 0xFFFF); | 103 | dma_reg = (u32)dst; |
106 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); | 104 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); |
107 | SSYNC(); | 105 | SSYNC(); |
108 | 106 | ||
109 | dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); | 107 | dma_reg = (u32)dst >> 16; |
110 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | 108 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); |
111 | SSYNC(); | 109 | SSYNC(); |
112 | 110 | ||
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index a44a450c860d..3c69a76ec392 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -1191,8 +1191,13 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1191 | 1191 | ||
1192 | bd = tx_ch->head; | 1192 | bd = tx_ch->head; |
1193 | 1193 | ||
1194 | /* | ||
1195 | * If Head is null then this could mean that a abort interrupt | ||
1196 | * that needs to be acknowledged. | ||
1197 | */ | ||
1194 | if (NULL == bd) { | 1198 | if (NULL == bd) { |
1195 | DBG(1, "null BD\n"); | 1199 | DBG(1, "null BD\n"); |
1200 | tx_ram->tx_complete = 0; | ||
1196 | continue; | 1201 | continue; |
1197 | } | 1202 | } |
1198 | 1203 | ||
@@ -1412,15 +1417,6 @@ static int cppi_channel_abort(struct dma_channel *channel) | |||
1412 | 1417 | ||
1413 | if (cppi_ch->transmit) { | 1418 | if (cppi_ch->transmit) { |
1414 | struct cppi_tx_stateram __iomem *tx_ram; | 1419 | struct cppi_tx_stateram __iomem *tx_ram; |
1415 | int enabled; | ||
1416 | |||
1417 | /* mask interrupts raised to signal teardown complete. */ | ||
1418 | enabled = musb_readl(tibase, DAVINCI_TXCPPI_INTENAB_REG) | ||
1419 | & (1 << cppi_ch->index); | ||
1420 | if (enabled) | ||
1421 | musb_writel(tibase, DAVINCI_TXCPPI_INTCLR_REG, | ||
1422 | (1 << cppi_ch->index)); | ||
1423 | |||
1424 | /* REVISIT put timeouts on these controller handshakes */ | 1420 | /* REVISIT put timeouts on these controller handshakes */ |
1425 | 1421 | ||
1426 | cppi_dump_tx(6, cppi_ch, " (teardown)"); | 1422 | cppi_dump_tx(6, cppi_ch, " (teardown)"); |
@@ -1435,7 +1431,6 @@ static int cppi_channel_abort(struct dma_channel *channel) | |||
1435 | do { | 1431 | do { |
1436 | value = musb_readl(&tx_ram->tx_complete, 0); | 1432 | value = musb_readl(&tx_ram->tx_complete, 0); |
1437 | } while (0xFFFFFFFC != value); | 1433 | } while (0xFFFFFFFC != value); |
1438 | musb_writel(&tx_ram->tx_complete, 0, 0xFFFFFFFC); | ||
1439 | 1434 | ||
1440 | /* FIXME clean up the transfer state ... here? | 1435 | /* FIXME clean up the transfer state ... here? |
1441 | * the completion routine should get called with | 1436 | * the completion routine should get called with |
@@ -1448,23 +1443,15 @@ static int cppi_channel_abort(struct dma_channel *channel) | |||
1448 | musb_writew(regs, MUSB_TXCSR, value); | 1443 | musb_writew(regs, MUSB_TXCSR, value); |
1449 | musb_writew(regs, MUSB_TXCSR, value); | 1444 | musb_writew(regs, MUSB_TXCSR, value); |
1450 | 1445 | ||
1451 | /* While we scrub the TX state RAM, ensure that we clean | 1446 | /* |
1452 | * up any interrupt that's currently asserted: | ||
1453 | * 1. Write to completion Ptr value 0x1(bit 0 set) | 1447 | * 1. Write to completion Ptr value 0x1(bit 0 set) |
1454 | * (write back mode) | 1448 | * (write back mode) |
1455 | * 2. Write to completion Ptr value 0x0(bit 0 cleared) | 1449 | * 2. Wait for abort interrupt and then put the channel in |
1456 | * (compare mode) | 1450 | * compare mode by writing 1 to the tx_complete register. |
1457 | * Value written is compared(for bits 31:2) and when | ||
1458 | * equal, interrupt is deasserted. | ||
1459 | */ | 1451 | */ |
1460 | cppi_reset_tx(tx_ram, 1); | 1452 | cppi_reset_tx(tx_ram, 1); |
1461 | musb_writel(&tx_ram->tx_complete, 0, 0); | 1453 | cppi_ch->head = 0; |
1462 | 1454 | musb_writel(&tx_ram->tx_complete, 0, 1); | |
1463 | /* re-enable interrupt */ | ||
1464 | if (enabled) | ||
1465 | musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG, | ||
1466 | (1 << cppi_ch->index)); | ||
1467 | |||
1468 | cppi_dump_tx(5, cppi_ch, " (done teardown)"); | 1455 | cppi_dump_tx(5, cppi_ch, " (done teardown)"); |
1469 | 1456 | ||
1470 | /* REVISIT tx side _should_ clean up the same way | 1457 | /* REVISIT tx side _should_ clean up the same way |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 738efd8063b5..b4bbf8f2c238 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -557,6 +557,69 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
557 | handled = IRQ_HANDLED; | 557 | handled = IRQ_HANDLED; |
558 | } | 558 | } |
559 | 559 | ||
560 | |||
561 | if (int_usb & MUSB_INTR_SUSPEND) { | ||
562 | DBG(1, "SUSPEND (%s) devctl %02x power %02x\n", | ||
563 | otg_state_string(musb), devctl, power); | ||
564 | handled = IRQ_HANDLED; | ||
565 | |||
566 | switch (musb->xceiv->state) { | ||
567 | #ifdef CONFIG_USB_MUSB_OTG | ||
568 | case OTG_STATE_A_PERIPHERAL: | ||
569 | /* We also come here if the cable is removed, since | ||
570 | * this silicon doesn't report ID-no-longer-grounded. | ||
571 | * | ||
572 | * We depend on T(a_wait_bcon) to shut us down, and | ||
573 | * hope users don't do anything dicey during this | ||
574 | * undesired detour through A_WAIT_BCON. | ||
575 | */ | ||
576 | musb_hnp_stop(musb); | ||
577 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
578 | musb_root_disconnect(musb); | ||
579 | musb_platform_try_idle(musb, jiffies | ||
580 | + msecs_to_jiffies(musb->a_wait_bcon | ||
581 | ? : OTG_TIME_A_WAIT_BCON)); | ||
582 | |||
583 | break; | ||
584 | #endif | ||
585 | case OTG_STATE_B_IDLE: | ||
586 | if (!musb->is_active) | ||
587 | break; | ||
588 | case OTG_STATE_B_PERIPHERAL: | ||
589 | musb_g_suspend(musb); | ||
590 | musb->is_active = is_otg_enabled(musb) | ||
591 | && musb->xceiv->gadget->b_hnp_enable; | ||
592 | if (musb->is_active) { | ||
593 | #ifdef CONFIG_USB_MUSB_OTG | ||
594 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; | ||
595 | DBG(1, "HNP: Setting timer for b_ase0_brst\n"); | ||
596 | mod_timer(&musb->otg_timer, jiffies | ||
597 | + msecs_to_jiffies( | ||
598 | OTG_TIME_B_ASE0_BRST)); | ||
599 | #endif | ||
600 | } | ||
601 | break; | ||
602 | case OTG_STATE_A_WAIT_BCON: | ||
603 | if (musb->a_wait_bcon != 0) | ||
604 | musb_platform_try_idle(musb, jiffies | ||
605 | + msecs_to_jiffies(musb->a_wait_bcon)); | ||
606 | break; | ||
607 | case OTG_STATE_A_HOST: | ||
608 | musb->xceiv->state = OTG_STATE_A_SUSPEND; | ||
609 | musb->is_active = is_otg_enabled(musb) | ||
610 | && musb->xceiv->host->b_hnp_enable; | ||
611 | break; | ||
612 | case OTG_STATE_B_HOST: | ||
613 | /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ | ||
614 | DBG(1, "REVISIT: SUSPEND as B_HOST\n"); | ||
615 | break; | ||
616 | default: | ||
617 | /* "should not happen" */ | ||
618 | musb->is_active = 0; | ||
619 | break; | ||
620 | } | ||
621 | } | ||
622 | |||
560 | if (int_usb & MUSB_INTR_CONNECT) { | 623 | if (int_usb & MUSB_INTR_CONNECT) { |
561 | struct usb_hcd *hcd = musb_to_hcd(musb); | 624 | struct usb_hcd *hcd = musb_to_hcd(musb); |
562 | 625 | ||
@@ -625,10 +688,61 @@ b_host: | |||
625 | } | 688 | } |
626 | #endif /* CONFIG_USB_MUSB_HDRC_HCD */ | 689 | #endif /* CONFIG_USB_MUSB_HDRC_HCD */ |
627 | 690 | ||
691 | if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) { | ||
692 | DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n", | ||
693 | otg_state_string(musb), | ||
694 | MUSB_MODE(musb), devctl); | ||
695 | handled = IRQ_HANDLED; | ||
696 | |||
697 | switch (musb->xceiv->state) { | ||
698 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
699 | case OTG_STATE_A_HOST: | ||
700 | case OTG_STATE_A_SUSPEND: | ||
701 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
702 | musb_root_disconnect(musb); | ||
703 | if (musb->a_wait_bcon != 0 && is_otg_enabled(musb)) | ||
704 | musb_platform_try_idle(musb, jiffies | ||
705 | + msecs_to_jiffies(musb->a_wait_bcon)); | ||
706 | break; | ||
707 | #endif /* HOST */ | ||
708 | #ifdef CONFIG_USB_MUSB_OTG | ||
709 | case OTG_STATE_B_HOST: | ||
710 | /* REVISIT this behaves for "real disconnect" | ||
711 | * cases; make sure the other transitions from | ||
712 | * from B_HOST act right too. The B_HOST code | ||
713 | * in hnp_stop() is currently not used... | ||
714 | */ | ||
715 | musb_root_disconnect(musb); | ||
716 | musb_to_hcd(musb)->self.is_b_host = 0; | ||
717 | musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
718 | MUSB_DEV_MODE(musb); | ||
719 | musb_g_disconnect(musb); | ||
720 | break; | ||
721 | case OTG_STATE_A_PERIPHERAL: | ||
722 | musb_hnp_stop(musb); | ||
723 | musb_root_disconnect(musb); | ||
724 | /* FALLTHROUGH */ | ||
725 | case OTG_STATE_B_WAIT_ACON: | ||
726 | /* FALLTHROUGH */ | ||
727 | #endif /* OTG */ | ||
728 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
729 | case OTG_STATE_B_PERIPHERAL: | ||
730 | case OTG_STATE_B_IDLE: | ||
731 | musb_g_disconnect(musb); | ||
732 | break; | ||
733 | #endif /* GADGET */ | ||
734 | default: | ||
735 | WARNING("unhandled DISCONNECT transition (%s)\n", | ||
736 | otg_state_string(musb)); | ||
737 | break; | ||
738 | } | ||
739 | } | ||
740 | |||
628 | /* mentor saves a bit: bus reset and babble share the same irq. | 741 | /* mentor saves a bit: bus reset and babble share the same irq. |
629 | * only host sees babble; only peripheral sees bus reset. | 742 | * only host sees babble; only peripheral sees bus reset. |
630 | */ | 743 | */ |
631 | if (int_usb & MUSB_INTR_RESET) { | 744 | if (int_usb & MUSB_INTR_RESET) { |
745 | handled = IRQ_HANDLED; | ||
632 | if (is_host_capable() && (devctl & MUSB_DEVCTL_HM) != 0) { | 746 | if (is_host_capable() && (devctl & MUSB_DEVCTL_HM) != 0) { |
633 | /* | 747 | /* |
634 | * Looks like non-HS BABBLE can be ignored, but | 748 | * Looks like non-HS BABBLE can be ignored, but |
@@ -641,7 +755,7 @@ b_host: | |||
641 | DBG(1, "BABBLE devctl: %02x\n", devctl); | 755 | DBG(1, "BABBLE devctl: %02x\n", devctl); |
642 | else { | 756 | else { |
643 | ERR("Stopping host session -- babble\n"); | 757 | ERR("Stopping host session -- babble\n"); |
644 | musb_writeb(mbase, MUSB_DEVCTL, 0); | 758 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); |
645 | } | 759 | } |
646 | } else if (is_peripheral_capable()) { | 760 | } else if (is_peripheral_capable()) { |
647 | DBG(1, "BUS RESET as %s\n", otg_state_string(musb)); | 761 | DBG(1, "BUS RESET as %s\n", otg_state_string(musb)); |
@@ -686,29 +800,7 @@ b_host: | |||
686 | otg_state_string(musb)); | 800 | otg_state_string(musb)); |
687 | } | 801 | } |
688 | } | 802 | } |
689 | |||
690 | handled = IRQ_HANDLED; | ||
691 | } | 803 | } |
692 | schedule_work(&musb->irq_work); | ||
693 | |||
694 | return handled; | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * Interrupt Service Routine to record USB "global" interrupts. | ||
699 | * Since these do not happen often and signify things of | ||
700 | * paramount importance, it seems OK to check them individually; | ||
701 | * the order of the tests is specified in the manual | ||
702 | * | ||
703 | * @param musb instance pointer | ||
704 | * @param int_usb register contents | ||
705 | * @param devctl | ||
706 | * @param power | ||
707 | */ | ||
708 | static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | ||
709 | u8 devctl, u8 power) | ||
710 | { | ||
711 | irqreturn_t handled = IRQ_NONE; | ||
712 | 804 | ||
713 | #if 0 | 805 | #if 0 |
714 | /* REVISIT ... this would be for multiplexing periodic endpoints, or | 806 | /* REVISIT ... this would be for multiplexing periodic endpoints, or |
@@ -755,117 +847,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | |||
755 | } | 847 | } |
756 | #endif | 848 | #endif |
757 | 849 | ||
758 | if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) { | 850 | schedule_work(&musb->irq_work); |
759 | DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n", | ||
760 | otg_state_string(musb), | ||
761 | MUSB_MODE(musb), devctl); | ||
762 | handled = IRQ_HANDLED; | ||
763 | |||
764 | switch (musb->xceiv->state) { | ||
765 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
766 | case OTG_STATE_A_HOST: | ||
767 | case OTG_STATE_A_SUSPEND: | ||
768 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
769 | musb_root_disconnect(musb); | ||
770 | if (musb->a_wait_bcon != 0 && is_otg_enabled(musb)) | ||
771 | musb_platform_try_idle(musb, jiffies | ||
772 | + msecs_to_jiffies(musb->a_wait_bcon)); | ||
773 | break; | ||
774 | #endif /* HOST */ | ||
775 | #ifdef CONFIG_USB_MUSB_OTG | ||
776 | case OTG_STATE_B_HOST: | ||
777 | /* REVISIT this behaves for "real disconnect" | ||
778 | * cases; make sure the other transitions from | ||
779 | * from B_HOST act right too. The B_HOST code | ||
780 | * in hnp_stop() is currently not used... | ||
781 | */ | ||
782 | musb_root_disconnect(musb); | ||
783 | musb_to_hcd(musb)->self.is_b_host = 0; | ||
784 | musb->xceiv->state = OTG_STATE_B_PERIPHERAL; | ||
785 | MUSB_DEV_MODE(musb); | ||
786 | musb_g_disconnect(musb); | ||
787 | break; | ||
788 | case OTG_STATE_A_PERIPHERAL: | ||
789 | musb_hnp_stop(musb); | ||
790 | musb_root_disconnect(musb); | ||
791 | /* FALLTHROUGH */ | ||
792 | case OTG_STATE_B_WAIT_ACON: | ||
793 | /* FALLTHROUGH */ | ||
794 | #endif /* OTG */ | ||
795 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
796 | case OTG_STATE_B_PERIPHERAL: | ||
797 | case OTG_STATE_B_IDLE: | ||
798 | musb_g_disconnect(musb); | ||
799 | break; | ||
800 | #endif /* GADGET */ | ||
801 | default: | ||
802 | WARNING("unhandled DISCONNECT transition (%s)\n", | ||
803 | otg_state_string(musb)); | ||
804 | break; | ||
805 | } | ||
806 | |||
807 | schedule_work(&musb->irq_work); | ||
808 | } | ||
809 | |||
810 | if (int_usb & MUSB_INTR_SUSPEND) { | ||
811 | DBG(1, "SUSPEND (%s) devctl %02x power %02x\n", | ||
812 | otg_state_string(musb), devctl, power); | ||
813 | handled = IRQ_HANDLED; | ||
814 | |||
815 | switch (musb->xceiv->state) { | ||
816 | #ifdef CONFIG_USB_MUSB_OTG | ||
817 | case OTG_STATE_A_PERIPHERAL: | ||
818 | /* We also come here if the cable is removed, since | ||
819 | * this silicon doesn't report ID-no-longer-grounded. | ||
820 | * | ||
821 | * We depend on T(a_wait_bcon) to shut us down, and | ||
822 | * hope users don't do anything dicey during this | ||
823 | * undesired detour through A_WAIT_BCON. | ||
824 | */ | ||
825 | musb_hnp_stop(musb); | ||
826 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
827 | musb_root_disconnect(musb); | ||
828 | musb_platform_try_idle(musb, jiffies | ||
829 | + msecs_to_jiffies(musb->a_wait_bcon | ||
830 | ? : OTG_TIME_A_WAIT_BCON)); | ||
831 | break; | ||
832 | #endif | ||
833 | case OTG_STATE_B_PERIPHERAL: | ||
834 | musb_g_suspend(musb); | ||
835 | musb->is_active = is_otg_enabled(musb) | ||
836 | && musb->xceiv->gadget->b_hnp_enable; | ||
837 | if (musb->is_active) { | ||
838 | #ifdef CONFIG_USB_MUSB_OTG | ||
839 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; | ||
840 | DBG(1, "HNP: Setting timer for b_ase0_brst\n"); | ||
841 | mod_timer(&musb->otg_timer, jiffies | ||
842 | + msecs_to_jiffies( | ||
843 | OTG_TIME_B_ASE0_BRST)); | ||
844 | #endif | ||
845 | } | ||
846 | break; | ||
847 | case OTG_STATE_A_WAIT_BCON: | ||
848 | if (musb->a_wait_bcon != 0) | ||
849 | musb_platform_try_idle(musb, jiffies | ||
850 | + msecs_to_jiffies(musb->a_wait_bcon)); | ||
851 | break; | ||
852 | case OTG_STATE_A_HOST: | ||
853 | musb->xceiv->state = OTG_STATE_A_SUSPEND; | ||
854 | musb->is_active = is_otg_enabled(musb) | ||
855 | && musb->xceiv->host->b_hnp_enable; | ||
856 | break; | ||
857 | case OTG_STATE_B_HOST: | ||
858 | /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ | ||
859 | DBG(1, "REVISIT: SUSPEND as B_HOST\n"); | ||
860 | break; | ||
861 | default: | ||
862 | /* "should not happen" */ | ||
863 | musb->is_active = 0; | ||
864 | break; | ||
865 | } | ||
866 | schedule_work(&musb->irq_work); | ||
867 | } | ||
868 | |||
869 | 851 | ||
870 | return handled; | 852 | return handled; |
871 | } | 853 | } |
@@ -1095,6 +1077,36 @@ static struct fifo_cfg __initdata mode_4_cfg[] = { | |||
1095 | { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, }, | 1077 | { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, }, |
1096 | }; | 1078 | }; |
1097 | 1079 | ||
1080 | /* mode 5 - fits in 8KB */ | ||
1081 | static struct fifo_cfg __initdata mode_5_cfg[] = { | ||
1082 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, | ||
1083 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, | ||
1084 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, | ||
1085 | { .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, }, | ||
1086 | { .hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512, }, | ||
1087 | { .hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512, }, | ||
1088 | { .hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 512, }, | ||
1089 | { .hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 512, }, | ||
1090 | { .hw_ep_num = 5, .style = FIFO_TX, .maxpacket = 512, }, | ||
1091 | { .hw_ep_num = 5, .style = FIFO_RX, .maxpacket = 512, }, | ||
1092 | { .hw_ep_num = 6, .style = FIFO_TX, .maxpacket = 32, }, | ||
1093 | { .hw_ep_num = 6, .style = FIFO_RX, .maxpacket = 32, }, | ||
1094 | { .hw_ep_num = 7, .style = FIFO_TX, .maxpacket = 32, }, | ||
1095 | { .hw_ep_num = 7, .style = FIFO_RX, .maxpacket = 32, }, | ||
1096 | { .hw_ep_num = 8, .style = FIFO_TX, .maxpacket = 32, }, | ||
1097 | { .hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 32, }, | ||
1098 | { .hw_ep_num = 9, .style = FIFO_TX, .maxpacket = 32, }, | ||
1099 | { .hw_ep_num = 9, .style = FIFO_RX, .maxpacket = 32, }, | ||
1100 | { .hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 32, }, | ||
1101 | { .hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 32, }, | ||
1102 | { .hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 32, }, | ||
1103 | { .hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 32, }, | ||
1104 | { .hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 32, }, | ||
1105 | { .hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 32, }, | ||
1106 | { .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 512, }, | ||
1107 | { .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, }, | ||
1108 | { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, }, | ||
1109 | }; | ||
1098 | 1110 | ||
1099 | /* | 1111 | /* |
1100 | * configure a fifo; for non-shared endpoints, this may be called | 1112 | * configure a fifo; for non-shared endpoints, this may be called |
@@ -1210,6 +1222,10 @@ static int __init ep_config_from_table(struct musb *musb) | |||
1210 | cfg = mode_4_cfg; | 1222 | cfg = mode_4_cfg; |
1211 | n = ARRAY_SIZE(mode_4_cfg); | 1223 | n = ARRAY_SIZE(mode_4_cfg); |
1212 | break; | 1224 | break; |
1225 | case 5: | ||
1226 | cfg = mode_5_cfg; | ||
1227 | n = ARRAY_SIZE(mode_5_cfg); | ||
1228 | break; | ||
1213 | } | 1229 | } |
1214 | 1230 | ||
1215 | printk(KERN_DEBUG "%s: setup fifo_mode %d\n", | 1231 | printk(KERN_DEBUG "%s: setup fifo_mode %d\n", |
@@ -1314,9 +1330,6 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, }; | |||
1314 | */ | 1330 | */ |
1315 | static int __init musb_core_init(u16 musb_type, struct musb *musb) | 1331 | static int __init musb_core_init(u16 musb_type, struct musb *musb) |
1316 | { | 1332 | { |
1317 | #ifdef MUSB_AHB_ID | ||
1318 | u32 data; | ||
1319 | #endif | ||
1320 | u8 reg; | 1333 | u8 reg; |
1321 | char *type; | 1334 | char *type; |
1322 | char aInfo[90], aRevision[32], aDate[12]; | 1335 | char aInfo[90], aRevision[32], aDate[12]; |
@@ -1328,23 +1341,17 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1328 | reg = musb_read_configdata(mbase); | 1341 | reg = musb_read_configdata(mbase); |
1329 | 1342 | ||
1330 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); | 1343 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); |
1331 | if (reg & MUSB_CONFIGDATA_DYNFIFO) | 1344 | if (reg & MUSB_CONFIGDATA_DYNFIFO) { |
1332 | strcat(aInfo, ", dyn FIFOs"); | 1345 | strcat(aInfo, ", dyn FIFOs"); |
1346 | musb->dyn_fifo = true; | ||
1347 | } | ||
1333 | if (reg & MUSB_CONFIGDATA_MPRXE) { | 1348 | if (reg & MUSB_CONFIGDATA_MPRXE) { |
1334 | strcat(aInfo, ", bulk combine"); | 1349 | strcat(aInfo, ", bulk combine"); |
1335 | #ifdef C_MP_RX | ||
1336 | musb->bulk_combine = true; | 1350 | musb->bulk_combine = true; |
1337 | #else | ||
1338 | strcat(aInfo, " (X)"); /* no driver support */ | ||
1339 | #endif | ||
1340 | } | 1351 | } |
1341 | if (reg & MUSB_CONFIGDATA_MPTXE) { | 1352 | if (reg & MUSB_CONFIGDATA_MPTXE) { |
1342 | strcat(aInfo, ", bulk split"); | 1353 | strcat(aInfo, ", bulk split"); |
1343 | #ifdef C_MP_TX | ||
1344 | musb->bulk_split = true; | 1354 | musb->bulk_split = true; |
1345 | #else | ||
1346 | strcat(aInfo, " (X)"); /* no driver support */ | ||
1347 | #endif | ||
1348 | } | 1355 | } |
1349 | if (reg & MUSB_CONFIGDATA_HBRXE) { | 1356 | if (reg & MUSB_CONFIGDATA_HBRXE) { |
1350 | strcat(aInfo, ", HB-ISO Rx"); | 1357 | strcat(aInfo, ", HB-ISO Rx"); |
@@ -1360,20 +1367,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1360 | printk(KERN_DEBUG "%s: ConfigData=0x%02x (%s)\n", | 1367 | printk(KERN_DEBUG "%s: ConfigData=0x%02x (%s)\n", |
1361 | musb_driver_name, reg, aInfo); | 1368 | musb_driver_name, reg, aInfo); |
1362 | 1369 | ||
1363 | #ifdef MUSB_AHB_ID | ||
1364 | data = musb_readl(mbase, 0x404); | ||
1365 | sprintf(aDate, "%04d-%02x-%02x", (data & 0xffff), | ||
1366 | (data >> 16) & 0xff, (data >> 24) & 0xff); | ||
1367 | /* FIXME ID2 and ID3 are unused */ | ||
1368 | data = musb_readl(mbase, 0x408); | ||
1369 | printk(KERN_DEBUG "ID2=%lx\n", (long unsigned)data); | ||
1370 | data = musb_readl(mbase, 0x40c); | ||
1371 | printk(KERN_DEBUG "ID3=%lx\n", (long unsigned)data); | ||
1372 | reg = musb_readb(mbase, 0x400); | ||
1373 | musb_type = ('M' == reg) ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC; | ||
1374 | #else | ||
1375 | aDate[0] = 0; | 1370 | aDate[0] = 0; |
1376 | #endif | ||
1377 | if (MUSB_CONTROLLER_MHDRC == musb_type) { | 1371 | if (MUSB_CONTROLLER_MHDRC == musb_type) { |
1378 | musb->is_multipoint = 1; | 1372 | musb->is_multipoint = 1; |
1379 | type = "M"; | 1373 | type = "M"; |
@@ -1404,21 +1398,10 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1404 | musb->nr_endpoints = 1; | 1398 | musb->nr_endpoints = 1; |
1405 | musb->epmask = 1; | 1399 | musb->epmask = 1; |
1406 | 1400 | ||
1407 | if (reg & MUSB_CONFIGDATA_DYNFIFO) { | 1401 | if (musb->dyn_fifo) |
1408 | if (musb->config->dyn_fifo) | 1402 | status = ep_config_from_table(musb); |
1409 | status = ep_config_from_table(musb); | 1403 | else |
1410 | else { | 1404 | status = ep_config_from_hw(musb); |
1411 | ERR("reconfigure software for Dynamic FIFOs\n"); | ||
1412 | status = -ENODEV; | ||
1413 | } | ||
1414 | } else { | ||
1415 | if (!musb->config->dyn_fifo) | ||
1416 | status = ep_config_from_hw(musb); | ||
1417 | else { | ||
1418 | ERR("reconfigure software for static FIFOs\n"); | ||
1419 | return -ENODEV; | ||
1420 | } | ||
1421 | } | ||
1422 | 1405 | ||
1423 | if (status < 0) | 1406 | if (status < 0) |
1424 | return status; | 1407 | return status; |
@@ -1587,11 +1570,6 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
1587 | ep_num++; | 1570 | ep_num++; |
1588 | } | 1571 | } |
1589 | 1572 | ||
1590 | /* finish handling "global" interrupts after handling fifos */ | ||
1591 | if (musb->int_usb) | ||
1592 | retval |= musb_stage2_irq(musb, | ||
1593 | musb->int_usb, devctl, power); | ||
1594 | |||
1595 | return retval; | 1573 | return retval; |
1596 | } | 1574 | } |
1597 | 1575 | ||
@@ -1696,7 +1674,7 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, | |||
1696 | unsigned long val; | 1674 | unsigned long val; |
1697 | 1675 | ||
1698 | if (sscanf(buf, "%lu", &val) < 1) { | 1676 | if (sscanf(buf, "%lu", &val) < 1) { |
1699 | printk(KERN_ERR "Invalid VBUS timeout ms value\n"); | 1677 | dev_err(dev, "Invalid VBUS timeout ms value\n"); |
1700 | return -EINVAL; | 1678 | return -EINVAL; |
1701 | } | 1679 | } |
1702 | 1680 | ||
@@ -1746,7 +1724,7 @@ musb_srp_store(struct device *dev, struct device_attribute *attr, | |||
1746 | 1724 | ||
1747 | if (sscanf(buf, "%hu", &srp) != 1 | 1725 | if (sscanf(buf, "%hu", &srp) != 1 |
1748 | || (srp != 1)) { | 1726 | || (srp != 1)) { |
1749 | printk(KERN_ERR "SRP: Value must be 1\n"); | 1727 | dev_err(dev, "SRP: Value must be 1\n"); |
1750 | return -EINVAL; | 1728 | return -EINVAL; |
1751 | } | 1729 | } |
1752 | 1730 | ||
@@ -1759,6 +1737,19 @@ static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store); | |||
1759 | 1737 | ||
1760 | #endif /* CONFIG_USB_GADGET_MUSB_HDRC */ | 1738 | #endif /* CONFIG_USB_GADGET_MUSB_HDRC */ |
1761 | 1739 | ||
1740 | static struct attribute *musb_attributes[] = { | ||
1741 | &dev_attr_mode.attr, | ||
1742 | &dev_attr_vbus.attr, | ||
1743 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
1744 | &dev_attr_srp.attr, | ||
1745 | #endif | ||
1746 | NULL | ||
1747 | }; | ||
1748 | |||
1749 | static const struct attribute_group musb_attr_group = { | ||
1750 | .attrs = musb_attributes, | ||
1751 | }; | ||
1752 | |||
1762 | #endif /* sysfs */ | 1753 | #endif /* sysfs */ |
1763 | 1754 | ||
1764 | /* Only used to provide driver mode change events */ | 1755 | /* Only used to provide driver mode change events */ |
@@ -1833,11 +1824,7 @@ static void musb_free(struct musb *musb) | |||
1833 | */ | 1824 | */ |
1834 | 1825 | ||
1835 | #ifdef CONFIG_SYSFS | 1826 | #ifdef CONFIG_SYSFS |
1836 | device_remove_file(musb->controller, &dev_attr_mode); | 1827 | sysfs_remove_group(&musb->controller->kobj, &musb_attr_group); |
1837 | device_remove_file(musb->controller, &dev_attr_vbus); | ||
1838 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
1839 | device_remove_file(musb->controller, &dev_attr_srp); | ||
1840 | #endif | ||
1841 | #endif | 1828 | #endif |
1842 | 1829 | ||
1843 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | 1830 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
@@ -2017,22 +2004,10 @@ bad_config: | |||
2017 | musb->irq_wake = 0; | 2004 | musb->irq_wake = 0; |
2018 | } | 2005 | } |
2019 | 2006 | ||
2020 | pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n", | ||
2021 | musb_driver_name, | ||
2022 | ({char *s; | ||
2023 | switch (musb->board_mode) { | ||
2024 | case MUSB_HOST: s = "Host"; break; | ||
2025 | case MUSB_PERIPHERAL: s = "Peripheral"; break; | ||
2026 | default: s = "OTG"; break; | ||
2027 | }; s; }), | ||
2028 | ctrl, | ||
2029 | (is_dma_capable() && musb->dma_controller) | ||
2030 | ? "DMA" : "PIO", | ||
2031 | musb->nIrq); | ||
2032 | |||
2033 | /* host side needs more setup */ | 2007 | /* host side needs more setup */ |
2034 | if (is_host_enabled(musb)) { | 2008 | if (is_host_enabled(musb)) { |
2035 | struct usb_hcd *hcd = musb_to_hcd(musb); | 2009 | struct usb_hcd *hcd = musb_to_hcd(musb); |
2010 | u8 busctl; | ||
2036 | 2011 | ||
2037 | otg_set_host(musb->xceiv, &hcd->self); | 2012 | otg_set_host(musb->xceiv, &hcd->self); |
2038 | 2013 | ||
@@ -2040,6 +2015,13 @@ bad_config: | |||
2040 | hcd->self.otg_port = 1; | 2015 | hcd->self.otg_port = 1; |
2041 | musb->xceiv->host = &hcd->self; | 2016 | musb->xceiv->host = &hcd->self; |
2042 | hcd->power_budget = 2 * (plat->power ? : 250); | 2017 | hcd->power_budget = 2 * (plat->power ? : 250); |
2018 | |||
2019 | /* program PHY to use external vBus if required */ | ||
2020 | if (plat->extvbus) { | ||
2021 | busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL); | ||
2022 | busctl |= MUSB_ULPI_USE_EXTVBUS; | ||
2023 | musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl); | ||
2024 | } | ||
2043 | } | 2025 | } |
2044 | 2026 | ||
2045 | /* For the host-only role, we can activate right away. | 2027 | /* For the host-only role, we can activate right away. |
@@ -2079,26 +2061,26 @@ bad_config: | |||
2079 | } | 2061 | } |
2080 | 2062 | ||
2081 | #ifdef CONFIG_SYSFS | 2063 | #ifdef CONFIG_SYSFS |
2082 | status = device_create_file(dev, &dev_attr_mode); | 2064 | status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); |
2083 | status = device_create_file(dev, &dev_attr_vbus); | ||
2084 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
2085 | status = device_create_file(dev, &dev_attr_srp); | ||
2086 | #endif /* CONFIG_USB_GADGET_MUSB_HDRC */ | ||
2087 | status = 0; | ||
2088 | #endif | 2065 | #endif |
2089 | if (status) | 2066 | if (status) |
2090 | goto fail2; | 2067 | goto fail2; |
2091 | 2068 | ||
2069 | dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", | ||
2070 | ({char *s; | ||
2071 | switch (musb->board_mode) { | ||
2072 | case MUSB_HOST: s = "Host"; break; | ||
2073 | case MUSB_PERIPHERAL: s = "Peripheral"; break; | ||
2074 | default: s = "OTG"; break; | ||
2075 | }; s; }), | ||
2076 | ctrl, | ||
2077 | (is_dma_capable() && musb->dma_controller) | ||
2078 | ? "DMA" : "PIO", | ||
2079 | musb->nIrq); | ||
2080 | |||
2092 | return 0; | 2081 | return 0; |
2093 | 2082 | ||
2094 | fail2: | 2083 | fail2: |
2095 | #ifdef CONFIG_SYSFS | ||
2096 | device_remove_file(musb->controller, &dev_attr_mode); | ||
2097 | device_remove_file(musb->controller, &dev_attr_vbus); | ||
2098 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
2099 | device_remove_file(musb->controller, &dev_attr_srp); | ||
2100 | #endif | ||
2101 | #endif | ||
2102 | musb_platform_exit(musb); | 2084 | musb_platform_exit(musb); |
2103 | fail: | 2085 | fail: |
2104 | dev_err(musb->controller, | 2086 | dev_err(musb->controller, |
@@ -2127,6 +2109,7 @@ static int __init musb_probe(struct platform_device *pdev) | |||
2127 | { | 2109 | { |
2128 | struct device *dev = &pdev->dev; | 2110 | struct device *dev = &pdev->dev; |
2129 | int irq = platform_get_irq(pdev, 0); | 2111 | int irq = platform_get_irq(pdev, 0); |
2112 | int status; | ||
2130 | struct resource *iomem; | 2113 | struct resource *iomem; |
2131 | void __iomem *base; | 2114 | void __iomem *base; |
2132 | 2115 | ||
@@ -2134,7 +2117,7 @@ static int __init musb_probe(struct platform_device *pdev) | |||
2134 | if (!iomem || irq == 0) | 2117 | if (!iomem || irq == 0) |
2135 | return -ENODEV; | 2118 | return -ENODEV; |
2136 | 2119 | ||
2137 | base = ioremap(iomem->start, iomem->end - iomem->start + 1); | 2120 | base = ioremap(iomem->start, resource_size(iomem)); |
2138 | if (!base) { | 2121 | if (!base) { |
2139 | dev_err(dev, "ioremap failed\n"); | 2122 | dev_err(dev, "ioremap failed\n"); |
2140 | return -ENOMEM; | 2123 | return -ENOMEM; |
@@ -2144,7 +2127,12 @@ static int __init musb_probe(struct platform_device *pdev) | |||
2144 | /* clobbered by use_dma=n */ | 2127 | /* clobbered by use_dma=n */ |
2145 | orig_dma_mask = dev->dma_mask; | 2128 | orig_dma_mask = dev->dma_mask; |
2146 | #endif | 2129 | #endif |
2147 | return musb_init_controller(dev, irq, base); | 2130 | |
2131 | status = musb_init_controller(dev, irq, base); | ||
2132 | if (status < 0) | ||
2133 | iounmap(base); | ||
2134 | |||
2135 | return status; | ||
2148 | } | 2136 | } |
2149 | 2137 | ||
2150 | static int __exit musb_remove(struct platform_device *pdev) | 2138 | static int __exit musb_remove(struct platform_device *pdev) |
@@ -2173,6 +2161,148 @@ static int __exit musb_remove(struct platform_device *pdev) | |||
2173 | 2161 | ||
2174 | #ifdef CONFIG_PM | 2162 | #ifdef CONFIG_PM |
2175 | 2163 | ||
2164 | static struct musb_context_registers musb_context; | ||
2165 | |||
2166 | void musb_save_context(struct musb *musb) | ||
2167 | { | ||
2168 | int i; | ||
2169 | void __iomem *musb_base = musb->mregs; | ||
2170 | |||
2171 | if (is_host_enabled(musb)) { | ||
2172 | musb_context.frame = musb_readw(musb_base, MUSB_FRAME); | ||
2173 | musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); | ||
2174 | } | ||
2175 | musb_context.power = musb_readb(musb_base, MUSB_POWER); | ||
2176 | musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); | ||
2177 | musb_context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); | ||
2178 | musb_context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); | ||
2179 | musb_context.index = musb_readb(musb_base, MUSB_INDEX); | ||
2180 | musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL); | ||
2181 | |||
2182 | for (i = 0; i < MUSB_C_NUM_EPS; ++i) { | ||
2183 | musb_writeb(musb_base, MUSB_INDEX, i); | ||
2184 | musb_context.index_regs[i].txmaxp = | ||
2185 | musb_readw(musb_base, 0x10 + MUSB_TXMAXP); | ||
2186 | musb_context.index_regs[i].txcsr = | ||
2187 | musb_readw(musb_base, 0x10 + MUSB_TXCSR); | ||
2188 | musb_context.index_regs[i].rxmaxp = | ||
2189 | musb_readw(musb_base, 0x10 + MUSB_RXMAXP); | ||
2190 | musb_context.index_regs[i].rxcsr = | ||
2191 | musb_readw(musb_base, 0x10 + MUSB_RXCSR); | ||
2192 | |||
2193 | if (musb->dyn_fifo) { | ||
2194 | musb_context.index_regs[i].txfifoadd = | ||
2195 | musb_read_txfifoadd(musb_base); | ||
2196 | musb_context.index_regs[i].rxfifoadd = | ||
2197 | musb_read_rxfifoadd(musb_base); | ||
2198 | musb_context.index_regs[i].txfifosz = | ||
2199 | musb_read_txfifosz(musb_base); | ||
2200 | musb_context.index_regs[i].rxfifosz = | ||
2201 | musb_read_rxfifosz(musb_base); | ||
2202 | } | ||
2203 | if (is_host_enabled(musb)) { | ||
2204 | musb_context.index_regs[i].txtype = | ||
2205 | musb_readb(musb_base, 0x10 + MUSB_TXTYPE); | ||
2206 | musb_context.index_regs[i].txinterval = | ||
2207 | musb_readb(musb_base, 0x10 + MUSB_TXINTERVAL); | ||
2208 | musb_context.index_regs[i].rxtype = | ||
2209 | musb_readb(musb_base, 0x10 + MUSB_RXTYPE); | ||
2210 | musb_context.index_regs[i].rxinterval = | ||
2211 | musb_readb(musb_base, 0x10 + MUSB_RXINTERVAL); | ||
2212 | |||
2213 | musb_context.index_regs[i].txfunaddr = | ||
2214 | musb_read_txfunaddr(musb_base, i); | ||
2215 | musb_context.index_regs[i].txhubaddr = | ||
2216 | musb_read_txhubaddr(musb_base, i); | ||
2217 | musb_context.index_regs[i].txhubport = | ||
2218 | musb_read_txhubport(musb_base, i); | ||
2219 | |||
2220 | musb_context.index_regs[i].rxfunaddr = | ||
2221 | musb_read_rxfunaddr(musb_base, i); | ||
2222 | musb_context.index_regs[i].rxhubaddr = | ||
2223 | musb_read_rxhubaddr(musb_base, i); | ||
2224 | musb_context.index_regs[i].rxhubport = | ||
2225 | musb_read_rxhubport(musb_base, i); | ||
2226 | } | ||
2227 | } | ||
2228 | |||
2229 | musb_writeb(musb_base, MUSB_INDEX, musb_context.index); | ||
2230 | |||
2231 | musb_platform_save_context(musb, &musb_context); | ||
2232 | } | ||
2233 | |||
2234 | void musb_restore_context(struct musb *musb) | ||
2235 | { | ||
2236 | int i; | ||
2237 | void __iomem *musb_base = musb->mregs; | ||
2238 | void __iomem *ep_target_regs; | ||
2239 | |||
2240 | musb_platform_restore_context(musb, &musb_context); | ||
2241 | |||
2242 | if (is_host_enabled(musb)) { | ||
2243 | musb_writew(musb_base, MUSB_FRAME, musb_context.frame); | ||
2244 | musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode); | ||
2245 | } | ||
2246 | musb_writeb(musb_base, MUSB_POWER, musb_context.power); | ||
2247 | musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe); | ||
2248 | musb_writew(musb_base, MUSB_INTRRXE, musb_context.intrrxe); | ||
2249 | musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe); | ||
2250 | musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl); | ||
2251 | |||
2252 | for (i = 0; i < MUSB_C_NUM_EPS; ++i) { | ||
2253 | musb_writeb(musb_base, MUSB_INDEX, i); | ||
2254 | musb_writew(musb_base, 0x10 + MUSB_TXMAXP, | ||
2255 | musb_context.index_regs[i].txmaxp); | ||
2256 | musb_writew(musb_base, 0x10 + MUSB_TXCSR, | ||
2257 | musb_context.index_regs[i].txcsr); | ||
2258 | musb_writew(musb_base, 0x10 + MUSB_RXMAXP, | ||
2259 | musb_context.index_regs[i].rxmaxp); | ||
2260 | musb_writew(musb_base, 0x10 + MUSB_RXCSR, | ||
2261 | musb_context.index_regs[i].rxcsr); | ||
2262 | |||
2263 | if (musb->dyn_fifo) { | ||
2264 | musb_write_txfifosz(musb_base, | ||
2265 | musb_context.index_regs[i].txfifosz); | ||
2266 | musb_write_rxfifosz(musb_base, | ||
2267 | musb_context.index_regs[i].rxfifosz); | ||
2268 | musb_write_txfifoadd(musb_base, | ||
2269 | musb_context.index_regs[i].txfifoadd); | ||
2270 | musb_write_rxfifoadd(musb_base, | ||
2271 | musb_context.index_regs[i].rxfifoadd); | ||
2272 | } | ||
2273 | |||
2274 | if (is_host_enabled(musb)) { | ||
2275 | musb_writeb(musb_base, 0x10 + MUSB_TXTYPE, | ||
2276 | musb_context.index_regs[i].txtype); | ||
2277 | musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL, | ||
2278 | musb_context.index_regs[i].txinterval); | ||
2279 | musb_writeb(musb_base, 0x10 + MUSB_RXTYPE, | ||
2280 | musb_context.index_regs[i].rxtype); | ||
2281 | musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL, | ||
2282 | |||
2283 | musb_context.index_regs[i].rxinterval); | ||
2284 | musb_write_txfunaddr(musb_base, i, | ||
2285 | musb_context.index_regs[i].txfunaddr); | ||
2286 | musb_write_txhubaddr(musb_base, i, | ||
2287 | musb_context.index_regs[i].txhubaddr); | ||
2288 | musb_write_txhubport(musb_base, i, | ||
2289 | musb_context.index_regs[i].txhubport); | ||
2290 | |||
2291 | ep_target_regs = | ||
2292 | musb_read_target_reg_base(i, musb_base); | ||
2293 | |||
2294 | musb_write_rxfunaddr(ep_target_regs, | ||
2295 | musb_context.index_regs[i].rxfunaddr); | ||
2296 | musb_write_rxhubaddr(ep_target_regs, | ||
2297 | musb_context.index_regs[i].rxhubaddr); | ||
2298 | musb_write_rxhubport(ep_target_regs, | ||
2299 | musb_context.index_regs[i].rxhubport); | ||
2300 | } | ||
2301 | } | ||
2302 | |||
2303 | musb_writeb(musb_base, MUSB_INDEX, musb_context.index); | ||
2304 | } | ||
2305 | |||
2176 | static int musb_suspend(struct device *dev) | 2306 | static int musb_suspend(struct device *dev) |
2177 | { | 2307 | { |
2178 | struct platform_device *pdev = to_platform_device(dev); | 2308 | struct platform_device *pdev = to_platform_device(dev); |
@@ -2194,6 +2324,8 @@ static int musb_suspend(struct device *dev) | |||
2194 | */ | 2324 | */ |
2195 | } | 2325 | } |
2196 | 2326 | ||
2327 | musb_save_context(musb); | ||
2328 | |||
2197 | if (musb->set_clock) | 2329 | if (musb->set_clock) |
2198 | musb->set_clock(musb->clock, 0); | 2330 | musb->set_clock(musb->clock, 0); |
2199 | else | 2331 | else |
@@ -2215,6 +2347,8 @@ static int musb_resume_noirq(struct device *dev) | |||
2215 | else | 2347 | else |
2216 | clk_enable(musb->clock); | 2348 | clk_enable(musb->clock); |
2217 | 2349 | ||
2350 | musb_restore_context(musb); | ||
2351 | |||
2218 | /* for static cmos like DaVinci, register values were preserved | 2352 | /* for static cmos like DaVinci, register values were preserved |
2219 | * unless for some reason the whole soc powered down or the USB | 2353 | * unless for some reason the whole soc powered down or the USB |
2220 | * module got reset through the PSC (vs just being disabled). | 2354 | * module got reset through the PSC (vs just being disabled). |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 5514c7ee85bd..d849fb81c131 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -52,6 +52,15 @@ struct musb; | |||
52 | struct musb_hw_ep; | 52 | struct musb_hw_ep; |
53 | struct musb_ep; | 53 | struct musb_ep; |
54 | 54 | ||
55 | /* Helper defines for struct musb->hwvers */ | ||
56 | #define MUSB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f) | ||
57 | #define MUSB_HWVERS_MINOR(x) (x & 0x3ff) | ||
58 | #define MUSB_HWVERS_RC 0x8000 | ||
59 | #define MUSB_HWVERS_1300 0x52C | ||
60 | #define MUSB_HWVERS_1400 0x590 | ||
61 | #define MUSB_HWVERS_1800 0x720 | ||
62 | #define MUSB_HWVERS_1900 0x784 | ||
63 | #define MUSB_HWVERS_2000 0x800 | ||
55 | 64 | ||
56 | #include "musb_debug.h" | 65 | #include "musb_debug.h" |
57 | #include "musb_dma.h" | 66 | #include "musb_dma.h" |
@@ -322,13 +331,6 @@ struct musb { | |||
322 | struct clk *clock; | 331 | struct clk *clock; |
323 | irqreturn_t (*isr)(int, void *); | 332 | irqreturn_t (*isr)(int, void *); |
324 | struct work_struct irq_work; | 333 | struct work_struct irq_work; |
325 | #define MUSB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f) | ||
326 | #define MUSB_HWVERS_MINOR(x) (x & 0x3ff) | ||
327 | #define MUSB_HWVERS_RC 0x8000 | ||
328 | #define MUSB_HWVERS_1300 0x52C | ||
329 | #define MUSB_HWVERS_1400 0x590 | ||
330 | #define MUSB_HWVERS_1800 0x720 | ||
331 | #define MUSB_HWVERS_2000 0x800 | ||
332 | u16 hwvers; | 334 | u16 hwvers; |
333 | 335 | ||
334 | /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */ | 336 | /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */ |
@@ -411,22 +413,15 @@ struct musb { | |||
411 | 413 | ||
412 | unsigned hb_iso_rx:1; /* high bandwidth iso rx? */ | 414 | unsigned hb_iso_rx:1; /* high bandwidth iso rx? */ |
413 | unsigned hb_iso_tx:1; /* high bandwidth iso tx? */ | 415 | unsigned hb_iso_tx:1; /* high bandwidth iso tx? */ |
416 | unsigned dyn_fifo:1; /* dynamic FIFO supported? */ | ||
414 | 417 | ||
415 | #ifdef C_MP_TX | 418 | unsigned bulk_split:1; |
416 | unsigned bulk_split:1; | ||
417 | #define can_bulk_split(musb,type) \ | 419 | #define can_bulk_split(musb,type) \ |
418 | (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split) | 420 | (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split) |
419 | #else | ||
420 | #define can_bulk_split(musb, type) 0 | ||
421 | #endif | ||
422 | 421 | ||
423 | #ifdef C_MP_RX | 422 | unsigned bulk_combine:1; |
424 | unsigned bulk_combine:1; | ||
425 | #define can_bulk_combine(musb,type) \ | 423 | #define can_bulk_combine(musb,type) \ |
426 | (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine) | 424 | (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine) |
427 | #else | ||
428 | #define can_bulk_combine(musb, type) 0 | ||
429 | #endif | ||
430 | 425 | ||
431 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | 426 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
432 | /* is_suspended means USB B_PERIPHERAL suspend */ | 427 | /* is_suspended means USB B_PERIPHERAL suspend */ |
@@ -461,6 +456,45 @@ struct musb { | |||
461 | #endif | 456 | #endif |
462 | }; | 457 | }; |
463 | 458 | ||
459 | #ifdef CONFIG_PM | ||
460 | struct musb_csr_regs { | ||
461 | /* FIFO registers */ | ||
462 | u16 txmaxp, txcsr, rxmaxp, rxcsr; | ||
463 | u16 rxfifoadd, txfifoadd; | ||
464 | u8 txtype, txinterval, rxtype, rxinterval; | ||
465 | u8 rxfifosz, txfifosz; | ||
466 | u8 txfunaddr, txhubaddr, txhubport; | ||
467 | u8 rxfunaddr, rxhubaddr, rxhubport; | ||
468 | }; | ||
469 | |||
470 | struct musb_context_registers { | ||
471 | |||
472 | #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) | ||
473 | u32 otg_sysconfig, otg_forcestandby; | ||
474 | #endif | ||
475 | u8 power; | ||
476 | u16 intrtxe, intrrxe; | ||
477 | u8 intrusbe; | ||
478 | u16 frame; | ||
479 | u8 index, testmode; | ||
480 | |||
481 | u8 devctl, misc; | ||
482 | |||
483 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; | ||
484 | }; | ||
485 | |||
486 | #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) | ||
487 | extern void musb_platform_save_context(struct musb *musb, | ||
488 | struct musb_context_registers *musb_context); | ||
489 | extern void musb_platform_restore_context(struct musb *musb, | ||
490 | struct musb_context_registers *musb_context); | ||
491 | #else | ||
492 | #define musb_platform_save_context(m, x) do {} while (0) | ||
493 | #define musb_platform_restore_context(m, x) do {} while (0) | ||
494 | #endif | ||
495 | |||
496 | #endif | ||
497 | |||
464 | static inline void musb_set_vbus(struct musb *musb, int is_on) | 498 | static inline void musb_set_vbus(struct musb *musb, int is_on) |
465 | { | 499 | { |
466 | musb->board_set_vbus(musb, is_on); | 500 | musb->board_set_vbus(musb, is_on); |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index cbcf14a236e6..a9f288cd70ed 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -895,7 +895,14 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
895 | /* REVISIT if can_bulk_split(), use by updating "tmp"; | 895 | /* REVISIT if can_bulk_split(), use by updating "tmp"; |
896 | * likewise high bandwidth periodic tx | 896 | * likewise high bandwidth periodic tx |
897 | */ | 897 | */ |
898 | musb_writew(regs, MUSB_TXMAXP, tmp); | 898 | /* Set TXMAXP with the FIFO size of the endpoint |
899 | * to disable double buffering mode. Currently, It seems that double | ||
900 | * buffering has problem if musb RTL revision number < 2.0. | ||
901 | */ | ||
902 | if (musb->hwvers < MUSB_HWVERS_2000) | ||
903 | musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); | ||
904 | else | ||
905 | musb_writew(regs, MUSB_TXMAXP, tmp); | ||
899 | 906 | ||
900 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; | 907 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; |
901 | if (musb_readw(regs, MUSB_TXCSR) | 908 | if (musb_readw(regs, MUSB_TXCSR) |
@@ -925,7 +932,13 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
925 | /* REVISIT if can_bulk_combine() use by updating "tmp" | 932 | /* REVISIT if can_bulk_combine() use by updating "tmp" |
926 | * likewise high bandwidth periodic rx | 933 | * likewise high bandwidth periodic rx |
927 | */ | 934 | */ |
928 | musb_writew(regs, MUSB_RXMAXP, tmp); | 935 | /* Set RXMAXP with the FIFO size of the endpoint |
936 | * to disable double buffering mode. | ||
937 | */ | ||
938 | if (musb->hwvers < MUSB_HWVERS_2000) | ||
939 | musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx); | ||
940 | else | ||
941 | musb_writew(regs, MUSB_RXMAXP, tmp); | ||
929 | 942 | ||
930 | /* force shared fifo to OUT-only mode */ | 943 | /* force shared fifo to OUT-only mode */ |
931 | if (hw_ep->is_shared_fifo) { | 944 | if (hw_ep->is_shared_fifo) { |
@@ -1697,8 +1710,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1697 | return -EINVAL; | 1710 | return -EINVAL; |
1698 | 1711 | ||
1699 | /* driver must be initialized to support peripheral mode */ | 1712 | /* driver must be initialized to support peripheral mode */ |
1700 | if (!musb || !(musb->board_mode == MUSB_OTG | 1713 | if (!musb) { |
1701 | || musb->board_mode != MUSB_OTG)) { | ||
1702 | DBG(1, "%s, no dev??\n", __func__); | 1714 | DBG(1, "%s, no dev??\n", __func__); |
1703 | return -ENODEV; | 1715 | return -ENODEV; |
1704 | } | 1716 | } |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 74c4c3698f1e..3421cf9858b5 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -605,8 +605,14 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
605 | musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg); | 605 | musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg); |
606 | musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg); | 606 | musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg); |
607 | /* NOTE: bulk combining rewrites high bits of maxpacket */ | 607 | /* NOTE: bulk combining rewrites high bits of maxpacket */ |
608 | musb_writew(ep->regs, MUSB_RXMAXP, | 608 | /* Set RXMAXP with the FIFO size of the endpoint |
609 | qh->maxpacket | ((qh->hb_mult - 1) << 11)); | 609 | * to disable double buffer mode. |
610 | */ | ||
611 | if (musb->hwvers < MUSB_HWVERS_2000) | ||
612 | musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx); | ||
613 | else | ||
614 | musb_writew(ep->regs, MUSB_RXMAXP, | ||
615 | qh->maxpacket | ((qh->hb_mult - 1) << 11)); | ||
610 | 616 | ||
611 | ep->rx_reinit = 0; | 617 | ep->rx_reinit = 0; |
612 | } | 618 | } |
@@ -1771,6 +1777,9 @@ static int musb_schedule( | |||
1771 | int best_end, epnum; | 1777 | int best_end, epnum; |
1772 | struct musb_hw_ep *hw_ep = NULL; | 1778 | struct musb_hw_ep *hw_ep = NULL; |
1773 | struct list_head *head = NULL; | 1779 | struct list_head *head = NULL; |
1780 | u8 toggle; | ||
1781 | u8 txtype; | ||
1782 | struct urb *urb = next_urb(qh); | ||
1774 | 1783 | ||
1775 | /* use fixed hardware for control and bulk */ | 1784 | /* use fixed hardware for control and bulk */ |
1776 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { | 1785 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { |
@@ -1809,6 +1818,27 @@ static int musb_schedule( | |||
1809 | diff -= (qh->maxpacket * qh->hb_mult); | 1818 | diff -= (qh->maxpacket * qh->hb_mult); |
1810 | 1819 | ||
1811 | if (diff >= 0 && best_diff > diff) { | 1820 | if (diff >= 0 && best_diff > diff) { |
1821 | |||
1822 | /* | ||
1823 | * Mentor controller has a bug in that if we schedule | ||
1824 | * a BULK Tx transfer on an endpoint that had earlier | ||
1825 | * handled ISOC then the BULK transfer has to start on | ||
1826 | * a zero toggle. If the BULK transfer starts on a 1 | ||
1827 | * toggle then this transfer will fail as the mentor | ||
1828 | * controller starts the Bulk transfer on a 0 toggle | ||
1829 | * irrespective of the programming of the toggle bits | ||
1830 | * in the TXCSR register. Check for this condition | ||
1831 | * while allocating the EP for a Tx Bulk transfer. If | ||
1832 | * so skip this EP. | ||
1833 | */ | ||
1834 | hw_ep = musb->endpoints + epnum; | ||
1835 | toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); | ||
1836 | txtype = (musb_readb(hw_ep->regs, MUSB_TXTYPE) | ||
1837 | >> 4) & 0x3; | ||
1838 | if (!is_in && (qh->type == USB_ENDPOINT_XFER_BULK) && | ||
1839 | toggle && (txtype == USB_ENDPOINT_XFER_ISOC)) | ||
1840 | continue; | ||
1841 | |||
1812 | best_diff = diff; | 1842 | best_diff = diff; |
1813 | best_end = epnum; | 1843 | best_end = epnum; |
1814 | } | 1844 | } |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 473a94ef905f..292894a2c247 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -72,6 +72,10 @@ | |||
72 | #define MUSB_DEVCTL_HR 0x02 | 72 | #define MUSB_DEVCTL_HR 0x02 |
73 | #define MUSB_DEVCTL_SESSION 0x01 | 73 | #define MUSB_DEVCTL_SESSION 0x01 |
74 | 74 | ||
75 | /* MUSB ULPI VBUSCONTROL */ | ||
76 | #define MUSB_ULPI_USE_EXTVBUS 0x01 | ||
77 | #define MUSB_ULPI_USE_EXTVBUSIND 0x02 | ||
78 | |||
75 | /* TESTMODE */ | 79 | /* TESTMODE */ |
76 | #define MUSB_TEST_FORCE_HOST 0x80 | 80 | #define MUSB_TEST_FORCE_HOST 0x80 |
77 | #define MUSB_TEST_FIFO_ACCESS 0x40 | 81 | #define MUSB_TEST_FIFO_ACCESS 0x40 |
@@ -246,6 +250,7 @@ | |||
246 | 250 | ||
247 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ | 251 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ |
248 | #define MUSB_HWVERS 0x6C /* 8 bit */ | 252 | #define MUSB_HWVERS 0x6C /* 8 bit */ |
253 | #define MUSB_ULPI_BUSCONTROL 0x70 /* 8 bit */ | ||
249 | 254 | ||
250 | #define MUSB_EPINFO 0x78 /* 8 bit */ | 255 | #define MUSB_EPINFO 0x78 /* 8 bit */ |
251 | #define MUSB_RAMINFO 0x79 /* 8 bit */ | 256 | #define MUSB_RAMINFO 0x79 /* 8 bit */ |
@@ -321,6 +326,26 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | |||
321 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | 326 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); |
322 | } | 327 | } |
323 | 328 | ||
329 | static inline u8 musb_read_txfifosz(void __iomem *mbase) | ||
330 | { | ||
331 | return musb_readb(mbase, MUSB_TXFIFOSZ); | ||
332 | } | ||
333 | |||
334 | static inline u16 musb_read_txfifoadd(void __iomem *mbase) | ||
335 | { | ||
336 | return musb_readw(mbase, MUSB_TXFIFOADD); | ||
337 | } | ||
338 | |||
339 | static inline u8 musb_read_rxfifosz(void __iomem *mbase) | ||
340 | { | ||
341 | return musb_readb(mbase, MUSB_RXFIFOSZ); | ||
342 | } | ||
343 | |||
344 | static inline u16 musb_read_rxfifoadd(void __iomem *mbase) | ||
345 | { | ||
346 | return musb_readw(mbase, MUSB_RXFIFOADD); | ||
347 | } | ||
348 | |||
324 | static inline u8 musb_read_configdata(void __iomem *mbase) | 349 | static inline u8 musb_read_configdata(void __iomem *mbase) |
325 | { | 350 | { |
326 | musb_writeb(mbase, MUSB_INDEX, 0); | 351 | musb_writeb(mbase, MUSB_INDEX, 0); |
@@ -376,6 +401,36 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | |||
376 | qh_h_port_reg); | 401 | qh_h_port_reg); |
377 | } | 402 | } |
378 | 403 | ||
404 | static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) | ||
405 | { | ||
406 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR)); | ||
407 | } | ||
408 | |||
409 | static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) | ||
410 | { | ||
411 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR)); | ||
412 | } | ||
413 | |||
414 | static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) | ||
415 | { | ||
416 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT)); | ||
417 | } | ||
418 | |||
419 | static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) | ||
420 | { | ||
421 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR)); | ||
422 | } | ||
423 | |||
424 | static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) | ||
425 | { | ||
426 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR)); | ||
427 | } | ||
428 | |||
429 | static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) | ||
430 | { | ||
431 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT)); | ||
432 | } | ||
433 | |||
379 | #else /* CONFIG_BLACKFIN */ | 434 | #else /* CONFIG_BLACKFIN */ |
380 | 435 | ||
381 | #define USB_BASE USB_FADDR | 436 | #define USB_BASE USB_FADDR |
@@ -455,6 +510,22 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | |||
455 | { | 510 | { |
456 | } | 511 | } |
457 | 512 | ||
513 | static inline u8 musb_read_txfifosz(void __iomem *mbase) | ||
514 | { | ||
515 | } | ||
516 | |||
517 | static inline u16 musb_read_txfifoadd(void __iomem *mbase) | ||
518 | { | ||
519 | } | ||
520 | |||
521 | static inline u8 musb_read_rxfifosz(void __iomem *mbase) | ||
522 | { | ||
523 | } | ||
524 | |||
525 | static inline u16 musb_read_rxfifoadd(void __iomem *mbase) | ||
526 | { | ||
527 | } | ||
528 | |||
458 | static inline u8 musb_read_configdata(void __iomem *mbase) | 529 | static inline u8 musb_read_configdata(void __iomem *mbase) |
459 | { | 530 | { |
460 | return 0; | 531 | return 0; |
@@ -462,7 +533,11 @@ static inline u8 musb_read_configdata(void __iomem *mbase) | |||
462 | 533 | ||
463 | static inline u16 musb_read_hwvers(void __iomem *mbase) | 534 | static inline u16 musb_read_hwvers(void __iomem *mbase) |
464 | { | 535 | { |
465 | return 0; | 536 | /* |
537 | * This register is invisible on Blackfin, actually the MUSB | ||
538 | * RTL version of Blackfin is 1.9, so just harcode its value. | ||
539 | */ | ||
540 | return MUSB_HWVERS_1900; | ||
466 | } | 541 | } |
467 | 542 | ||
468 | static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) | 543 | static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) |
@@ -500,6 +575,30 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | |||
500 | { | 575 | { |
501 | } | 576 | } |
502 | 577 | ||
578 | static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) | ||
579 | { | ||
580 | } | ||
581 | |||
582 | static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) | ||
583 | { | ||
584 | } | ||
585 | |||
586 | static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) | ||
587 | { | ||
588 | } | ||
589 | |||
590 | static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) | ||
591 | { | ||
592 | } | ||
593 | |||
594 | static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) | ||
595 | { | ||
596 | } | ||
597 | |||
598 | static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) | ||
599 | { | ||
600 | } | ||
601 | |||
503 | #endif /* CONFIG_BLACKFIN */ | 602 | #endif /* CONFIG_BLACKFIN */ |
504 | 603 | ||
505 | #endif /* __MUSB_REGS_H__ */ | 604 | #endif /* __MUSB_REGS_H__ */ |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index a237550f91bf..2fa7d5c00f31 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -250,20 +250,39 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
250 | u8 bchannel; | 250 | u8 bchannel; |
251 | u8 int_hsdma; | 251 | u8 int_hsdma; |
252 | 252 | ||
253 | u32 addr; | 253 | u32 addr, count; |
254 | u16 csr; | 254 | u16 csr; |
255 | 255 | ||
256 | spin_lock_irqsave(&musb->lock, flags); | 256 | spin_lock_irqsave(&musb->lock, flags); |
257 | 257 | ||
258 | int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR); | 258 | int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR); |
259 | if (!int_hsdma) | ||
260 | goto done; | ||
261 | 259 | ||
262 | #ifdef CONFIG_BLACKFIN | 260 | #ifdef CONFIG_BLACKFIN |
263 | /* Clear DMA interrupt flags */ | 261 | /* Clear DMA interrupt flags */ |
264 | musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma); | 262 | musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma); |
265 | #endif | 263 | #endif |
266 | 264 | ||
265 | if (!int_hsdma) { | ||
266 | DBG(2, "spurious DMA irq\n"); | ||
267 | |||
268 | for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { | ||
269 | musb_channel = (struct musb_dma_channel *) | ||
270 | &(controller->channel[bchannel]); | ||
271 | channel = &musb_channel->channel; | ||
272 | if (channel->status == MUSB_DMA_STATUS_BUSY) { | ||
273 | count = musb_read_hsdma_count(mbase, bchannel); | ||
274 | |||
275 | if (count == 0) | ||
276 | int_hsdma |= (1 << bchannel); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | DBG(2, "int_hsdma = 0x%x\n", int_hsdma); | ||
281 | |||
282 | if (!int_hsdma) | ||
283 | goto done; | ||
284 | } | ||
285 | |||
267 | for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { | 286 | for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { |
268 | if (int_hsdma & (1 << bchannel)) { | 287 | if (int_hsdma & (1 << bchannel)) { |
269 | musb_channel = (struct musb_dma_channel *) | 288 | musb_channel = (struct musb_dma_channel *) |
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h index 1299d92dc83f..613f95a058f7 100644 --- a/drivers/usb/musb/musbhsdma.h +++ b/drivers/usb/musb/musbhsdma.h | |||
@@ -55,6 +55,10 @@ | |||
55 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \ | 55 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \ |
56 | addr) | 56 | addr) |
57 | 57 | ||
58 | #define musb_read_hsdma_count(mbase, bchannel) \ | ||
59 | musb_readl(mbase, \ | ||
60 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT)) | ||
61 | |||
58 | #define musb_write_hsdma_count(mbase, bchannel, len) \ | 62 | #define musb_write_hsdma_count(mbase, bchannel, len) \ |
59 | musb_writel(mbase, \ | 63 | musb_writel(mbase, \ |
60 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \ | 64 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \ |
@@ -96,6 +100,19 @@ static inline void musb_write_hsdma_addr(void __iomem *mbase, | |||
96 | ((u16)(((u32) dma_addr >> 16) & 0xFFFF))); | 100 | ((u16)(((u32) dma_addr >> 16) & 0xFFFF))); |
97 | } | 101 | } |
98 | 102 | ||
103 | static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel) | ||
104 | { | ||
105 | u32 count = musb_readw(mbase, | ||
106 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH)); | ||
107 | |||
108 | count = count << 16; | ||
109 | |||
110 | count |= musb_readw(mbase, | ||
111 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW)); | ||
112 | |||
113 | return count; | ||
114 | } | ||
115 | |||
99 | static inline void musb_write_hsdma_count(void __iomem *mbase, | 116 | static inline void musb_write_hsdma_count(void __iomem *mbase, |
100 | u8 bchannel, u32 len) | 117 | u8 bchannel, u32 len) |
101 | { | 118 | { |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 83beeac5e7bf..3fe16867b5a8 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -220,7 +220,7 @@ int __init musb_platform_init(struct musb *musb) | |||
220 | 220 | ||
221 | musb_platform_resume(musb); | 221 | musb_platform_resume(musb); |
222 | 222 | ||
223 | l = omap_readl(OTG_SYSCONFIG); | 223 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); |
224 | l &= ~ENABLEWAKEUP; /* disable wakeup */ | 224 | l &= ~ENABLEWAKEUP; /* disable wakeup */ |
225 | l &= ~NOSTDBY; /* remove possible nostdby */ | 225 | l &= ~NOSTDBY; /* remove possible nostdby */ |
226 | l |= SMARTSTDBY; /* enable smart standby */ | 226 | l |= SMARTSTDBY; /* enable smart standby */ |
@@ -233,17 +233,19 @@ int __init musb_platform_init(struct musb *musb) | |||
233 | */ | 233 | */ |
234 | if (!cpu_is_omap3430()) | 234 | if (!cpu_is_omap3430()) |
235 | l |= AUTOIDLE; /* enable auto idle */ | 235 | l |= AUTOIDLE; /* enable auto idle */ |
236 | omap_writel(l, OTG_SYSCONFIG); | 236 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); |
237 | 237 | ||
238 | l = omap_readl(OTG_INTERFSEL); | 238 | l = musb_readl(musb->mregs, OTG_INTERFSEL); |
239 | l |= ULPI_12PIN; | 239 | l |= ULPI_12PIN; |
240 | omap_writel(l, OTG_INTERFSEL); | 240 | musb_writel(musb->mregs, OTG_INTERFSEL, l); |
241 | 241 | ||
242 | pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " | 242 | pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " |
243 | "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", | 243 | "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", |
244 | omap_readl(OTG_REVISION), omap_readl(OTG_SYSCONFIG), | 244 | musb_readl(musb->mregs, OTG_REVISION), |
245 | omap_readl(OTG_SYSSTATUS), omap_readl(OTG_INTERFSEL), | 245 | musb_readl(musb->mregs, OTG_SYSCONFIG), |
246 | omap_readl(OTG_SIMENABLE)); | 246 | musb_readl(musb->mregs, OTG_SYSSTATUS), |
247 | musb_readl(musb->mregs, OTG_INTERFSEL), | ||
248 | musb_readl(musb->mregs, OTG_SIMENABLE)); | ||
247 | 249 | ||
248 | omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1); | 250 | omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1); |
249 | 251 | ||
@@ -255,6 +257,22 @@ int __init musb_platform_init(struct musb *musb) | |||
255 | return 0; | 257 | return 0; |
256 | } | 258 | } |
257 | 259 | ||
260 | #ifdef CONFIG_PM | ||
261 | void musb_platform_save_context(struct musb *musb, | ||
262 | struct musb_context_registers *musb_context) | ||
263 | { | ||
264 | musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG); | ||
265 | musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY); | ||
266 | } | ||
267 | |||
268 | void musb_platform_restore_context(struct musb *musb, | ||
269 | struct musb_context_registers *musb_context) | ||
270 | { | ||
271 | musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig); | ||
272 | musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby); | ||
273 | } | ||
274 | #endif | ||
275 | |||
258 | int musb_platform_suspend(struct musb *musb) | 276 | int musb_platform_suspend(struct musb *musb) |
259 | { | 277 | { |
260 | u32 l; | 278 | u32 l; |
@@ -263,13 +281,13 @@ int musb_platform_suspend(struct musb *musb) | |||
263 | return 0; | 281 | return 0; |
264 | 282 | ||
265 | /* in any role */ | 283 | /* in any role */ |
266 | l = omap_readl(OTG_FORCESTDBY); | 284 | l = musb_readl(musb->mregs, OTG_FORCESTDBY); |
267 | l |= ENABLEFORCE; /* enable MSTANDBY */ | 285 | l |= ENABLEFORCE; /* enable MSTANDBY */ |
268 | omap_writel(l, OTG_FORCESTDBY); | 286 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); |
269 | 287 | ||
270 | l = omap_readl(OTG_SYSCONFIG); | 288 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); |
271 | l |= ENABLEWAKEUP; /* enable wakeup */ | 289 | l |= ENABLEWAKEUP; /* enable wakeup */ |
272 | omap_writel(l, OTG_SYSCONFIG); | 290 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); |
273 | 291 | ||
274 | otg_set_suspend(musb->xceiv, 1); | 292 | otg_set_suspend(musb->xceiv, 1); |
275 | 293 | ||
@@ -295,13 +313,13 @@ static int musb_platform_resume(struct musb *musb) | |||
295 | else | 313 | else |
296 | clk_enable(musb->clock); | 314 | clk_enable(musb->clock); |
297 | 315 | ||
298 | l = omap_readl(OTG_SYSCONFIG); | 316 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); |
299 | l &= ~ENABLEWAKEUP; /* disable wakeup */ | 317 | l &= ~ENABLEWAKEUP; /* disable wakeup */ |
300 | omap_writel(l, OTG_SYSCONFIG); | 318 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); |
301 | 319 | ||
302 | l = omap_readl(OTG_FORCESTDBY); | 320 | l = musb_readl(musb->mregs, OTG_FORCESTDBY); |
303 | l &= ~ENABLEFORCE; /* disable MSTANDBY */ | 321 | l &= ~ENABLEFORCE; /* disable MSTANDBY */ |
304 | omap_writel(l, OTG_FORCESTDBY); | 322 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); |
305 | 323 | ||
306 | return 0; | 324 | return 0; |
307 | } | 325 | } |
diff --git a/drivers/usb/musb/omap2430.h b/drivers/usb/musb/omap2430.h index fbede7798aed..40b3c02ae9f0 100644 --- a/drivers/usb/musb/omap2430.h +++ b/drivers/usb/musb/omap2430.h | |||
@@ -10,47 +10,43 @@ | |||
10 | #ifndef __MUSB_OMAP243X_H__ | 10 | #ifndef __MUSB_OMAP243X_H__ |
11 | #define __MUSB_OMAP243X_H__ | 11 | #define __MUSB_OMAP243X_H__ |
12 | 12 | ||
13 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) | ||
14 | #include <mach/hardware.h> | ||
15 | #include <plat/usb.h> | 13 | #include <plat/usb.h> |
16 | 14 | ||
17 | /* | 15 | /* |
18 | * OMAP2430-specific definitions | 16 | * OMAP2430-specific definitions |
19 | */ | 17 | */ |
20 | 18 | ||
21 | #define MENTOR_BASE_OFFSET 0 | 19 | #define OTG_REVISION 0x400 |
22 | #if defined(CONFIG_ARCH_OMAP2430) | 20 | |
23 | #define OMAP_HSOTG_BASE (OMAP243X_HS_BASE) | 21 | #define OTG_SYSCONFIG 0x404 |
24 | #elif defined(CONFIG_ARCH_OMAP3430) | ||
25 | #define OMAP_HSOTG_BASE (OMAP34XX_HSUSB_OTG_BASE) | ||
26 | #endif | ||
27 | #define OMAP_HSOTG(offset) (OMAP_HSOTG_BASE + 0x400 + (offset)) | ||
28 | #define OTG_REVISION OMAP_HSOTG(0x0) | ||
29 | #define OTG_SYSCONFIG OMAP_HSOTG(0x4) | ||
30 | # define MIDLEMODE 12 /* bit position */ | 22 | # define MIDLEMODE 12 /* bit position */ |
31 | # define FORCESTDBY (0 << MIDLEMODE) | 23 | # define FORCESTDBY (0 << MIDLEMODE) |
32 | # define NOSTDBY (1 << MIDLEMODE) | 24 | # define NOSTDBY (1 << MIDLEMODE) |
33 | # define SMARTSTDBY (2 << MIDLEMODE) | 25 | # define SMARTSTDBY (2 << MIDLEMODE) |
26 | |||
34 | # define SIDLEMODE 3 /* bit position */ | 27 | # define SIDLEMODE 3 /* bit position */ |
35 | # define FORCEIDLE (0 << SIDLEMODE) | 28 | # define FORCEIDLE (0 << SIDLEMODE) |
36 | # define NOIDLE (1 << SIDLEMODE) | 29 | # define NOIDLE (1 << SIDLEMODE) |
37 | # define SMARTIDLE (2 << SIDLEMODE) | 30 | # define SMARTIDLE (2 << SIDLEMODE) |
31 | |||
38 | # define ENABLEWAKEUP (1 << 2) | 32 | # define ENABLEWAKEUP (1 << 2) |
39 | # define SOFTRST (1 << 1) | 33 | # define SOFTRST (1 << 1) |
40 | # define AUTOIDLE (1 << 0) | 34 | # define AUTOIDLE (1 << 0) |
41 | #define OTG_SYSSTATUS OMAP_HSOTG(0x8) | 35 | |
36 | #define OTG_SYSSTATUS 0x408 | ||
42 | # define RESETDONE (1 << 0) | 37 | # define RESETDONE (1 << 0) |
43 | #define OTG_INTERFSEL OMAP_HSOTG(0xc) | 38 | |
39 | #define OTG_INTERFSEL 0x40c | ||
44 | # define EXTCP (1 << 2) | 40 | # define EXTCP (1 << 2) |
45 | # define PHYSEL 0 /* bit position */ | 41 | # define PHYSEL 0 /* bit position */ |
46 | # define UTMI_8BIT (0 << PHYSEL) | 42 | # define UTMI_8BIT (0 << PHYSEL) |
47 | # define ULPI_12PIN (1 << PHYSEL) | 43 | # define ULPI_12PIN (1 << PHYSEL) |
48 | # define ULPI_8PIN (2 << PHYSEL) | 44 | # define ULPI_8PIN (2 << PHYSEL) |
49 | #define OTG_SIMENABLE OMAP_HSOTG(0x10) | 45 | |
46 | #define OTG_SIMENABLE 0x410 | ||
50 | # define TM1 (1 << 0) | 47 | # define TM1 (1 << 0) |
51 | #define OTG_FORCESTDBY OMAP_HSOTG(0x14) | ||
52 | # define ENABLEFORCE (1 << 0) | ||
53 | 48 | ||
54 | #endif /* CONFIG_ARCH_OMAP2430 */ | 49 | #define OTG_FORCESTDBY 0x414 |
50 | # define ENABLEFORCE (1 << 0) | ||
55 | 51 | ||
56 | #endif /* __MUSB_OMAP243X_H__ */ | 52 | #endif /* __MUSB_OMAP243X_H__ */ |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 88b587c703e9..ab776a8d98ca 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -1118,7 +1118,7 @@ int __init musb_platform_init(struct musb *musb) | |||
1118 | } | 1118 | } |
1119 | musb->sync = mem->start; | 1119 | musb->sync = mem->start; |
1120 | 1120 | ||
1121 | sync = ioremap(mem->start, mem->end - mem->start + 1); | 1121 | sync = ioremap(mem->start, resource_size(mem)); |
1122 | if (!sync) { | 1122 | if (!sync) { |
1123 | pr_debug("ioremap for sync failed\n"); | 1123 | pr_debug("ioremap for sync failed\n"); |
1124 | ret = -ENOMEM; | 1124 | ret = -ENOMEM; |
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index e13c77052e5e..1c868096bd6f 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c | |||
@@ -648,7 +648,7 @@ void dma_controller_destroy(struct dma_controller *c) | |||
648 | } | 648 | } |
649 | } | 649 | } |
650 | 650 | ||
651 | if (!tusb_dma->multichannel && tusb_dma && tusb_dma->ch >= 0) | 651 | if (tusb_dma && !tusb_dma->multichannel && tusb_dma->ch >= 0) |
652 | omap_free_dma(tusb_dma->ch); | 652 | omap_free_dma(tusb_dma->ch); |
653 | 653 | ||
654 | kfree(tusb_dma); | 654 | kfree(tusb_dma); |
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 2be9f2fa41f9..3e4e9f434d78 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/i2c/twl.h> | 36 | #include <linux/i2c/twl.h> |
37 | #include <linux/regulator/consumer.h> | 37 | #include <linux/regulator/consumer.h> |
38 | #include <linux/err.h> | 38 | #include <linux/err.h> |
39 | 39 | #include <linux/notifier.h> | |
40 | 40 | ||
41 | /* Register defines */ | 41 | /* Register defines */ |
42 | 42 | ||
@@ -236,15 +236,6 @@ | |||
236 | #define PMBR1 0x0D | 236 | #define PMBR1 0x0D |
237 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) | 237 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) |
238 | 238 | ||
239 | |||
240 | |||
241 | enum linkstat { | ||
242 | USB_LINK_UNKNOWN = 0, | ||
243 | USB_LINK_NONE, | ||
244 | USB_LINK_VBUS, | ||
245 | USB_LINK_ID, | ||
246 | }; | ||
247 | |||
248 | struct twl4030_usb { | 239 | struct twl4030_usb { |
249 | struct otg_transceiver otg; | 240 | struct otg_transceiver otg; |
250 | struct device *dev; | 241 | struct device *dev; |
@@ -347,10 +338,10 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) | |||
347 | 338 | ||
348 | /*-------------------------------------------------------------------------*/ | 339 | /*-------------------------------------------------------------------------*/ |
349 | 340 | ||
350 | static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | 341 | static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) |
351 | { | 342 | { |
352 | int status; | 343 | int status; |
353 | int linkstat = USB_LINK_UNKNOWN; | 344 | int linkstat = USB_EVENT_NONE; |
354 | 345 | ||
355 | /* | 346 | /* |
356 | * For ID/VBUS sensing, see manual section 15.4.8 ... | 347 | * For ID/VBUS sensing, see manual section 15.4.8 ... |
@@ -368,11 +359,11 @@ static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
368 | dev_err(twl->dev, "USB link status err %d\n", status); | 359 | dev_err(twl->dev, "USB link status err %d\n", status); |
369 | else if (status & (BIT(7) | BIT(2))) { | 360 | else if (status & (BIT(7) | BIT(2))) { |
370 | if (status & BIT(2)) | 361 | if (status & BIT(2)) |
371 | linkstat = USB_LINK_ID; | 362 | linkstat = USB_EVENT_ID; |
372 | else | 363 | else |
373 | linkstat = USB_LINK_VBUS; | 364 | linkstat = USB_EVENT_VBUS; |
374 | } else | 365 | } else |
375 | linkstat = USB_LINK_NONE; | 366 | linkstat = USB_EVENT_NONE; |
376 | 367 | ||
377 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", | 368 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", |
378 | status, status, linkstat); | 369 | status, status, linkstat); |
@@ -383,7 +374,7 @@ static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
383 | 374 | ||
384 | spin_lock_irq(&twl->lock); | 375 | spin_lock_irq(&twl->lock); |
385 | twl->linkstat = linkstat; | 376 | twl->linkstat = linkstat; |
386 | if (linkstat == USB_LINK_ID) { | 377 | if (linkstat == USB_EVENT_ID) { |
387 | twl->otg.default_a = true; | 378 | twl->otg.default_a = true; |
388 | twl->otg.state = OTG_STATE_A_IDLE; | 379 | twl->otg.state = OTG_STATE_A_IDLE; |
389 | } else { | 380 | } else { |
@@ -564,7 +555,7 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev, | |||
564 | 555 | ||
565 | spin_lock_irqsave(&twl->lock, flags); | 556 | spin_lock_irqsave(&twl->lock, flags); |
566 | ret = sprintf(buf, "%s\n", | 557 | ret = sprintf(buf, "%s\n", |
567 | (twl->linkstat == USB_LINK_VBUS) ? "on" : "off"); | 558 | (twl->linkstat == USB_EVENT_VBUS) ? "on" : "off"); |
568 | spin_unlock_irqrestore(&twl->lock, flags); | 559 | spin_unlock_irqrestore(&twl->lock, flags); |
569 | 560 | ||
570 | return ret; | 561 | return ret; |
@@ -576,17 +567,8 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
576 | struct twl4030_usb *twl = _twl; | 567 | struct twl4030_usb *twl = _twl; |
577 | int status; | 568 | int status; |
578 | 569 | ||
579 | #ifdef CONFIG_LOCKDEP | ||
580 | /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which | ||
581 | * we don't want and can't tolerate. Although it might be | ||
582 | * friendlier not to borrow this thread context... | ||
583 | */ | ||
584 | local_irq_enable(); | ||
585 | #endif | ||
586 | |||
587 | status = twl4030_usb_linkstat(twl); | 570 | status = twl4030_usb_linkstat(twl); |
588 | if (status != USB_LINK_UNKNOWN) { | 571 | if (status >= 0) { |
589 | |||
590 | /* FIXME add a set_power() method so that B-devices can | 572 | /* FIXME add a set_power() method so that B-devices can |
591 | * configure the charger appropriately. It's not always | 573 | * configure the charger appropriately. It's not always |
592 | * correct to consume VBUS power, and how much current to | 574 | * correct to consume VBUS power, and how much current to |
@@ -598,12 +580,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
598 | * USB_LINK_VBUS state. musb_hdrc won't care until it | 580 | * USB_LINK_VBUS state. musb_hdrc won't care until it |
599 | * starts to handle softconnect right. | 581 | * starts to handle softconnect right. |
600 | */ | 582 | */ |
601 | if (status == USB_LINK_NONE) | 583 | if (status == USB_EVENT_NONE) |
602 | twl4030_phy_suspend(twl, 0); | 584 | twl4030_phy_suspend(twl, 0); |
603 | else | 585 | else |
604 | twl4030_phy_resume(twl); | 586 | twl4030_phy_resume(twl); |
605 | 587 | ||
606 | twl4030charger_usb_en(status == USB_LINK_VBUS); | 588 | blocking_notifier_call_chain(&twl->otg.notifier, status, |
589 | twl->otg.gadget); | ||
607 | } | 590 | } |
608 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 591 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
609 | 592 | ||
@@ -693,6 +676,8 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
693 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 676 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
694 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | 677 | dev_warn(&pdev->dev, "could not create sysfs file\n"); |
695 | 678 | ||
679 | BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); | ||
680 | |||
696 | /* Our job is to use irqs and status from the power module | 681 | /* Our job is to use irqs and status from the power module |
697 | * to keep the transceiver disabled when nothing's connected. | 682 | * to keep the transceiver disabled when nothing's connected. |
698 | * | 683 | * |
@@ -702,7 +687,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
702 | * need both handles, otherwise just one suffices. | 687 | * need both handles, otherwise just one suffices. |
703 | */ | 688 | */ |
704 | twl->irq_enabled = true; | 689 | twl->irq_enabled = true; |
705 | status = request_irq(twl->irq, twl4030_usb_irq, | 690 | status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, |
706 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 691 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, |
707 | "twl4030_usb", twl); | 692 | "twl4030_usb", twl); |
708 | if (status < 0) { | 693 | if (status < 0) { |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c480ea4c19f2..c78b255e3f83 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -472,6 +472,17 @@ config USB_SERIAL_OTI6858 | |||
472 | To compile this driver as a module, choose M here: the | 472 | To compile this driver as a module, choose M here: the |
473 | module will be called oti6858. | 473 | module will be called oti6858. |
474 | 474 | ||
475 | config USB_SERIAL_QCAUX | ||
476 | tristate "USB Qualcomm Auxiliary Serial Port Driver" | ||
477 | ---help--- | ||
478 | Say Y here if you want to use the auxiliary serial ports provided | ||
479 | by many modems based on Qualcomm chipsets. These ports often use | ||
480 | a proprietary protocol called DM and cannot be used for AT- or | ||
481 | PPP-based communication. | ||
482 | |||
483 | To compile this driver as a module, choose M here: the | ||
484 | module will be called moto_modem. If unsure, choose N. | ||
485 | |||
475 | config USB_SERIAL_QUALCOMM | 486 | config USB_SERIAL_QUALCOMM |
476 | tristate "USB Qualcomm Serial modem" | 487 | tristate "USB Qualcomm Serial modem" |
477 | help | 488 | help |
@@ -600,6 +611,14 @@ config USB_SERIAL_OPTICON | |||
600 | To compile this driver as a module, choose M here: the | 611 | To compile this driver as a module, choose M here: the |
601 | module will be called opticon. | 612 | module will be called opticon. |
602 | 613 | ||
614 | config USB_SERIAL_VIVOPAY_SERIAL | ||
615 | tristate "USB ViVOpay serial interface driver" | ||
616 | help | ||
617 | Say Y here if you want to use a ViVOtech ViVOpay USB device. | ||
618 | |||
619 | To compile this driver as a module, choose M here: the | ||
620 | module will be called vivopay-serial. | ||
621 | |||
603 | config USB_SERIAL_DEBUG | 622 | config USB_SERIAL_DEBUG |
604 | tristate "USB Debugging Device" | 623 | tristate "USB Debugging Device" |
605 | help | 624 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 66619beb6cc0..83c9e431a568 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -45,6 +45,7 @@ obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o | |||
45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | 45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o |
46 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o | 46 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o |
47 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 47 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
48 | obj-$(CONFIG_USB_SERIAL_QCAUX) += qcaux.o | ||
48 | obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o | 49 | obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o |
49 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o | 50 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o |
50 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o | 51 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o |
@@ -55,4 +56,5 @@ obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | |||
55 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o | 56 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o |
56 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o | 57 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o |
57 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o | 58 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o |
59 | obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o | ||
58 | 60 | ||
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index b10ac8409411..365db1097bfd 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -78,7 +78,7 @@ static int debug; | |||
78 | #define DRIVER_DESC "AIRcable USB Driver" | 78 | #define DRIVER_DESC "AIRcable USB Driver" |
79 | 79 | ||
80 | /* ID table that will be registered with USB core */ | 80 | /* ID table that will be registered with USB core */ |
81 | static struct usb_device_id id_table [] = { | 81 | static const struct usb_device_id id_table[] = { |
82 | { USB_DEVICE(AIRCABLE_VID, AIRCABLE_USB_PID) }, | 82 | { USB_DEVICE(AIRCABLE_VID, AIRCABLE_USB_PID) }, |
83 | { }, | 83 | { }, |
84 | }; | 84 | }; |
@@ -468,10 +468,6 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
468 | 468 | ||
469 | if (status) { | 469 | if (status) { |
470 | dbg("%s - urb status = %d", __func__, status); | 470 | dbg("%s - urb status = %d", __func__, status); |
471 | if (!port->port.count) { | ||
472 | dbg("%s - port is closed, exiting.", __func__); | ||
473 | return; | ||
474 | } | ||
475 | if (status == -EPROTO) { | 471 | if (status == -EPROTO) { |
476 | dbg("%s - caught -EPROTO, resubmitting the urb", | 472 | dbg("%s - caught -EPROTO, resubmitting the urb", |
477 | __func__); | 473 | __func__); |
@@ -530,23 +526,19 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
530 | } | 526 | } |
531 | tty_kref_put(tty); | 527 | tty_kref_put(tty); |
532 | 528 | ||
533 | /* Schedule the next read _if_ we are still open */ | 529 | /* Schedule the next read */ |
534 | if (port->port.count) { | 530 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
535 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 531 | usb_rcvbulkpipe(port->serial->dev, |
536 | usb_rcvbulkpipe(port->serial->dev, | 532 | port->bulk_in_endpointAddress), |
537 | port->bulk_in_endpointAddress), | 533 | port->read_urb->transfer_buffer, |
538 | port->read_urb->transfer_buffer, | 534 | port->read_urb->transfer_buffer_length, |
539 | port->read_urb->transfer_buffer_length, | 535 | aircable_read_bulk_callback, port); |
540 | aircable_read_bulk_callback, port); | 536 | |
541 | 537 | result = usb_submit_urb(urb, GFP_ATOMIC); | |
542 | result = usb_submit_urb(urb, GFP_ATOMIC); | 538 | if (result && result != -EPERM) |
543 | if (result) | 539 | dev_err(&urb->dev->dev, |
544 | dev_err(&urb->dev->dev, | 540 | "%s - failed resubmitting read urb, error %d\n", |
545 | "%s - failed resubmitting read urb, error %d\n", | 541 | __func__, result); |
546 | __func__, result); | ||
547 | } | ||
548 | |||
549 | return; | ||
550 | } | 542 | } |
551 | 543 | ||
552 | /* Based on ftdi_sio.c throttle */ | 544 | /* Based on ftdi_sio.c throttle */ |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index a9c2dec8e3fb..547c9448c28c 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -50,7 +50,7 @@ static int debug; | |||
50 | /* usb timeout of 1 second */ | 50 | /* usb timeout of 1 second */ |
51 | #define ARK_TIMEOUT (1*HZ) | 51 | #define ARK_TIMEOUT (1*HZ) |
52 | 52 | ||
53 | static struct usb_device_id id_table [] = { | 53 | static const struct usb_device_id id_table[] = { |
54 | { USB_DEVICE(0x6547, 0x0232) }, | 54 | { USB_DEVICE(0x6547, 0x0232) }, |
55 | { USB_DEVICE(0x18ec, 0x3118) }, /* USB to IrDA adapter */ | 55 | { USB_DEVICE(0x18ec, 0x3118) }, /* USB to IrDA adapter */ |
56 | { }, | 56 | { }, |
@@ -733,7 +733,6 @@ static void ark3116_read_bulk_callback(struct urb *urb) | |||
733 | 733 | ||
734 | tty = tty_port_tty_get(&port->port); | 734 | tty = tty_port_tty_get(&port->port); |
735 | if (tty) { | 735 | if (tty) { |
736 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
737 | /* overrun is special, not associated with a char */ | 736 | /* overrun is special, not associated with a char */ |
738 | if (unlikely(lsr & UART_LSR_OE)) | 737 | if (unlikely(lsr & UART_LSR_OE)) |
739 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 738 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index a0467bc61627..1295e44e3f1c 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -103,7 +103,7 @@ static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, | |||
103 | unsigned int set, unsigned int clear); | 103 | unsigned int set, unsigned int clear); |
104 | 104 | ||
105 | 105 | ||
106 | static struct usb_device_id id_table_combined [] = { | 106 | static const struct usb_device_id id_table_combined[] = { |
107 | { USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) }, | 107 | { USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) }, |
108 | { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) }, | 108 | { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) }, |
109 | { USB_DEVICE(PERACOM_VID, PERACOM_PID) }, | 109 | { USB_DEVICE(PERACOM_VID, PERACOM_PID) }, |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 59eff721fcc5..9f4fed1968b5 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
23 | #include <linux/usb/serial.h> | 23 | #include <linux/usb/serial.h> |
24 | #include <linux/serial.h> | 24 | #include <linux/serial.h> |
25 | #include <asm/unaligned.h> | ||
25 | 26 | ||
26 | #define DEFAULT_BAUD_RATE 9600 | 27 | #define DEFAULT_BAUD_RATE 9600 |
27 | #define DEFAULT_TIMEOUT 1000 | 28 | #define DEFAULT_TIMEOUT 1000 |
@@ -70,7 +71,7 @@ | |||
70 | 71 | ||
71 | static int debug; | 72 | static int debug; |
72 | 73 | ||
73 | static struct usb_device_id id_table [] = { | 74 | static const struct usb_device_id id_table[] = { |
74 | { USB_DEVICE(0x4348, 0x5523) }, | 75 | { USB_DEVICE(0x4348, 0x5523) }, |
75 | { USB_DEVICE(0x1a86, 0x7523) }, | 76 | { USB_DEVICE(0x1a86, 0x7523) }, |
76 | { }, | 77 | { }, |
@@ -392,16 +393,22 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state) | |||
392 | struct usb_serial_port *port = tty->driver_data; | 393 | struct usb_serial_port *port = tty->driver_data; |
393 | int r; | 394 | int r; |
394 | uint16_t reg_contents; | 395 | uint16_t reg_contents; |
395 | uint8_t break_reg[2]; | 396 | uint8_t *break_reg; |
396 | 397 | ||
397 | dbg("%s()", __func__); | 398 | dbg("%s()", __func__); |
398 | 399 | ||
400 | break_reg = kmalloc(2, GFP_KERNEL); | ||
401 | if (!break_reg) { | ||
402 | dev_err(&port->dev, "%s - kmalloc failed\n", __func__); | ||
403 | return; | ||
404 | } | ||
405 | |||
399 | r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG, | 406 | r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG, |
400 | ch341_break_reg, 0, break_reg, sizeof(break_reg)); | 407 | ch341_break_reg, 0, break_reg, 2); |
401 | if (r < 0) { | 408 | if (r < 0) { |
402 | printk(KERN_WARNING "%s: USB control read error whilst getting" | 409 | dev_err(&port->dev, "%s - USB control read error (%d)\n", |
403 | " break register contents.\n", __FILE__); | 410 | __func__, r); |
404 | return; | 411 | goto out; |
405 | } | 412 | } |
406 | dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x", | 413 | dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x", |
407 | __func__, break_reg[0], break_reg[1]); | 414 | __func__, break_reg[0], break_reg[1]); |
@@ -416,12 +423,14 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state) | |||
416 | } | 423 | } |
417 | dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x", | 424 | dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x", |
418 | __func__, break_reg[0], break_reg[1]); | 425 | __func__, break_reg[0], break_reg[1]); |
419 | reg_contents = (uint16_t)break_reg[0] | ((uint16_t)break_reg[1] << 8); | 426 | reg_contents = get_unaligned_le16(break_reg); |
420 | r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG, | 427 | r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG, |
421 | ch341_break_reg, reg_contents); | 428 | ch341_break_reg, reg_contents); |
422 | if (r < 0) | 429 | if (r < 0) |
423 | printk(KERN_WARNING "%s: USB control write error whilst setting" | 430 | dev_err(&port->dev, "%s - USB control write error (%d)\n", |
424 | " break register contents.\n", __FILE__); | 431 | __func__, r); |
432 | out: | ||
433 | kfree(break_reg); | ||
425 | } | 434 | } |
426 | 435 | ||
427 | static int ch341_tiocmset(struct tty_struct *tty, struct file *file, | 436 | static int ch341_tiocmset(struct tty_struct *tty, struct file *file, |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index bd254ec97d14..507382b0a9ed 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -55,7 +55,7 @@ static int cp210x_carrier_raised(struct usb_serial_port *p); | |||
55 | 55 | ||
56 | static int debug; | 56 | static int debug; |
57 | 57 | ||
58 | static struct usb_device_id id_table [] = { | 58 | static const struct usb_device_id id_table[] = { |
59 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ | 59 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ |
60 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ | 60 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ |
61 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ | 61 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ |
@@ -91,11 +91,12 @@ static struct usb_device_id id_table [] = { | |||
91 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | 91 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ |
92 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ | 92 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ |
93 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ | 93 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ |
94 | { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */ | ||
94 | { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ | 95 | { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ |
95 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | 96 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ |
96 | { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ | 97 | { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ |
97 | { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ | 98 | { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ |
98 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | 99 | { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */ |
99 | { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ | 100 | { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ |
100 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | 101 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
101 | { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ | 102 | { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ |
@@ -612,7 +613,7 @@ static void cp210x_set_termios(struct tty_struct *tty, | |||
612 | baud); | 613 | baud); |
613 | if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, | 614 | if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, |
614 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { | 615 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { |
615 | dbg("Baud rate requested not supported by device\n"); | 616 | dbg("Baud rate requested not supported by device"); |
616 | baud = tty_termios_baud_rate(old_termios); | 617 | baud = tty_termios_baud_rate(old_termios); |
617 | } | 618 | } |
618 | } | 619 | } |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index b0f6402a91ca..f744ab7a3b19 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -70,7 +70,7 @@ static void cyberjack_read_int_callback(struct urb *urb); | |||
70 | static void cyberjack_read_bulk_callback(struct urb *urb); | 70 | static void cyberjack_read_bulk_callback(struct urb *urb); |
71 | static void cyberjack_write_bulk_callback(struct urb *urb); | 71 | static void cyberjack_write_bulk_callback(struct urb *urb); |
72 | 72 | ||
73 | static struct usb_device_id id_table [] = { | 73 | static const struct usb_device_id id_table[] = { |
74 | { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) }, | 74 | { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) }, |
75 | { } /* Terminating entry */ | 75 | { } /* Terminating entry */ |
76 | }; | 76 | }; |
@@ -391,11 +391,10 @@ static void cyberjack_read_bulk_callback(struct urb *urb) | |||
391 | 391 | ||
392 | tty = tty_port_tty_get(&port->port); | 392 | tty = tty_port_tty_get(&port->port); |
393 | if (!tty) { | 393 | if (!tty) { |
394 | dbg("%s - ignoring since device not open\n", __func__); | 394 | dbg("%s - ignoring since device not open", __func__); |
395 | return; | 395 | return; |
396 | } | 396 | } |
397 | if (urb->actual_length) { | 397 | if (urb->actual_length) { |
398 | tty_buffer_request_room(tty, urb->actual_length); | ||
399 | tty_insert_flip_string(tty, data, urb->actual_length); | 398 | tty_insert_flip_string(tty, data, urb->actual_length); |
400 | tty_flip_buffer_push(tty); | 399 | tty_flip_buffer_push(tty); |
401 | } | 400 | } |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index a591ebec0f89..baf74b44e6ed 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -66,17 +66,15 @@ | |||
66 | #include <linux/serial.h> | 66 | #include <linux/serial.h> |
67 | #include <linux/delay.h> | 67 | #include <linux/delay.h> |
68 | #include <linux/uaccess.h> | 68 | #include <linux/uaccess.h> |
69 | #include <asm/unaligned.h> | ||
69 | 70 | ||
70 | #include "cypress_m8.h" | 71 | #include "cypress_m8.h" |
71 | 72 | ||
72 | 73 | ||
73 | #ifdef CONFIG_USB_SERIAL_DEBUG | 74 | static int debug; |
74 | static int debug = 1; | ||
75 | #else | ||
76 | static int debug; | ||
77 | #endif | ||
78 | static int stats; | 75 | static int stats; |
79 | static int interval; | 76 | static int interval; |
77 | static int unstable_bauds; | ||
80 | 78 | ||
81 | /* | 79 | /* |
82 | * Version Information | 80 | * Version Information |
@@ -89,24 +87,24 @@ static int interval; | |||
89 | #define CYPRESS_BUF_SIZE 1024 | 87 | #define CYPRESS_BUF_SIZE 1024 |
90 | #define CYPRESS_CLOSING_WAIT (30*HZ) | 88 | #define CYPRESS_CLOSING_WAIT (30*HZ) |
91 | 89 | ||
92 | static struct usb_device_id id_table_earthmate [] = { | 90 | static const struct usb_device_id id_table_earthmate[] = { |
93 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, | 91 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, |
94 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, | 92 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, |
95 | { } /* Terminating entry */ | 93 | { } /* Terminating entry */ |
96 | }; | 94 | }; |
97 | 95 | ||
98 | static struct usb_device_id id_table_cyphidcomrs232 [] = { | 96 | static const struct usb_device_id id_table_cyphidcomrs232[] = { |
99 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, | 97 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, |
100 | { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, | 98 | { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, |
101 | { } /* Terminating entry */ | 99 | { } /* Terminating entry */ |
102 | }; | 100 | }; |
103 | 101 | ||
104 | static struct usb_device_id id_table_nokiaca42v2 [] = { | 102 | static const struct usb_device_id id_table_nokiaca42v2[] = { |
105 | { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, | 103 | { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, |
106 | { } /* Terminating entry */ | 104 | { } /* Terminating entry */ |
107 | }; | 105 | }; |
108 | 106 | ||
109 | static struct usb_device_id id_table_combined [] = { | 107 | static const struct usb_device_id id_table_combined[] = { |
110 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, | 108 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, |
111 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, | 109 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, |
112 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, | 110 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, |
@@ -295,6 +293,9 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) | |||
295 | struct cypress_private *priv; | 293 | struct cypress_private *priv; |
296 | priv = usb_get_serial_port_data(port); | 294 | priv = usb_get_serial_port_data(port); |
297 | 295 | ||
296 | if (unstable_bauds) | ||
297 | return new_rate; | ||
298 | |||
298 | /* | 299 | /* |
299 | * The general purpose firmware for the Cypress M8 allows for | 300 | * The general purpose firmware for the Cypress M8 allows for |
300 | * a maximum speed of 57600bps (I have no idea whether DeLorme | 301 | * a maximum speed of 57600bps (I have no idea whether DeLorme |
@@ -344,7 +345,8 @@ static int cypress_serial_control(struct tty_struct *tty, | |||
344 | { | 345 | { |
345 | int new_baudrate = 0, retval = 0, tries = 0; | 346 | int new_baudrate = 0, retval = 0, tries = 0; |
346 | struct cypress_private *priv; | 347 | struct cypress_private *priv; |
347 | __u8 feature_buffer[5]; | 348 | u8 *feature_buffer; |
349 | const unsigned int feature_len = 5; | ||
348 | unsigned long flags; | 350 | unsigned long flags; |
349 | 351 | ||
350 | dbg("%s", __func__); | 352 | dbg("%s", __func__); |
@@ -354,17 +356,18 @@ static int cypress_serial_control(struct tty_struct *tty, | |||
354 | if (!priv->comm_is_ok) | 356 | if (!priv->comm_is_ok) |
355 | return -ENODEV; | 357 | return -ENODEV; |
356 | 358 | ||
359 | feature_buffer = kcalloc(feature_len, sizeof(u8), GFP_KERNEL); | ||
360 | if (!feature_buffer) | ||
361 | return -ENOMEM; | ||
362 | |||
357 | switch (cypress_request_type) { | 363 | switch (cypress_request_type) { |
358 | case CYPRESS_SET_CONFIG: | 364 | case CYPRESS_SET_CONFIG: |
359 | new_baudrate = priv->baud_rate; | ||
360 | /* 0 means 'Hang up' so doesn't change the true bit rate */ | 365 | /* 0 means 'Hang up' so doesn't change the true bit rate */ |
361 | if (baud_rate == 0) | 366 | new_baudrate = priv->baud_rate; |
362 | new_baudrate = priv->baud_rate; | 367 | if (baud_rate && baud_rate != priv->baud_rate) { |
363 | /* Change of speed ? */ | ||
364 | else if (baud_rate != priv->baud_rate) { | ||
365 | dbg("%s - baud rate is changing", __func__); | 368 | dbg("%s - baud rate is changing", __func__); |
366 | retval = analyze_baud_rate(port, baud_rate); | 369 | retval = analyze_baud_rate(port, baud_rate); |
367 | if (retval >= 0) { | 370 | if (retval >= 0) { |
368 | new_baudrate = retval; | 371 | new_baudrate = retval; |
369 | dbg("%s - New baud rate set to %d", | 372 | dbg("%s - New baud rate set to %d", |
370 | __func__, new_baudrate); | 373 | __func__, new_baudrate); |
@@ -373,9 +376,8 @@ static int cypress_serial_control(struct tty_struct *tty, | |||
373 | dbg("%s - baud rate is being sent as %d", | 376 | dbg("%s - baud rate is being sent as %d", |
374 | __func__, new_baudrate); | 377 | __func__, new_baudrate); |
375 | 378 | ||
376 | memset(feature_buffer, 0, sizeof(feature_buffer)); | ||
377 | /* fill the feature_buffer with new configuration */ | 379 | /* fill the feature_buffer with new configuration */ |
378 | *((u_int32_t *)feature_buffer) = new_baudrate; | 380 | put_unaligned_le32(new_baudrate, feature_buffer); |
379 | feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ | 381 | feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ |
380 | /* 1 bit gap */ | 382 | /* 1 bit gap */ |
381 | feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */ | 383 | feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */ |
@@ -397,15 +399,15 @@ static int cypress_serial_control(struct tty_struct *tty, | |||
397 | HID_REQ_SET_REPORT, | 399 | HID_REQ_SET_REPORT, |
398 | USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, | 400 | USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, |
399 | 0x0300, 0, feature_buffer, | 401 | 0x0300, 0, feature_buffer, |
400 | sizeof(feature_buffer), 500); | 402 | feature_len, 500); |
401 | 403 | ||
402 | if (tries++ >= 3) | 404 | if (tries++ >= 3) |
403 | break; | 405 | break; |
404 | 406 | ||
405 | } while (retval != sizeof(feature_buffer) && | 407 | } while (retval != feature_len && |
406 | retval != -ENODEV); | 408 | retval != -ENODEV); |
407 | 409 | ||
408 | if (retval != sizeof(feature_buffer)) { | 410 | if (retval != feature_len) { |
409 | dev_err(&port->dev, "%s - failed sending serial " | 411 | dev_err(&port->dev, "%s - failed sending serial " |
410 | "line settings - %d\n", __func__, retval); | 412 | "line settings - %d\n", __func__, retval); |
411 | cypress_set_dead(port); | 413 | cypress_set_dead(port); |
@@ -425,43 +427,42 @@ static int cypress_serial_control(struct tty_struct *tty, | |||
425 | /* Not implemented for this device, | 427 | /* Not implemented for this device, |
426 | and if we try to do it we're likely | 428 | and if we try to do it we're likely |
427 | to crash the hardware. */ | 429 | to crash the hardware. */ |
428 | return -ENOTTY; | 430 | retval = -ENOTTY; |
431 | goto out; | ||
429 | } | 432 | } |
430 | dbg("%s - retreiving serial line settings", __func__); | 433 | dbg("%s - retreiving serial line settings", __func__); |
431 | /* set initial values in feature buffer */ | ||
432 | memset(feature_buffer, 0, sizeof(feature_buffer)); | ||
433 | |||
434 | do { | 434 | do { |
435 | retval = usb_control_msg(port->serial->dev, | 435 | retval = usb_control_msg(port->serial->dev, |
436 | usb_rcvctrlpipe(port->serial->dev, 0), | 436 | usb_rcvctrlpipe(port->serial->dev, 0), |
437 | HID_REQ_GET_REPORT, | 437 | HID_REQ_GET_REPORT, |
438 | USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, | 438 | USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, |
439 | 0x0300, 0, feature_buffer, | 439 | 0x0300, 0, feature_buffer, |
440 | sizeof(feature_buffer), 500); | 440 | feature_len, 500); |
441 | 441 | ||
442 | if (tries++ >= 3) | 442 | if (tries++ >= 3) |
443 | break; | 443 | break; |
444 | } while (retval != sizeof(feature_buffer) | 444 | } while (retval != feature_len |
445 | && retval != -ENODEV); | 445 | && retval != -ENODEV); |
446 | 446 | ||
447 | if (retval != sizeof(feature_buffer)) { | 447 | if (retval != feature_len) { |
448 | dev_err(&port->dev, "%s - failed to retrieve serial " | 448 | dev_err(&port->dev, "%s - failed to retrieve serial " |
449 | "line settings - %d\n", __func__, retval); | 449 | "line settings - %d\n", __func__, retval); |
450 | cypress_set_dead(port); | 450 | cypress_set_dead(port); |
451 | return retval; | 451 | goto out; |
452 | } else { | 452 | } else { |
453 | spin_lock_irqsave(&priv->lock, flags); | 453 | spin_lock_irqsave(&priv->lock, flags); |
454 | /* store the config in one byte, and later | 454 | /* store the config in one byte, and later |
455 | use bit masks to check values */ | 455 | use bit masks to check values */ |
456 | priv->current_config = feature_buffer[4]; | 456 | priv->current_config = feature_buffer[4]; |
457 | priv->baud_rate = *((u_int32_t *)feature_buffer); | 457 | priv->baud_rate = get_unaligned_le32(feature_buffer); |
458 | spin_unlock_irqrestore(&priv->lock, flags); | 458 | spin_unlock_irqrestore(&priv->lock, flags); |
459 | } | 459 | } |
460 | } | 460 | } |
461 | spin_lock_irqsave(&priv->lock, flags); | 461 | spin_lock_irqsave(&priv->lock, flags); |
462 | ++priv->cmd_count; | 462 | ++priv->cmd_count; |
463 | spin_unlock_irqrestore(&priv->lock, flags); | 463 | spin_unlock_irqrestore(&priv->lock, flags); |
464 | 464 | out: | |
465 | kfree(feature_buffer); | ||
465 | return retval; | 466 | return retval; |
466 | } /* cypress_serial_control */ | 467 | } /* cypress_serial_control */ |
467 | 468 | ||
@@ -690,7 +691,6 @@ static void cypress_dtr_rts(struct usb_serial_port *port, int on) | |||
690 | { | 691 | { |
691 | struct cypress_private *priv = usb_get_serial_port_data(port); | 692 | struct cypress_private *priv = usb_get_serial_port_data(port); |
692 | /* drop dtr and rts */ | 693 | /* drop dtr and rts */ |
693 | priv = usb_get_serial_port_data(port); | ||
694 | spin_lock_irq(&priv->lock); | 694 | spin_lock_irq(&priv->lock); |
695 | if (on == 0) | 695 | if (on == 0) |
696 | priv->line_control = 0; | 696 | priv->line_control = 0; |
@@ -1307,13 +1307,9 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1307 | spin_unlock_irqrestore(&priv->lock, flags); | 1307 | spin_unlock_irqrestore(&priv->lock, flags); |
1308 | 1308 | ||
1309 | /* process read if there is data other than line status */ | 1309 | /* process read if there is data other than line status */ |
1310 | if (tty && (bytes > i)) { | 1310 | if (tty && bytes > i) { |
1311 | bytes = tty_buffer_request_room(tty, bytes); | 1311 | tty_insert_flip_string_fixed_flag(tty, data + i, |
1312 | for (; i < bytes ; ++i) { | 1312 | bytes - i, tty_flag); |
1313 | dbg("pushing byte number %d - %d - %c", i, data[i], | ||
1314 | data[i]); | ||
1315 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1316 | } | ||
1317 | tty_flip_buffer_push(tty); | 1313 | tty_flip_buffer_push(tty); |
1318 | } | 1314 | } |
1319 | 1315 | ||
@@ -1325,9 +1321,9 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1325 | continue_read: | 1321 | continue_read: |
1326 | tty_kref_put(tty); | 1322 | tty_kref_put(tty); |
1327 | 1323 | ||
1328 | /* Continue trying to always read... unless the port has closed. */ | 1324 | /* Continue trying to always read */ |
1329 | 1325 | ||
1330 | if (port->port.count > 0 && priv->comm_is_ok) { | 1326 | if (priv->comm_is_ok) { |
1331 | usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, | 1327 | usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, |
1332 | usb_rcvintpipe(port->serial->dev, | 1328 | usb_rcvintpipe(port->serial->dev, |
1333 | port->interrupt_in_endpointAddress), | 1329 | port->interrupt_in_endpointAddress), |
@@ -1336,7 +1332,7 @@ continue_read: | |||
1336 | cypress_read_int_callback, port, | 1332 | cypress_read_int_callback, port, |
1337 | priv->read_urb_interval); | 1333 | priv->read_urb_interval); |
1338 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1334 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
1339 | if (result) { | 1335 | if (result && result != -EPERM) { |
1340 | dev_err(&urb->dev->dev, "%s - failed resubmitting " | 1336 | dev_err(&urb->dev->dev, "%s - failed resubmitting " |
1341 | "read urb, error %d\n", __func__, | 1337 | "read urb, error %d\n", __func__, |
1342 | result); | 1338 | result); |
@@ -1650,3 +1646,5 @@ module_param(stats, bool, S_IRUGO | S_IWUSR); | |||
1650 | MODULE_PARM_DESC(stats, "Enable statistics or not"); | 1646 | MODULE_PARM_DESC(stats, "Enable statistics or not"); |
1651 | module_param(interval, int, S_IRUGO | S_IWUSR); | 1647 | module_param(interval, int, S_IRUGO | S_IWUSR); |
1652 | MODULE_PARM_DESC(interval, "Overrides interrupt interval"); | 1648 | MODULE_PARM_DESC(interval, "Overrides interrupt interval"); |
1649 | module_param(unstable_bauds, bool, S_IRUGO | S_IWUSR); | ||
1650 | MODULE_PARM_DESC(unstable_bauds, "Allow unstable baud rates"); | ||
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 68e80be6b9e1..68b0aa5e516c 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -470,18 +470,18 @@ static int digi_read_oob_callback(struct urb *urb); | |||
470 | 470 | ||
471 | static int debug; | 471 | static int debug; |
472 | 472 | ||
473 | static struct usb_device_id id_table_combined [] = { | 473 | static const struct usb_device_id id_table_combined[] = { |
474 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) }, | 474 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) }, |
475 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) }, | 475 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) }, |
476 | { } /* Terminating entry */ | 476 | { } /* Terminating entry */ |
477 | }; | 477 | }; |
478 | 478 | ||
479 | static struct usb_device_id id_table_2 [] = { | 479 | static const struct usb_device_id id_table_2[] = { |
480 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) }, | 480 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) }, |
481 | { } /* Terminating entry */ | 481 | { } /* Terminating entry */ |
482 | }; | 482 | }; |
483 | 483 | ||
484 | static struct usb_device_id id_table_4 [] = { | 484 | static const struct usb_device_id id_table_4[] = { |
485 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) }, | 485 | { USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) }, |
486 | { } /* Terminating entry */ | 486 | { } /* Terminating entry */ |
487 | }; | 487 | }; |
@@ -1262,10 +1262,10 @@ static void digi_write_bulk_callback(struct urb *urb) | |||
1262 | return; | 1262 | return; |
1263 | } | 1263 | } |
1264 | 1264 | ||
1265 | /* try to send any buffered data on this port, if it is open */ | 1265 | /* try to send any buffered data on this port */ |
1266 | spin_lock(&priv->dp_port_lock); | 1266 | spin_lock(&priv->dp_port_lock); |
1267 | priv->dp_write_urb_in_use = 0; | 1267 | priv->dp_write_urb_in_use = 0; |
1268 | if (port->port.count && priv->dp_out_buf_len > 0) { | 1268 | if (priv->dp_out_buf_len > 0) { |
1269 | *((unsigned char *)(port->write_urb->transfer_buffer)) | 1269 | *((unsigned char *)(port->write_urb->transfer_buffer)) |
1270 | = (unsigned char)DIGI_CMD_SEND_DATA; | 1270 | = (unsigned char)DIGI_CMD_SEND_DATA; |
1271 | *((unsigned char *)(port->write_urb->transfer_buffer) + 1) | 1271 | *((unsigned char *)(port->write_urb->transfer_buffer) + 1) |
@@ -1288,7 +1288,7 @@ static void digi_write_bulk_callback(struct urb *urb) | |||
1288 | schedule_work(&priv->dp_wakeup_work); | 1288 | schedule_work(&priv->dp_wakeup_work); |
1289 | 1289 | ||
1290 | spin_unlock(&priv->dp_port_lock); | 1290 | spin_unlock(&priv->dp_port_lock); |
1291 | if (ret) | 1291 | if (ret && ret != -EPERM) |
1292 | dev_err(&port->dev, | 1292 | dev_err(&port->dev, |
1293 | "%s: usb_submit_urb failed, ret=%d, port=%d\n", | 1293 | "%s: usb_submit_urb failed, ret=%d, port=%d\n", |
1294 | __func__, ret, priv->dp_port_num); | 1294 | __func__, ret, priv->dp_port_num); |
@@ -1353,8 +1353,7 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1353 | struct digi_port *priv = usb_get_serial_port_data(port); | 1353 | struct digi_port *priv = usb_get_serial_port_data(port); |
1354 | struct ktermios not_termios; | 1354 | struct ktermios not_termios; |
1355 | 1355 | ||
1356 | dbg("digi_open: TOP: port=%d, open_count=%d", | 1356 | dbg("digi_open: TOP: port=%d", priv->dp_port_num); |
1357 | priv->dp_port_num, port->port.count); | ||
1358 | 1357 | ||
1359 | /* be sure the device is started up */ | 1358 | /* be sure the device is started up */ |
1360 | if (digi_startup_device(port->serial) != 0) | 1359 | if (digi_startup_device(port->serial) != 0) |
@@ -1393,8 +1392,7 @@ static void digi_close(struct usb_serial_port *port) | |||
1393 | unsigned char buf[32]; | 1392 | unsigned char buf[32]; |
1394 | struct digi_port *priv = usb_get_serial_port_data(port); | 1393 | struct digi_port *priv = usb_get_serial_port_data(port); |
1395 | 1394 | ||
1396 | dbg("digi_close: TOP: port=%d, open_count=%d", | 1395 | dbg("digi_close: TOP: port=%d", priv->dp_port_num); |
1397 | priv->dp_port_num, port->port.count); | ||
1398 | 1396 | ||
1399 | mutex_lock(&port->serial->disc_mutex); | 1397 | mutex_lock(&port->serial->disc_mutex); |
1400 | /* if disconnected, just clear flags */ | 1398 | /* if disconnected, just clear flags */ |
@@ -1629,7 +1627,7 @@ static void digi_read_bulk_callback(struct urb *urb) | |||
1629 | /* continue read */ | 1627 | /* continue read */ |
1630 | urb->dev = port->serial->dev; | 1628 | urb->dev = port->serial->dev; |
1631 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 1629 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
1632 | if (ret != 0) { | 1630 | if (ret != 0 && ret != -EPERM) { |
1633 | dev_err(&port->dev, | 1631 | dev_err(&port->dev, |
1634 | "%s: failed resubmitting urb, ret=%d, port=%d\n", | 1632 | "%s: failed resubmitting urb, ret=%d, port=%d\n", |
1635 | __func__, ret, priv->dp_port_num); | 1633 | __func__, ret, priv->dp_port_num); |
@@ -1658,12 +1656,11 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1658 | int port_status = ((unsigned char *)urb->transfer_buffer)[2]; | 1656 | int port_status = ((unsigned char *)urb->transfer_buffer)[2]; |
1659 | unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3; | 1657 | unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3; |
1660 | int flag, throttled; | 1658 | int flag, throttled; |
1661 | int i; | ||
1662 | int status = urb->status; | 1659 | int status = urb->status; |
1663 | 1660 | ||
1664 | /* do not process callbacks on closed ports */ | 1661 | /* do not process callbacks on closed ports */ |
1665 | /* but do continue the read chain */ | 1662 | /* but do continue the read chain */ |
1666 | if (port->port.count == 0) | 1663 | if (urb->status == -ENOENT) |
1667 | return 0; | 1664 | return 0; |
1668 | 1665 | ||
1669 | /* short/multiple packet check */ | 1666 | /* short/multiple packet check */ |
@@ -1705,17 +1702,9 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1705 | 1702 | ||
1706 | /* data length is len-1 (one byte of len is port_status) */ | 1703 | /* data length is len-1 (one byte of len is port_status) */ |
1707 | --len; | 1704 | --len; |
1708 | |||
1709 | len = tty_buffer_request_room(tty, len); | ||
1710 | if (len > 0) { | 1705 | if (len > 0) { |
1711 | /* Hot path */ | 1706 | tty_insert_flip_string_fixed_flag(tty, data, len, |
1712 | if (flag == TTY_NORMAL) | 1707 | flag); |
1713 | tty_insert_flip_string(tty, data, len); | ||
1714 | else { | ||
1715 | for (i = 0; i < len; i++) | ||
1716 | tty_insert_flip_char(tty, | ||
1717 | data[i], flag); | ||
1718 | } | ||
1719 | tty_flip_buffer_push(tty); | 1708 | tty_flip_buffer_push(tty); |
1720 | } | 1709 | } |
1721 | } | 1710 | } |
@@ -1776,8 +1765,7 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1776 | 1765 | ||
1777 | tty = tty_port_tty_get(&port->port); | 1766 | tty = tty_port_tty_get(&port->port); |
1778 | rts = 0; | 1767 | rts = 0; |
1779 | if (port->port.count) | 1768 | rts = tty->termios->c_cflag & CRTSCTS; |
1780 | rts = tty->termios->c_cflag & CRTSCTS; | ||
1781 | 1769 | ||
1782 | if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { | 1770 | if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { |
1783 | spin_lock(&priv->dp_port_lock); | 1771 | spin_lock(&priv->dp_port_lock); |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 7dd0e3eadbe6..5f740a1eacab 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -93,7 +93,7 @@ static void empeg_init_termios(struct tty_struct *tty); | |||
93 | static void empeg_write_bulk_callback(struct urb *urb); | 93 | static void empeg_write_bulk_callback(struct urb *urb); |
94 | static void empeg_read_bulk_callback(struct urb *urb); | 94 | static void empeg_read_bulk_callback(struct urb *urb); |
95 | 95 | ||
96 | static struct usb_device_id id_table [] = { | 96 | static const struct usb_device_id id_table[] = { |
97 | { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, | 97 | { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, |
98 | { } /* Terminating entry */ | 98 | { } /* Terminating entry */ |
99 | }; | 99 | }; |
@@ -346,7 +346,6 @@ static void empeg_read_bulk_callback(struct urb *urb) | |||
346 | tty = tty_port_tty_get(&port->port); | 346 | tty = tty_port_tty_get(&port->port); |
347 | 347 | ||
348 | if (urb->actual_length) { | 348 | if (urb->actual_length) { |
349 | tty_buffer_request_room(tty, urb->actual_length); | ||
350 | tty_insert_flip_string(tty, data, urb->actual_length); | 349 | tty_insert_flip_string(tty, data, urb->actual_length); |
351 | tty_flip_buffer_push(tty); | 350 | tty_flip_buffer_push(tty); |
352 | bytes_in += urb->actual_length; | 351 | bytes_in += urb->actual_length; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 7638828e7317..6af0dfa5f5ac 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -33,12 +33,12 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/smp_lock.h> | ||
37 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
38 | #include <linux/tty_driver.h> | 37 | #include <linux/tty_driver.h> |
39 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
40 | #include <linux/module.h> | 39 | #include <linux/module.h> |
41 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/mutex.h> | ||
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
43 | #include <linux/usb.h> | 43 | #include <linux/usb.h> |
44 | #include <linux/serial.h> | 44 | #include <linux/serial.h> |
@@ -88,10 +88,10 @@ struct ftdi_private { | |||
88 | 88 | ||
89 | unsigned int latency; /* latency setting in use */ | 89 | unsigned int latency; /* latency setting in use */ |
90 | spinlock_t tx_lock; /* spinlock for transmit state */ | 90 | spinlock_t tx_lock; /* spinlock for transmit state */ |
91 | unsigned long tx_bytes; | ||
92 | unsigned long tx_outstanding_bytes; | 91 | unsigned long tx_outstanding_bytes; |
93 | unsigned long tx_outstanding_urbs; | 92 | unsigned long tx_outstanding_urbs; |
94 | unsigned short max_packet_size; | 93 | unsigned short max_packet_size; |
94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */ | ||
95 | }; | 95 | }; |
96 | 96 | ||
97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -614,6 +614,7 @@ static struct usb_device_id id_table_combined [] = { | |||
614 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, | 614 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, |
615 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, | 615 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, |
616 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, | 616 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, |
617 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | ||
617 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, | 618 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, |
618 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 619 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
619 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, | 620 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, |
@@ -737,6 +738,10 @@ static struct usb_device_id id_table_combined [] = { | |||
737 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 738 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
738 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, | 739 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, |
739 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, | 740 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, |
741 | { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, | ||
742 | { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, | ||
743 | { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, | ||
744 | { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, | ||
740 | { }, /* Optional parameter entry */ | 745 | { }, /* Optional parameter entry */ |
741 | { } /* Terminating entry */ | 746 | { } /* Terminating entry */ |
742 | }; | 747 | }; |
@@ -812,7 +817,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
812 | .name = "ftdi_sio", | 817 | .name = "ftdi_sio", |
813 | }, | 818 | }, |
814 | .description = "FTDI USB Serial Device", | 819 | .description = "FTDI USB Serial Device", |
815 | .usb_driver = &ftdi_driver , | 820 | .usb_driver = &ftdi_driver, |
816 | .id_table = id_table_combined, | 821 | .id_table = id_table_combined, |
817 | .num_ports = 1, | 822 | .num_ports = 1, |
818 | .probe = ftdi_sio_probe, | 823 | .probe = ftdi_sio_probe, |
@@ -828,8 +833,8 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
828 | .chars_in_buffer = ftdi_chars_in_buffer, | 833 | .chars_in_buffer = ftdi_chars_in_buffer, |
829 | .read_bulk_callback = ftdi_read_bulk_callback, | 834 | .read_bulk_callback = ftdi_read_bulk_callback, |
830 | .write_bulk_callback = ftdi_write_bulk_callback, | 835 | .write_bulk_callback = ftdi_write_bulk_callback, |
831 | .tiocmget = ftdi_tiocmget, | 836 | .tiocmget = ftdi_tiocmget, |
832 | .tiocmset = ftdi_tiocmset, | 837 | .tiocmset = ftdi_tiocmset, |
833 | .ioctl = ftdi_ioctl, | 838 | .ioctl = ftdi_ioctl, |
834 | .set_termios = ftdi_set_termios, | 839 | .set_termios = ftdi_set_termios, |
835 | .break_ctl = ftdi_break_ctl, | 840 | .break_ctl = ftdi_break_ctl, |
@@ -935,7 +940,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
935 | unsigned int clear) | 940 | unsigned int clear) |
936 | { | 941 | { |
937 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 942 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
938 | char *buf; | ||
939 | unsigned urb_value; | 943 | unsigned urb_value; |
940 | int rv; | 944 | int rv; |
941 | 945 | ||
@@ -944,10 +948,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
944 | return 0; /* no change */ | 948 | return 0; /* no change */ |
945 | } | 949 | } |
946 | 950 | ||
947 | buf = kmalloc(1, GFP_NOIO); | ||
948 | if (!buf) | ||
949 | return -ENOMEM; | ||
950 | |||
951 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | 951 | clear &= ~set; /* 'set' takes precedence over 'clear' */ |
952 | urb_value = 0; | 952 | urb_value = 0; |
953 | if (clear & TIOCM_DTR) | 953 | if (clear & TIOCM_DTR) |
@@ -963,9 +963,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
963 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, | 963 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, |
964 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | 964 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, |
965 | urb_value, priv->interface, | 965 | urb_value, priv->interface, |
966 | buf, 0, WDR_TIMEOUT); | 966 | NULL, 0, WDR_TIMEOUT); |
967 | |||
968 | kfree(buf); | ||
969 | if (rv < 0) { | 967 | if (rv < 0) { |
970 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", | 968 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", |
971 | __func__, | 969 | __func__, |
@@ -1124,16 +1122,11 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
1124 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | 1122 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) |
1125 | { | 1123 | { |
1126 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1124 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1127 | char *buf; | ||
1128 | __u16 urb_value; | 1125 | __u16 urb_value; |
1129 | __u16 urb_index; | 1126 | __u16 urb_index; |
1130 | __u32 urb_index_value; | 1127 | __u32 urb_index_value; |
1131 | int rv; | 1128 | int rv; |
1132 | 1129 | ||
1133 | buf = kmalloc(1, GFP_NOIO); | ||
1134 | if (!buf) | ||
1135 | return -ENOMEM; | ||
1136 | |||
1137 | urb_index_value = get_ftdi_divisor(tty, port); | 1130 | urb_index_value = get_ftdi_divisor(tty, port); |
1138 | urb_value = (__u16)urb_index_value; | 1131 | urb_value = (__u16)urb_index_value; |
1139 | urb_index = (__u16)(urb_index_value >> 16); | 1132 | urb_index = (__u16)(urb_index_value >> 16); |
@@ -1146,9 +1139,7 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | |||
1146 | FTDI_SIO_SET_BAUDRATE_REQUEST, | 1139 | FTDI_SIO_SET_BAUDRATE_REQUEST, |
1147 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, | 1140 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, |
1148 | urb_value, urb_index, | 1141 | urb_value, urb_index, |
1149 | buf, 0, WDR_SHORT_TIMEOUT); | 1142 | NULL, 0, WDR_SHORT_TIMEOUT); |
1150 | |||
1151 | kfree(buf); | ||
1152 | return rv; | 1143 | return rv; |
1153 | } | 1144 | } |
1154 | 1145 | ||
@@ -1156,8 +1147,7 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1156 | { | 1147 | { |
1157 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1148 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1158 | struct usb_device *udev = port->serial->dev; | 1149 | struct usb_device *udev = port->serial->dev; |
1159 | char buf[1]; | 1150 | int rv; |
1160 | int rv = 0; | ||
1161 | int l = priv->latency; | 1151 | int l = priv->latency; |
1162 | 1152 | ||
1163 | if (priv->flags & ASYNC_LOW_LATENCY) | 1153 | if (priv->flags & ASYNC_LOW_LATENCY) |
@@ -1170,8 +1160,7 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1170 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1160 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1171 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1161 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1172 | l, priv->interface, | 1162 | l, priv->interface, |
1173 | buf, 0, WDR_TIMEOUT); | 1163 | NULL, 0, WDR_TIMEOUT); |
1174 | |||
1175 | if (rv < 0) | 1164 | if (rv < 0) |
1176 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); | 1165 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); |
1177 | return rv; | 1166 | return rv; |
@@ -1181,24 +1170,29 @@ static int read_latency_timer(struct usb_serial_port *port) | |||
1181 | { | 1170 | { |
1182 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1171 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1183 | struct usb_device *udev = port->serial->dev; | 1172 | struct usb_device *udev = port->serial->dev; |
1184 | unsigned short latency = 0; | 1173 | unsigned char *buf; |
1185 | int rv = 0; | 1174 | int rv; |
1186 | |||
1187 | 1175 | ||
1188 | dbg("%s", __func__); | 1176 | dbg("%s", __func__); |
1189 | 1177 | ||
1178 | buf = kmalloc(1, GFP_KERNEL); | ||
1179 | if (!buf) | ||
1180 | return -ENOMEM; | ||
1181 | |||
1190 | rv = usb_control_msg(udev, | 1182 | rv = usb_control_msg(udev, |
1191 | usb_rcvctrlpipe(udev, 0), | 1183 | usb_rcvctrlpipe(udev, 0), |
1192 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | 1184 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, |
1193 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | 1185 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, |
1194 | 0, priv->interface, | 1186 | 0, priv->interface, |
1195 | (char *) &latency, 1, WDR_TIMEOUT); | 1187 | buf, 1, WDR_TIMEOUT); |
1196 | 1188 | if (rv < 0) | |
1197 | if (rv < 0) { | ||
1198 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); | 1189 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); |
1199 | return -EIO; | 1190 | else |
1200 | } | 1191 | priv->latency = buf[0]; |
1201 | return latency; | 1192 | |
1193 | kfree(buf); | ||
1194 | |||
1195 | return rv; | ||
1202 | } | 1196 | } |
1203 | 1197 | ||
1204 | static int get_serial_info(struct usb_serial_port *port, | 1198 | static int get_serial_info(struct usb_serial_port *port, |
@@ -1229,7 +1223,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1229 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | 1223 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) |
1230 | return -EFAULT; | 1224 | return -EFAULT; |
1231 | 1225 | ||
1232 | lock_kernel(); | 1226 | mutex_lock(&priv->cfg_lock); |
1233 | old_priv = *priv; | 1227 | old_priv = *priv; |
1234 | 1228 | ||
1235 | /* Do error checking and permission checking */ | 1229 | /* Do error checking and permission checking */ |
@@ -1237,7 +1231,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1237 | if (!capable(CAP_SYS_ADMIN)) { | 1231 | if (!capable(CAP_SYS_ADMIN)) { |
1238 | if (((new_serial.flags & ~ASYNC_USR_MASK) != | 1232 | if (((new_serial.flags & ~ASYNC_USR_MASK) != |
1239 | (priv->flags & ~ASYNC_USR_MASK))) { | 1233 | (priv->flags & ~ASYNC_USR_MASK))) { |
1240 | unlock_kernel(); | 1234 | mutex_unlock(&priv->cfg_lock); |
1241 | return -EPERM; | 1235 | return -EPERM; |
1242 | } | 1236 | } |
1243 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | | 1237 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | |
@@ -1248,7 +1242,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1248 | 1242 | ||
1249 | if ((new_serial.baud_base != priv->baud_base) && | 1243 | if ((new_serial.baud_base != priv->baud_base) && |
1250 | (new_serial.baud_base < 9600)) { | 1244 | (new_serial.baud_base < 9600)) { |
1251 | unlock_kernel(); | 1245 | mutex_unlock(&priv->cfg_lock); |
1252 | return -EINVAL; | 1246 | return -EINVAL; |
1253 | } | 1247 | } |
1254 | 1248 | ||
@@ -1278,11 +1272,11 @@ check_and_exit: | |||
1278 | (priv->flags & ASYNC_SPD_MASK)) || | 1272 | (priv->flags & ASYNC_SPD_MASK)) || |
1279 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && | 1273 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && |
1280 | (old_priv.custom_divisor != priv->custom_divisor))) { | 1274 | (old_priv.custom_divisor != priv->custom_divisor))) { |
1281 | unlock_kernel(); | 1275 | mutex_unlock(&priv->cfg_lock); |
1282 | change_speed(tty, port); | 1276 | change_speed(tty, port); |
1283 | } | 1277 | } |
1284 | else | 1278 | else |
1285 | unlock_kernel(); | 1279 | mutex_unlock(&priv->cfg_lock); |
1286 | return 0; | 1280 | return 0; |
1287 | 1281 | ||
1288 | } /* set_serial_info */ | 1282 | } /* set_serial_info */ |
@@ -1338,20 +1332,20 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1338 | __func__); | 1332 | __func__); |
1339 | } | 1333 | } |
1340 | } else if (version < 0x200) { | 1334 | } else if (version < 0x200) { |
1341 | /* Old device. Assume its the original SIO. */ | 1335 | /* Old device. Assume it's the original SIO. */ |
1342 | priv->chip_type = SIO; | 1336 | priv->chip_type = SIO; |
1343 | priv->baud_base = 12000000 / 16; | 1337 | priv->baud_base = 12000000 / 16; |
1344 | priv->write_offset = 1; | 1338 | priv->write_offset = 1; |
1345 | } else if (version < 0x400) { | 1339 | } else if (version < 0x400) { |
1346 | /* Assume its an FT8U232AM (or FT8U245AM) */ | 1340 | /* Assume it's an FT8U232AM (or FT8U245AM) */ |
1347 | /* (It might be a BM because of the iSerialNumber bug, | 1341 | /* (It might be a BM because of the iSerialNumber bug, |
1348 | * but it will still work as an AM device.) */ | 1342 | * but it will still work as an AM device.) */ |
1349 | priv->chip_type = FT8U232AM; | 1343 | priv->chip_type = FT8U232AM; |
1350 | } else if (version < 0x600) { | 1344 | } else if (version < 0x600) { |
1351 | /* Assume its an FT232BM (or FT245BM) */ | 1345 | /* Assume it's an FT232BM (or FT245BM) */ |
1352 | priv->chip_type = FT232BM; | 1346 | priv->chip_type = FT232BM; |
1353 | } else { | 1347 | } else { |
1354 | /* Assume its an FT232R */ | 1348 | /* Assume it's an FT232R */ |
1355 | priv->chip_type = FT232RL; | 1349 | priv->chip_type = FT232RL; |
1356 | } | 1350 | } |
1357 | dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); | 1351 | dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); |
@@ -1371,7 +1365,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) | |||
1371 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; | 1365 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; |
1372 | 1366 | ||
1373 | unsigned num_endpoints; | 1367 | unsigned num_endpoints; |
1374 | int i = 0; | 1368 | int i; |
1375 | 1369 | ||
1376 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | 1370 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; |
1377 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | 1371 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); |
@@ -1423,7 +1417,7 @@ static ssize_t store_latency_timer(struct device *dev, | |||
1423 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1417 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1424 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1418 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1425 | int v = simple_strtoul(valbuf, NULL, 10); | 1419 | int v = simple_strtoul(valbuf, NULL, 10); |
1426 | int rv = 0; | 1420 | int rv; |
1427 | 1421 | ||
1428 | priv->latency = v; | 1422 | priv->latency = v; |
1429 | rv = write_latency_timer(port); | 1423 | rv = write_latency_timer(port); |
@@ -1440,9 +1434,8 @@ static ssize_t store_event_char(struct device *dev, | |||
1440 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1434 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1441 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1435 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1442 | struct usb_device *udev = port->serial->dev; | 1436 | struct usb_device *udev = port->serial->dev; |
1443 | char buf[1]; | ||
1444 | int v = simple_strtoul(valbuf, NULL, 10); | 1437 | int v = simple_strtoul(valbuf, NULL, 10); |
1445 | int rv = 0; | 1438 | int rv; |
1446 | 1439 | ||
1447 | dbg("%s: setting event char = %i", __func__, v); | 1440 | dbg("%s: setting event char = %i", __func__, v); |
1448 | 1441 | ||
@@ -1451,8 +1444,7 @@ static ssize_t store_event_char(struct device *dev, | |||
1451 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, | 1444 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, |
1452 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, | 1445 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, |
1453 | v, priv->interface, | 1446 | v, priv->interface, |
1454 | buf, 0, WDR_TIMEOUT); | 1447 | NULL, 0, WDR_TIMEOUT); |
1455 | |||
1456 | if (rv < 0) { | 1448 | if (rv < 0) { |
1457 | dbg("Unable to write event character: %i", rv); | 1449 | dbg("Unable to write event character: %i", rv); |
1458 | return -EIO; | 1450 | return -EIO; |
@@ -1551,9 +1543,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1551 | 1543 | ||
1552 | kref_init(&priv->kref); | 1544 | kref_init(&priv->kref); |
1553 | spin_lock_init(&priv->tx_lock); | 1545 | spin_lock_init(&priv->tx_lock); |
1546 | mutex_init(&priv->cfg_lock); | ||
1554 | init_waitqueue_head(&priv->delta_msr_wait); | 1547 | init_waitqueue_head(&priv->delta_msr_wait); |
1555 | /* This will push the characters through immediately rather | 1548 | |
1556 | than queue a task to deliver them */ | ||
1557 | priv->flags = ASYNC_LOW_LATENCY; | 1549 | priv->flags = ASYNC_LOW_LATENCY; |
1558 | 1550 | ||
1559 | if (quirk && quirk->port_probe) | 1551 | if (quirk && quirk->port_probe) |
@@ -1585,7 +1577,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1585 | 1577 | ||
1586 | ftdi_determine_type(port); | 1578 | ftdi_determine_type(port); |
1587 | ftdi_set_max_packet_size(port); | 1579 | ftdi_set_max_packet_size(port); |
1588 | read_latency_timer(port); | 1580 | if (read_latency_timer(port) < 0) |
1581 | priv->latency = 16; | ||
1589 | create_sysfs_attrs(port); | 1582 | create_sysfs_attrs(port); |
1590 | return 0; | 1583 | return 0; |
1591 | } | 1584 | } |
@@ -1630,8 +1623,6 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1630 | { | 1623 | { |
1631 | struct usb_device *udev = serial->dev; | 1624 | struct usb_device *udev = serial->dev; |
1632 | int latency = ndi_latency_timer; | 1625 | int latency = ndi_latency_timer; |
1633 | int rv = 0; | ||
1634 | char buf[1]; | ||
1635 | 1626 | ||
1636 | if (latency == 0) | 1627 | if (latency == 0) |
1637 | latency = 1; | 1628 | latency = 1; |
@@ -1641,10 +1632,11 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1641 | dbg("%s setting NDI device latency to %d", __func__, latency); | 1632 | dbg("%s setting NDI device latency to %d", __func__, latency); |
1642 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); | 1633 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); |
1643 | 1634 | ||
1644 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 1635 | /* FIXME: errors are not returned */ |
1636 | usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
1645 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1637 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1646 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1638 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1647 | latency, 0, buf, 0, WDR_TIMEOUT); | 1639 | latency, 0, NULL, 0, WDR_TIMEOUT); |
1648 | return 0; | 1640 | return 0; |
1649 | } | 1641 | } |
1650 | 1642 | ||
@@ -1720,7 +1712,7 @@ static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | |||
1720 | urb->transfer_buffer_length, | 1712 | urb->transfer_buffer_length, |
1721 | ftdi_read_bulk_callback, port); | 1713 | ftdi_read_bulk_callback, port); |
1722 | result = usb_submit_urb(urb, mem_flags); | 1714 | result = usb_submit_urb(urb, mem_flags); |
1723 | if (result) | 1715 | if (result && result != -EPERM) |
1724 | dev_err(&port->dev, | 1716 | dev_err(&port->dev, |
1725 | "%s - failed submitting read urb, error %d\n", | 1717 | "%s - failed submitting read urb, error %d\n", |
1726 | __func__, result); | 1718 | __func__, result); |
@@ -1732,16 +1724,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1732 | struct usb_device *dev = port->serial->dev; | 1724 | struct usb_device *dev = port->serial->dev; |
1733 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1725 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1734 | unsigned long flags; | 1726 | unsigned long flags; |
1735 | 1727 | int result; | |
1736 | int result = 0; | ||
1737 | char buf[1]; /* Needed for the usb_control_msg I think */ | ||
1738 | 1728 | ||
1739 | dbg("%s", __func__); | 1729 | dbg("%s", __func__); |
1740 | 1730 | ||
1741 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1742 | priv->tx_bytes = 0; | ||
1743 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1744 | |||
1745 | write_latency_timer(port); | 1731 | write_latency_timer(port); |
1746 | 1732 | ||
1747 | /* No error checking for this (will get errors later anyway) */ | 1733 | /* No error checking for this (will get errors later anyway) */ |
@@ -1749,7 +1735,7 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1749 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1735 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1750 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, | 1736 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, |
1751 | FTDI_SIO_RESET_SIO, | 1737 | FTDI_SIO_RESET_SIO, |
1752 | priv->interface, buf, 0, WDR_TIMEOUT); | 1738 | priv->interface, NULL, 0, WDR_TIMEOUT); |
1753 | 1739 | ||
1754 | /* Termios defaults are set by usb_serial_init. We don't change | 1740 | /* Termios defaults are set by usb_serial_init. We don't change |
1755 | port->tty->termios - this would lose speed settings, etc. | 1741 | port->tty->termios - this would lose speed settings, etc. |
@@ -1777,7 +1763,6 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1777 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | 1763 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) |
1778 | { | 1764 | { |
1779 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1765 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1780 | char buf[1]; | ||
1781 | 1766 | ||
1782 | mutex_lock(&port->serial->disc_mutex); | 1767 | mutex_lock(&port->serial->disc_mutex); |
1783 | if (!port->serial->disconnected) { | 1768 | if (!port->serial->disconnected) { |
@@ -1786,7 +1771,7 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | |||
1786 | usb_sndctrlpipe(port->serial->dev, 0), | 1771 | usb_sndctrlpipe(port->serial->dev, 0), |
1787 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1772 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1788 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1773 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1789 | 0, priv->interface, buf, 0, | 1774 | 0, priv->interface, NULL, 0, |
1790 | WDR_TIMEOUT) < 0) { | 1775 | WDR_TIMEOUT) < 0) { |
1791 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 1776 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
1792 | } | 1777 | } |
@@ -1847,7 +1832,7 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1847 | spin_lock_irqsave(&priv->tx_lock, flags); | 1832 | spin_lock_irqsave(&priv->tx_lock, flags); |
1848 | if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { | 1833 | if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { |
1849 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1834 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1850 | dbg("%s - write limit hit\n", __func__); | 1835 | dbg("%s - write limit hit", __func__); |
1851 | return 0; | 1836 | return 0; |
1852 | } | 1837 | } |
1853 | priv->tx_outstanding_urbs++; | 1838 | priv->tx_outstanding_urbs++; |
@@ -1927,7 +1912,6 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1927 | } else { | 1912 | } else { |
1928 | spin_lock_irqsave(&priv->tx_lock, flags); | 1913 | spin_lock_irqsave(&priv->tx_lock, flags); |
1929 | priv->tx_outstanding_bytes += count; | 1914 | priv->tx_outstanding_bytes += count; |
1930 | priv->tx_bytes += count; | ||
1931 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1915 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1932 | } | 1916 | } |
1933 | 1917 | ||
@@ -2154,8 +2138,7 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2154 | { | 2138 | { |
2155 | struct usb_serial_port *port = tty->driver_data; | 2139 | struct usb_serial_port *port = tty->driver_data; |
2156 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2140 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2157 | __u16 urb_value = 0; | 2141 | __u16 urb_value; |
2158 | char buf[1]; | ||
2159 | 2142 | ||
2160 | /* break_state = -1 to turn on break, and 0 to turn off break */ | 2143 | /* break_state = -1 to turn on break, and 0 to turn off break */ |
2161 | /* see drivers/char/tty_io.c to see it used */ | 2144 | /* see drivers/char/tty_io.c to see it used */ |
@@ -2171,7 +2154,7 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2171 | FTDI_SIO_SET_DATA_REQUEST, | 2154 | FTDI_SIO_SET_DATA_REQUEST, |
2172 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2155 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2173 | urb_value , priv->interface, | 2156 | urb_value , priv->interface, |
2174 | buf, 0, WDR_TIMEOUT) < 0) { | 2157 | NULL, 0, WDR_TIMEOUT) < 0) { |
2175 | dev_err(&port->dev, "%s FAILED to enable/disable break state " | 2158 | dev_err(&port->dev, "%s FAILED to enable/disable break state " |
2176 | "(state was %d)\n", __func__, break_state); | 2159 | "(state was %d)\n", __func__, break_state); |
2177 | } | 2160 | } |
@@ -2195,7 +2178,6 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2195 | struct ktermios *termios = tty->termios; | 2178 | struct ktermios *termios = tty->termios; |
2196 | unsigned int cflag = termios->c_cflag; | 2179 | unsigned int cflag = termios->c_cflag; |
2197 | __u16 urb_value; /* will hold the new flags */ | 2180 | __u16 urb_value; /* will hold the new flags */ |
2198 | char buf[1]; /* Perhaps I should dynamically alloc this? */ | ||
2199 | 2181 | ||
2200 | /* Added for xon/xoff support */ | 2182 | /* Added for xon/xoff support */ |
2201 | unsigned int iflag = termios->c_iflag; | 2183 | unsigned int iflag = termios->c_iflag; |
@@ -2246,12 +2228,10 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2246 | } | 2228 | } |
2247 | if (cflag & CSIZE) { | 2229 | if (cflag & CSIZE) { |
2248 | switch (cflag & CSIZE) { | 2230 | switch (cflag & CSIZE) { |
2249 | case CS5: urb_value |= 5; dbg("Setting CS5"); break; | ||
2250 | case CS6: urb_value |= 6; dbg("Setting CS6"); break; | ||
2251 | case CS7: urb_value |= 7; dbg("Setting CS7"); break; | 2231 | case CS7: urb_value |= 7; dbg("Setting CS7"); break; |
2252 | case CS8: urb_value |= 8; dbg("Setting CS8"); break; | 2232 | case CS8: urb_value |= 8; dbg("Setting CS8"); break; |
2253 | default: | 2233 | default: |
2254 | dev_err(&port->dev, "CSIZE was set but not CS5-CS8\n"); | 2234 | dev_err(&port->dev, "CSIZE was set but not CS7-CS8\n"); |
2255 | } | 2235 | } |
2256 | } | 2236 | } |
2257 | 2237 | ||
@@ -2263,7 +2243,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2263 | FTDI_SIO_SET_DATA_REQUEST, | 2243 | FTDI_SIO_SET_DATA_REQUEST, |
2264 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2244 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2265 | urb_value , priv->interface, | 2245 | urb_value , priv->interface, |
2266 | buf, 0, WDR_SHORT_TIMEOUT) < 0) { | 2246 | NULL, 0, WDR_SHORT_TIMEOUT) < 0) { |
2267 | dev_err(&port->dev, "%s FAILED to set " | 2247 | dev_err(&port->dev, "%s FAILED to set " |
2268 | "databits/stopbits/parity\n", __func__); | 2248 | "databits/stopbits/parity\n", __func__); |
2269 | } | 2249 | } |
@@ -2275,7 +2255,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2275 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2255 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2276 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2256 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2277 | 0, priv->interface, | 2257 | 0, priv->interface, |
2278 | buf, 0, WDR_TIMEOUT) < 0) { | 2258 | NULL, 0, WDR_TIMEOUT) < 0) { |
2279 | dev_err(&port->dev, | 2259 | dev_err(&port->dev, |
2280 | "%s error from disable flowcontrol urb\n", | 2260 | "%s error from disable flowcontrol urb\n", |
2281 | __func__); | 2261 | __func__); |
@@ -2301,7 +2281,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2301 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2281 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2302 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2282 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2303 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), | 2283 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), |
2304 | buf, 0, WDR_TIMEOUT) < 0) { | 2284 | NULL, 0, WDR_TIMEOUT) < 0) { |
2305 | dev_err(&port->dev, | 2285 | dev_err(&port->dev, |
2306 | "urb failed to set to rts/cts flow control\n"); | 2286 | "urb failed to set to rts/cts flow control\n"); |
2307 | } | 2287 | } |
@@ -2333,7 +2313,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2333 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2313 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2334 | urb_value , (FTDI_SIO_XON_XOFF_HS | 2314 | urb_value , (FTDI_SIO_XON_XOFF_HS |
2335 | | priv->interface), | 2315 | | priv->interface), |
2336 | buf, 0, WDR_TIMEOUT) < 0) { | 2316 | NULL, 0, WDR_TIMEOUT) < 0) { |
2337 | dev_err(&port->dev, "urb failed to set to " | 2317 | dev_err(&port->dev, "urb failed to set to " |
2338 | "xon/xoff flow control\n"); | 2318 | "xon/xoff flow control\n"); |
2339 | } | 2319 | } |
@@ -2347,7 +2327,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2347 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2327 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2348 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2328 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2349 | 0, priv->interface, | 2329 | 0, priv->interface, |
2350 | buf, 0, WDR_TIMEOUT) < 0) { | 2330 | NULL, 0, WDR_TIMEOUT) < 0) { |
2351 | dev_err(&port->dev, | 2331 | dev_err(&port->dev, |
2352 | "urb failed to clear flow control\n"); | 2332 | "urb failed to clear flow control\n"); |
2353 | } | 2333 | } |
@@ -2361,21 +2341,22 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2361 | { | 2341 | { |
2362 | struct usb_serial_port *port = tty->driver_data; | 2342 | struct usb_serial_port *port = tty->driver_data; |
2363 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2343 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2364 | unsigned char buf[2]; | 2344 | unsigned char *buf; |
2345 | int len; | ||
2365 | int ret; | 2346 | int ret; |
2366 | 2347 | ||
2367 | dbg("%s TIOCMGET", __func__); | 2348 | dbg("%s TIOCMGET", __func__); |
2349 | |||
2350 | buf = kmalloc(2, GFP_KERNEL); | ||
2351 | if (!buf) | ||
2352 | return -ENOMEM; | ||
2353 | /* | ||
2354 | * The 8U232AM returns a two byte value (the SIO a 1 byte value) in | ||
2355 | * the same format as the data returned from the in point. | ||
2356 | */ | ||
2368 | switch (priv->chip_type) { | 2357 | switch (priv->chip_type) { |
2369 | case SIO: | 2358 | case SIO: |
2370 | /* Request the status from the device */ | 2359 | len = 1; |
2371 | ret = usb_control_msg(port->serial->dev, | ||
2372 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2373 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2374 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2375 | 0, 0, | ||
2376 | buf, 1, WDR_TIMEOUT); | ||
2377 | if (ret < 0) | ||
2378 | return ret; | ||
2379 | break; | 2360 | break; |
2380 | case FT8U232AM: | 2361 | case FT8U232AM: |
2381 | case FT232BM: | 2362 | case FT232BM: |
@@ -2383,27 +2364,30 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2383 | case FT232RL: | 2364 | case FT232RL: |
2384 | case FT2232H: | 2365 | case FT2232H: |
2385 | case FT4232H: | 2366 | case FT4232H: |
2386 | /* the 8U232AM returns a two byte value (the sio is a 1 byte | 2367 | len = 2; |
2387 | value) - in the same format as the data returned from the in | ||
2388 | point */ | ||
2389 | ret = usb_control_msg(port->serial->dev, | ||
2390 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2391 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2392 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2393 | 0, priv->interface, | ||
2394 | buf, 2, WDR_TIMEOUT); | ||
2395 | if (ret < 0) | ||
2396 | return ret; | ||
2397 | break; | 2368 | break; |
2398 | default: | 2369 | default: |
2399 | return -EFAULT; | 2370 | ret = -EFAULT; |
2371 | goto out; | ||
2400 | } | 2372 | } |
2401 | 2373 | ||
2402 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | 2374 | ret = usb_control_msg(port->serial->dev, |
2375 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2376 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2377 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2378 | 0, priv->interface, | ||
2379 | buf, len, WDR_TIMEOUT); | ||
2380 | if (ret < 0) | ||
2381 | goto out; | ||
2382 | |||
2383 | ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | ||
2403 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | | 2384 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | |
2404 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | | 2385 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | |
2405 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | | 2386 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | |
2406 | priv->last_dtr_rts; | 2387 | priv->last_dtr_rts; |
2388 | out: | ||
2389 | kfree(buf); | ||
2390 | return ret; | ||
2407 | } | 2391 | } |
2408 | 2392 | ||
2409 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, | 2393 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, |
@@ -2508,8 +2492,7 @@ void ftdi_unthrottle(struct tty_struct *tty) | |||
2508 | port->throttled = port->throttle_req = 0; | 2492 | port->throttled = port->throttle_req = 0; |
2509 | spin_unlock_irqrestore(&port->lock, flags); | 2493 | spin_unlock_irqrestore(&port->lock, flags); |
2510 | 2494 | ||
2511 | /* Resubmit urb if throttled and open. */ | 2495 | if (was_throttled) |
2512 | if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | ||
2513 | ftdi_submit_read_urb(port, GFP_KERNEL); | 2496 | ftdi_submit_read_urb(port, GFP_KERNEL); |
2514 | } | 2497 | } |
2515 | 2498 | ||
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index b0e0d64f822e..ff9bf80327a3 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -28,13 +28,13 @@ | |||
28 | #define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */ | 28 | #define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */ |
29 | #define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */ | 29 | #define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */ |
30 | #define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of the port */ | 30 | #define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of the port */ |
31 | #define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modern status register */ | 31 | #define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modem status register */ |
32 | #define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ | 32 | #define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ |
33 | #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ | 33 | #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ |
34 | #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ | 34 | #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ |
35 | #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ | 35 | #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ |
36 | 36 | ||
37 | /* Interface indicies for FT2232, FT2232H and FT4232H devices*/ | 37 | /* Interface indices for FT2232, FT2232H and FT4232H devices */ |
38 | #define INTERFACE_A 1 | 38 | #define INTERFACE_A 1 |
39 | #define INTERFACE_B 2 | 39 | #define INTERFACE_B 2 |
40 | #define INTERFACE_C 3 | 40 | #define INTERFACE_C 3 |
@@ -270,7 +270,7 @@ typedef enum { | |||
270 | * BmRequestType: 0100 0000b | 270 | * BmRequestType: 0100 0000b |
271 | * bRequest: FTDI_SIO_SET_FLOW_CTRL | 271 | * bRequest: FTDI_SIO_SET_FLOW_CTRL |
272 | * wValue: Xoff/Xon | 272 | * wValue: Xoff/Xon |
273 | * wIndex: Protocol/Port - hIndex is protocl / lIndex is port | 273 | * wIndex: Protocol/Port - hIndex is protocol / lIndex is port |
274 | * wLength: 0 | 274 | * wLength: 0 |
275 | * Data: None | 275 | * Data: None |
276 | * | 276 | * |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index c8951aeed983..0727e198503e 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ | 22 | #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ |
23 | #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ | 23 | #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ |
24 | #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ | 24 | #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ |
25 | #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ | 25 | #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ |
26 | #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ | 26 | #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ |
27 | 27 | ||
28 | 28 | ||
@@ -49,7 +49,7 @@ | |||
49 | #define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 | 49 | #define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 |
50 | #define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 | 50 | #define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 |
51 | 51 | ||
52 | #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ | 52 | #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */ |
53 | 53 | ||
54 | /* OpenDCC (www.opendcc.de) product id */ | 54 | /* OpenDCC (www.opendcc.de) product id */ |
55 | #define FTDI_OPENDCC_PID 0xBFD8 | 55 | #define FTDI_OPENDCC_PID 0xBFD8 |
@@ -185,7 +185,7 @@ | |||
185 | #define FTDI_ELV_TFD128_PID 0xE0EC /* ELV Temperatur-Feuchte-Datenlogger TFD 128 */ | 185 | #define FTDI_ELV_TFD128_PID 0xE0EC /* ELV Temperatur-Feuchte-Datenlogger TFD 128 */ |
186 | #define FTDI_ELV_FM3RX_PID 0xE0ED /* ELV Messwertuebertragung FM3 RX */ | 186 | #define FTDI_ELV_FM3RX_PID 0xE0ED /* ELV Messwertuebertragung FM3 RX */ |
187 | #define FTDI_ELV_WS777_PID 0xE0EE /* Conrad WS 777 */ | 187 | #define FTDI_ELV_WS777_PID 0xE0EE /* Conrad WS 777 */ |
188 | #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ | 188 | #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Energy monitor EM 1010 PC */ |
189 | #define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ | 189 | #define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ |
190 | #define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ | 190 | #define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ |
191 | #define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ | 191 | #define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ |
@@ -212,8 +212,8 @@ | |||
212 | * drivers, or possibly the Comedi drivers in some cases. */ | 212 | * drivers, or possibly the Comedi drivers in some cases. */ |
213 | #define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ | 213 | #define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ |
214 | #define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ | 214 | #define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ |
215 | #define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ | 215 | #define FTDI_ELV_TFM100_PID 0xFB5D /* Temperatur-Feuchte-Messgeraet (TFM 100) */ |
216 | #define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ | 216 | #define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkuhr (UDF 77) */ |
217 | #define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ | 217 | #define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ |
218 | 218 | ||
219 | /* | 219 | /* |
@@ -320,7 +320,7 @@ | |||
320 | 320 | ||
321 | /* | 321 | /* |
322 | * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, | 322 | * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, |
323 | * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices | 323 | * USB-TTY aktiv, USB-TTY passiv. Some PIDs are used by several devices |
324 | * and I'm not entirely sure which are used by which. | 324 | * and I'm not entirely sure which are used by which. |
325 | */ | 325 | */ |
326 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 | 326 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 |
@@ -330,10 +330,10 @@ | |||
330 | * Linx Technologies product ids | 330 | * Linx Technologies product ids |
331 | */ | 331 | */ |
332 | #define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ | 332 | #define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ |
333 | #define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ | 333 | #define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ |
334 | #define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ | 334 | #define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ |
335 | #define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ | 335 | #define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ |
336 | #define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ | 336 | #define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ |
337 | 337 | ||
338 | /* | 338 | /* |
339 | * Oceanic product ids | 339 | * Oceanic product ids |
@@ -494,6 +494,13 @@ | |||
494 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | 494 | #define RATOC_PRODUCT_ID_USB60F 0xb020 |
495 | 495 | ||
496 | /* | 496 | /* |
497 | * Contec products (http://www.contec.com) | ||
498 | * Submitted by Daniel Sangorrin | ||
499 | */ | ||
500 | #define CONTEC_VID 0x06CE /* Vendor ID */ | ||
501 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ | ||
502 | |||
503 | /* | ||
497 | * Definitions for B&B Electronics products. | 504 | * Definitions for B&B Electronics products. |
498 | */ | 505 | */ |
499 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ | 506 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ |
@@ -642,7 +649,7 @@ | |||
642 | #define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ | 649 | #define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ |
643 | #define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ | 650 | #define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ |
644 | 651 | ||
645 | /* Larsen and Brusgaard AltiTrack/USBtrack */ | 652 | /* Larsen and Brusgaard AltiTrack/USBtrack */ |
646 | #define LARSENBRUSGAARD_VID 0x0FD8 | 653 | #define LARSENBRUSGAARD_VID 0x0FD8 |
647 | #define LB_ALTITRACK_PID 0x0001 | 654 | #define LB_ALTITRACK_PID 0x0001 |
648 | 655 | ||
@@ -971,7 +978,7 @@ | |||
971 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ | 978 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ |
972 | 979 | ||
973 | /* | 980 | /* |
974 | * Dresden Elektronic Sensor Terminal Board | 981 | * Dresden Elektronik Sensor Terminal Board |
975 | */ | 982 | */ |
976 | #define DE_VID 0x1cf1 /* Vendor ID */ | 983 | #define DE_VID 0x1cf1 /* Vendor ID */ |
977 | #define STB_PID 0x0001 /* Sensor Terminal Board */ | 984 | #define STB_PID 0x0001 /* Sensor Terminal Board */ |
@@ -1002,3 +1009,11 @@ | |||
1002 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ | 1009 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ |
1003 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ | 1010 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ |
1004 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ | 1011 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ |
1012 | |||
1013 | /* | ||
1014 | * MJS Gadgets HD Radio / XM Radio / Sirius Radio interfaces (using VID 0x0403) | ||
1015 | */ | ||
1016 | #define MJSG_GENERIC_PID 0x9378 | ||
1017 | #define MJSG_SR_RADIO_PID 0x9379 | ||
1018 | #define MJSG_XM_RADIO_PID 0x937A | ||
1019 | #define MJSG_HD_RADIO_PID 0x937C | ||
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index d30f736d2cc5..e21ce9ddfc63 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | static int debug; | 19 | static int debug; |
20 | 20 | ||
21 | static struct usb_device_id id_table [] = { | 21 | static const struct usb_device_id id_table[] = { |
22 | { USB_DEVICE(0x1404, 0xcddc) }, | 22 | { USB_DEVICE(0x1404, 0xcddc) }, |
23 | { }, | 23 | { }, |
24 | }; | 24 | }; |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 5ac900e5a50e..a42b29a695b2 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -210,7 +210,7 @@ static unsigned char const PRIVATE_REQ[] | |||
210 | 210 | ||
211 | 211 | ||
212 | 212 | ||
213 | static struct usb_device_id id_table [] = { | 213 | static const struct usb_device_id id_table[] = { |
214 | /* the same device id seems to be used by all | 214 | /* the same device id seems to be used by all |
215 | usb enabled GPS devices */ | 215 | usb enabled GPS devices */ |
216 | { USB_DEVICE(GARMIN_VENDOR_ID, 3) }, | 216 | { USB_DEVICE(GARMIN_VENDOR_ID, 3) }, |
@@ -271,7 +271,6 @@ static void send_to_tty(struct usb_serial_port *port, | |||
271 | usb_serial_debug_data(debug, &port->dev, | 271 | usb_serial_debug_data(debug, &port->dev, |
272 | __func__, actual_length, data); | 272 | __func__, actual_length, data); |
273 | 273 | ||
274 | tty_buffer_request_room(tty, actual_length); | ||
275 | tty_insert_flip_string(tty, data, actual_length); | 274 | tty_insert_flip_string(tty, data, actual_length); |
276 | tty_flip_buffer_push(tty); | 275 | tty_flip_buffer_push(tty); |
277 | } | 276 | } |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 83443d6306d6..89fac36684c5 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/usb/serial.h> | 20 | #include <linux/usb/serial.h> |
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/kfifo.h> | 22 | #include <linux/kfifo.h> |
23 | #include <linux/serial.h> | ||
23 | 24 | ||
24 | static int debug; | 25 | static int debug; |
25 | 26 | ||
@@ -41,7 +42,7 @@ static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ | |||
41 | 42 | ||
42 | /* we want to look at all devices, as the vendor/product id can change | 43 | /* we want to look at all devices, as the vendor/product id can change |
43 | * depending on the command line argument */ | 44 | * depending on the command line argument */ |
44 | static struct usb_device_id generic_serial_ids[] = { | 45 | static const struct usb_device_id generic_serial_ids[] = { |
45 | {.driver_info = 42}, | 46 | {.driver_info = 42}, |
46 | {} | 47 | {} |
47 | }; | 48 | }; |
@@ -194,7 +195,7 @@ static int usb_serial_multi_urb_write(struct tty_struct *tty, | |||
194 | if (port->urbs_in_flight > | 195 | if (port->urbs_in_flight > |
195 | port->serial->type->max_in_flight_urbs) { | 196 | port->serial->type->max_in_flight_urbs) { |
196 | spin_unlock_irqrestore(&port->lock, flags); | 197 | spin_unlock_irqrestore(&port->lock, flags); |
197 | dbg("%s - write limit hit\n", __func__); | 198 | dbg("%s - write limit hit", __func__); |
198 | return bwrite; | 199 | return bwrite; |
199 | } | 200 | } |
200 | port->tx_bytes_flight += towrite; | 201 | port->tx_bytes_flight += towrite; |
@@ -585,7 +586,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
585 | 586 | ||
586 | for (i = 0; i < serial->num_ports; i++) { | 587 | for (i = 0; i < serial->num_ports; i++) { |
587 | port = serial->port[i]; | 588 | port = serial->port[i]; |
588 | if (!port->port.count) | 589 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) |
589 | continue; | 590 | continue; |
590 | 591 | ||
591 | if (port->read_urb) { | 592 | if (port->read_urb) { |
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 431329275133..809379159b0e 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #define HP_VENDOR_ID 0x03f0 | 29 | #define HP_VENDOR_ID 0x03f0 |
30 | #define HP49GP_PRODUCT_ID 0x0121 | 30 | #define HP49GP_PRODUCT_ID 0x0121 |
31 | 31 | ||
32 | static struct usb_device_id id_table [] = { | 32 | static const struct usb_device_id id_table[] = { |
33 | { USB_DEVICE(HP_VENDOR_ID, HP49GP_PRODUCT_ID) }, | 33 | { USB_DEVICE(HP_VENDOR_ID, HP49GP_PRODUCT_ID) }, |
34 | { } /* Terminating entry */ | 34 | { } /* Terminating entry */ |
35 | }; | 35 | }; |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index b97960ac92f2..3ef8df0ef888 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -364,42 +364,6 @@ static void update_edgeport_E2PROM(struct edgeport_serial *edge_serial) | |||
364 | release_firmware(fw); | 364 | release_firmware(fw); |
365 | } | 365 | } |
366 | 366 | ||
367 | |||
368 | /************************************************************************ | ||
369 | * * | ||
370 | * Get string descriptor from device * | ||
371 | * * | ||
372 | ************************************************************************/ | ||
373 | static int get_string(struct usb_device *dev, int Id, char *string, int buflen) | ||
374 | { | ||
375 | struct usb_string_descriptor StringDesc; | ||
376 | struct usb_string_descriptor *pStringDesc; | ||
377 | |||
378 | dbg("%s - USB String ID = %d", __func__, Id); | ||
379 | |||
380 | if (!usb_get_descriptor(dev, USB_DT_STRING, Id, | ||
381 | &StringDesc, sizeof(StringDesc))) | ||
382 | return 0; | ||
383 | |||
384 | pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL); | ||
385 | if (!pStringDesc) | ||
386 | return 0; | ||
387 | |||
388 | if (!usb_get_descriptor(dev, USB_DT_STRING, Id, | ||
389 | pStringDesc, StringDesc.bLength)) { | ||
390 | kfree(pStringDesc); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | unicode_to_ascii(string, buflen, | ||
395 | pStringDesc->wData, pStringDesc->bLength/2); | ||
396 | |||
397 | kfree(pStringDesc); | ||
398 | dbg("%s - USB String %s", __func__, string); | ||
399 | return strlen(string); | ||
400 | } | ||
401 | |||
402 | |||
403 | #if 0 | 367 | #if 0 |
404 | /************************************************************************ | 368 | /************************************************************************ |
405 | * | 369 | * |
@@ -2007,7 +1971,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
2007 | return; | 1971 | return; |
2008 | 1972 | ||
2009 | case IOSP_EXT_STATUS_RX_CHECK_RSP: | 1973 | case IOSP_EXT_STATUS_RX_CHECK_RSP: |
2010 | dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3); | 1974 | dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============", __func__, edge_serial->rxPort, byte3); |
2011 | /* Port->RxCheckRsp = true; */ | 1975 | /* Port->RxCheckRsp = true; */ |
2012 | return; | 1976 | return; |
2013 | } | 1977 | } |
@@ -2075,7 +2039,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
2075 | break; | 2039 | break; |
2076 | 2040 | ||
2077 | default: | 2041 | default: |
2078 | dbg("%s - Unrecognized IOSP status code %u\n", __func__, code); | 2042 | dbg("%s - Unrecognized IOSP status code %u", __func__, code); |
2079 | break; | 2043 | break; |
2080 | } | 2044 | } |
2081 | return; | 2045 | return; |
@@ -2091,18 +2055,13 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | |||
2091 | { | 2055 | { |
2092 | int cnt; | 2056 | int cnt; |
2093 | 2057 | ||
2094 | do { | 2058 | cnt = tty_insert_flip_string(tty, data, length); |
2095 | cnt = tty_buffer_request_room(tty, length); | 2059 | if (cnt < length) { |
2096 | if (cnt < length) { | 2060 | dev_err(dev, "%s - dropping data, %d bytes lost\n", |
2097 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 2061 | __func__, length - cnt); |
2098 | __func__, length - cnt); | 2062 | } |
2099 | if (cnt == 0) | 2063 | data += cnt; |
2100 | break; | 2064 | length -= cnt; |
2101 | } | ||
2102 | tty_insert_flip_string(tty, data, cnt); | ||
2103 | data += cnt; | ||
2104 | length -= cnt; | ||
2105 | } while (length > 0); | ||
2106 | 2065 | ||
2107 | tty_flip_buffer_push(tty); | 2066 | tty_flip_buffer_push(tty); |
2108 | } | 2067 | } |
@@ -2530,7 +2489,7 @@ static int calc_baud_rate_divisor(int baudrate, int *divisor) | |||
2530 | 2489 | ||
2531 | *divisor = custom; | 2490 | *divisor = custom; |
2532 | 2491 | ||
2533 | dbg("%s - Baud %d = %d\n", __func__, baudrate, custom); | 2492 | dbg("%s - Baud %d = %d", __func__, baudrate, custom); |
2534 | return 0; | 2493 | return 0; |
2535 | } | 2494 | } |
2536 | 2495 | ||
@@ -2915,7 +2874,7 @@ static void load_application_firmware(struct edgeport_serial *edge_serial) | |||
2915 | break; | 2874 | break; |
2916 | 2875 | ||
2917 | case EDGE_DOWNLOAD_FILE_NONE: | 2876 | case EDGE_DOWNLOAD_FILE_NONE: |
2918 | dbg ("No download file specified, skipping download\n"); | 2877 | dbg("No download file specified, skipping download"); |
2919 | return; | 2878 | return; |
2920 | 2879 | ||
2921 | default: | 2880 | default: |
@@ -2997,10 +2956,12 @@ static int edge_startup(struct usb_serial *serial) | |||
2997 | usb_set_serial_data(serial, edge_serial); | 2956 | usb_set_serial_data(serial, edge_serial); |
2998 | 2957 | ||
2999 | /* get the name for the device from the device */ | 2958 | /* get the name for the device from the device */ |
3000 | i = get_string(dev, dev->descriptor.iManufacturer, | 2959 | i = usb_string(dev, dev->descriptor.iManufacturer, |
3001 | &edge_serial->name[0], MAX_NAME_LEN+1); | 2960 | &edge_serial->name[0], MAX_NAME_LEN+1); |
2961 | if (i < 0) | ||
2962 | i = 0; | ||
3002 | edge_serial->name[i++] = ' '; | 2963 | edge_serial->name[i++] = ' '; |
3003 | get_string(dev, dev->descriptor.iProduct, | 2964 | usb_string(dev, dev->descriptor.iProduct, |
3004 | &edge_serial->name[i], MAX_NAME_LEN+2 - i); | 2965 | &edge_serial->name[i], MAX_NAME_LEN+2 - i); |
3005 | 2966 | ||
3006 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); | 2967 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); |
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 9241d3147513..feb56a4ca799 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h | |||
@@ -14,7 +14,7 @@ | |||
14 | #ifndef IO_TABLES_H | 14 | #ifndef IO_TABLES_H |
15 | #define IO_TABLES_H | 15 | #define IO_TABLES_H |
16 | 16 | ||
17 | static struct usb_device_id edgeport_2port_id_table [] = { | 17 | static const struct usb_device_id edgeport_2port_id_table[] = { |
18 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2) }, | 18 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2) }, |
19 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2I) }, | 19 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2I) }, |
20 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_421) }, | 20 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_421) }, |
@@ -23,7 +23,7 @@ static struct usb_device_id edgeport_2port_id_table [] = { | |||
23 | { } | 23 | { } |
24 | }; | 24 | }; |
25 | 25 | ||
26 | static struct usb_device_id edgeport_4port_id_table [] = { | 26 | static const struct usb_device_id edgeport_4port_id_table[] = { |
27 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, | 27 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, |
28 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) }, | 28 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) }, |
29 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) }, | 29 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) }, |
@@ -37,7 +37,7 @@ static struct usb_device_id edgeport_4port_id_table [] = { | |||
37 | { } | 37 | { } |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct usb_device_id edgeport_8port_id_table [] = { | 40 | static const struct usb_device_id edgeport_8port_id_table[] = { |
41 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8) }, | 41 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8) }, |
42 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) }, | 42 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) }, |
43 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8I) }, | 43 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8I) }, |
@@ -47,7 +47,7 @@ static struct usb_device_id edgeport_8port_id_table [] = { | |||
47 | { } | 47 | { } |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct usb_device_id Epic_port_id_table [] = { | 50 | static const struct usb_device_id Epic_port_id_table[] = { |
51 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, | 51 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, |
52 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, | 52 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, |
53 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, | 53 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, |
@@ -60,7 +60,7 @@ static struct usb_device_id Epic_port_id_table [] = { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | /* Devices that this driver supports */ | 62 | /* Devices that this driver supports */ |
63 | static struct usb_device_id id_table_combined [] = { | 63 | static const struct usb_device_id id_table_combined[] = { |
64 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, | 64 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, |
65 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) }, | 65 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) }, |
66 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) }, | 66 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) }, |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index d4cc0f7af400..aa876f71f228 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -134,7 +134,7 @@ struct edgeport_serial { | |||
134 | 134 | ||
135 | 135 | ||
136 | /* Devices that this driver supports */ | 136 | /* Devices that this driver supports */ |
137 | static struct usb_device_id edgeport_1port_id_table [] = { | 137 | static const struct usb_device_id edgeport_1port_id_table[] = { |
138 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, | 138 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, |
139 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) }, | 139 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) }, |
140 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) }, | 140 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) }, |
@@ -154,7 +154,7 @@ static struct usb_device_id edgeport_1port_id_table [] = { | |||
154 | { } | 154 | { } |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static struct usb_device_id edgeport_2port_id_table [] = { | 157 | static const struct usb_device_id edgeport_2port_id_table[] = { |
158 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, | 158 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, |
159 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) }, | 159 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) }, |
160 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, | 160 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, |
@@ -177,7 +177,7 @@ static struct usb_device_id edgeport_2port_id_table [] = { | |||
177 | }; | 177 | }; |
178 | 178 | ||
179 | /* Devices that this driver supports */ | 179 | /* Devices that this driver supports */ |
180 | static struct usb_device_id id_table_combined [] = { | 180 | static const struct usb_device_id id_table_combined[] = { |
181 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, | 181 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, |
182 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) }, | 182 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) }, |
183 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) }, | 183 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) }, |
@@ -413,11 +413,18 @@ static int write_boot_mem(struct edgeport_serial *serial, | |||
413 | { | 413 | { |
414 | int status = 0; | 414 | int status = 0; |
415 | int i; | 415 | int i; |
416 | __u8 temp; | 416 | u8 *temp; |
417 | 417 | ||
418 | /* Must do a read before write */ | 418 | /* Must do a read before write */ |
419 | if (!serial->TiReadI2C) { | 419 | if (!serial->TiReadI2C) { |
420 | status = read_boot_mem(serial, 0, 1, &temp); | 420 | temp = kmalloc(1, GFP_KERNEL); |
421 | if (!temp) { | ||
422 | dev_err(&serial->serial->dev->dev, | ||
423 | "%s - out of memory\n", __func__); | ||
424 | return -ENOMEM; | ||
425 | } | ||
426 | status = read_boot_mem(serial, 0, 1, temp); | ||
427 | kfree(temp); | ||
421 | if (status) | 428 | if (status) |
422 | return status; | 429 | return status; |
423 | } | 430 | } |
@@ -935,37 +942,47 @@ static int build_i2c_fw_hdr(__u8 *header, struct device *dev) | |||
935 | static int i2c_type_bootmode(struct edgeport_serial *serial) | 942 | static int i2c_type_bootmode(struct edgeport_serial *serial) |
936 | { | 943 | { |
937 | int status; | 944 | int status; |
938 | __u8 data; | 945 | u8 *data; |
946 | |||
947 | data = kmalloc(1, GFP_KERNEL); | ||
948 | if (!data) { | ||
949 | dev_err(&serial->serial->dev->dev, | ||
950 | "%s - out of memory\n", __func__); | ||
951 | return -ENOMEM; | ||
952 | } | ||
939 | 953 | ||
940 | /* Try to read type 2 */ | 954 | /* Try to read type 2 */ |
941 | status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ, | 955 | status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ, |
942 | DTK_ADDR_SPACE_I2C_TYPE_II, 0, &data, 0x01); | 956 | DTK_ADDR_SPACE_I2C_TYPE_II, 0, data, 0x01); |
943 | if (status) | 957 | if (status) |
944 | dbg("%s - read 2 status error = %d", __func__, status); | 958 | dbg("%s - read 2 status error = %d", __func__, status); |
945 | else | 959 | else |
946 | dbg("%s - read 2 data = 0x%x", __func__, data); | 960 | dbg("%s - read 2 data = 0x%x", __func__, *data); |
947 | if ((!status) && (data == UMP5152 || data == UMP3410)) { | 961 | if ((!status) && (*data == UMP5152 || *data == UMP3410)) { |
948 | dbg("%s - ROM_TYPE_II", __func__); | 962 | dbg("%s - ROM_TYPE_II", __func__); |
949 | serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; | 963 | serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; |
950 | return 0; | 964 | goto out; |
951 | } | 965 | } |
952 | 966 | ||
953 | /* Try to read type 3 */ | 967 | /* Try to read type 3 */ |
954 | status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ, | 968 | status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ, |
955 | DTK_ADDR_SPACE_I2C_TYPE_III, 0, &data, 0x01); | 969 | DTK_ADDR_SPACE_I2C_TYPE_III, 0, data, 0x01); |
956 | if (status) | 970 | if (status) |
957 | dbg("%s - read 3 status error = %d", __func__, status); | 971 | dbg("%s - read 3 status error = %d", __func__, status); |
958 | else | 972 | else |
959 | dbg("%s - read 2 data = 0x%x", __func__, data); | 973 | dbg("%s - read 2 data = 0x%x", __func__, *data); |
960 | if ((!status) && (data == UMP5152 || data == UMP3410)) { | 974 | if ((!status) && (*data == UMP5152 || *data == UMP3410)) { |
961 | dbg("%s - ROM_TYPE_III", __func__); | 975 | dbg("%s - ROM_TYPE_III", __func__); |
962 | serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III; | 976 | serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III; |
963 | return 0; | 977 | goto out; |
964 | } | 978 | } |
965 | 979 | ||
966 | dbg("%s - Unknown", __func__); | 980 | dbg("%s - Unknown", __func__); |
967 | serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; | 981 | serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; |
968 | return -ENODEV; | 982 | status = -ENODEV; |
983 | out: | ||
984 | kfree(data); | ||
985 | return status; | ||
969 | } | 986 | } |
970 | 987 | ||
971 | static int bulk_xfer(struct usb_serial *serial, void *buffer, | 988 | static int bulk_xfer(struct usb_serial *serial, void *buffer, |
@@ -1113,7 +1130,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1113 | I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc); | 1130 | I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc); |
1114 | if (start_address != 0) { | 1131 | if (start_address != 0) { |
1115 | struct ti_i2c_firmware_rec *firmware_version; | 1132 | struct ti_i2c_firmware_rec *firmware_version; |
1116 | __u8 record; | 1133 | u8 *record; |
1117 | 1134 | ||
1118 | dbg("%s - Found Type FIRMWARE (Type 2) record", | 1135 | dbg("%s - Found Type FIRMWARE (Type 2) record", |
1119 | __func__); | 1136 | __func__); |
@@ -1165,6 +1182,15 @@ static int download_fw(struct edgeport_serial *serial) | |||
1165 | OperationalMajorVersion, | 1182 | OperationalMajorVersion, |
1166 | OperationalMinorVersion); | 1183 | OperationalMinorVersion); |
1167 | 1184 | ||
1185 | record = kmalloc(1, GFP_KERNEL); | ||
1186 | if (!record) { | ||
1187 | dev_err(dev, "%s - out of memory.\n", | ||
1188 | __func__); | ||
1189 | kfree(firmware_version); | ||
1190 | kfree(rom_desc); | ||
1191 | kfree(ti_manuf_desc); | ||
1192 | return -ENOMEM; | ||
1193 | } | ||
1168 | /* In order to update the I2C firmware we must | 1194 | /* In order to update the I2C firmware we must |
1169 | * change the type 2 record to type 0xF2. This | 1195 | * change the type 2 record to type 0xF2. This |
1170 | * will force the UMP to come up in Boot Mode. | 1196 | * will force the UMP to come up in Boot Mode. |
@@ -1177,13 +1203,14 @@ static int download_fw(struct edgeport_serial *serial) | |||
1177 | * firmware will update the record type from | 1203 | * firmware will update the record type from |
1178 | * 0xf2 to 0x02. | 1204 | * 0xf2 to 0x02. |
1179 | */ | 1205 | */ |
1180 | record = I2C_DESC_TYPE_FIRMWARE_BLANK; | 1206 | *record = I2C_DESC_TYPE_FIRMWARE_BLANK; |
1181 | 1207 | ||
1182 | /* Change the I2C Firmware record type to | 1208 | /* Change the I2C Firmware record type to |
1183 | 0xf2 to trigger an update */ | 1209 | 0xf2 to trigger an update */ |
1184 | status = write_rom(serial, start_address, | 1210 | status = write_rom(serial, start_address, |
1185 | sizeof(record), &record); | 1211 | sizeof(*record), record); |
1186 | if (status) { | 1212 | if (status) { |
1213 | kfree(record); | ||
1187 | kfree(firmware_version); | 1214 | kfree(firmware_version); |
1188 | kfree(rom_desc); | 1215 | kfree(rom_desc); |
1189 | kfree(ti_manuf_desc); | 1216 | kfree(ti_manuf_desc); |
@@ -1196,19 +1223,21 @@ static int download_fw(struct edgeport_serial *serial) | |||
1196 | */ | 1223 | */ |
1197 | status = read_rom(serial, | 1224 | status = read_rom(serial, |
1198 | start_address, | 1225 | start_address, |
1199 | sizeof(record), | 1226 | sizeof(*record), |
1200 | &record); | 1227 | record); |
1201 | if (status) { | 1228 | if (status) { |
1229 | kfree(record); | ||
1202 | kfree(firmware_version); | 1230 | kfree(firmware_version); |
1203 | kfree(rom_desc); | 1231 | kfree(rom_desc); |
1204 | kfree(ti_manuf_desc); | 1232 | kfree(ti_manuf_desc); |
1205 | return status; | 1233 | return status; |
1206 | } | 1234 | } |
1207 | 1235 | ||
1208 | if (record != I2C_DESC_TYPE_FIRMWARE_BLANK) { | 1236 | if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) { |
1209 | dev_err(dev, | 1237 | dev_err(dev, |
1210 | "%s - error resetting device\n", | 1238 | "%s - error resetting device\n", |
1211 | __func__); | 1239 | __func__); |
1240 | kfree(record); | ||
1212 | kfree(firmware_version); | 1241 | kfree(firmware_version); |
1213 | kfree(rom_desc); | 1242 | kfree(rom_desc); |
1214 | kfree(ti_manuf_desc); | 1243 | kfree(ti_manuf_desc); |
@@ -1226,6 +1255,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1226 | __func__, status); | 1255 | __func__, status); |
1227 | 1256 | ||
1228 | /* return an error on purpose. */ | 1257 | /* return an error on purpose. */ |
1258 | kfree(record); | ||
1229 | kfree(firmware_version); | 1259 | kfree(firmware_version); |
1230 | kfree(rom_desc); | 1260 | kfree(rom_desc); |
1231 | kfree(ti_manuf_desc); | 1261 | kfree(ti_manuf_desc); |
@@ -1686,7 +1716,7 @@ static void edge_interrupt_callback(struct urb *urb) | |||
1686 | case TIUMP_INTERRUPT_CODE_MSR: /* MSR */ | 1716 | case TIUMP_INTERRUPT_CODE_MSR: /* MSR */ |
1687 | /* Copy MSR from UMP */ | 1717 | /* Copy MSR from UMP */ |
1688 | msr = data[1]; | 1718 | msr = data[1]; |
1689 | dbg("%s - ===== Port %u MSR Status = %02x ======\n", | 1719 | dbg("%s - ===== Port %u MSR Status = %02x ======", |
1690 | __func__, port_number, msr); | 1720 | __func__, port_number, msr); |
1691 | handle_new_msr(edge_port, msr); | 1721 | handle_new_msr(edge_port, msr); |
1692 | break; | 1722 | break; |
@@ -1790,7 +1820,6 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | |||
1790 | { | 1820 | { |
1791 | int queued; | 1821 | int queued; |
1792 | 1822 | ||
1793 | tty_buffer_request_room(tty, length); | ||
1794 | queued = tty_insert_flip_string(tty, data, length); | 1823 | queued = tty_insert_flip_string(tty, data, length); |
1795 | if (queued < length) | 1824 | if (queued < length) |
1796 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1825 | dev_err(dev, "%s - dropping data, %d bytes lost\n", |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index d6231c38813e..3fea9298eb15 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -747,7 +747,6 @@ static void ipaq_read_bulk_callback(struct urb *urb) | |||
747 | 747 | ||
748 | tty = tty_port_tty_get(&port->port); | 748 | tty = tty_port_tty_get(&port->port); |
749 | if (tty && urb->actual_length) { | 749 | if (tty && urb->actual_length) { |
750 | tty_buffer_request_room(tty, urb->actual_length); | ||
751 | tty_insert_flip_string(tty, data, urb->actual_length); | 750 | tty_insert_flip_string(tty, data, urb->actual_length); |
752 | tty_flip_buffer_push(tty); | 751 | tty_flip_buffer_push(tty); |
753 | bytes_in += urb->actual_length; | 752 | bytes_in += urb->actual_length; |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 727d323f092a..e1d07840cee6 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -134,7 +134,7 @@ enum { | |||
134 | 134 | ||
135 | #define IPW_WANTS_TO_SEND 0x30 | 135 | #define IPW_WANTS_TO_SEND 0x30 |
136 | 136 | ||
137 | static struct usb_device_id usb_ipw_ids[] = { | 137 | static const struct usb_device_id usb_ipw_ids[] = { |
138 | { USB_DEVICE(IPW_VID, IPW_PID) }, | 138 | { USB_DEVICE(IPW_VID, IPW_PID) }, |
139 | { }, | 139 | { }, |
140 | }; | 140 | }; |
@@ -172,7 +172,6 @@ static void ipw_read_bulk_callback(struct urb *urb) | |||
172 | 172 | ||
173 | tty = tty_port_tty_get(&port->port); | 173 | tty = tty_port_tty_get(&port->port); |
174 | if (tty && urb->actual_length) { | 174 | if (tty && urb->actual_length) { |
175 | tty_buffer_request_room(tty, urb->actual_length); | ||
176 | tty_insert_flip_string(tty, data, urb->actual_length); | 175 | tty_insert_flip_string(tty, data, urb->actual_length); |
177 | tty_flip_buffer_push(tty); | 176 | tty_flip_buffer_push(tty); |
178 | } | 177 | } |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 95d8d26b9a44..4a0f51974232 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -100,7 +100,7 @@ static u8 ir_baud; | |||
100 | static u8 ir_xbof; | 100 | static u8 ir_xbof; |
101 | static u8 ir_add_bof; | 101 | static u8 ir_add_bof; |
102 | 102 | ||
103 | static struct usb_device_id ir_id_table[] = { | 103 | static const struct usb_device_id ir_id_table[] = { |
104 | { USB_DEVICE(0x050f, 0x0180) }, /* KC Technology, KC-180 */ | 104 | { USB_DEVICE(0x050f, 0x0180) }, /* KC Technology, KC-180 */ |
105 | { USB_DEVICE(0x08e9, 0x0100) }, /* XTNDAccess */ | 105 | { USB_DEVICE(0x08e9, 0x0100) }, /* XTNDAccess */ |
106 | { USB_DEVICE(0x09c4, 0x0011) }, /* ACTiSys ACT-IR2000U */ | 106 | { USB_DEVICE(0x09c4, 0x0011) }, /* ACTiSys ACT-IR2000U */ |
@@ -445,11 +445,6 @@ static void ir_read_bulk_callback(struct urb *urb) | |||
445 | 445 | ||
446 | dbg("%s - port %d", __func__, port->number); | 446 | dbg("%s - port %d", __func__, port->number); |
447 | 447 | ||
448 | if (!port->port.count) { | ||
449 | dbg("%s - port closed.", __func__); | ||
450 | return; | ||
451 | } | ||
452 | |||
453 | switch (status) { | 448 | switch (status) { |
454 | case 0: /* Successful */ | 449 | case 0: /* Successful */ |
455 | /* | 450 | /* |
@@ -462,10 +457,8 @@ static void ir_read_bulk_callback(struct urb *urb) | |||
462 | usb_serial_debug_data(debug, &port->dev, __func__, | 457 | usb_serial_debug_data(debug, &port->dev, __func__, |
463 | urb->actual_length, data); | 458 | urb->actual_length, data); |
464 | tty = tty_port_tty_get(&port->port); | 459 | tty = tty_port_tty_get(&port->port); |
465 | if (tty_buffer_request_room(tty, urb->actual_length - 1)) { | 460 | tty_insert_flip_string(tty, data+1, urb->actual_length - 1); |
466 | tty_insert_flip_string(tty, data+1, urb->actual_length - 1); | 461 | tty_flip_buffer_push(tty); |
467 | tty_flip_buffer_push(tty); | ||
468 | } | ||
469 | tty_kref_put(tty); | 462 | tty_kref_put(tty); |
470 | 463 | ||
471 | /* | 464 | /* |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index e6e02b178d2b..43f13cf2f016 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -43,7 +43,7 @@ static int debug; | |||
43 | #define DRIVER_VERSION "v0.11" | 43 | #define DRIVER_VERSION "v0.11" |
44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" | 44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" |
45 | 45 | ||
46 | static struct usb_device_id id_table[] = { | 46 | static const struct usb_device_id id_table[] = { |
47 | {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, | 47 | {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, |
48 | {} /* Terminating entry */ | 48 | {} /* Terminating entry */ |
49 | }; | 49 | }; |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index f8c4b07033ff..297163c3c610 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -464,13 +464,9 @@ static void usa26_indat_callback(struct urb *urb) | |||
464 | 464 | ||
465 | /* Resubmit urb so we continue receiving */ | 465 | /* Resubmit urb so we continue receiving */ |
466 | urb->dev = port->serial->dev; | 466 | urb->dev = port->serial->dev; |
467 | if (port->port.count) { | 467 | err = usb_submit_urb(urb, GFP_ATOMIC); |
468 | err = usb_submit_urb(urb, GFP_ATOMIC); | 468 | if (err != 0) |
469 | if (err != 0) | 469 | dbg("%s - resubmit read urb failed. (%d)", __func__, err); |
470 | dbg("%s - resubmit read urb failed. (%d)", | ||
471 | __func__, err); | ||
472 | } | ||
473 | return; | ||
474 | } | 470 | } |
475 | 471 | ||
476 | /* Outdat handling is common for all devices */ | 472 | /* Outdat handling is common for all devices */ |
@@ -483,8 +479,7 @@ static void usa2x_outdat_callback(struct urb *urb) | |||
483 | p_priv = usb_get_serial_port_data(port); | 479 | p_priv = usb_get_serial_port_data(port); |
484 | dbg("%s - urb %d", __func__, urb == p_priv->out_urbs[1]); | 480 | dbg("%s - urb %d", __func__, urb == p_priv->out_urbs[1]); |
485 | 481 | ||
486 | if (port->port.count) | 482 | usb_serial_port_softint(port); |
487 | usb_serial_port_softint(port); | ||
488 | } | 483 | } |
489 | 484 | ||
490 | static void usa26_inack_callback(struct urb *urb) | 485 | static void usa26_inack_callback(struct urb *urb) |
@@ -615,12 +610,10 @@ static void usa28_indat_callback(struct urb *urb) | |||
615 | 610 | ||
616 | /* Resubmit urb so we continue receiving */ | 611 | /* Resubmit urb so we continue receiving */ |
617 | urb->dev = port->serial->dev; | 612 | urb->dev = port->serial->dev; |
618 | if (port->port.count) { | 613 | err = usb_submit_urb(urb, GFP_ATOMIC); |
619 | err = usb_submit_urb(urb, GFP_ATOMIC); | 614 | if (err != 0) |
620 | if (err != 0) | 615 | dbg("%s - resubmit read urb failed. (%d)", |
621 | dbg("%s - resubmit read urb failed. (%d)", | 616 | __func__, err); |
622 | __func__, err); | ||
623 | } | ||
624 | p_priv->in_flip ^= 1; | 617 | p_priv->in_flip ^= 1; |
625 | 618 | ||
626 | urb = p_priv->in_urbs[p_priv->in_flip]; | 619 | urb = p_priv->in_urbs[p_priv->in_flip]; |
@@ -856,12 +849,9 @@ static void usa49_indat_callback(struct urb *urb) | |||
856 | 849 | ||
857 | /* Resubmit urb so we continue receiving */ | 850 | /* Resubmit urb so we continue receiving */ |
858 | urb->dev = port->serial->dev; | 851 | urb->dev = port->serial->dev; |
859 | if (port->port.count) { | 852 | err = usb_submit_urb(urb, GFP_ATOMIC); |
860 | err = usb_submit_urb(urb, GFP_ATOMIC); | 853 | if (err != 0) |
861 | if (err != 0) | 854 | dbg("%s - resubmit read urb failed. (%d)", __func__, err); |
862 | dbg("%s - resubmit read urb failed. (%d)", | ||
863 | __func__, err); | ||
864 | } | ||
865 | } | 855 | } |
866 | 856 | ||
867 | static void usa49wg_indat_callback(struct urb *urb) | 857 | static void usa49wg_indat_callback(struct urb *urb) |
@@ -904,11 +894,7 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
904 | /* no error on any byte */ | 894 | /* no error on any byte */ |
905 | i++; | 895 | i++; |
906 | for (x = 1; x < len ; ++x) | 896 | for (x = 1; x < len ; ++x) |
907 | if (port->port.count) | 897 | tty_insert_flip_char(tty, data[i++], 0); |
908 | tty_insert_flip_char(tty, | ||
909 | data[i++], 0); | ||
910 | else | ||
911 | i++; | ||
912 | } else { | 898 | } else { |
913 | /* | 899 | /* |
914 | * some bytes had errors, every byte has status | 900 | * some bytes had errors, every byte has status |
@@ -922,14 +908,12 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
922 | if (stat & RXERROR_PARITY) | 908 | if (stat & RXERROR_PARITY) |
923 | flag |= TTY_PARITY; | 909 | flag |= TTY_PARITY; |
924 | /* XXX should handle break (0x10) */ | 910 | /* XXX should handle break (0x10) */ |
925 | if (port->port.count) | 911 | tty_insert_flip_char(tty, |
926 | tty_insert_flip_char(tty, | ||
927 | data[i+1], flag); | 912 | data[i+1], flag); |
928 | i += 2; | 913 | i += 2; |
929 | } | 914 | } |
930 | } | 915 | } |
931 | if (port->port.count) | 916 | tty_flip_buffer_push(tty); |
932 | tty_flip_buffer_push(tty); | ||
933 | tty_kref_put(tty); | 917 | tty_kref_put(tty); |
934 | } | 918 | } |
935 | } | 919 | } |
@@ -1013,13 +997,9 @@ static void usa90_indat_callback(struct urb *urb) | |||
1013 | 997 | ||
1014 | /* Resubmit urb so we continue receiving */ | 998 | /* Resubmit urb so we continue receiving */ |
1015 | urb->dev = port->serial->dev; | 999 | urb->dev = port->serial->dev; |
1016 | if (port->port.count) { | 1000 | err = usb_submit_urb(urb, GFP_ATOMIC); |
1017 | err = usb_submit_urb(urb, GFP_ATOMIC); | 1001 | if (err != 0) |
1018 | if (err != 0) | 1002 | dbg("%s - resubmit read urb failed. (%d)", __func__, err); |
1019 | dbg("%s - resubmit read urb failed. (%d)", | ||
1020 | __func__, err); | ||
1021 | } | ||
1022 | return; | ||
1023 | } | 1003 | } |
1024 | 1004 | ||
1025 | 1005 | ||
@@ -2418,8 +2398,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, | |||
2418 | msg.portEnabled = 0; | 2398 | msg.portEnabled = 0; |
2419 | /* Sending intermediate configs */ | 2399 | /* Sending intermediate configs */ |
2420 | else { | 2400 | else { |
2421 | if (port->port.count) | 2401 | msg.portEnabled = 1; |
2422 | msg.portEnabled = 1; | ||
2423 | msg.txBreak = (p_priv->break_on); | 2402 | msg.txBreak = (p_priv->break_on); |
2424 | } | 2403 | } |
2425 | 2404 | ||
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 30771e5b3973..bf3297ddd186 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
@@ -456,7 +456,7 @@ static const struct keyspan_device_details *keyspan_devices[] = { | |||
456 | NULL, | 456 | NULL, |
457 | }; | 457 | }; |
458 | 458 | ||
459 | static struct usb_device_id keyspan_ids_combined[] = { | 459 | static const struct usb_device_id keyspan_ids_combined[] = { |
460 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, | 460 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, |
461 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) }, | 461 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) }, |
462 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) }, | 462 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) }, |
@@ -497,7 +497,7 @@ static struct usb_driver keyspan_driver = { | |||
497 | }; | 497 | }; |
498 | 498 | ||
499 | /* usb_device_id table for the pre-firmware download keyspan devices */ | 499 | /* usb_device_id table for the pre-firmware download keyspan devices */ |
500 | static struct usb_device_id keyspan_pre_ids[] = { | 500 | static const struct usb_device_id keyspan_pre_ids[] = { |
501 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, | 501 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, |
502 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) }, | 502 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) }, |
503 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) }, | 503 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) }, |
@@ -513,7 +513,7 @@ static struct usb_device_id keyspan_pre_ids[] = { | |||
513 | { } /* Terminating entry */ | 513 | { } /* Terminating entry */ |
514 | }; | 514 | }; |
515 | 515 | ||
516 | static struct usb_device_id keyspan_1port_ids[] = { | 516 | static const struct usb_device_id keyspan_1port_ids[] = { |
517 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) }, | 517 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) }, |
518 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) }, | 518 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) }, |
519 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) }, | 519 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) }, |
@@ -524,7 +524,7 @@ static struct usb_device_id keyspan_1port_ids[] = { | |||
524 | { } /* Terminating entry */ | 524 | { } /* Terminating entry */ |
525 | }; | 525 | }; |
526 | 526 | ||
527 | static struct usb_device_id keyspan_2port_ids[] = { | 527 | static const struct usb_device_id keyspan_2port_ids[] = { |
528 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, | 528 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, |
529 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, | 529 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, |
530 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, | 530 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, |
@@ -532,7 +532,7 @@ static struct usb_device_id keyspan_2port_ids[] = { | |||
532 | { } /* Terminating entry */ | 532 | { } /* Terminating entry */ |
533 | }; | 533 | }; |
534 | 534 | ||
535 | static struct usb_device_id keyspan_4port_ids[] = { | 535 | static const struct usb_device_id keyspan_4port_ids[] = { |
536 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) }, | 536 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) }, |
537 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, | 537 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, |
538 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)}, | 538 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)}, |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 84f08e968e0b..185fe9a7d4e0 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -125,7 +125,7 @@ struct keyspan_pda_private { | |||
125 | #define ENTREGRA_VENDOR_ID 0x1645 | 125 | #define ENTREGRA_VENDOR_ID 0x1645 |
126 | #define ENTREGRA_FAKE_ID 0x8093 | 126 | #define ENTREGRA_FAKE_ID 0x8093 |
127 | 127 | ||
128 | static struct usb_device_id id_table_combined [] = { | 128 | static const struct usb_device_id id_table_combined[] = { |
129 | #ifdef KEYSPAN | 129 | #ifdef KEYSPAN |
130 | { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) }, | 130 | { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) }, |
131 | #endif | 131 | #endif |
@@ -147,20 +147,20 @@ static struct usb_driver keyspan_pda_driver = { | |||
147 | .no_dynamic_id = 1, | 147 | .no_dynamic_id = 1, |
148 | }; | 148 | }; |
149 | 149 | ||
150 | static struct usb_device_id id_table_std [] = { | 150 | static const struct usb_device_id id_table_std[] = { |
151 | { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) }, | 151 | { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) }, |
152 | { } /* Terminating entry */ | 152 | { } /* Terminating entry */ |
153 | }; | 153 | }; |
154 | 154 | ||
155 | #ifdef KEYSPAN | 155 | #ifdef KEYSPAN |
156 | static struct usb_device_id id_table_fake [] = { | 156 | static const struct usb_device_id id_table_fake[] = { |
157 | { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) }, | 157 | { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) }, |
158 | { } /* Terminating entry */ | 158 | { } /* Terminating entry */ |
159 | }; | 159 | }; |
160 | #endif | 160 | #endif |
161 | 161 | ||
162 | #ifdef XIRCOM | 162 | #ifdef XIRCOM |
163 | static struct usb_device_id id_table_fake_xircom [] = { | 163 | static const struct usb_device_id id_table_fake_xircom[] = { |
164 | { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) }, | 164 | { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) }, |
165 | { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) }, | 165 | { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) }, |
166 | { } | 166 | { } |
@@ -429,13 +429,20 @@ static int keyspan_pda_get_modem_info(struct usb_serial *serial, | |||
429 | unsigned char *value) | 429 | unsigned char *value) |
430 | { | 430 | { |
431 | int rc; | 431 | int rc; |
432 | unsigned char data; | 432 | u8 *data; |
433 | |||
434 | data = kmalloc(1, GFP_KERNEL); | ||
435 | if (!data) | ||
436 | return -ENOMEM; | ||
437 | |||
433 | rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 438 | rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
434 | 3, /* get pins */ | 439 | 3, /* get pins */ |
435 | USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN, | 440 | USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN, |
436 | 0, 0, &data, 1, 2000); | 441 | 0, 0, data, 1, 2000); |
437 | if (rc >= 0) | 442 | if (rc >= 0) |
438 | *value = data; | 443 | *value = *data; |
444 | |||
445 | kfree(data); | ||
439 | return rc; | 446 | return rc; |
440 | } | 447 | } |
441 | 448 | ||
@@ -543,7 +550,14 @@ static int keyspan_pda_write(struct tty_struct *tty, | |||
543 | device how much room it really has. This is done only on | 550 | device how much room it really has. This is done only on |
544 | scheduler time, since usb_control_msg() sleeps. */ | 551 | scheduler time, since usb_control_msg() sleeps. */ |
545 | if (count > priv->tx_room && !in_interrupt()) { | 552 | if (count > priv->tx_room && !in_interrupt()) { |
546 | unsigned char room; | 553 | u8 *room; |
554 | |||
555 | room = kmalloc(1, GFP_KERNEL); | ||
556 | if (!room) { | ||
557 | rc = -ENOMEM; | ||
558 | goto exit; | ||
559 | } | ||
560 | |||
547 | rc = usb_control_msg(serial->dev, | 561 | rc = usb_control_msg(serial->dev, |
548 | usb_rcvctrlpipe(serial->dev, 0), | 562 | usb_rcvctrlpipe(serial->dev, 0), |
549 | 6, /* write_room */ | 563 | 6, /* write_room */ |
@@ -551,9 +565,14 @@ static int keyspan_pda_write(struct tty_struct *tty, | |||
551 | | USB_DIR_IN, | 565 | | USB_DIR_IN, |
552 | 0, /* value: 0 means "remaining room" */ | 566 | 0, /* value: 0 means "remaining room" */ |
553 | 0, /* index */ | 567 | 0, /* index */ |
554 | &room, | 568 | room, |
555 | 1, | 569 | 1, |
556 | 2000); | 570 | 2000); |
571 | if (rc > 0) { | ||
572 | dbg(" roomquery says %d", *room); | ||
573 | priv->tx_room = *room; | ||
574 | } | ||
575 | kfree(room); | ||
557 | if (rc < 0) { | 576 | if (rc < 0) { |
558 | dbg(" roomquery failed"); | 577 | dbg(" roomquery failed"); |
559 | goto exit; | 578 | goto exit; |
@@ -563,8 +582,6 @@ static int keyspan_pda_write(struct tty_struct *tty, | |||
563 | rc = -EIO; /* device didn't return any data */ | 582 | rc = -EIO; /* device didn't return any data */ |
564 | goto exit; | 583 | goto exit; |
565 | } | 584 | } |
566 | dbg(" roomquery says %d", room); | ||
567 | priv->tx_room = room; | ||
568 | } | 585 | } |
569 | if (count > priv->tx_room) { | 586 | if (count > priv->tx_room) { |
570 | /* we're about to completely fill the Tx buffer, so | 587 | /* we're about to completely fill the Tx buffer, so |
@@ -684,18 +701,22 @@ static int keyspan_pda_open(struct tty_struct *tty, | |||
684 | struct usb_serial_port *port) | 701 | struct usb_serial_port *port) |
685 | { | 702 | { |
686 | struct usb_serial *serial = port->serial; | 703 | struct usb_serial *serial = port->serial; |
687 | unsigned char room; | 704 | u8 *room; |
688 | int rc = 0; | 705 | int rc = 0; |
689 | struct keyspan_pda_private *priv; | 706 | struct keyspan_pda_private *priv; |
690 | 707 | ||
691 | /* find out how much room is in the Tx ring */ | 708 | /* find out how much room is in the Tx ring */ |
709 | room = kmalloc(1, GFP_KERNEL); | ||
710 | if (!room) | ||
711 | return -ENOMEM; | ||
712 | |||
692 | rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 713 | rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
693 | 6, /* write_room */ | 714 | 6, /* write_room */ |
694 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE | 715 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
695 | | USB_DIR_IN, | 716 | | USB_DIR_IN, |
696 | 0, /* value */ | 717 | 0, /* value */ |
697 | 0, /* index */ | 718 | 0, /* index */ |
698 | &room, | 719 | room, |
699 | 1, | 720 | 1, |
700 | 2000); | 721 | 2000); |
701 | if (rc < 0) { | 722 | if (rc < 0) { |
@@ -708,8 +729,8 @@ static int keyspan_pda_open(struct tty_struct *tty, | |||
708 | goto error; | 729 | goto error; |
709 | } | 730 | } |
710 | priv = usb_get_serial_port_data(port); | 731 | priv = usb_get_serial_port_data(port); |
711 | priv->tx_room = room; | 732 | priv->tx_room = *room; |
712 | priv->tx_throttled = room ? 0 : 1; | 733 | priv->tx_throttled = *room ? 0 : 1; |
713 | 734 | ||
714 | /*Start reading from the device*/ | 735 | /*Start reading from the device*/ |
715 | port->interrupt_in_urb->dev = serial->dev; | 736 | port->interrupt_in_urb->dev = serial->dev; |
@@ -718,8 +739,8 @@ static int keyspan_pda_open(struct tty_struct *tty, | |||
718 | dbg("%s - usb_submit_urb(read int) failed", __func__); | 739 | dbg("%s - usb_submit_urb(read int) failed", __func__); |
719 | goto error; | 740 | goto error; |
720 | } | 741 | } |
721 | |||
722 | error: | 742 | error: |
743 | kfree(room); | ||
723 | return rc; | 744 | return rc; |
724 | } | 745 | } |
725 | static void keyspan_pda_close(struct usb_serial_port *port) | 746 | static void keyspan_pda_close(struct usb_serial_port *port) |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 3a7873806f46..8eef91ba4b1c 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -94,7 +94,7 @@ static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, | |||
94 | /* | 94 | /* |
95 | * All of the device info needed for the KLSI converters. | 95 | * All of the device info needed for the KLSI converters. |
96 | */ | 96 | */ |
97 | static struct usb_device_id id_table [] = { | 97 | static const struct usb_device_id id_table[] = { |
98 | { USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) }, | 98 | { USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) }, |
99 | { USB_DEVICE(KLSI_VID, KLSI_KL5KUSB105D_PID) }, | 99 | { USB_DEVICE(KLSI_VID, KLSI_KL5KUSB105D_PID) }, |
100 | { } /* Terminating entry */ | 100 | { } /* Terminating entry */ |
@@ -212,10 +212,19 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, | |||
212 | unsigned long *line_state_p) | 212 | unsigned long *line_state_p) |
213 | { | 213 | { |
214 | int rc; | 214 | int rc; |
215 | __u8 status_buf[KLSI_STATUSBUF_LEN] = { -1, -1}; | 215 | u8 *status_buf; |
216 | __u16 status; | 216 | __u16 status; |
217 | 217 | ||
218 | dev_info(&port->serial->dev->dev, "sending SIO Poll request\n"); | 218 | dev_info(&port->serial->dev->dev, "sending SIO Poll request\n"); |
219 | |||
220 | status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL); | ||
221 | if (!status_buf) { | ||
222 | dev_err(&port->dev, "%s - out of memory for status buffer.\n", | ||
223 | __func__); | ||
224 | return -ENOMEM; | ||
225 | } | ||
226 | status_buf[0] = 0xff; | ||
227 | status_buf[1] = 0xff; | ||
219 | rc = usb_control_msg(port->serial->dev, | 228 | rc = usb_control_msg(port->serial->dev, |
220 | usb_rcvctrlpipe(port->serial->dev, 0), | 229 | usb_rcvctrlpipe(port->serial->dev, 0), |
221 | KL5KUSB105A_SIO_POLL, | 230 | KL5KUSB105A_SIO_POLL, |
@@ -236,6 +245,8 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, | |||
236 | 245 | ||
237 | *line_state_p = klsi_105_status2linestate(status); | 246 | *line_state_p = klsi_105_status2linestate(status); |
238 | } | 247 | } |
248 | |||
249 | kfree(status_buf); | ||
239 | return rc; | 250 | return rc; |
240 | } | 251 | } |
241 | 252 | ||
@@ -364,7 +375,7 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
364 | int rc; | 375 | int rc; |
365 | int i; | 376 | int i; |
366 | unsigned long line_state; | 377 | unsigned long line_state; |
367 | struct klsi_105_port_settings cfg; | 378 | struct klsi_105_port_settings *cfg; |
368 | unsigned long flags; | 379 | unsigned long flags; |
369 | 380 | ||
370 | dbg("%s port %d", __func__, port->number); | 381 | dbg("%s port %d", __func__, port->number); |
@@ -376,12 +387,18 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
376 | * Then read the modem line control and store values in | 387 | * Then read the modem line control and store values in |
377 | * priv->line_state. | 388 | * priv->line_state. |
378 | */ | 389 | */ |
379 | cfg.pktlen = 5; | 390 | cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); |
380 | cfg.baudrate = kl5kusb105a_sio_b9600; | 391 | if (!cfg) { |
381 | cfg.databits = kl5kusb105a_dtb_8; | 392 | dev_err(&port->dev, "%s - out of memory for config buffer.\n", |
382 | cfg.unknown1 = 0; | 393 | __func__); |
383 | cfg.unknown2 = 1; | 394 | return -ENOMEM; |
384 | klsi_105_chg_port_settings(port, &cfg); | 395 | } |
396 | cfg->pktlen = 5; | ||
397 | cfg->baudrate = kl5kusb105a_sio_b9600; | ||
398 | cfg->databits = kl5kusb105a_dtb_8; | ||
399 | cfg->unknown1 = 0; | ||
400 | cfg->unknown2 = 1; | ||
401 | klsi_105_chg_port_settings(port, cfg); | ||
385 | 402 | ||
386 | /* set up termios structure */ | 403 | /* set up termios structure */ |
387 | spin_lock_irqsave(&priv->lock, flags); | 404 | spin_lock_irqsave(&priv->lock, flags); |
@@ -391,11 +408,11 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
391 | priv->termios.c_lflag = tty->termios->c_lflag; | 408 | priv->termios.c_lflag = tty->termios->c_lflag; |
392 | for (i = 0; i < NCCS; i++) | 409 | for (i = 0; i < NCCS; i++) |
393 | priv->termios.c_cc[i] = tty->termios->c_cc[i]; | 410 | priv->termios.c_cc[i] = tty->termios->c_cc[i]; |
394 | priv->cfg.pktlen = cfg.pktlen; | 411 | priv->cfg.pktlen = cfg->pktlen; |
395 | priv->cfg.baudrate = cfg.baudrate; | 412 | priv->cfg.baudrate = cfg->baudrate; |
396 | priv->cfg.databits = cfg.databits; | 413 | priv->cfg.databits = cfg->databits; |
397 | priv->cfg.unknown1 = cfg.unknown1; | 414 | priv->cfg.unknown1 = cfg->unknown1; |
398 | priv->cfg.unknown2 = cfg.unknown2; | 415 | priv->cfg.unknown2 = cfg->unknown2; |
399 | spin_unlock_irqrestore(&priv->lock, flags); | 416 | spin_unlock_irqrestore(&priv->lock, flags); |
400 | 417 | ||
401 | /* READ_ON and urb submission */ | 418 | /* READ_ON and urb submission */ |
@@ -441,6 +458,7 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
441 | retval = rc; | 458 | retval = rc; |
442 | 459 | ||
443 | exit: | 460 | exit: |
461 | kfree(cfg); | ||
444 | return retval; | 462 | return retval; |
445 | } /* klsi_105_open */ | 463 | } /* klsi_105_open */ |
446 | 464 | ||
@@ -681,7 +699,6 @@ static void klsi_105_read_bulk_callback(struct urb *urb) | |||
681 | bytes_sent = urb->actual_length - 2; | 699 | bytes_sent = urb->actual_length - 2; |
682 | } | 700 | } |
683 | 701 | ||
684 | tty_buffer_request_room(tty, bytes_sent); | ||
685 | tty_insert_flip_string(tty, data + 2, bytes_sent); | 702 | tty_insert_flip_string(tty, data + 2, bytes_sent); |
686 | tty_flip_buffer_push(tty); | 703 | tty_flip_buffer_push(tty); |
687 | tty_kref_put(tty); | 704 | tty_kref_put(tty); |
@@ -714,10 +731,17 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
714 | unsigned int old_iflag = old_termios->c_iflag; | 731 | unsigned int old_iflag = old_termios->c_iflag; |
715 | unsigned int cflag = tty->termios->c_cflag; | 732 | unsigned int cflag = tty->termios->c_cflag; |
716 | unsigned int old_cflag = old_termios->c_cflag; | 733 | unsigned int old_cflag = old_termios->c_cflag; |
717 | struct klsi_105_port_settings cfg; | 734 | struct klsi_105_port_settings *cfg; |
718 | unsigned long flags; | 735 | unsigned long flags; |
719 | speed_t baud; | 736 | speed_t baud; |
720 | 737 | ||
738 | cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); | ||
739 | if (!cfg) { | ||
740 | dev_err(&port->dev, "%s - out of memory for config buffer.\n", | ||
741 | __func__); | ||
742 | return; | ||
743 | } | ||
744 | |||
721 | /* lock while we are modifying the settings */ | 745 | /* lock while we are modifying the settings */ |
722 | spin_lock_irqsave(&priv->lock, flags); | 746 | spin_lock_irqsave(&priv->lock, flags); |
723 | 747 | ||
@@ -793,11 +817,11 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
793 | case CS5: | 817 | case CS5: |
794 | dbg("%s - 5 bits/byte not supported", __func__); | 818 | dbg("%s - 5 bits/byte not supported", __func__); |
795 | spin_unlock_irqrestore(&priv->lock, flags); | 819 | spin_unlock_irqrestore(&priv->lock, flags); |
796 | return ; | 820 | goto err; |
797 | case CS6: | 821 | case CS6: |
798 | dbg("%s - 6 bits/byte not supported", __func__); | 822 | dbg("%s - 6 bits/byte not supported", __func__); |
799 | spin_unlock_irqrestore(&priv->lock, flags); | 823 | spin_unlock_irqrestore(&priv->lock, flags); |
800 | return ; | 824 | goto err; |
801 | case CS7: | 825 | case CS7: |
802 | priv->cfg.databits = kl5kusb105a_dtb_7; | 826 | priv->cfg.databits = kl5kusb105a_dtb_7; |
803 | break; | 827 | break; |
@@ -856,11 +880,13 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
856 | #endif | 880 | #endif |
857 | ; | 881 | ; |
858 | } | 882 | } |
859 | memcpy(&cfg, &priv->cfg, sizeof(cfg)); | 883 | memcpy(cfg, &priv->cfg, sizeof(*cfg)); |
860 | spin_unlock_irqrestore(&priv->lock, flags); | 884 | spin_unlock_irqrestore(&priv->lock, flags); |
861 | 885 | ||
862 | /* now commit changes to device */ | 886 | /* now commit changes to device */ |
863 | klsi_105_chg_port_settings(port, &cfg); | 887 | klsi_105_chg_port_settings(port, cfg); |
888 | err: | ||
889 | kfree(cfg); | ||
864 | } /* klsi_105_set_termios */ | 890 | } /* klsi_105_set_termios */ |
865 | 891 | ||
866 | 892 | ||
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 45ea694b3ae6..c113a2a0e10c 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -86,7 +86,7 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
86 | struct usb_serial_port *port, struct ktermios *old); | 86 | struct usb_serial_port *port, struct ktermios *old); |
87 | static void kobil_init_termios(struct tty_struct *tty); | 87 | static void kobil_init_termios(struct tty_struct *tty); |
88 | 88 | ||
89 | static struct usb_device_id id_table [] = { | 89 | static const struct usb_device_id id_table[] = { |
90 | { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) }, | 90 | { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) }, |
91 | { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) }, | 91 | { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) }, |
92 | { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) }, | 92 | { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) }, |
@@ -388,7 +388,6 @@ static void kobil_read_int_callback(struct urb *urb) | |||
388 | */ | 388 | */ |
389 | /* END DEBUG */ | 389 | /* END DEBUG */ |
390 | 390 | ||
391 | tty_buffer_request_room(tty, urb->actual_length); | ||
392 | tty_insert_flip_string(tty, data, urb->actual_length); | 391 | tty_insert_flip_string(tty, data, urb->actual_length); |
393 | tty_flip_buffer_push(tty); | 392 | tty_flip_buffer_push(tty); |
394 | } | 393 | } |
@@ -624,7 +623,6 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
624 | unsigned short urb_val = 0; | 623 | unsigned short urb_val = 0; |
625 | int c_cflag = tty->termios->c_cflag; | 624 | int c_cflag = tty->termios->c_cflag; |
626 | speed_t speed; | 625 | speed_t speed; |
627 | void *settings; | ||
628 | 626 | ||
629 | priv = usb_get_serial_port_data(port); | 627 | priv = usb_get_serial_port_data(port); |
630 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || | 628 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || |
@@ -647,25 +645,13 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
647 | } | 645 | } |
648 | urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : | 646 | urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : |
649 | SUSBCR_SPASB_1StopBit; | 647 | SUSBCR_SPASB_1StopBit; |
650 | |||
651 | settings = kzalloc(50, GFP_KERNEL); | ||
652 | if (!settings) | ||
653 | return; | ||
654 | |||
655 | sprintf(settings, "%d ", speed); | ||
656 | |||
657 | if (c_cflag & PARENB) { | 648 | if (c_cflag & PARENB) { |
658 | if (c_cflag & PARODD) { | 649 | if (c_cflag & PARODD) |
659 | urb_val |= SUSBCR_SPASB_OddParity; | 650 | urb_val |= SUSBCR_SPASB_OddParity; |
660 | strcat(settings, "Odd Parity"); | 651 | else |
661 | } else { | ||
662 | urb_val |= SUSBCR_SPASB_EvenParity; | 652 | urb_val |= SUSBCR_SPASB_EvenParity; |
663 | strcat(settings, "Even Parity"); | 653 | } else |
664 | } | ||
665 | } else { | ||
666 | urb_val |= SUSBCR_SPASB_NoParity; | 654 | urb_val |= SUSBCR_SPASB_NoParity; |
667 | strcat(settings, "No Parity"); | ||
668 | } | ||
669 | tty->termios->c_cflag &= ~CMSPAR; | 655 | tty->termios->c_cflag &= ~CMSPAR; |
670 | tty_encode_baud_rate(tty, speed, speed); | 656 | tty_encode_baud_rate(tty, speed, speed); |
671 | 657 | ||
@@ -675,11 +661,10 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
675 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 661 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
676 | urb_val, | 662 | urb_val, |
677 | 0, | 663 | 0, |
678 | settings, | 664 | NULL, |
679 | 0, | 665 | 0, |
680 | KOBIL_TIMEOUT | 666 | KOBIL_TIMEOUT |
681 | ); | 667 | ); |
682 | kfree(settings); | ||
683 | } | 668 | } |
684 | 669 | ||
685 | static int kobil_ioctl(struct tty_struct *tty, struct file *file, | 670 | static int kobil_ioctl(struct tty_struct *tty, struct file *file, |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index cd009cb280a5..2849f8c32015 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -75,6 +75,7 @@ | |||
75 | #include <linux/module.h> | 75 | #include <linux/module.h> |
76 | #include <linux/spinlock.h> | 76 | #include <linux/spinlock.h> |
77 | #include <linux/uaccess.h> | 77 | #include <linux/uaccess.h> |
78 | #include <asm/unaligned.h> | ||
78 | #include <linux/usb.h> | 79 | #include <linux/usb.h> |
79 | #include <linux/usb/serial.h> | 80 | #include <linux/usb/serial.h> |
80 | #include "mct_u232.h" | 81 | #include "mct_u232.h" |
@@ -110,7 +111,7 @@ static void mct_u232_unthrottle(struct tty_struct *tty); | |||
110 | /* | 111 | /* |
111 | * All of the device info needed for the MCT USB-RS232 converter. | 112 | * All of the device info needed for the MCT USB-RS232 converter. |
112 | */ | 113 | */ |
113 | static struct usb_device_id id_table_combined [] = { | 114 | static const struct usb_device_id id_table_combined[] = { |
114 | { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) }, | 115 | { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) }, |
115 | { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) }, | 116 | { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) }, |
116 | { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) }, | 117 | { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) }, |
@@ -231,19 +232,22 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, | |||
231 | static int mct_u232_set_baud_rate(struct tty_struct *tty, | 232 | static int mct_u232_set_baud_rate(struct tty_struct *tty, |
232 | struct usb_serial *serial, struct usb_serial_port *port, speed_t value) | 233 | struct usb_serial *serial, struct usb_serial_port *port, speed_t value) |
233 | { | 234 | { |
234 | __le32 divisor; | 235 | unsigned int divisor; |
235 | int rc; | 236 | int rc; |
236 | unsigned char zero_byte = 0; | 237 | unsigned char *buf; |
237 | unsigned char cts_enable_byte = 0; | 238 | unsigned char cts_enable_byte = 0; |
238 | speed_t speed; | 239 | speed_t speed; |
239 | 240 | ||
240 | divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value, | 241 | buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); |
241 | &speed)); | 242 | if (buf == NULL) |
243 | return -ENOMEM; | ||
242 | 244 | ||
245 | divisor = mct_u232_calculate_baud_rate(serial, value, &speed); | ||
246 | put_unaligned_le32(cpu_to_le32(divisor), buf); | ||
243 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 247 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
244 | MCT_U232_SET_BAUD_RATE_REQUEST, | 248 | MCT_U232_SET_BAUD_RATE_REQUEST, |
245 | MCT_U232_SET_REQUEST_TYPE, | 249 | MCT_U232_SET_REQUEST_TYPE, |
246 | 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE, | 250 | 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE, |
247 | WDR_TIMEOUT); | 251 | WDR_TIMEOUT); |
248 | if (rc < 0) /*FIXME: What value speed results */ | 252 | if (rc < 0) /*FIXME: What value speed results */ |
249 | dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n", | 253 | dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n", |
@@ -269,10 +273,11 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty, | |||
269 | a device which is not asserting 'CTS'. | 273 | a device which is not asserting 'CTS'. |
270 | */ | 274 | */ |
271 | 275 | ||
276 | buf[0] = 0; | ||
272 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 277 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
273 | MCT_U232_SET_UNKNOWN1_REQUEST, | 278 | MCT_U232_SET_UNKNOWN1_REQUEST, |
274 | MCT_U232_SET_REQUEST_TYPE, | 279 | MCT_U232_SET_REQUEST_TYPE, |
275 | 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE, | 280 | 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE, |
276 | WDR_TIMEOUT); | 281 | WDR_TIMEOUT); |
277 | if (rc < 0) | 282 | if (rc < 0) |
278 | dev_err(&port->dev, "Sending USB device request code %d " | 283 | dev_err(&port->dev, "Sending USB device request code %d " |
@@ -284,30 +289,40 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty, | |||
284 | 289 | ||
285 | dbg("set_baud_rate: send second control message, data = %02X", | 290 | dbg("set_baud_rate: send second control message, data = %02X", |
286 | cts_enable_byte); | 291 | cts_enable_byte); |
292 | buf[0] = cts_enable_byte; | ||
287 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 293 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
288 | MCT_U232_SET_CTS_REQUEST, | 294 | MCT_U232_SET_CTS_REQUEST, |
289 | MCT_U232_SET_REQUEST_TYPE, | 295 | MCT_U232_SET_REQUEST_TYPE, |
290 | 0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE, | 296 | 0, 0, buf, MCT_U232_SET_CTS_SIZE, |
291 | WDR_TIMEOUT); | 297 | WDR_TIMEOUT); |
292 | if (rc < 0) | 298 | if (rc < 0) |
293 | dev_err(&port->dev, "Sending USB device request code %d " | 299 | dev_err(&port->dev, "Sending USB device request code %d " |
294 | "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc); | 300 | "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc); |
295 | 301 | ||
302 | kfree(buf); | ||
296 | return rc; | 303 | return rc; |
297 | } /* mct_u232_set_baud_rate */ | 304 | } /* mct_u232_set_baud_rate */ |
298 | 305 | ||
299 | static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr) | 306 | static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr) |
300 | { | 307 | { |
301 | int rc; | 308 | int rc; |
309 | unsigned char *buf; | ||
310 | |||
311 | buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); | ||
312 | if (buf == NULL) | ||
313 | return -ENOMEM; | ||
314 | |||
315 | buf[0] = lcr; | ||
302 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 316 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
303 | MCT_U232_SET_LINE_CTRL_REQUEST, | 317 | MCT_U232_SET_LINE_CTRL_REQUEST, |
304 | MCT_U232_SET_REQUEST_TYPE, | 318 | MCT_U232_SET_REQUEST_TYPE, |
305 | 0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE, | 319 | 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE, |
306 | WDR_TIMEOUT); | 320 | WDR_TIMEOUT); |
307 | if (rc < 0) | 321 | if (rc < 0) |
308 | dev_err(&serial->dev->dev, | 322 | dev_err(&serial->dev->dev, |
309 | "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); | 323 | "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); |
310 | dbg("set_line_ctrl: 0x%x", lcr); | 324 | dbg("set_line_ctrl: 0x%x", lcr); |
325 | kfree(buf); | ||
311 | return rc; | 326 | return rc; |
312 | } /* mct_u232_set_line_ctrl */ | 327 | } /* mct_u232_set_line_ctrl */ |
313 | 328 | ||
@@ -315,23 +330,31 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial, | |||
315 | unsigned int control_state) | 330 | unsigned int control_state) |
316 | { | 331 | { |
317 | int rc; | 332 | int rc; |
318 | unsigned char mcr = MCT_U232_MCR_NONE; | 333 | unsigned char mcr; |
334 | unsigned char *buf; | ||
335 | |||
336 | buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); | ||
337 | if (buf == NULL) | ||
338 | return -ENOMEM; | ||
319 | 339 | ||
340 | mcr = MCT_U232_MCR_NONE; | ||
320 | if (control_state & TIOCM_DTR) | 341 | if (control_state & TIOCM_DTR) |
321 | mcr |= MCT_U232_MCR_DTR; | 342 | mcr |= MCT_U232_MCR_DTR; |
322 | if (control_state & TIOCM_RTS) | 343 | if (control_state & TIOCM_RTS) |
323 | mcr |= MCT_U232_MCR_RTS; | 344 | mcr |= MCT_U232_MCR_RTS; |
324 | 345 | ||
346 | buf[0] = mcr; | ||
325 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 347 | rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
326 | MCT_U232_SET_MODEM_CTRL_REQUEST, | 348 | MCT_U232_SET_MODEM_CTRL_REQUEST, |
327 | MCT_U232_SET_REQUEST_TYPE, | 349 | MCT_U232_SET_REQUEST_TYPE, |
328 | 0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE, | 350 | 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE, |
329 | WDR_TIMEOUT); | 351 | WDR_TIMEOUT); |
330 | if (rc < 0) | 352 | if (rc < 0) |
331 | dev_err(&serial->dev->dev, | 353 | dev_err(&serial->dev->dev, |
332 | "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); | 354 | "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); |
333 | dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); | 355 | dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); |
334 | 356 | ||
357 | kfree(buf); | ||
335 | return rc; | 358 | return rc; |
336 | } /* mct_u232_set_modem_ctrl */ | 359 | } /* mct_u232_set_modem_ctrl */ |
337 | 360 | ||
@@ -339,17 +362,27 @@ static int mct_u232_get_modem_stat(struct usb_serial *serial, | |||
339 | unsigned char *msr) | 362 | unsigned char *msr) |
340 | { | 363 | { |
341 | int rc; | 364 | int rc; |
365 | unsigned char *buf; | ||
366 | |||
367 | buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); | ||
368 | if (buf == NULL) { | ||
369 | *msr = 0; | ||
370 | return -ENOMEM; | ||
371 | } | ||
342 | rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 372 | rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
343 | MCT_U232_GET_MODEM_STAT_REQUEST, | 373 | MCT_U232_GET_MODEM_STAT_REQUEST, |
344 | MCT_U232_GET_REQUEST_TYPE, | 374 | MCT_U232_GET_REQUEST_TYPE, |
345 | 0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE, | 375 | 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE, |
346 | WDR_TIMEOUT); | 376 | WDR_TIMEOUT); |
347 | if (rc < 0) { | 377 | if (rc < 0) { |
348 | dev_err(&serial->dev->dev, | 378 | dev_err(&serial->dev->dev, |
349 | "Get MODEM STATus failed (error = %d)\n", rc); | 379 | "Get MODEM STATus failed (error = %d)\n", rc); |
350 | *msr = 0; | 380 | *msr = 0; |
381 | } else { | ||
382 | *msr = buf[0]; | ||
351 | } | 383 | } |
352 | dbg("get_modem_stat: 0x%x", *msr); | 384 | dbg("get_modem_stat: 0x%x", *msr); |
385 | kfree(buf); | ||
353 | return rc; | 386 | return rc; |
354 | } /* mct_u232_get_modem_stat */ | 387 | } /* mct_u232_get_modem_stat */ |
355 | 388 | ||
diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h index 07b6bec31dc8..7417d5ce1e23 100644 --- a/drivers/usb/serial/mct_u232.h +++ b/drivers/usb/serial/mct_u232.h | |||
@@ -73,6 +73,8 @@ | |||
73 | #define MCT_U232_SET_CTS_REQUEST 12 | 73 | #define MCT_U232_SET_CTS_REQUEST 12 |
74 | #define MCT_U232_SET_CTS_SIZE 1 | 74 | #define MCT_U232_SET_CTS_SIZE 1 |
75 | 75 | ||
76 | #define MCT_U232_MAX_SIZE 4 /* of MCT_XXX_SIZE */ | ||
77 | |||
76 | /* | 78 | /* |
77 | * Baud rate (divisor) | 79 | * Baud rate (divisor) |
78 | * Actually, there are two of them, MCT website calls them "Philips solution" | 80 | * Actually, there are two of them, MCT website calls them "Philips solution" |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 763e32a44be0..0d47f2c4d59f 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -81,12 +81,15 @@ struct moschip_serial { | |||
81 | 81 | ||
82 | static int debug; | 82 | static int debug; |
83 | 83 | ||
84 | static struct usb_serial_driver moschip7720_2port_driver; | ||
85 | |||
84 | #define USB_VENDOR_ID_MOSCHIP 0x9710 | 86 | #define USB_VENDOR_ID_MOSCHIP 0x9710 |
85 | #define MOSCHIP_DEVICE_ID_7720 0x7720 | 87 | #define MOSCHIP_DEVICE_ID_7720 0x7720 |
86 | #define MOSCHIP_DEVICE_ID_7715 0x7715 | 88 | #define MOSCHIP_DEVICE_ID_7715 0x7715 |
87 | 89 | ||
88 | static struct usb_device_id moschip_port_id_table[] = { | 90 | static const struct usb_device_id moschip_port_id_table[] = { |
89 | { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) }, | 91 | { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) }, |
92 | { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7715) }, | ||
90 | { } /* terminating entry */ | 93 | { } /* terminating entry */ |
91 | }; | 94 | }; |
92 | MODULE_DEVICE_TABLE(usb, moschip_port_id_table); | 95 | MODULE_DEVICE_TABLE(usb, moschip_port_id_table); |
@@ -106,7 +109,7 @@ static void mos7720_interrupt_callback(struct urb *urb) | |||
106 | __u8 sp1; | 109 | __u8 sp1; |
107 | __u8 sp2; | 110 | __u8 sp2; |
108 | 111 | ||
109 | dbg("%s", " : Entering\n"); | 112 | dbg(" : Entering"); |
110 | 113 | ||
111 | switch (status) { | 114 | switch (status) { |
112 | case 0: | 115 | case 0: |
@@ -186,6 +189,75 @@ exit: | |||
186 | } | 189 | } |
187 | 190 | ||
188 | /* | 191 | /* |
192 | * mos7715_interrupt_callback | ||
193 | * this is the 7715's callback function for when we have received data on | ||
194 | * the interrupt endpoint. | ||
195 | */ | ||
196 | static void mos7715_interrupt_callback(struct urb *urb) | ||
197 | { | ||
198 | int result; | ||
199 | int length; | ||
200 | int status = urb->status; | ||
201 | __u8 *data; | ||
202 | __u8 iir; | ||
203 | |||
204 | switch (status) { | ||
205 | case 0: | ||
206 | /* success */ | ||
207 | break; | ||
208 | case -ECONNRESET: | ||
209 | case -ENOENT: | ||
210 | case -ESHUTDOWN: | ||
211 | /* this urb is terminated, clean up */ | ||
212 | dbg("%s - urb shutting down with status: %d", __func__, | ||
213 | status); | ||
214 | return; | ||
215 | default: | ||
216 | dbg("%s - nonzero urb status received: %d", __func__, | ||
217 | status); | ||
218 | goto exit; | ||
219 | } | ||
220 | |||
221 | length = urb->actual_length; | ||
222 | data = urb->transfer_buffer; | ||
223 | |||
224 | /* Structure of data from 7715 device: | ||
225 | * Byte 1: IIR serial Port | ||
226 | * Byte 2: unused | ||
227 | * Byte 2: DSR parallel port | ||
228 | * Byte 4: FIFO status for both */ | ||
229 | |||
230 | if (unlikely(length != 4)) { | ||
231 | dbg("Wrong data !!!"); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | iir = data[0]; | ||
236 | if (!(iir & 0x01)) { /* serial port interrupt pending */ | ||
237 | switch (iir & 0x0f) { | ||
238 | case SERIAL_IIR_RLS: | ||
239 | dbg("Serial Port: Receiver status error or address " | ||
240 | "bit detected in 9-bit mode\n"); | ||
241 | break; | ||
242 | case SERIAL_IIR_CTI: | ||
243 | dbg("Serial Port: Receiver time out"); | ||
244 | break; | ||
245 | case SERIAL_IIR_MS: | ||
246 | dbg("Serial Port: Modem status change"); | ||
247 | break; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | exit: | ||
252 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
253 | if (result) | ||
254 | dev_err(&urb->dev->dev, | ||
255 | "%s - Error %d submitting control urb\n", | ||
256 | __func__, result); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | /* | ||
189 | * mos7720_bulk_in_callback | 261 | * mos7720_bulk_in_callback |
190 | * this is the callback function for when we have received data on the | 262 | * this is the callback function for when we have received data on the |
191 | * bulk in endpoint. | 263 | * bulk in endpoint. |
@@ -206,7 +278,7 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
206 | 278 | ||
207 | mos7720_port = urb->context; | 279 | mos7720_port = urb->context; |
208 | if (!mos7720_port) { | 280 | if (!mos7720_port) { |
209 | dbg("%s", "NULL mos7720_port pointer \n"); | 281 | dbg("NULL mos7720_port pointer"); |
210 | return ; | 282 | return ; |
211 | } | 283 | } |
212 | 284 | ||
@@ -218,7 +290,6 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
218 | 290 | ||
219 | tty = tty_port_tty_get(&port->port); | 291 | tty = tty_port_tty_get(&port->port); |
220 | if (tty && urb->actual_length) { | 292 | if (tty && urb->actual_length) { |
221 | tty_buffer_request_room(tty, urb->actual_length); | ||
222 | tty_insert_flip_string(tty, data, urb->actual_length); | 293 | tty_insert_flip_string(tty, data, urb->actual_length); |
223 | tty_flip_buffer_push(tty); | 294 | tty_flip_buffer_push(tty); |
224 | } | 295 | } |
@@ -275,17 +346,15 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) | |||
275 | * this function will be used for sending command to device | 346 | * this function will be used for sending command to device |
276 | */ | 347 | */ |
277 | static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value, | 348 | static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value, |
278 | __u16 index, void *data) | 349 | __u16 index, u8 *data) |
279 | { | 350 | { |
280 | int status; | 351 | int status; |
281 | unsigned int pipe; | 352 | u8 *buf; |
282 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | 353 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); |
283 | __u8 requesttype; | ||
284 | __u16 size = 0x0000; | ||
285 | 354 | ||
286 | if (value < MOS_MAX_PORT) { | 355 | if (value < MOS_MAX_PORT) { |
287 | if (product == MOSCHIP_DEVICE_ID_7715) | 356 | if (product == MOSCHIP_DEVICE_ID_7715) |
288 | value = value*0x100+0x100; | 357 | value = 0x0200; /* identifies the 7715's serial port */ |
289 | else | 358 | else |
290 | value = value*0x100+0x200; | 359 | value = value*0x100+0x200; |
291 | } else { | 360 | } else { |
@@ -298,27 +367,58 @@ static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value, | |||
298 | } | 367 | } |
299 | 368 | ||
300 | if (request == MOS_WRITE) { | 369 | if (request == MOS_WRITE) { |
301 | request = (__u8)MOS_WRITE; | 370 | value = value + *data; |
302 | requesttype = (__u8)0x40; | 371 | status = usb_control_msg(serial->dev, |
303 | value = value + (__u16)*((unsigned char *)data); | 372 | usb_sndctrlpipe(serial->dev, 0), MOS_WRITE, |
304 | data = NULL; | 373 | 0x40, value, index, NULL, 0, MOS_WDR_TIMEOUT); |
305 | pipe = usb_sndctrlpipe(serial->dev, 0); | ||
306 | } else { | 374 | } else { |
307 | request = (__u8)MOS_READ; | 375 | buf = kmalloc(1, GFP_KERNEL); |
308 | requesttype = (__u8)0xC0; | 376 | if (!buf) { |
309 | size = 0x01; | 377 | status = -ENOMEM; |
310 | pipe = usb_rcvctrlpipe(serial->dev, 0); | 378 | goto out; |
379 | } | ||
380 | status = usb_control_msg(serial->dev, | ||
381 | usb_rcvctrlpipe(serial->dev, 0), MOS_READ, | ||
382 | 0xc0, value, index, buf, 1, MOS_WDR_TIMEOUT); | ||
383 | *data = *buf; | ||
384 | kfree(buf); | ||
311 | } | 385 | } |
312 | 386 | out: | |
313 | status = usb_control_msg(serial->dev, pipe, request, requesttype, | ||
314 | value, index, data, size, MOS_WDR_TIMEOUT); | ||
315 | |||
316 | if (status < 0) | 387 | if (status < 0) |
317 | dbg("Command Write failed Value %x index %x\n", value, index); | 388 | dbg("Command Write failed Value %x index %x", value, index); |
318 | 389 | ||
319 | return status; | 390 | return status; |
320 | } | 391 | } |
321 | 392 | ||
393 | |||
394 | /* | ||
395 | * mos77xx_probe | ||
396 | * this function installs the appropriate read interrupt endpoint callback | ||
397 | * depending on whether the device is a 7720 or 7715, thus avoiding costly | ||
398 | * run-time checks in the high-frequency callback routine itself. | ||
399 | */ | ||
400 | static int mos77xx_probe(struct usb_serial *serial, | ||
401 | const struct usb_device_id *id) | ||
402 | { | ||
403 | if (id->idProduct == MOSCHIP_DEVICE_ID_7715) | ||
404 | moschip7720_2port_driver.read_int_callback = | ||
405 | mos7715_interrupt_callback; | ||
406 | else | ||
407 | moschip7720_2port_driver.read_int_callback = | ||
408 | mos7720_interrupt_callback; | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int mos77xx_calc_num_ports(struct usb_serial *serial) | ||
414 | { | ||
415 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | ||
416 | if (product == MOSCHIP_DEVICE_ID_7715) | ||
417 | return 1; | ||
418 | |||
419 | return 2; | ||
420 | } | ||
421 | |||
322 | static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) | 422 | static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) |
323 | { | 423 | { |
324 | struct usb_serial *serial; | 424 | struct usb_serial *serial; |
@@ -390,7 +490,7 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
390 | */ | 490 | */ |
391 | port_number = port->number - port->serial->minor; | 491 | port_number = port->number - port->serial->minor; |
392 | send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data); | 492 | send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data); |
393 | dbg("SS::%p LSR:%x\n", mos7720_port, data); | 493 | dbg("SS::%p LSR:%x", mos7720_port, data); |
394 | 494 | ||
395 | dbg("Check:Sending Command .........."); | 495 | dbg("Check:Sending Command .........."); |
396 | 496 | ||
@@ -729,7 +829,7 @@ static void mos7720_throttle(struct tty_struct *tty) | |||
729 | struct moschip_port *mos7720_port; | 829 | struct moschip_port *mos7720_port; |
730 | int status; | 830 | int status; |
731 | 831 | ||
732 | dbg("%s- port %d\n", __func__, port->number); | 832 | dbg("%s- port %d", __func__, port->number); |
733 | 833 | ||
734 | mos7720_port = usb_get_serial_port_data(port); | 834 | mos7720_port = usb_get_serial_port_data(port); |
735 | 835 | ||
@@ -1208,7 +1308,7 @@ static void mos7720_set_termios(struct tty_struct *tty, | |||
1208 | return; | 1308 | return; |
1209 | } | 1309 | } |
1210 | 1310 | ||
1211 | dbg("%s\n", "setting termios - ASPIRE"); | 1311 | dbg("setting termios - ASPIRE"); |
1212 | 1312 | ||
1213 | cflag = tty->termios->c_cflag; | 1313 | cflag = tty->termios->c_cflag; |
1214 | 1314 | ||
@@ -1226,7 +1326,7 @@ static void mos7720_set_termios(struct tty_struct *tty, | |||
1226 | change_port_settings(tty, mos7720_port, old_termios); | 1326 | change_port_settings(tty, mos7720_port, old_termios); |
1227 | 1327 | ||
1228 | if (!port->read_urb) { | 1328 | if (!port->read_urb) { |
1229 | dbg("%s", "URB KILLED !!!!!\n"); | 1329 | dbg("URB KILLED !!!!!"); |
1230 | return; | 1330 | return; |
1231 | } | 1331 | } |
1232 | 1332 | ||
@@ -1495,6 +1595,7 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1495 | struct usb_device *dev; | 1595 | struct usb_device *dev; |
1496 | int i; | 1596 | int i; |
1497 | char data; | 1597 | char data; |
1598 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | ||
1498 | 1599 | ||
1499 | dbg("%s: Entering ..........", __func__); | 1600 | dbg("%s: Entering ..........", __func__); |
1500 | 1601 | ||
@@ -1514,6 +1615,29 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1514 | 1615 | ||
1515 | usb_set_serial_data(serial, mos7720_serial); | 1616 | usb_set_serial_data(serial, mos7720_serial); |
1516 | 1617 | ||
1618 | /* | ||
1619 | * The 7715 uses the first bulk in/out endpoint pair for the parallel | ||
1620 | * port, and the second for the serial port. Because the usbserial core | ||
1621 | * assumes both pairs are serial ports, we must engage in a bit of | ||
1622 | * subterfuge and swap the pointers for ports 0 and 1 in order to make | ||
1623 | * port 0 point to the serial port. However, both moschip devices use a | ||
1624 | * single interrupt-in endpoint for both ports (as mentioned a little | ||
1625 | * further down), and this endpoint was assigned to port 0. So after | ||
1626 | * the swap, we must copy the interrupt endpoint elements from port 1 | ||
1627 | * (as newly assigned) to port 0, and null out port 1 pointers. | ||
1628 | */ | ||
1629 | if (product == MOSCHIP_DEVICE_ID_7715) { | ||
1630 | struct usb_serial_port *tmp = serial->port[0]; | ||
1631 | serial->port[0] = serial->port[1]; | ||
1632 | serial->port[1] = tmp; | ||
1633 | serial->port[0]->interrupt_in_urb = tmp->interrupt_in_urb; | ||
1634 | serial->port[0]->interrupt_in_buffer = tmp->interrupt_in_buffer; | ||
1635 | serial->port[0]->interrupt_in_endpointAddress = | ||
1636 | tmp->interrupt_in_endpointAddress; | ||
1637 | serial->port[1]->interrupt_in_urb = NULL; | ||
1638 | serial->port[1]->interrupt_in_buffer = NULL; | ||
1639 | } | ||
1640 | |||
1517 | /* we set up the pointers to the endpoints in the mos7720_open * | 1641 | /* we set up the pointers to the endpoints in the mos7720_open * |
1518 | * function, as the structures aren't created yet. */ | 1642 | * function, as the structures aren't created yet. */ |
1519 | 1643 | ||
@@ -1529,7 +1653,7 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1529 | 1653 | ||
1530 | /* Initialize all port interrupt end point to port 0 int | 1654 | /* Initialize all port interrupt end point to port 0 int |
1531 | * endpoint. Our device has only one interrupt endpoint | 1655 | * endpoint. Our device has only one interrupt endpoint |
1532 | * comman to all ports */ | 1656 | * common to all ports */ |
1533 | serial->port[i]->interrupt_in_endpointAddress = | 1657 | serial->port[i]->interrupt_in_endpointAddress = |
1534 | serial->port[0]->interrupt_in_endpointAddress; | 1658 | serial->port[0]->interrupt_in_endpointAddress; |
1535 | 1659 | ||
@@ -1584,11 +1708,12 @@ static struct usb_serial_driver moschip7720_2port_driver = { | |||
1584 | .description = "Moschip 2 port adapter", | 1708 | .description = "Moschip 2 port adapter", |
1585 | .usb_driver = &usb_driver, | 1709 | .usb_driver = &usb_driver, |
1586 | .id_table = moschip_port_id_table, | 1710 | .id_table = moschip_port_id_table, |
1587 | .num_ports = 2, | 1711 | .calc_num_ports = mos77xx_calc_num_ports, |
1588 | .open = mos7720_open, | 1712 | .open = mos7720_open, |
1589 | .close = mos7720_close, | 1713 | .close = mos7720_close, |
1590 | .throttle = mos7720_throttle, | 1714 | .throttle = mos7720_throttle, |
1591 | .unthrottle = mos7720_unthrottle, | 1715 | .unthrottle = mos7720_unthrottle, |
1716 | .probe = mos77xx_probe, | ||
1592 | .attach = mos7720_startup, | 1717 | .attach = mos7720_startup, |
1593 | .release = mos7720_release, | 1718 | .release = mos7720_release, |
1594 | .ioctl = mos7720_ioctl, | 1719 | .ioctl = mos7720_ioctl, |
@@ -1600,7 +1725,7 @@ static struct usb_serial_driver moschip7720_2port_driver = { | |||
1600 | .chars_in_buffer = mos7720_chars_in_buffer, | 1725 | .chars_in_buffer = mos7720_chars_in_buffer, |
1601 | .break_ctl = mos7720_break, | 1726 | .break_ctl = mos7720_break, |
1602 | .read_bulk_callback = mos7720_bulk_in_callback, | 1727 | .read_bulk_callback = mos7720_bulk_in_callback, |
1603 | .read_int_callback = mos7720_interrupt_callback, | 1728 | .read_int_callback = NULL /* dynamically assigned in probe() */ |
1604 | }; | 1729 | }; |
1605 | 1730 | ||
1606 | static int __init moschip7720_init(void) | 1731 | static int __init moschip7720_init(void) |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2cfe2451ed97..2fda1c0182b7 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -181,7 +181,7 @@ | |||
181 | #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ | 181 | #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ |
182 | 182 | ||
183 | 183 | ||
184 | static struct usb_device_id moschip_port_id_table[] = { | 184 | static const struct usb_device_id moschip_port_id_table[] = { |
185 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 185 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
186 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 186 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
187 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, | 187 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
@@ -198,7 +198,7 @@ static struct usb_device_id moschip_port_id_table[] = { | |||
198 | {} /* terminating entry */ | 198 | {} /* terminating entry */ |
199 | }; | 199 | }; |
200 | 200 | ||
201 | static __devinitdata struct usb_device_id moschip_id_table_combined[] = { | 201 | static const struct usb_device_id moschip_id_table_combined[] __devinitconst = { |
202 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 202 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
203 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 203 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
204 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, | 204 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
@@ -283,12 +283,19 @@ static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg, | |||
283 | { | 283 | { |
284 | struct usb_device *dev = port->serial->dev; | 284 | struct usb_device *dev = port->serial->dev; |
285 | int ret = 0; | 285 | int ret = 0; |
286 | u8 *buf; | ||
287 | |||
288 | buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL); | ||
289 | if (!buf) | ||
290 | return -ENOMEM; | ||
286 | 291 | ||
287 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, | 292 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, |
288 | MCS_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH, | 293 | MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH, |
289 | MOS_WDR_TIMEOUT); | 294 | MOS_WDR_TIMEOUT); |
295 | *val = buf[0]; | ||
290 | dbg("mos7840_get_reg_sync offset is %x, return val %x", reg, *val); | 296 | dbg("mos7840_get_reg_sync offset is %x, return val %x", reg, *val); |
291 | *val = (*val) & 0x00ff; | 297 | |
298 | kfree(buf); | ||
292 | return ret; | 299 | return ret; |
293 | } | 300 | } |
294 | 301 | ||
@@ -341,6 +348,11 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, | |||
341 | struct usb_device *dev = port->serial->dev; | 348 | struct usb_device *dev = port->serial->dev; |
342 | int ret = 0; | 349 | int ret = 0; |
343 | __u16 Wval; | 350 | __u16 Wval; |
351 | u8 *buf; | ||
352 | |||
353 | buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL); | ||
354 | if (!buf) | ||
355 | return -ENOMEM; | ||
344 | 356 | ||
345 | /* dbg("application number is %4x", | 357 | /* dbg("application number is %4x", |
346 | (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */ | 358 | (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */ |
@@ -364,9 +376,11 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, | |||
364 | } | 376 | } |
365 | } | 377 | } |
366 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, | 378 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, |
367 | MCS_RD_RTYPE, Wval, reg, val, VENDOR_READ_LENGTH, | 379 | MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH, |
368 | MOS_WDR_TIMEOUT); | 380 | MOS_WDR_TIMEOUT); |
369 | *val = (*val) & 0x00ff; | 381 | *val = buf[0]; |
382 | |||
383 | kfree(buf); | ||
370 | return ret; | 384 | return ret; |
371 | } | 385 | } |
372 | 386 | ||
@@ -750,7 +764,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
750 | if (urb->actual_length) { | 764 | if (urb->actual_length) { |
751 | tty = tty_port_tty_get(&mos7840_port->port->port); | 765 | tty = tty_port_tty_get(&mos7840_port->port->port); |
752 | if (tty) { | 766 | if (tty) { |
753 | tty_buffer_request_room(tty, urb->actual_length); | ||
754 | tty_insert_flip_string(tty, data, urb->actual_length); | 767 | tty_insert_flip_string(tty, data, urb->actual_length); |
755 | dbg(" %s ", data); | 768 | dbg(" %s ", data); |
756 | tty_flip_buffer_push(tty); | 769 | tty_flip_buffer_push(tty); |
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c index 99bd00f5188a..cf1718394e18 100644 --- a/drivers/usb/serial/moto_modem.c +++ b/drivers/usb/serial/moto_modem.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
22 | #include <linux/usb/serial.h> | 22 | #include <linux/usb/serial.h> |
23 | 23 | ||
24 | static struct usb_device_id id_table [] = { | 24 | static const struct usb_device_id id_table[] = { |
25 | { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ | 25 | { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ |
26 | { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ | 26 | { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ |
27 | { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ | 27 | { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 5ceaa4c6be09..04a6cbbed2c0 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | static int debug; | 23 | static int debug; |
24 | 24 | ||
25 | static struct usb_device_id id_table [] = { | 25 | static const struct usb_device_id id_table[] = { |
26 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ | 26 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ |
27 | { }, | 27 | { }, |
28 | }; | 28 | }; |
@@ -66,7 +66,6 @@ static void navman_read_int_callback(struct urb *urb) | |||
66 | 66 | ||
67 | tty = tty_port_tty_get(&port->port); | 67 | tty = tty_port_tty_get(&port->port); |
68 | if (tty && urb->actual_length) { | 68 | if (tty && urb->actual_length) { |
69 | tty_buffer_request_room(tty, urb->actual_length); | ||
70 | tty_insert_flip_string(tty, data, urb->actual_length); | 69 | tty_insert_flip_string(tty, data, urb->actual_length); |
71 | tty_flip_buffer_push(tty); | 70 | tty_flip_buffer_push(tty); |
72 | } | 71 | } |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 062265038bf0..89c724c0ac0a 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -75,7 +75,7 @@ static void omninet_disconnect(struct usb_serial *serial); | |||
75 | static void omninet_release(struct usb_serial *serial); | 75 | static void omninet_release(struct usb_serial *serial); |
76 | static int omninet_attach(struct usb_serial *serial); | 76 | static int omninet_attach(struct usb_serial *serial); |
77 | 77 | ||
78 | static struct usb_device_id id_table[] = { | 78 | static const struct usb_device_id id_table[] = { |
79 | { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, | 79 | { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, |
80 | { USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) }, | 80 | { USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) }, |
81 | { } /* Terminating entry */ | 81 | { } /* Terminating entry */ |
@@ -218,8 +218,8 @@ static void omninet_read_bulk_callback(struct urb *urb) | |||
218 | 218 | ||
219 | if (debug && header->oh_xxx != 0x30) { | 219 | if (debug && header->oh_xxx != 0x30) { |
220 | if (urb->actual_length) { | 220 | if (urb->actual_length) { |
221 | printk(KERN_DEBUG __FILE__ | 221 | printk(KERN_DEBUG "%s: omninet_read %d: ", |
222 | ": omninet_read %d: ", header->oh_len); | 222 | __FILE__, header->oh_len); |
223 | for (i = 0; i < (header->oh_len + | 223 | for (i = 0; i < (header->oh_len + |
224 | OMNINET_HEADERLEN); i++) | 224 | OMNINET_HEADERLEN); i++) |
225 | printk("%.2x ", data[i]); | 225 | printk("%.2x ", data[i]); |
@@ -332,7 +332,7 @@ static void omninet_write_bulk_callback(struct urb *urb) | |||
332 | struct usb_serial_port *port = urb->context; | 332 | struct usb_serial_port *port = urb->context; |
333 | int status = urb->status; | 333 | int status = urb->status; |
334 | 334 | ||
335 | dbg("%s - port %0x\n", __func__, port->number); | 335 | dbg("%s - port %0x", __func__, port->number); |
336 | 336 | ||
337 | port->write_urb_busy = 0; | 337 | port->write_urb_busy = 0; |
338 | if (status) { | 338 | if (status) { |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 4cdb975caa89..f37476e22684 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | static int debug; | 23 | static int debug; |
24 | 24 | ||
25 | static struct usb_device_id id_table[] = { | 25 | static const struct usb_device_id id_table[] = { |
26 | { USB_DEVICE(0x065a, 0x0009) }, | 26 | { USB_DEVICE(0x065a, 0x0009) }, |
27 | { }, | 27 | { }, |
28 | }; | 28 | }; |
@@ -55,7 +55,6 @@ static void opticon_bulk_callback(struct urb *urb) | |||
55 | int status = urb->status; | 55 | int status = urb->status; |
56 | struct tty_struct *tty; | 56 | struct tty_struct *tty; |
57 | int result; | 57 | int result; |
58 | int available_room = 0; | ||
59 | int data_length; | 58 | int data_length; |
60 | 59 | ||
61 | dbg("%s - port %d", __func__, port->number); | 60 | dbg("%s - port %d", __func__, port->number); |
@@ -96,13 +95,9 @@ static void opticon_bulk_callback(struct urb *urb) | |||
96 | /* real data, send it to the tty layer */ | 95 | /* real data, send it to the tty layer */ |
97 | tty = tty_port_tty_get(&port->port); | 96 | tty = tty_port_tty_get(&port->port); |
98 | if (tty) { | 97 | if (tty) { |
99 | available_room = tty_buffer_request_room(tty, | 98 | tty_insert_flip_string(tty, data, |
100 | data_length); | 99 | data_length); |
101 | if (available_room) { | 100 | tty_flip_buffer_push(tty); |
102 | tty_insert_flip_string(tty, data, | ||
103 | available_room); | ||
104 | tty_flip_buffer_push(tty); | ||
105 | } | ||
106 | tty_kref_put(tty); | 101 | tty_kref_put(tty); |
107 | } | 102 | } |
108 | } else { | 103 | } else { |
@@ -217,7 +212,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
217 | spin_lock_irqsave(&priv->lock, flags); | 212 | spin_lock_irqsave(&priv->lock, flags); |
218 | if (priv->outstanding_urbs > URB_UPPER_LIMIT) { | 213 | if (priv->outstanding_urbs > URB_UPPER_LIMIT) { |
219 | spin_unlock_irqrestore(&priv->lock, flags); | 214 | spin_unlock_irqrestore(&priv->lock, flags); |
220 | dbg("%s - write limit hit\n", __func__); | 215 | dbg("%s - write limit hit", __func__); |
221 | return 0; | 216 | return 0; |
222 | } | 217 | } |
223 | priv->outstanding_urbs++; | 218 | priv->outstanding_urbs++; |
@@ -288,7 +283,7 @@ static int opticon_write_room(struct tty_struct *tty) | |||
288 | spin_lock_irqsave(&priv->lock, flags); | 283 | spin_lock_irqsave(&priv->lock, flags); |
289 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { | 284 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { |
290 | spin_unlock_irqrestore(&priv->lock, flags); | 285 | spin_unlock_irqrestore(&priv->lock, flags); |
291 | dbg("%s - write limit hit\n", __func__); | 286 | dbg("%s - write limit hit", __func__); |
292 | return 0; | 287 | return 0; |
293 | } | 288 | } |
294 | spin_unlock_irqrestore(&priv->lock, flags); | 289 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6e94a6711f08..847b805d63a3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -336,15 +336,42 @@ static int option_resume(struct usb_serial *serial); | |||
336 | #define AIRPLUS_VENDOR_ID 0x1011 | 336 | #define AIRPLUS_VENDOR_ID 0x1011 |
337 | #define AIRPLUS_PRODUCT_MCD650 0x3198 | 337 | #define AIRPLUS_PRODUCT_MCD650 0x3198 |
338 | 338 | ||
339 | /* Longcheer/Longsung vendor ID; makes whitelabel devices that | ||
340 | * many other vendors like 4G Systems, Alcatel, ChinaBird, | ||
341 | * Mobidata, etc sell under their own brand names. | ||
342 | */ | ||
343 | #define LONGCHEER_VENDOR_ID 0x1c9e | ||
344 | |||
339 | /* 4G Systems products */ | 345 | /* 4G Systems products */ |
340 | #define FOUR_G_SYSTEMS_VENDOR_ID 0x1c9e | 346 | /* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick * |
347 | * It seems to contain a Qualcomm QSC6240/6290 chipset */ | ||
341 | #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 | 348 | #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 |
342 | 349 | ||
343 | /* Haier products */ | 350 | /* Haier products */ |
344 | #define HAIER_VENDOR_ID 0x201e | 351 | #define HAIER_VENDOR_ID 0x201e |
345 | #define HAIER_PRODUCT_CE100 0x2009 | 352 | #define HAIER_PRODUCT_CE100 0x2009 |
346 | 353 | ||
347 | static struct usb_device_id option_ids[] = { | 354 | /* some devices interfaces need special handling due to a number of reasons */ |
355 | enum option_blacklist_reason { | ||
356 | OPTION_BLACKLIST_NONE = 0, | ||
357 | OPTION_BLACKLIST_SENDSETUP = 1, | ||
358 | OPTION_BLACKLIST_RESERVED_IF = 2 | ||
359 | }; | ||
360 | |||
361 | struct option_blacklist_info { | ||
362 | const u32 infolen; /* number of interface numbers on blacklist */ | ||
363 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | ||
364 | enum option_blacklist_reason reason; | ||
365 | }; | ||
366 | |||
367 | static const u8 four_g_w14_no_sendsetup[] = { 0, 1 }; | ||
368 | static const struct option_blacklist_info four_g_w14_blacklist = { | ||
369 | .infolen = ARRAY_SIZE(four_g_w14_no_sendsetup), | ||
370 | .ifaceinfo = four_g_w14_no_sendsetup, | ||
371 | .reason = OPTION_BLACKLIST_SENDSETUP | ||
372 | }; | ||
373 | |||
374 | static const struct usb_device_id option_ids[] = { | ||
348 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 375 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
349 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 376 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
350 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, | 377 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, |
@@ -644,7 +671,9 @@ static struct usb_device_id option_ids[] = { | |||
644 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, | 671 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, |
645 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 672 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
646 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, | 673 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, |
647 | { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) }, | 674 | { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), |
675 | .driver_info = (kernel_ulong_t)&four_g_w14_blacklist | ||
676 | }, | ||
648 | { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, | 677 | { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, |
649 | { } /* Terminating entry */ | 678 | { } /* Terminating entry */ |
650 | }; | 679 | }; |
@@ -709,6 +738,7 @@ struct option_intf_private { | |||
709 | spinlock_t susp_lock; | 738 | spinlock_t susp_lock; |
710 | unsigned int suspended:1; | 739 | unsigned int suspended:1; |
711 | int in_flight; | 740 | int in_flight; |
741 | struct option_blacklist_info *blacklist_info; | ||
712 | }; | 742 | }; |
713 | 743 | ||
714 | struct option_port_private { | 744 | struct option_port_private { |
@@ -778,9 +808,27 @@ static int option_probe(struct usb_serial *serial, | |||
778 | if (!data) | 808 | if (!data) |
779 | return -ENOMEM; | 809 | return -ENOMEM; |
780 | spin_lock_init(&data->susp_lock); | 810 | spin_lock_init(&data->susp_lock); |
811 | data->blacklist_info = (struct option_blacklist_info*) id->driver_info; | ||
781 | return 0; | 812 | return 0; |
782 | } | 813 | } |
783 | 814 | ||
815 | static enum option_blacklist_reason is_blacklisted(const u8 ifnum, | ||
816 | const struct option_blacklist_info *blacklist) | ||
817 | { | ||
818 | const u8 *info; | ||
819 | int i; | ||
820 | |||
821 | if (blacklist) { | ||
822 | info = blacklist->ifaceinfo; | ||
823 | |||
824 | for (i = 0; i < blacklist->infolen; i++) { | ||
825 | if (info[i] == ifnum) | ||
826 | return blacklist->reason; | ||
827 | } | ||
828 | } | ||
829 | return OPTION_BLACKLIST_NONE; | ||
830 | } | ||
831 | |||
784 | static void option_set_termios(struct tty_struct *tty, | 832 | static void option_set_termios(struct tty_struct *tty, |
785 | struct usb_serial_port *port, struct ktermios *old_termios) | 833 | struct usb_serial_port *port, struct ktermios *old_termios) |
786 | { | 834 | { |
@@ -921,7 +969,6 @@ static void option_indat_callback(struct urb *urb) | |||
921 | } else { | 969 | } else { |
922 | tty = tty_port_tty_get(&port->port); | 970 | tty = tty_port_tty_get(&port->port); |
923 | if (urb->actual_length) { | 971 | if (urb->actual_length) { |
924 | tty_buffer_request_room(tty, urb->actual_length); | ||
925 | tty_insert_flip_string(tty, data, urb->actual_length); | 972 | tty_insert_flip_string(tty, data, urb->actual_length); |
926 | tty_flip_buffer_push(tty); | 973 | tty_flip_buffer_push(tty); |
927 | } else | 974 | } else |
@@ -929,9 +976,9 @@ static void option_indat_callback(struct urb *urb) | |||
929 | tty_kref_put(tty); | 976 | tty_kref_put(tty); |
930 | 977 | ||
931 | /* Resubmit urb so we continue receiving */ | 978 | /* Resubmit urb so we continue receiving */ |
932 | if (port->port.count && status != -ESHUTDOWN) { | 979 | if (status != -ESHUTDOWN) { |
933 | err = usb_submit_urb(urb, GFP_ATOMIC); | 980 | err = usb_submit_urb(urb, GFP_ATOMIC); |
934 | if (err) | 981 | if (err && err != -EPERM) |
935 | printk(KERN_ERR "%s: resubmit read urb failed. " | 982 | printk(KERN_ERR "%s: resubmit read urb failed. " |
936 | "(%d)", __func__, err); | 983 | "(%d)", __func__, err); |
937 | else | 984 | else |
@@ -985,7 +1032,7 @@ static void option_instat_callback(struct urb *urb) | |||
985 | (struct usb_ctrlrequest *)urb->transfer_buffer; | 1032 | (struct usb_ctrlrequest *)urb->transfer_buffer; |
986 | 1033 | ||
987 | if (!req_pkt) { | 1034 | if (!req_pkt) { |
988 | dbg("%s: NULL req_pkt\n", __func__); | 1035 | dbg("%s: NULL req_pkt", __func__); |
989 | return; | 1036 | return; |
990 | } | 1037 | } |
991 | if ((req_pkt->bRequestType == 0xA1) && | 1038 | if ((req_pkt->bRequestType == 0xA1) && |
@@ -1211,11 +1258,19 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
1211 | static int option_send_setup(struct usb_serial_port *port) | 1258 | static int option_send_setup(struct usb_serial_port *port) |
1212 | { | 1259 | { |
1213 | struct usb_serial *serial = port->serial; | 1260 | struct usb_serial *serial = port->serial; |
1261 | struct option_intf_private *intfdata = | ||
1262 | (struct option_intf_private *) serial->private; | ||
1214 | struct option_port_private *portdata; | 1263 | struct option_port_private *portdata; |
1215 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | 1264 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; |
1216 | int val = 0; | 1265 | int val = 0; |
1217 | dbg("%s", __func__); | 1266 | dbg("%s", __func__); |
1218 | 1267 | ||
1268 | if (is_blacklisted(ifNum, intfdata->blacklist_info) == | ||
1269 | OPTION_BLACKLIST_SENDSETUP) { | ||
1270 | dbg("No send_setup on blacklisted interface #%d\n", ifNum); | ||
1271 | return -EIO; | ||
1272 | } | ||
1273 | |||
1219 | portdata = usb_get_serial_port_data(port); | 1274 | portdata = usb_get_serial_port_data(port); |
1220 | 1275 | ||
1221 | if (portdata->dtr_state) | 1276 | if (portdata->dtr_state) |
@@ -1401,7 +1456,7 @@ static int option_resume(struct usb_serial *serial) | |||
1401 | for (i = 0; i < serial->num_ports; i++) { | 1456 | for (i = 0; i < serial->num_ports; i++) { |
1402 | port = serial->port[i]; | 1457 | port = serial->port[i]; |
1403 | if (!port->interrupt_in_urb) { | 1458 | if (!port->interrupt_in_urb) { |
1404 | dbg("%s: No interrupt URB for port %d\n", __func__, i); | 1459 | dbg("%s: No interrupt URB for port %d", __func__, i); |
1405 | continue; | 1460 | continue; |
1406 | } | 1461 | } |
1407 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | 1462 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index c644e26394b4..deeacdea05db 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -58,7 +58,7 @@ | |||
58 | #define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>" | 58 | #define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>" |
59 | #define OTI6858_VERSION "0.1" | 59 | #define OTI6858_VERSION "0.1" |
60 | 60 | ||
61 | static struct usb_device_id id_table [] = { | 61 | static const struct usb_device_id id_table[] = { |
62 | { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) }, | 62 | { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) }, |
63 | { } | 63 | { } |
64 | }; | 64 | }; |
@@ -302,7 +302,7 @@ void send_data(struct work_struct *work) | |||
302 | struct usb_serial_port *port = priv->port; | 302 | struct usb_serial_port *port = priv->port; |
303 | int count = 0, result; | 303 | int count = 0, result; |
304 | unsigned long flags; | 304 | unsigned long flags; |
305 | unsigned char allow; | 305 | u8 *allow; |
306 | 306 | ||
307 | dbg("%s(port = %d)", __func__, port->number); | 307 | dbg("%s(port = %d)", __func__, port->number); |
308 | 308 | ||
@@ -321,13 +321,20 @@ void send_data(struct work_struct *work) | |||
321 | count = port->bulk_out_size; | 321 | count = port->bulk_out_size; |
322 | 322 | ||
323 | if (count != 0) { | 323 | if (count != 0) { |
324 | allow = kmalloc(1, GFP_KERNEL); | ||
325 | if (!allow) { | ||
326 | dev_err(&port->dev, "%s(): kmalloc failed\n", | ||
327 | __func__); | ||
328 | return; | ||
329 | } | ||
324 | result = usb_control_msg(port->serial->dev, | 330 | result = usb_control_msg(port->serial->dev, |
325 | usb_rcvctrlpipe(port->serial->dev, 0), | 331 | usb_rcvctrlpipe(port->serial->dev, 0), |
326 | OTI6858_REQ_T_CHECK_TXBUFF, | 332 | OTI6858_REQ_T_CHECK_TXBUFF, |
327 | OTI6858_REQ_CHECK_TXBUFF, | 333 | OTI6858_REQ_CHECK_TXBUFF, |
328 | count, 0, &allow, 1, 100); | 334 | count, 0, allow, 1, 100); |
329 | if (result != 1 || allow != 0) | 335 | if (result != 1 || *allow != 0) |
330 | count = 0; | 336 | count = 0; |
337 | kfree(allow); | ||
331 | } | 338 | } |
332 | 339 | ||
333 | if (count == 0) { | 340 | if (count == 0) { |
@@ -578,9 +585,6 @@ static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
578 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 585 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
579 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 586 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
580 | 587 | ||
581 | if (port->port.count != 1) | ||
582 | return 0; | ||
583 | |||
584 | buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); | 588 | buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); |
585 | if (buf == NULL) { | 589 | if (buf == NULL) { |
586 | dev_err(&port->dev, "%s(): out of memory!\n", __func__); | 590 | dev_err(&port->dev, "%s(): out of memory!\n", __func__); |
@@ -927,10 +931,6 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
927 | spin_unlock_irqrestore(&priv->lock, flags); | 931 | spin_unlock_irqrestore(&priv->lock, flags); |
928 | 932 | ||
929 | if (status != 0) { | 933 | if (status != 0) { |
930 | if (!port->port.count) { | ||
931 | dbg("%s(): port is closed, exiting", __func__); | ||
932 | return; | ||
933 | } | ||
934 | /* | 934 | /* |
935 | if (status == -EPROTO) { | 935 | if (status == -EPROTO) { |
936 | * PL2303 mysteriously fails with -EPROTO reschedule | 936 | * PL2303 mysteriously fails with -EPROTO reschedule |
@@ -954,14 +954,12 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
954 | } | 954 | } |
955 | tty_kref_put(tty); | 955 | tty_kref_put(tty); |
956 | 956 | ||
957 | /* schedule the interrupt urb if we are still open */ | 957 | /* schedule the interrupt urb */ |
958 | if (port->port.count != 0) { | 958 | port->interrupt_in_urb->dev = port->serial->dev; |
959 | port->interrupt_in_urb->dev = port->serial->dev; | 959 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
960 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 960 | if (result != 0 && result != -EPERM) { |
961 | if (result != 0) { | 961 | dev_err(&port->dev, "%s(): usb_submit_urb() failed," |
962 | dev_err(&port->dev, "%s(): usb_submit_urb() failed," | 962 | " error %d\n", __func__, result); |
963 | " error %d\n", __func__, result); | ||
964 | } | ||
965 | } | 963 | } |
966 | } | 964 | } |
967 | 965 | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 9ec1a49e2362..73d5f346d3e0 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -50,7 +50,7 @@ struct pl2303_buf { | |||
50 | char *buf_put; | 50 | char *buf_put; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static struct usb_device_id id_table [] = { | 53 | static const struct usb_device_id id_table[] = { |
54 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) }, | 54 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) }, |
55 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) }, | 55 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) }, |
56 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) }, | 56 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) }, |
@@ -451,7 +451,6 @@ static void pl2303_send(struct usb_serial_port *port) | |||
451 | port->write_urb->transfer_buffer); | 451 | port->write_urb->transfer_buffer); |
452 | 452 | ||
453 | port->write_urb->transfer_buffer_length = count; | 453 | port->write_urb->transfer_buffer_length = count; |
454 | port->write_urb->dev = port->serial->dev; | ||
455 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 454 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); |
456 | if (result) { | 455 | if (result) { |
457 | dev_err(&port->dev, "%s - failed submitting write urb," | 456 | dev_err(&port->dev, "%s - failed submitting write urb," |
@@ -769,7 +768,6 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
769 | pl2303_set_termios(tty, port, &tmp_termios); | 768 | pl2303_set_termios(tty, port, &tmp_termios); |
770 | 769 | ||
771 | dbg("%s - submitting read urb", __func__); | 770 | dbg("%s - submitting read urb", __func__); |
772 | port->read_urb->dev = serial->dev; | ||
773 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | 771 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); |
774 | if (result) { | 772 | if (result) { |
775 | dev_err(&port->dev, "%s - failed submitting read urb," | 773 | dev_err(&port->dev, "%s - failed submitting read urb," |
@@ -779,7 +777,6 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
779 | } | 777 | } |
780 | 778 | ||
781 | dbg("%s - submitting interrupt urb", __func__); | 779 | dbg("%s - submitting interrupt urb", __func__); |
782 | port->interrupt_in_urb->dev = serial->dev; | ||
783 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 780 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
784 | if (result) { | 781 | if (result) { |
785 | dev_err(&port->dev, "%s - failed submitting interrupt urb," | 782 | dev_err(&port->dev, "%s - failed submitting interrupt urb," |
@@ -895,10 +892,23 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | |||
895 | static int pl2303_ioctl(struct tty_struct *tty, struct file *file, | 892 | static int pl2303_ioctl(struct tty_struct *tty, struct file *file, |
896 | unsigned int cmd, unsigned long arg) | 893 | unsigned int cmd, unsigned long arg) |
897 | { | 894 | { |
895 | struct serial_struct ser; | ||
898 | struct usb_serial_port *port = tty->driver_data; | 896 | struct usb_serial_port *port = tty->driver_data; |
899 | dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); | 897 | dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); |
900 | 898 | ||
901 | switch (cmd) { | 899 | switch (cmd) { |
900 | case TIOCGSERIAL: | ||
901 | memset(&ser, 0, sizeof ser); | ||
902 | ser.type = PORT_16654; | ||
903 | ser.line = port->serial->minor; | ||
904 | ser.port = port->number; | ||
905 | ser.baud_base = 460800; | ||
906 | |||
907 | if (copy_to_user((void __user *)arg, &ser, sizeof ser)) | ||
908 | return -EFAULT; | ||
909 | |||
910 | return 0; | ||
911 | |||
902 | case TIOCMIWAIT: | 912 | case TIOCMIWAIT: |
903 | dbg("%s (%d) TIOCMIWAIT", __func__, port->number); | 913 | dbg("%s (%d) TIOCMIWAIT", __func__, port->number); |
904 | return wait_modem_info(port, arg); | 914 | return wait_modem_info(port, arg); |
@@ -1042,7 +1052,6 @@ static void pl2303_push_data(struct tty_struct *tty, | |||
1042 | tty_flag = TTY_FRAME; | 1052 | tty_flag = TTY_FRAME; |
1043 | dbg("%s - tty_flag = %d", __func__, tty_flag); | 1053 | dbg("%s - tty_flag = %d", __func__, tty_flag); |
1044 | 1054 | ||
1045 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
1046 | /* overrun is special, not associated with a char */ | 1055 | /* overrun is special, not associated with a char */ |
1047 | if (line_status & UART_OVERRUN_ERROR) | 1056 | if (line_status & UART_OVERRUN_ERROR) |
1048 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1057 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
@@ -1072,16 +1081,11 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1072 | 1081 | ||
1073 | if (status) { | 1082 | if (status) { |
1074 | dbg("%s - urb status = %d", __func__, status); | 1083 | dbg("%s - urb status = %d", __func__, status); |
1075 | if (!port->port.count) { | ||
1076 | dbg("%s - port is closed, exiting.", __func__); | ||
1077 | return; | ||
1078 | } | ||
1079 | if (status == -EPROTO) { | 1084 | if (status == -EPROTO) { |
1080 | /* PL2303 mysteriously fails with -EPROTO reschedule | 1085 | /* PL2303 mysteriously fails with -EPROTO reschedule |
1081 | * the read */ | 1086 | * the read */ |
1082 | dbg("%s - caught -EPROTO, resubmitting the urb", | 1087 | dbg("%s - caught -EPROTO, resubmitting the urb", |
1083 | __func__); | 1088 | __func__); |
1084 | urb->dev = port->serial->dev; | ||
1085 | result = usb_submit_urb(urb, GFP_ATOMIC); | 1089 | result = usb_submit_urb(urb, GFP_ATOMIC); |
1086 | if (result) | 1090 | if (result) |
1087 | dev_err(&urb->dev->dev, "%s - failed" | 1091 | dev_err(&urb->dev->dev, "%s - failed" |
@@ -1108,15 +1112,10 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1108 | } | 1112 | } |
1109 | tty_kref_put(tty); | 1113 | tty_kref_put(tty); |
1110 | /* Schedule the next read _if_ we are still open */ | 1114 | /* Schedule the next read _if_ we are still open */ |
1111 | if (port->port.count) { | 1115 | result = usb_submit_urb(urb, GFP_ATOMIC); |
1112 | urb->dev = port->serial->dev; | 1116 | if (result && result != -EPERM) |
1113 | result = usb_submit_urb(urb, GFP_ATOMIC); | 1117 | dev_err(&urb->dev->dev, "%s - failed resubmitting" |
1114 | if (result) | 1118 | " read urb, error %d\n", __func__, result); |
1115 | dev_err(&urb->dev->dev, "%s - failed resubmitting" | ||
1116 | " read urb, error %d\n", __func__, result); | ||
1117 | } | ||
1118 | |||
1119 | return; | ||
1120 | } | 1119 | } |
1121 | 1120 | ||
1122 | static void pl2303_write_bulk_callback(struct urb *urb) | 1121 | static void pl2303_write_bulk_callback(struct urb *urb) |
@@ -1146,7 +1145,6 @@ static void pl2303_write_bulk_callback(struct urb *urb) | |||
1146 | dbg("%s - nonzero write bulk status received: %d", __func__, | 1145 | dbg("%s - nonzero write bulk status received: %d", __func__, |
1147 | status); | 1146 | status); |
1148 | port->write_urb->transfer_buffer_length = 1; | 1147 | port->write_urb->transfer_buffer_length = 1; |
1149 | port->write_urb->dev = port->serial->dev; | ||
1150 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 1148 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); |
1151 | if (result) | 1149 | if (result) |
1152 | dev_err(&urb->dev->dev, "%s - failed resubmitting write" | 1150 | dev_err(&urb->dev->dev, "%s - failed resubmitting write" |
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c new file mode 100644 index 000000000000..0b9362061713 --- /dev/null +++ b/drivers/usb/serial/qcaux.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Qualcomm USB Auxiliary Serial Port driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> | ||
5 | * Copyright (C) 2010 Dan Williams <dcbw@redhat.com> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * Devices listed here usually provide a CDC ACM port on which normal modem | ||
12 | * AT commands and PPP can be used. But when that port is in-use by PPP it | ||
13 | * cannot be used simultaneously for status or signal strength. Instead, the | ||
14 | * ports here can be queried for that information using the Qualcomm DM | ||
15 | * protocol. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/tty.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/usb.h> | ||
23 | #include <linux/usb/serial.h> | ||
24 | |||
25 | /* NOTE: for now, only use this driver for devices that provide a CDC-ACM port | ||
26 | * for normal AT commands, but also provide secondary USB interfaces for the | ||
27 | * QCDM-capable ports. Devices that do not provide a CDC-ACM port should | ||
28 | * probably be driven by option.ko. | ||
29 | */ | ||
30 | |||
31 | /* UTStarcom/Pantech/Curitel devices */ | ||
32 | #define UTSTARCOM_VENDOR_ID 0x106c | ||
33 | #define UTSTARCOM_PRODUCT_PC5740 0x3701 | ||
34 | #define UTSTARCOM_PRODUCT_PC5750 0x3702 /* aka Pantech PX-500 */ | ||
35 | #define UTSTARCOM_PRODUCT_UM150 0x3711 | ||
36 | #define UTSTARCOM_PRODUCT_UM175_V1 0x3712 | ||
37 | #define UTSTARCOM_PRODUCT_UM175_V2 0x3714 | ||
38 | #define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 | ||
39 | |||
40 | /* CMOTECH devices */ | ||
41 | #define CMOTECH_VENDOR_ID 0x16d8 | ||
42 | #define CMOTECH_PRODUCT_CDU550 0x5553 | ||
43 | #define CMOTECH_PRODUCT_CDX650 0x6512 | ||
44 | |||
45 | static struct usb_device_id id_table[] = { | ||
46 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) }, | ||
47 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) }, | ||
48 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM150, 0xff, 0x00, 0x00) }, | ||
49 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V1, 0xff, 0x00, 0x00) }, | ||
50 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V2, 0xff, 0x00, 0x00) }, | ||
51 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) }, | ||
52 | { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) }, | ||
53 | { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) }, | ||
54 | { }, | ||
55 | }; | ||
56 | MODULE_DEVICE_TABLE(usb, id_table); | ||
57 | |||
58 | static struct usb_driver qcaux_driver = { | ||
59 | .name = "qcaux", | ||
60 | .probe = usb_serial_probe, | ||
61 | .disconnect = usb_serial_disconnect, | ||
62 | .id_table = id_table, | ||
63 | .no_dynamic_id = 1, | ||
64 | }; | ||
65 | |||
66 | static struct usb_serial_driver qcaux_device = { | ||
67 | .driver = { | ||
68 | .owner = THIS_MODULE, | ||
69 | .name = "qcaux", | ||
70 | }, | ||
71 | .id_table = id_table, | ||
72 | .num_ports = 1, | ||
73 | }; | ||
74 | |||
75 | static int __init qcaux_init(void) | ||
76 | { | ||
77 | int retval; | ||
78 | |||
79 | retval = usb_serial_register(&qcaux_device); | ||
80 | if (retval) | ||
81 | return retval; | ||
82 | retval = usb_register(&qcaux_driver); | ||
83 | if (retval) | ||
84 | usb_serial_deregister(&qcaux_device); | ||
85 | return retval; | ||
86 | } | ||
87 | |||
88 | static void __exit qcaux_exit(void) | ||
89 | { | ||
90 | usb_deregister(&qcaux_driver); | ||
91 | usb_serial_deregister(&qcaux_device); | ||
92 | } | ||
93 | |||
94 | module_init(qcaux_init); | ||
95 | module_exit(qcaux_exit); | ||
96 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 7528b8d57f1c..310ff6ec6567 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | static int debug; | 22 | static int debug; |
23 | 23 | ||
24 | static struct usb_device_id id_table[] = { | 24 | static const struct usb_device_id id_table[] = { |
25 | {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */ | 25 | {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */ |
26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
diff --git a/drivers/usb/serial/siemens_mpi.c b/drivers/usb/serial/siemens_mpi.c index 951ea0c6ba77..cb8195cabfde 100644 --- a/drivers/usb/serial/siemens_mpi.c +++ b/drivers/usb/serial/siemens_mpi.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #define DRIVER_DESC "Driver for Siemens USB/MPI adapter" | 22 | #define DRIVER_DESC "Driver for Siemens USB/MPI adapter" |
23 | 23 | ||
24 | 24 | ||
25 | static struct usb_device_id id_table[] = { | 25 | static const struct usb_device_id id_table[] = { |
26 | /* Vendor and product id for 6ES7-972-0CB20-0XA0 */ | 26 | /* Vendor and product id for 6ES7-972-0CB20-0XA0 */ |
27 | { USB_DEVICE(0x908, 0x0004) }, | 27 | { USB_DEVICE(0x908, 0x0004) }, |
28 | { }, | 28 | { }, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 3eb6143bb646..34e6f894cba9 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -226,7 +226,7 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = { | |||
226 | .ifaceinfo = direct_ip_non_serial_ifaces, | 226 | .ifaceinfo = direct_ip_non_serial_ifaces, |
227 | }; | 227 | }; |
228 | 228 | ||
229 | static struct usb_device_id id_table [] = { | 229 | static const struct usb_device_id id_table[] = { |
230 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | 230 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ |
231 | { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ | 231 | { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ |
232 | { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ | 232 | { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ |
@@ -304,16 +304,6 @@ static struct usb_device_id id_table [] = { | |||
304 | }; | 304 | }; |
305 | MODULE_DEVICE_TABLE(usb, id_table); | 305 | MODULE_DEVICE_TABLE(usb, id_table); |
306 | 306 | ||
307 | static struct usb_driver sierra_driver = { | ||
308 | .name = "sierra", | ||
309 | .probe = usb_serial_probe, | ||
310 | .disconnect = usb_serial_disconnect, | ||
311 | .suspend = usb_serial_suspend, | ||
312 | .resume = usb_serial_resume, | ||
313 | .id_table = id_table, | ||
314 | .no_dynamic_id = 1, | ||
315 | .supports_autosuspend = 1, | ||
316 | }; | ||
317 | 307 | ||
318 | struct sierra_port_private { | 308 | struct sierra_port_private { |
319 | spinlock_t lock; /* lock the structure */ | 309 | spinlock_t lock; /* lock the structure */ |
@@ -477,7 +467,7 @@ static void sierra_outdat_callback(struct urb *urb) | |||
477 | static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | 467 | static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, |
478 | const unsigned char *buf, int count) | 468 | const unsigned char *buf, int count) |
479 | { | 469 | { |
480 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | 470 | struct sierra_port_private *portdata; |
481 | struct sierra_intf_private *intfdata; | 471 | struct sierra_intf_private *intfdata; |
482 | struct usb_serial *serial = port->serial; | 472 | struct usb_serial *serial = port->serial; |
483 | unsigned long flags; | 473 | unsigned long flags; |
@@ -604,14 +594,15 @@ static void sierra_indat_callback(struct urb *urb) | |||
604 | } else { | 594 | } else { |
605 | if (urb->actual_length) { | 595 | if (urb->actual_length) { |
606 | tty = tty_port_tty_get(&port->port); | 596 | tty = tty_port_tty_get(&port->port); |
607 | 597 | if (tty) { | |
608 | tty_buffer_request_room(tty, urb->actual_length); | 598 | tty_insert_flip_string(tty, data, |
609 | tty_insert_flip_string(tty, data, urb->actual_length); | 599 | urb->actual_length); |
610 | tty_flip_buffer_push(tty); | 600 | tty_flip_buffer_push(tty); |
611 | 601 | ||
612 | tty_kref_put(tty); | 602 | tty_kref_put(tty); |
613 | usb_serial_debug_data(debug, &port->dev, __func__, | 603 | usb_serial_debug_data(debug, &port->dev, |
614 | urb->actual_length, data); | 604 | __func__, urb->actual_length, data); |
605 | } | ||
615 | } else { | 606 | } else { |
616 | dev_dbg(&port->dev, "%s: empty read urb" | 607 | dev_dbg(&port->dev, "%s: empty read urb" |
617 | " received\n", __func__); | 608 | " received\n", __func__); |
@@ -619,10 +610,10 @@ static void sierra_indat_callback(struct urb *urb) | |||
619 | } | 610 | } |
620 | 611 | ||
621 | /* Resubmit urb so we continue receiving */ | 612 | /* Resubmit urb so we continue receiving */ |
622 | if (port->port.count && status != -ESHUTDOWN && status != -EPERM) { | 613 | if (status != -ESHUTDOWN && status != -EPERM) { |
623 | usb_mark_last_busy(port->serial->dev); | 614 | usb_mark_last_busy(port->serial->dev); |
624 | err = usb_submit_urb(urb, GFP_ATOMIC); | 615 | err = usb_submit_urb(urb, GFP_ATOMIC); |
625 | if (err) | 616 | if (err && err != -EPERM) |
626 | dev_err(&port->dev, "resubmit read urb failed." | 617 | dev_err(&port->dev, "resubmit read urb failed." |
627 | "(%d)\n", err); | 618 | "(%d)\n", err); |
628 | } | 619 | } |
@@ -681,11 +672,11 @@ static void sierra_instat_callback(struct urb *urb) | |||
681 | dev_dbg(&port->dev, "%s: error %d\n", __func__, status); | 672 | dev_dbg(&port->dev, "%s: error %d\n", __func__, status); |
682 | 673 | ||
683 | /* Resubmit urb so we continue receiving IRQ data */ | 674 | /* Resubmit urb so we continue receiving IRQ data */ |
684 | if (port->port.count && status != -ESHUTDOWN && status != -ENOENT) { | 675 | if (status != -ESHUTDOWN && status != -ENOENT) { |
685 | usb_mark_last_busy(serial->dev); | 676 | usb_mark_last_busy(serial->dev); |
686 | urb->dev = serial->dev; | 677 | urb->dev = serial->dev; |
687 | err = usb_submit_urb(urb, GFP_ATOMIC); | 678 | err = usb_submit_urb(urb, GFP_ATOMIC); |
688 | if (err) | 679 | if (err && err != -EPERM) |
689 | dev_err(&port->dev, "%s: resubmit intr urb " | 680 | dev_err(&port->dev, "%s: resubmit intr urb " |
690 | "failed. (%d)\n", __func__, err); | 681 | "failed. (%d)\n", __func__, err); |
691 | } | 682 | } |
@@ -1061,11 +1052,31 @@ static int sierra_resume(struct usb_serial *serial) | |||
1061 | 1052 | ||
1062 | return ec ? -EIO : 0; | 1053 | return ec ? -EIO : 0; |
1063 | } | 1054 | } |
1055 | |||
1056 | static int sierra_reset_resume(struct usb_interface *intf) | ||
1057 | { | ||
1058 | struct usb_serial *serial = usb_get_intfdata(intf); | ||
1059 | dev_err(&serial->dev->dev, "%s\n", __func__); | ||
1060 | return usb_serial_resume(intf); | ||
1061 | } | ||
1064 | #else | 1062 | #else |
1065 | #define sierra_suspend NULL | 1063 | #define sierra_suspend NULL |
1066 | #define sierra_resume NULL | 1064 | #define sierra_resume NULL |
1065 | #define sierra_reset_resume NULL | ||
1067 | #endif | 1066 | #endif |
1068 | 1067 | ||
1068 | static struct usb_driver sierra_driver = { | ||
1069 | .name = "sierra", | ||
1070 | .probe = usb_serial_probe, | ||
1071 | .disconnect = usb_serial_disconnect, | ||
1072 | .suspend = usb_serial_suspend, | ||
1073 | .resume = usb_serial_resume, | ||
1074 | .reset_resume = sierra_reset_resume, | ||
1075 | .id_table = id_table, | ||
1076 | .no_dynamic_id = 1, | ||
1077 | .supports_autosuspend = 1, | ||
1078 | }; | ||
1079 | |||
1069 | static struct usb_serial_driver sierra_device = { | 1080 | static struct usb_serial_driver sierra_device = { |
1070 | .driver = { | 1081 | .driver = { |
1071 | .owner = THIS_MODULE, | 1082 | .owner = THIS_MODULE, |
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 1e58220403d1..5d39191e7244 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -45,7 +45,7 @@ static int debug; | |||
45 | #define SPCP8x5_835_VID 0x04fc | 45 | #define SPCP8x5_835_VID 0x04fc |
46 | #define SPCP8x5_835_PID 0x0231 | 46 | #define SPCP8x5_835_PID 0x0231 |
47 | 47 | ||
48 | static struct usb_device_id id_table [] = { | 48 | static const struct usb_device_id id_table[] = { |
49 | { USB_DEVICE(SPCP8x5_PHILIPS_VID , SPCP8x5_PHILIPS_PID)}, | 49 | { USB_DEVICE(SPCP8x5_PHILIPS_VID , SPCP8x5_PHILIPS_PID)}, |
50 | { USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)}, | 50 | { USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)}, |
51 | { USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)}, | 51 | { USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)}, |
@@ -609,7 +609,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, | |||
609 | if (i < 0) | 609 | if (i < 0) |
610 | dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n", | 610 | dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n", |
611 | uartdata, i); | 611 | uartdata, i); |
612 | dbg("0x21:0x40:0:0 %d\n", i); | 612 | dbg("0x21:0x40:0:0 %d", i); |
613 | 613 | ||
614 | if (cflag & CRTSCTS) { | 614 | if (cflag & CRTSCTS) { |
615 | /* enable hardware flow control */ | 615 | /* enable hardware flow control */ |
@@ -677,7 +677,6 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) | |||
677 | struct tty_struct *tty; | 677 | struct tty_struct *tty; |
678 | unsigned char *data = urb->transfer_buffer; | 678 | unsigned char *data = urb->transfer_buffer; |
679 | unsigned long flags; | 679 | unsigned long flags; |
680 | int i; | ||
681 | int result = urb->status; | 680 | int result = urb->status; |
682 | u8 status; | 681 | u8 status; |
683 | char tty_flag; | 682 | char tty_flag; |
@@ -687,8 +686,6 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) | |||
687 | 686 | ||
688 | /* check the urb status */ | 687 | /* check the urb status */ |
689 | if (result) { | 688 | if (result) { |
690 | if (!port->port.count) | ||
691 | return; | ||
692 | if (result == -EPROTO) { | 689 | if (result == -EPROTO) { |
693 | /* spcp8x5 mysteriously fails with -EPROTO */ | 690 | /* spcp8x5 mysteriously fails with -EPROTO */ |
694 | /* reschedule the read */ | 691 | /* reschedule the read */ |
@@ -726,26 +723,20 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) | |||
726 | 723 | ||
727 | tty = tty_port_tty_get(&port->port); | 724 | tty = tty_port_tty_get(&port->port); |
728 | if (tty && urb->actual_length) { | 725 | if (tty && urb->actual_length) { |
729 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
730 | /* overrun is special, not associated with a char */ | 726 | /* overrun is special, not associated with a char */ |
731 | if (status & UART_OVERRUN_ERROR) | 727 | if (status & UART_OVERRUN_ERROR) |
732 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 728 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
733 | for (i = 0; i < urb->actual_length; ++i) | 729 | tty_insert_flip_string_fixed_flag(tty, data, |
734 | tty_insert_flip_char(tty, data[i], tty_flag); | 730 | urb->actual_length, tty_flag); |
735 | tty_flip_buffer_push(tty); | 731 | tty_flip_buffer_push(tty); |
736 | } | 732 | } |
737 | tty_kref_put(tty); | 733 | tty_kref_put(tty); |
738 | 734 | ||
739 | /* Schedule the next read _if_ we are still open */ | 735 | /* Schedule the next read */ |
740 | if (port->port.count) { | 736 | urb->dev = port->serial->dev; |
741 | urb->dev = port->serial->dev; | 737 | result = usb_submit_urb(urb , GFP_ATOMIC); |
742 | result = usb_submit_urb(urb , GFP_ATOMIC); | 738 | if (result) |
743 | if (result) | 739 | dev_dbg(&port->dev, "failed submitting read urb %d\n", result); |
744 | dev_dbg(&port->dev, "failed submitting read urb %d\n", | ||
745 | result); | ||
746 | } | ||
747 | |||
748 | return; | ||
749 | } | 740 | } |
750 | 741 | ||
751 | /* get data from ring buffer and then write to usb bus */ | 742 | /* get data from ring buffer and then write to usb bus */ |
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index b282c0f2d8e5..72398888858f 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | static int debug; | 22 | static int debug; |
23 | 23 | ||
24 | static struct usb_device_id id_table[] = { | 24 | static const struct usb_device_id id_table[] = { |
25 | { USB_DEVICE(0x05e0, 0x0600) }, | 25 | { USB_DEVICE(0x05e0, 0x0600) }, |
26 | { }, | 26 | { }, |
27 | }; | 27 | }; |
@@ -51,7 +51,6 @@ static void symbol_int_callback(struct urb *urb) | |||
51 | int status = urb->status; | 51 | int status = urb->status; |
52 | struct tty_struct *tty; | 52 | struct tty_struct *tty; |
53 | int result; | 53 | int result; |
54 | int available_room = 0; | ||
55 | int data_length; | 54 | int data_length; |
56 | 55 | ||
57 | dbg("%s - port %d", __func__, port->number); | 56 | dbg("%s - port %d", __func__, port->number); |
@@ -89,13 +88,8 @@ static void symbol_int_callback(struct urb *urb) | |||
89 | */ | 88 | */ |
90 | tty = tty_port_tty_get(&port->port); | 89 | tty = tty_port_tty_get(&port->port); |
91 | if (tty) { | 90 | if (tty) { |
92 | available_room = tty_buffer_request_room(tty, | 91 | tty_insert_flip_string(tty, &data[1], data_length); |
93 | data_length); | 92 | tty_flip_buffer_push(tty); |
94 | if (available_room) { | ||
95 | tty_insert_flip_string(tty, &data[1], | ||
96 | available_room); | ||
97 | tty_flip_buffer_push(tty); | ||
98 | } | ||
99 | tty_kref_put(tty); | 93 | tty_kref_put(tty); |
100 | } | 94 | } |
101 | } else { | 95 | } else { |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 1e9dc8821698..0afe5c71c17e 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -1271,14 +1271,13 @@ static void ti_recv(struct device *dev, struct tty_struct *tty, | |||
1271 | int cnt; | 1271 | int cnt; |
1272 | 1272 | ||
1273 | do { | 1273 | do { |
1274 | cnt = tty_buffer_request_room(tty, length); | 1274 | cnt = tty_insert_flip_string(tty, data, length); |
1275 | if (cnt < length) { | 1275 | if (cnt < length) { |
1276 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1276 | dev_err(dev, "%s - dropping data, %d bytes lost\n", |
1277 | __func__, length - cnt); | 1277 | __func__, length - cnt); |
1278 | if (cnt == 0) | 1278 | if (cnt == 0) |
1279 | break; | 1279 | break; |
1280 | } | 1280 | } |
1281 | tty_insert_flip_string(tty, data, cnt); | ||
1282 | tty_flip_buffer_push(tty); | 1281 | tty_flip_buffer_push(tty); |
1283 | data += cnt; | 1282 | data += cnt; |
1284 | length -= cnt; | 1283 | length -= cnt; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 33c85f7084f8..3873660d8217 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -358,10 +358,6 @@ static int serial_write(struct tty_struct *tty, const unsigned char *buf, | |||
358 | 358 | ||
359 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); | 359 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); |
360 | 360 | ||
361 | /* count is managed under the mutex lock for the tty so cannot | ||
362 | drop to zero until after the last close completes */ | ||
363 | WARN_ON(!port->port.count); | ||
364 | |||
365 | /* pass on to the driver specific version of this function */ | 361 | /* pass on to the driver specific version of this function */ |
366 | retval = port->serial->type->write(tty, port, buf, count); | 362 | retval = port->serial->type->write(tty, port, buf, count); |
367 | 363 | ||
@@ -373,7 +369,6 @@ static int serial_write_room(struct tty_struct *tty) | |||
373 | { | 369 | { |
374 | struct usb_serial_port *port = tty->driver_data; | 370 | struct usb_serial_port *port = tty->driver_data; |
375 | dbg("%s - port %d", __func__, port->number); | 371 | dbg("%s - port %d", __func__, port->number); |
376 | WARN_ON(!port->port.count); | ||
377 | /* pass on to the driver specific version of this function */ | 372 | /* pass on to the driver specific version of this function */ |
378 | return port->serial->type->write_room(tty); | 373 | return port->serial->type->write_room(tty); |
379 | } | 374 | } |
@@ -381,7 +376,7 @@ static int serial_write_room(struct tty_struct *tty) | |||
381 | static int serial_chars_in_buffer(struct tty_struct *tty) | 376 | static int serial_chars_in_buffer(struct tty_struct *tty) |
382 | { | 377 | { |
383 | struct usb_serial_port *port = tty->driver_data; | 378 | struct usb_serial_port *port = tty->driver_data; |
384 | dbg("%s = port %d", __func__, port->number); | 379 | dbg("%s - port %d", __func__, port->number); |
385 | 380 | ||
386 | /* if the device was unplugged then any remaining characters | 381 | /* if the device was unplugged then any remaining characters |
387 | fell out of the connector ;) */ | 382 | fell out of the connector ;) */ |
@@ -396,7 +391,6 @@ static void serial_throttle(struct tty_struct *tty) | |||
396 | struct usb_serial_port *port = tty->driver_data; | 391 | struct usb_serial_port *port = tty->driver_data; |
397 | dbg("%s - port %d", __func__, port->number); | 392 | dbg("%s - port %d", __func__, port->number); |
398 | 393 | ||
399 | WARN_ON(!port->port.count); | ||
400 | /* pass on to the driver specific version of this function */ | 394 | /* pass on to the driver specific version of this function */ |
401 | if (port->serial->type->throttle) | 395 | if (port->serial->type->throttle) |
402 | port->serial->type->throttle(tty); | 396 | port->serial->type->throttle(tty); |
@@ -407,7 +401,6 @@ static void serial_unthrottle(struct tty_struct *tty) | |||
407 | struct usb_serial_port *port = tty->driver_data; | 401 | struct usb_serial_port *port = tty->driver_data; |
408 | dbg("%s - port %d", __func__, port->number); | 402 | dbg("%s - port %d", __func__, port->number); |
409 | 403 | ||
410 | WARN_ON(!port->port.count); | ||
411 | /* pass on to the driver specific version of this function */ | 404 | /* pass on to the driver specific version of this function */ |
412 | if (port->serial->type->unthrottle) | 405 | if (port->serial->type->unthrottle) |
413 | port->serial->type->unthrottle(tty); | 406 | port->serial->type->unthrottle(tty); |
@@ -421,8 +414,6 @@ static int serial_ioctl(struct tty_struct *tty, struct file *file, | |||
421 | 414 | ||
422 | dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); | 415 | dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); |
423 | 416 | ||
424 | WARN_ON(!port->port.count); | ||
425 | |||
426 | /* pass on to the driver specific version of this function | 417 | /* pass on to the driver specific version of this function |
427 | if it is available */ | 418 | if it is available */ |
428 | if (port->serial->type->ioctl) { | 419 | if (port->serial->type->ioctl) { |
@@ -437,7 +428,6 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
437 | struct usb_serial_port *port = tty->driver_data; | 428 | struct usb_serial_port *port = tty->driver_data; |
438 | dbg("%s - port %d", __func__, port->number); | 429 | dbg("%s - port %d", __func__, port->number); |
439 | 430 | ||
440 | WARN_ON(!port->port.count); | ||
441 | /* pass on to the driver specific version of this function | 431 | /* pass on to the driver specific version of this function |
442 | if it is available */ | 432 | if it is available */ |
443 | if (port->serial->type->set_termios) | 433 | if (port->serial->type->set_termios) |
@@ -452,7 +442,6 @@ static int serial_break(struct tty_struct *tty, int break_state) | |||
452 | 442 | ||
453 | dbg("%s - port %d", __func__, port->number); | 443 | dbg("%s - port %d", __func__, port->number); |
454 | 444 | ||
455 | WARN_ON(!port->port.count); | ||
456 | /* pass on to the driver specific version of this function | 445 | /* pass on to the driver specific version of this function |
457 | if it is available */ | 446 | if it is available */ |
458 | if (port->serial->type->break_ctl) | 447 | if (port->serial->type->break_ctl) |
@@ -513,7 +502,6 @@ static int serial_tiocmget(struct tty_struct *tty, struct file *file) | |||
513 | 502 | ||
514 | dbg("%s - port %d", __func__, port->number); | 503 | dbg("%s - port %d", __func__, port->number); |
515 | 504 | ||
516 | WARN_ON(!port->port.count); | ||
517 | if (port->serial->type->tiocmget) | 505 | if (port->serial->type->tiocmget) |
518 | return port->serial->type->tiocmget(tty, file); | 506 | return port->serial->type->tiocmget(tty, file); |
519 | return -EINVAL; | 507 | return -EINVAL; |
@@ -526,7 +514,6 @@ static int serial_tiocmset(struct tty_struct *tty, struct file *file, | |||
526 | 514 | ||
527 | dbg("%s - port %d", __func__, port->number); | 515 | dbg("%s - port %d", __func__, port->number); |
528 | 516 | ||
529 | WARN_ON(!port->port.count); | ||
530 | if (port->serial->type->tiocmset) | 517 | if (port->serial->type->tiocmset) |
531 | return port->serial->type->tiocmset(tty, file, set, clear); | 518 | return port->serial->type->tiocmset(tty, file, set, clear); |
532 | return -EINVAL; | 519 | return -EINVAL; |
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index 7b5bfc4edd3d..252cc2d993b2 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c | |||
@@ -29,7 +29,7 @@ static char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = { | |||
29 | 0xff, | 29 | 0xff, |
30 | }; | 30 | }; |
31 | 31 | ||
32 | static struct usb_device_id id_table [] = { | 32 | static const struct usb_device_id id_table[] = { |
33 | { USB_DEVICE(0x0525, 0x127a) }, | 33 | { USB_DEVICE(0x0525, 0x127a) }, |
34 | { }, | 34 | { }, |
35 | }; | 35 | }; |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index ad1f9232292d..094942707c7d 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -368,7 +368,7 @@ static int visor_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
368 | spin_lock_irqsave(&priv->lock, flags); | 368 | spin_lock_irqsave(&priv->lock, flags); |
369 | if (priv->outstanding_urbs > URB_UPPER_LIMIT) { | 369 | if (priv->outstanding_urbs > URB_UPPER_LIMIT) { |
370 | spin_unlock_irqrestore(&priv->lock, flags); | 370 | spin_unlock_irqrestore(&priv->lock, flags); |
371 | dbg("%s - write limit hit\n", __func__); | 371 | dbg("%s - write limit hit", __func__); |
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
374 | priv->outstanding_urbs++; | 374 | priv->outstanding_urbs++; |
@@ -446,7 +446,7 @@ static int visor_write_room(struct tty_struct *tty) | |||
446 | spin_lock_irqsave(&priv->lock, flags); | 446 | spin_lock_irqsave(&priv->lock, flags); |
447 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { | 447 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { |
448 | spin_unlock_irqrestore(&priv->lock, flags); | 448 | spin_unlock_irqrestore(&priv->lock, flags); |
449 | dbg("%s - write limit hit\n", __func__); | 449 | dbg("%s - write limit hit", __func__); |
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | spin_unlock_irqrestore(&priv->lock, flags); | 452 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -503,13 +503,9 @@ static void visor_read_bulk_callback(struct urb *urb) | |||
503 | if (urb->actual_length) { | 503 | if (urb->actual_length) { |
504 | tty = tty_port_tty_get(&port->port); | 504 | tty = tty_port_tty_get(&port->port); |
505 | if (tty) { | 505 | if (tty) { |
506 | available_room = tty_buffer_request_room(tty, | 506 | tty_insert_flip_string(tty, data, |
507 | urb->actual_length); | 507 | urb->actual_length); |
508 | if (available_room) { | 508 | tty_flip_buffer_push(tty); |
509 | tty_insert_flip_string(tty, data, | ||
510 | available_room); | ||
511 | tty_flip_buffer_push(tty); | ||
512 | } | ||
513 | tty_kref_put(tty); | 509 | tty_kref_put(tty); |
514 | } | 510 | } |
515 | spin_lock(&priv->lock); | 511 | spin_lock(&priv->lock); |
@@ -807,10 +803,14 @@ static int clie_3_5_startup(struct usb_serial *serial) | |||
807 | { | 803 | { |
808 | struct device *dev = &serial->dev->dev; | 804 | struct device *dev = &serial->dev->dev; |
809 | int result; | 805 | int result; |
810 | u8 data; | 806 | u8 *data; |
811 | 807 | ||
812 | dbg("%s", __func__); | 808 | dbg("%s", __func__); |
813 | 809 | ||
810 | data = kmalloc(1, GFP_KERNEL); | ||
811 | if (!data) | ||
812 | return -ENOMEM; | ||
813 | |||
814 | /* | 814 | /* |
815 | * Note that PEG-300 series devices expect the following two calls. | 815 | * Note that PEG-300 series devices expect the following two calls. |
816 | */ | 816 | */ |
@@ -818,36 +818,42 @@ static int clie_3_5_startup(struct usb_serial *serial) | |||
818 | /* get the config number */ | 818 | /* get the config number */ |
819 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 819 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
820 | USB_REQ_GET_CONFIGURATION, USB_DIR_IN, | 820 | USB_REQ_GET_CONFIGURATION, USB_DIR_IN, |
821 | 0, 0, &data, 1, 3000); | 821 | 0, 0, data, 1, 3000); |
822 | if (result < 0) { | 822 | if (result < 0) { |
823 | dev_err(dev, "%s: get config number failed: %d\n", | 823 | dev_err(dev, "%s: get config number failed: %d\n", |
824 | __func__, result); | 824 | __func__, result); |
825 | return result; | 825 | goto out; |
826 | } | 826 | } |
827 | if (result != 1) { | 827 | if (result != 1) { |
828 | dev_err(dev, "%s: get config number bad return length: %d\n", | 828 | dev_err(dev, "%s: get config number bad return length: %d\n", |
829 | __func__, result); | 829 | __func__, result); |
830 | return -EIO; | 830 | result = -EIO; |
831 | goto out; | ||
831 | } | 832 | } |
832 | 833 | ||
833 | /* get the interface number */ | 834 | /* get the interface number */ |
834 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 835 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
835 | USB_REQ_GET_INTERFACE, | 836 | USB_REQ_GET_INTERFACE, |
836 | USB_DIR_IN | USB_RECIP_INTERFACE, | 837 | USB_DIR_IN | USB_RECIP_INTERFACE, |
837 | 0, 0, &data, 1, 3000); | 838 | 0, 0, data, 1, 3000); |
838 | if (result < 0) { | 839 | if (result < 0) { |
839 | dev_err(dev, "%s: get interface number failed: %d\n", | 840 | dev_err(dev, "%s: get interface number failed: %d\n", |
840 | __func__, result); | 841 | __func__, result); |
841 | return result; | 842 | goto out; |
842 | } | 843 | } |
843 | if (result != 1) { | 844 | if (result != 1) { |
844 | dev_err(dev, | 845 | dev_err(dev, |
845 | "%s: get interface number bad return length: %d\n", | 846 | "%s: get interface number bad return length: %d\n", |
846 | __func__, result); | 847 | __func__, result); |
847 | return -EIO; | 848 | result = -EIO; |
849 | goto out; | ||
848 | } | 850 | } |
849 | 851 | ||
850 | return generic_startup(serial); | 852 | result = generic_startup(serial); |
853 | out: | ||
854 | kfree(data); | ||
855 | |||
856 | return result; | ||
851 | } | 857 | } |
852 | 858 | ||
853 | static int treo_attach(struct usb_serial *serial) | 859 | static int treo_attach(struct usb_serial *serial) |
diff --git a/drivers/usb/serial/vivopay-serial.c b/drivers/usb/serial/vivopay-serial.c new file mode 100644 index 000000000000..f719d00972fc --- /dev/null +++ b/drivers/usb/serial/vivopay-serial.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001-2005 Greg Kroah-Hartman (greg@kroah.com) | ||
3 | * Copyright (C) 2009 Outpost Embedded, LLC | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/tty.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/usb.h> | ||
11 | #include <linux/usb/serial.h> | ||
12 | |||
13 | |||
14 | #define DRIVER_VERSION "v1.0" | ||
15 | #define DRIVER_DESC "ViVOpay USB Serial Driver" | ||
16 | |||
17 | #define VIVOPAY_VENDOR_ID 0x1d5f | ||
18 | |||
19 | |||
20 | static struct usb_device_id id_table [] = { | ||
21 | /* ViVOpay 8800 */ | ||
22 | { USB_DEVICE(VIVOPAY_VENDOR_ID, 0x1004) }, | ||
23 | { }, | ||
24 | }; | ||
25 | |||
26 | MODULE_DEVICE_TABLE(usb, id_table); | ||
27 | |||
28 | static struct usb_driver vivopay_serial_driver = { | ||
29 | .name = "vivopay-serial", | ||
30 | .probe = usb_serial_probe, | ||
31 | .disconnect = usb_serial_disconnect, | ||
32 | .id_table = id_table, | ||
33 | .no_dynamic_id = 1, | ||
34 | }; | ||
35 | |||
36 | static struct usb_serial_driver vivopay_serial_device = { | ||
37 | .driver = { | ||
38 | .owner = THIS_MODULE, | ||
39 | .name = "vivopay-serial", | ||
40 | }, | ||
41 | .id_table = id_table, | ||
42 | .usb_driver = &vivopay_serial_driver, | ||
43 | .num_ports = 1, | ||
44 | }; | ||
45 | |||
46 | static int __init vivopay_serial_init(void) | ||
47 | { | ||
48 | int retval; | ||
49 | retval = usb_serial_register(&vivopay_serial_device); | ||
50 | if (retval) | ||
51 | goto failed_usb_serial_register; | ||
52 | retval = usb_register(&vivopay_serial_driver); | ||
53 | if (retval) | ||
54 | goto failed_usb_register; | ||
55 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | ||
56 | DRIVER_DESC "\n"); | ||
57 | return 0; | ||
58 | failed_usb_register: | ||
59 | usb_serial_deregister(&vivopay_serial_device); | ||
60 | failed_usb_serial_register: | ||
61 | return retval; | ||
62 | } | ||
63 | |||
64 | static void __exit vivopay_serial_exit(void) | ||
65 | { | ||
66 | usb_deregister(&vivopay_serial_driver); | ||
67 | usb_serial_deregister(&vivopay_serial_device); | ||
68 | } | ||
69 | |||
70 | module_init(vivopay_serial_init); | ||
71 | module_exit(vivopay_serial_exit); | ||
72 | |||
73 | MODULE_AUTHOR("Forest Bond <forest.bond@outpostembedded.com>"); | ||
74 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
75 | MODULE_VERSION(DRIVER_VERSION); | ||
76 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 1093d2eb046a..12ed8209ca72 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -111,17 +111,17 @@ static int debug; | |||
111 | separate ID tables, and then a third table that combines them | 111 | separate ID tables, and then a third table that combines them |
112 | just for the purpose of exporting the autoloading information. | 112 | just for the purpose of exporting the autoloading information. |
113 | */ | 113 | */ |
114 | static struct usb_device_id id_table_std [] = { | 114 | static const struct usb_device_id id_table_std[] = { |
115 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) }, | 115 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) }, |
116 | { } /* Terminating entry */ | 116 | { } /* Terminating entry */ |
117 | }; | 117 | }; |
118 | 118 | ||
119 | static struct usb_device_id id_table_prerenumeration [] = { | 119 | static const struct usb_device_id id_table_prerenumeration[] = { |
120 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) }, | 120 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) }, |
121 | { } /* Terminating entry */ | 121 | { } /* Terminating entry */ |
122 | }; | 122 | }; |
123 | 123 | ||
124 | static struct usb_device_id id_table_combined [] = { | 124 | static const struct usb_device_id id_table_combined[] = { |
125 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) }, | 125 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) }, |
126 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) }, | 126 | { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) }, |
127 | { } /* Terminating entry */ | 127 | { } /* Terminating entry */ |
@@ -1492,21 +1492,9 @@ static void rx_data_softint(struct work_struct *work) | |||
1492 | wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); | 1492 | wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); |
1493 | urb = wrap->urb; | 1493 | urb = wrap->urb; |
1494 | 1494 | ||
1495 | if (tty && urb->actual_length) { | 1495 | if (tty && urb->actual_length) |
1496 | int len = tty_buffer_request_room(tty, | 1496 | sent += tty_insert_flip_string(tty, |
1497 | urb->actual_length); | 1497 | urb->transfer_buffer, urb->actual_length); |
1498 | /* This stuff can go away now I suspect */ | ||
1499 | if (unlikely(len < urb->actual_length)) { | ||
1500 | spin_lock_irqsave(&info->lock, flags); | ||
1501 | list_add(tmp, &info->rx_urb_q); | ||
1502 | spin_unlock_irqrestore(&info->lock, flags); | ||
1503 | tty_flip_buffer_push(tty); | ||
1504 | schedule_work(&info->rx_work); | ||
1505 | goto out; | ||
1506 | } | ||
1507 | tty_insert_flip_string(tty, urb->transfer_buffer, len); | ||
1508 | sent += len; | ||
1509 | } | ||
1510 | 1498 | ||
1511 | urb->dev = port->serial->dev; | 1499 | urb->dev = port->serial->dev; |
1512 | result = usb_submit_urb(urb, GFP_ATOMIC); | 1500 | result = usb_submit_urb(urb, GFP_ATOMIC); |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 80e65f29921c..198bb3ed95b2 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -202,7 +202,7 @@ static int onetouch_connect_input(struct us_data *ss) | |||
202 | goto fail1; | 202 | goto fail1; |
203 | 203 | ||
204 | onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN, | 204 | onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN, |
205 | GFP_ATOMIC, &onetouch->data_dma); | 205 | GFP_KERNEL, &onetouch->data_dma); |
206 | if (!onetouch->data) | 206 | if (!onetouch->data) |
207 | goto fail1; | 207 | goto fail1; |
208 | 208 | ||
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index aadc16b5eed7..4cc035562cc2 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -133,7 +133,7 @@ static int slave_configure(struct scsi_device *sdev) | |||
133 | 133 | ||
134 | if (us->fflags & US_FL_MAX_SECTORS_MIN) | 134 | if (us->fflags & US_FL_MAX_SECTORS_MIN) |
135 | max_sectors = PAGE_CACHE_SIZE >> 9; | 135 | max_sectors = PAGE_CACHE_SIZE >> 9; |
136 | if (queue_max_sectors(sdev->request_queue) > max_sectors) | 136 | if (queue_max_hw_sectors(sdev->request_queue) > max_sectors) |
137 | blk_queue_max_hw_sectors(sdev->request_queue, | 137 | blk_queue_max_hw_sectors(sdev->request_queue, |
138 | max_sectors); | 138 | max_sectors); |
139 | } else if (sdev->type == TYPE_TAPE) { | 139 | } else if (sdev->type == TYPE_TAPE) { |
@@ -484,7 +484,7 @@ static ssize_t show_max_sectors(struct device *dev, struct device_attribute *att | |||
484 | { | 484 | { |
485 | struct scsi_device *sdev = to_scsi_device(dev); | 485 | struct scsi_device *sdev = to_scsi_device(dev); |
486 | 486 | ||
487 | return sprintf(buf, "%u\n", queue_max_sectors(sdev->request_queue)); | 487 | return sprintf(buf, "%u\n", queue_max_hw_sectors(sdev->request_queue)); |
488 | } | 488 | } |
489 | 489 | ||
490 | /* Input routine for the sysfs max_sectors file */ | 490 | /* Input routine for the sysfs max_sectors file */ |
@@ -494,9 +494,9 @@ static ssize_t store_max_sectors(struct device *dev, struct device_attribute *at | |||
494 | struct scsi_device *sdev = to_scsi_device(dev); | 494 | struct scsi_device *sdev = to_scsi_device(dev); |
495 | unsigned short ms; | 495 | unsigned short ms; |
496 | 496 | ||
497 | if (sscanf(buf, "%hu", &ms) > 0 && ms <= SCSI_DEFAULT_MAX_SECTORS) { | 497 | if (sscanf(buf, "%hu", &ms) > 0) { |
498 | blk_queue_max_hw_sectors(sdev->request_queue, ms); | 498 | blk_queue_max_hw_sectors(sdev->request_queue, ms); |
499 | return strlen(buf); | 499 | return count; |
500 | } | 500 | } |
501 | return -EINVAL; | 501 | return -EINVAL; |
502 | } | 502 | } |
@@ -539,7 +539,7 @@ struct scsi_host_template usb_stor_host_template = { | |||
539 | .slave_configure = slave_configure, | 539 | .slave_configure = slave_configure, |
540 | 540 | ||
541 | /* lots of sg segments can be handled */ | 541 | /* lots of sg segments can be handled */ |
542 | .sg_tablesize = SG_ALL, | 542 | .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, |
543 | 543 | ||
544 | /* limit the total size of a transfer to 120 KB */ | 544 | /* limit the total size of a transfer to 120 KB */ |
545 | .max_sectors = 240, | 545 | .max_sectors = 240, |
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index b62a28814ebe..bd3f415893d8 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -1628,10 +1628,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1628 | return USB_STOR_TRANSPORT_ERROR; | 1628 | return USB_STOR_TRANSPORT_ERROR; |
1629 | } | 1629 | } |
1630 | 1630 | ||
1631 | if ( (result = usbat_multiple_write(us, | 1631 | result = usbat_multiple_write(us, registers, data, 7); |
1632 | registers, data, 7)) != USB_STOR_TRANSPORT_GOOD) { | 1632 | |
1633 | if (result != USB_STOR_TRANSPORT_GOOD) | ||
1633 | return result; | 1634 | return result; |
1634 | } | ||
1635 | 1635 | ||
1636 | /* | 1636 | /* |
1637 | * Write the 12-byte command header. | 1637 | * Write the 12-byte command header. |
@@ -1643,12 +1643,11 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1643 | * AT SPEED 4 IS UNRELIABLE!!! | 1643 | * AT SPEED 4 IS UNRELIABLE!!! |
1644 | */ | 1644 | */ |
1645 | 1645 | ||
1646 | if ((result = usbat_write_block(us, | 1646 | result = usbat_write_block(us, USBAT_ATA, srb->cmnd, 12, |
1647 | USBAT_ATA, srb->cmnd, 12, | 1647 | srb->cmnd[0] == GPCMD_BLANK ? 75 : 10, 0); |
1648 | (srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) != | 1648 | |
1649 | USB_STOR_TRANSPORT_GOOD)) { | 1649 | if (result != USB_STOR_TRANSPORT_GOOD) |
1650 | return result; | 1650 | return result; |
1651 | } | ||
1652 | 1651 | ||
1653 | /* If there is response data to be read in then do it here. */ | 1652 | /* If there is response data to be read in then do it here. */ |
1654 | 1653 | ||
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index cc313d16d727..468038126e5e 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <linux/errno.h> | 47 | #include <linux/errno.h> |
48 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
49 | 49 | ||
50 | #include <linux/usb/quirks.h> | ||
51 | |||
50 | #include <scsi/scsi.h> | 52 | #include <scsi/scsi.h> |
51 | #include <scsi/scsi_eh.h> | 53 | #include <scsi/scsi_eh.h> |
52 | #include <scsi/scsi_device.h> | 54 | #include <scsi/scsi_device.h> |
@@ -1297,6 +1299,10 @@ int usb_stor_port_reset(struct us_data *us) | |||
1297 | { | 1299 | { |
1298 | int result; | 1300 | int result; |
1299 | 1301 | ||
1302 | /*for these devices we must use the class specific method */ | ||
1303 | if (us->pusb_dev->quirks & USB_QUIRK_RESET_MORPHS) | ||
1304 | return -EPERM; | ||
1305 | |||
1300 | result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); | 1306 | result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); |
1301 | if (result < 0) | 1307 | if (result < 0) |
1302 | US_DEBUGP("unable to lock device for reset: %d\n", result); | 1308 | US_DEBUGP("unable to lock device for reset: %d\n", result); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 49575fba3756..98b549b1cab2 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -1147,8 +1147,8 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, | |||
1147 | 0 ), | 1147 | 0 ), |
1148 | 1148 | ||
1149 | /* Reported by Jan Dumon <j.dumon@option.com> | 1149 | /* Reported by Jan Dumon <j.dumon@option.com> |
1150 | * This device (wrongly) has a vendor-specific device descriptor. | 1150 | * These devices (wrongly) have a vendor-specific device descriptor. |
1151 | * The entry is needed so usb-storage can bind to it's mass-storage | 1151 | * These entries are needed so usb-storage can bind to their mass-storage |
1152 | * interface as an interface driver */ | 1152 | * interface as an interface driver */ |
1153 | UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, | 1153 | UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, |
1154 | "Option", | 1154 | "Option", |
@@ -1156,6 +1156,90 @@ UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, | |||
1156 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1156 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1157 | 0 ), | 1157 | 0 ), |
1158 | 1158 | ||
1159 | UNUSUAL_DEV( 0x0af0, 0x7701, 0x0000, 0x0000, | ||
1160 | "Option", | ||
1161 | "GI 0451 SD-Card", | ||
1162 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1163 | 0 ), | ||
1164 | |||
1165 | UNUSUAL_DEV( 0x0af0, 0x7706, 0x0000, 0x0000, | ||
1166 | "Option", | ||
1167 | "GI 0451 SD-Card", | ||
1168 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1169 | 0 ), | ||
1170 | |||
1171 | UNUSUAL_DEV( 0x0af0, 0x7901, 0x0000, 0x0000, | ||
1172 | "Option", | ||
1173 | "GI 0452 SD-Card", | ||
1174 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1175 | 0 ), | ||
1176 | |||
1177 | UNUSUAL_DEV( 0x0af0, 0x7A01, 0x0000, 0x0000, | ||
1178 | "Option", | ||
1179 | "GI 0461 SD-Card", | ||
1180 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1181 | 0 ), | ||
1182 | |||
1183 | UNUSUAL_DEV( 0x0af0, 0x7A05, 0x0000, 0x0000, | ||
1184 | "Option", | ||
1185 | "GI 0461 SD-Card", | ||
1186 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1187 | 0 ), | ||
1188 | |||
1189 | UNUSUAL_DEV( 0x0af0, 0x8300, 0x0000, 0x0000, | ||
1190 | "Option", | ||
1191 | "GI 033x SD-Card", | ||
1192 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1193 | 0 ), | ||
1194 | |||
1195 | UNUSUAL_DEV( 0x0af0, 0x8302, 0x0000, 0x0000, | ||
1196 | "Option", | ||
1197 | "GI 033x SD-Card", | ||
1198 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1199 | 0 ), | ||
1200 | |||
1201 | UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0000, | ||
1202 | "Option", | ||
1203 | "GI 033x SD-Card", | ||
1204 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1205 | 0 ), | ||
1206 | |||
1207 | UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000, | ||
1208 | "Option", | ||
1209 | "GI 070x SD-Card", | ||
1210 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1211 | 0 ), | ||
1212 | |||
1213 | UNUSUAL_DEV( 0x0af0, 0xd057, 0x0000, 0x0000, | ||
1214 | "Option", | ||
1215 | "GI 1505 SD-Card", | ||
1216 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1217 | 0 ), | ||
1218 | |||
1219 | UNUSUAL_DEV( 0x0af0, 0xd058, 0x0000, 0x0000, | ||
1220 | "Option", | ||
1221 | "GI 1509 SD-Card", | ||
1222 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1223 | 0 ), | ||
1224 | |||
1225 | UNUSUAL_DEV( 0x0af0, 0xd157, 0x0000, 0x0000, | ||
1226 | "Option", | ||
1227 | "GI 1515 SD-Card", | ||
1228 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1229 | 0 ), | ||
1230 | |||
1231 | UNUSUAL_DEV( 0x0af0, 0xd257, 0x0000, 0x0000, | ||
1232 | "Option", | ||
1233 | "GI 1215 SD-Card", | ||
1234 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1235 | 0 ), | ||
1236 | |||
1237 | UNUSUAL_DEV( 0x0af0, 0xd357, 0x0000, 0x0000, | ||
1238 | "Option", | ||
1239 | "GI 1505 SD-Card", | ||
1240 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1241 | 0 ), | ||
1242 | |||
1159 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | 1243 | /* Reported by Ben Efros <ben@pc-doctor.com> */ |
1160 | UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, | 1244 | UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, |
1161 | "Seagate", | 1245 | "Seagate", |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index b1e579c5c97c..61522787f39c 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #define USB_SKEL_PRODUCT_ID 0xfff0 | 28 | #define USB_SKEL_PRODUCT_ID 0xfff0 |
29 | 29 | ||
30 | /* table of devices that work with this driver */ | 30 | /* table of devices that work with this driver */ |
31 | static struct usb_device_id skel_table[] = { | 31 | static const struct usb_device_id skel_table[] = { |
32 | { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, | 32 | { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, |
33 | { } /* Terminating entry */ | 33 | { } /* Terminating entry */ |
34 | }; | 34 | }; |
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index 25eae405f622..51a8e0d5789d 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c | |||
@@ -641,7 +641,7 @@ static void cbaf_disconnect(struct usb_interface *iface) | |||
641 | kzfree(cbaf); | 641 | kzfree(cbaf); |
642 | } | 642 | } |
643 | 643 | ||
644 | static struct usb_device_id cbaf_id_table[] = { | 644 | static const struct usb_device_id cbaf_id_table[] = { |
645 | { USB_INTERFACE_INFO(0xef, 0x03, 0x01), }, | 645 | { USB_INTERFACE_INFO(0xef, 0x03, 0x01), }, |
646 | { }, | 646 | { }, |
647 | }; | 647 | }; |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index dced419f7aba..1c918286159c 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
@@ -868,7 +868,7 @@ static struct usb_wireless_cap_descriptor wusb_cap_descr_default = { | |||
868 | * reference that we'll drop. | 868 | * reference that we'll drop. |
869 | * | 869 | * |
870 | * First we need to determine if the device is a WUSB device (else we | 870 | * First we need to determine if the device is a WUSB device (else we |
871 | * ignore it). For that we use the speed setting (USB_SPEED_VARIABLE) | 871 | * ignore it). For that we use the speed setting (USB_SPEED_WIRELESS) |
872 | * [FIXME: maybe we'd need something more definitive]. If so, we track | 872 | * [FIXME: maybe we'd need something more definitive]. If so, we track |
873 | * it's usb_busd and from there, the WUSB HC. | 873 | * it's usb_busd and from there, the WUSB HC. |
874 | * | 874 | * |
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index 3b52161e6e9c..2d827397e30b 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c | |||
@@ -263,7 +263,7 @@ int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) | |||
263 | { | 263 | { |
264 | int result = 0; | 264 | int result = 0; |
265 | 265 | ||
266 | if (memcmp(chid, &wusb_ckhdid_zero, sizeof(chid)) == 0) | 266 | if (memcmp(chid, &wusb_ckhdid_zero, sizeof(*chid)) == 0) |
267 | chid = NULL; | 267 | chid = NULL; |
268 | 268 | ||
269 | mutex_lock(&wusbhc->mutex); | 269 | mutex_lock(&wusbhc->mutex); |
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index eb677cf56106..9239d033a0a3 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h | |||
@@ -2,8 +2,8 @@ | |||
2 | #define _LINUX_TTY_FLIP_H | 2 | #define _LINUX_TTY_FLIP_H |
3 | 3 | ||
4 | extern int tty_buffer_request_room(struct tty_struct *tty, size_t size); | 4 | extern int tty_buffer_request_room(struct tty_struct *tty, size_t size); |
5 | extern int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size); | ||
6 | extern int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size); | 5 | extern int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size); |
6 | extern int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, const unsigned char *chars, char flag, size_t size); | ||
7 | extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size); | 7 | extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size); |
8 | extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size); | 8 | extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size); |
9 | void tty_schedule_flip(struct tty_struct *tty); | 9 | void tty_schedule_flip(struct tty_struct *tty); |
@@ -20,4 +20,9 @@ static inline int tty_insert_flip_char(struct tty_struct *tty, | |||
20 | return tty_insert_flip_string_flags(tty, &ch, &flag, 1); | 20 | return tty_insert_flip_string_flags(tty, &ch, &flag, 1); |
21 | } | 21 | } |
22 | 22 | ||
23 | static inline int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size) | ||
24 | { | ||
25 | return tty_insert_flip_string_fixed_flag(tty, chars, TTY_NORMAL, size); | ||
26 | } | ||
27 | |||
23 | #endif /* _LINUX_TTY_FLIP_H */ | 28 | #endif /* _LINUX_TTY_FLIP_H */ |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 332eaea61021..3492abf82e75 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -122,7 +122,6 @@ enum usb_interface_condition { | |||
122 | * number from the USB core by calling usb_register_dev(). | 122 | * number from the USB core by calling usb_register_dev(). |
123 | * @condition: binding state of the interface: not bound, binding | 123 | * @condition: binding state of the interface: not bound, binding |
124 | * (in probe()), bound to a driver, or unbinding (in disconnect()) | 124 | * (in probe()), bound to a driver, or unbinding (in disconnect()) |
125 | * @is_active: flag set when the interface is bound and not suspended. | ||
126 | * @sysfs_files_created: sysfs attributes exist | 125 | * @sysfs_files_created: sysfs attributes exist |
127 | * @ep_devs_created: endpoint child pseudo-devices exist | 126 | * @ep_devs_created: endpoint child pseudo-devices exist |
128 | * @unregistering: flag set when the interface is being unregistered | 127 | * @unregistering: flag set when the interface is being unregistered |
@@ -135,8 +134,7 @@ enum usb_interface_condition { | |||
135 | * @dev: driver model's view of this device | 134 | * @dev: driver model's view of this device |
136 | * @usb_dev: if an interface is bound to the USB major, this will point | 135 | * @usb_dev: if an interface is bound to the USB major, this will point |
137 | * to the sysfs representation for that device. | 136 | * to the sysfs representation for that device. |
138 | * @pm_usage_cnt: PM usage counter for this interface; autosuspend is not | 137 | * @pm_usage_cnt: PM usage counter for this interface |
139 | * allowed unless the counter is 0. | ||
140 | * @reset_ws: Used for scheduling resets from atomic context. | 138 | * @reset_ws: Used for scheduling resets from atomic context. |
141 | * @reset_running: set to 1 if the interface is currently running a | 139 | * @reset_running: set to 1 if the interface is currently running a |
142 | * queued reset so that usb_cancel_queued_reset() doesn't try to | 140 | * queued reset so that usb_cancel_queued_reset() doesn't try to |
@@ -184,7 +182,6 @@ struct usb_interface { | |||
184 | int minor; /* minor number this interface is | 182 | int minor; /* minor number this interface is |
185 | * bound to */ | 183 | * bound to */ |
186 | enum usb_interface_condition condition; /* state of binding */ | 184 | enum usb_interface_condition condition; /* state of binding */ |
187 | unsigned is_active:1; /* the interface is not suspended */ | ||
188 | unsigned sysfs_files_created:1; /* the sysfs attributes exist */ | 185 | unsigned sysfs_files_created:1; /* the sysfs attributes exist */ |
189 | unsigned ep_devs_created:1; /* endpoint "devices" exist */ | 186 | unsigned ep_devs_created:1; /* endpoint "devices" exist */ |
190 | unsigned unregistering:1; /* unregistration is in progress */ | 187 | unsigned unregistering:1; /* unregistration is in progress */ |
@@ -401,7 +398,6 @@ struct usb_tt; | |||
401 | * @portnum: parent port number (origin 1) | 398 | * @portnum: parent port number (origin 1) |
402 | * @level: number of USB hub ancestors | 399 | * @level: number of USB hub ancestors |
403 | * @can_submit: URBs may be submitted | 400 | * @can_submit: URBs may be submitted |
404 | * @discon_suspended: disconnected while suspended | ||
405 | * @persist_enabled: USB_PERSIST enabled for this device | 401 | * @persist_enabled: USB_PERSIST enabled for this device |
406 | * @have_langid: whether string_langid is valid | 402 | * @have_langid: whether string_langid is valid |
407 | * @authorized: policy has said we can use it; | 403 | * @authorized: policy has said we can use it; |
@@ -421,20 +417,15 @@ struct usb_tt; | |||
421 | * @usbfs_dentry: usbfs dentry entry for the device | 417 | * @usbfs_dentry: usbfs dentry entry for the device |
422 | * @maxchild: number of ports if hub | 418 | * @maxchild: number of ports if hub |
423 | * @children: child devices - USB devices that are attached to this hub | 419 | * @children: child devices - USB devices that are attached to this hub |
424 | * @pm_usage_cnt: usage counter for autosuspend | ||
425 | * @quirks: quirks of the whole device | 420 | * @quirks: quirks of the whole device |
426 | * @urbnum: number of URBs submitted for the whole device | 421 | * @urbnum: number of URBs submitted for the whole device |
427 | * @active_duration: total time device is not suspended | 422 | * @active_duration: total time device is not suspended |
428 | * @autosuspend: for delayed autosuspends | ||
429 | * @autoresume: for autoresumes requested while in_interrupt | ||
430 | * @pm_mutex: protects PM operations | ||
431 | * @last_busy: time of last use | 423 | * @last_busy: time of last use |
432 | * @autosuspend_delay: in jiffies | 424 | * @autosuspend_delay: in jiffies |
433 | * @connect_time: time device was first connected | 425 | * @connect_time: time device was first connected |
434 | * @do_remote_wakeup: remote wakeup should be enabled | 426 | * @do_remote_wakeup: remote wakeup should be enabled |
435 | * @reset_resume: needs reset instead of resume | 427 | * @reset_resume: needs reset instead of resume |
436 | * @autosuspend_disabled: autosuspend disabled by the user | 428 | * @autosuspend_disabled: autosuspend disabled by the user |
437 | * @skip_sys_resume: skip the next system resume | ||
438 | * @wusb_dev: if this is a Wireless USB device, link to the WUSB | 429 | * @wusb_dev: if this is a Wireless USB device, link to the WUSB |
439 | * specific data for the device. | 430 | * specific data for the device. |
440 | * @slot_id: Slot ID assigned by xHCI | 431 | * @slot_id: Slot ID assigned by xHCI |
@@ -475,7 +466,6 @@ struct usb_device { | |||
475 | u8 level; | 466 | u8 level; |
476 | 467 | ||
477 | unsigned can_submit:1; | 468 | unsigned can_submit:1; |
478 | unsigned discon_suspended:1; | ||
479 | unsigned persist_enabled:1; | 469 | unsigned persist_enabled:1; |
480 | unsigned have_langid:1; | 470 | unsigned have_langid:1; |
481 | unsigned authorized:1; | 471 | unsigned authorized:1; |
@@ -499,17 +489,12 @@ struct usb_device { | |||
499 | int maxchild; | 489 | int maxchild; |
500 | struct usb_device *children[USB_MAXCHILDREN]; | 490 | struct usb_device *children[USB_MAXCHILDREN]; |
501 | 491 | ||
502 | int pm_usage_cnt; | ||
503 | u32 quirks; | 492 | u32 quirks; |
504 | atomic_t urbnum; | 493 | atomic_t urbnum; |
505 | 494 | ||
506 | unsigned long active_duration; | 495 | unsigned long active_duration; |
507 | 496 | ||
508 | #ifdef CONFIG_PM | 497 | #ifdef CONFIG_PM |
509 | struct delayed_work autosuspend; | ||
510 | struct work_struct autoresume; | ||
511 | struct mutex pm_mutex; | ||
512 | |||
513 | unsigned long last_busy; | 498 | unsigned long last_busy; |
514 | int autosuspend_delay; | 499 | int autosuspend_delay; |
515 | unsigned long connect_time; | 500 | unsigned long connect_time; |
@@ -517,7 +502,6 @@ struct usb_device { | |||
517 | unsigned do_remote_wakeup:1; | 502 | unsigned do_remote_wakeup:1; |
518 | unsigned reset_resume:1; | 503 | unsigned reset_resume:1; |
519 | unsigned autosuspend_disabled:1; | 504 | unsigned autosuspend_disabled:1; |
520 | unsigned skip_sys_resume:1; | ||
521 | #endif | 505 | #endif |
522 | struct wusb_dev *wusb_dev; | 506 | struct wusb_dev *wusb_dev; |
523 | int slot_id; | 507 | int slot_id; |
@@ -542,21 +526,15 @@ extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); | |||
542 | 526 | ||
543 | /* USB autosuspend and autoresume */ | 527 | /* USB autosuspend and autoresume */ |
544 | #ifdef CONFIG_USB_SUSPEND | 528 | #ifdef CONFIG_USB_SUSPEND |
529 | extern int usb_enable_autosuspend(struct usb_device *udev); | ||
530 | extern int usb_disable_autosuspend(struct usb_device *udev); | ||
531 | |||
545 | extern int usb_autopm_get_interface(struct usb_interface *intf); | 532 | extern int usb_autopm_get_interface(struct usb_interface *intf); |
546 | extern void usb_autopm_put_interface(struct usb_interface *intf); | 533 | extern void usb_autopm_put_interface(struct usb_interface *intf); |
547 | extern int usb_autopm_get_interface_async(struct usb_interface *intf); | 534 | extern int usb_autopm_get_interface_async(struct usb_interface *intf); |
548 | extern void usb_autopm_put_interface_async(struct usb_interface *intf); | 535 | extern void usb_autopm_put_interface_async(struct usb_interface *intf); |
549 | 536 | extern void usb_autopm_get_interface_no_resume(struct usb_interface *intf); | |
550 | static inline void usb_autopm_get_interface_no_resume( | 537 | extern void usb_autopm_put_interface_no_suspend(struct usb_interface *intf); |
551 | struct usb_interface *intf) | ||
552 | { | ||
553 | atomic_inc(&intf->pm_usage_cnt); | ||
554 | } | ||
555 | static inline void usb_autopm_put_interface_no_suspend( | ||
556 | struct usb_interface *intf) | ||
557 | { | ||
558 | atomic_dec(&intf->pm_usage_cnt); | ||
559 | } | ||
560 | 538 | ||
561 | static inline void usb_mark_last_busy(struct usb_device *udev) | 539 | static inline void usb_mark_last_busy(struct usb_device *udev) |
562 | { | 540 | { |
@@ -565,6 +543,11 @@ static inline void usb_mark_last_busy(struct usb_device *udev) | |||
565 | 543 | ||
566 | #else | 544 | #else |
567 | 545 | ||
546 | static inline int usb_enable_autosuspend(struct usb_device *udev) | ||
547 | { return 0; } | ||
548 | static inline int usb_disable_autosuspend(struct usb_device *udev) | ||
549 | { return 0; } | ||
550 | |||
568 | static inline int usb_autopm_get_interface(struct usb_interface *intf) | 551 | static inline int usb_autopm_get_interface(struct usb_interface *intf) |
569 | { return 0; } | 552 | { return 0; } |
570 | static inline int usb_autopm_get_interface_async(struct usb_interface *intf) | 553 | static inline int usb_autopm_get_interface_async(struct usb_interface *intf) |
@@ -1583,14 +1566,18 @@ extern void usb_register_notify(struct notifier_block *nb); | |||
1583 | extern void usb_unregister_notify(struct notifier_block *nb); | 1566 | extern void usb_unregister_notify(struct notifier_block *nb); |
1584 | 1567 | ||
1585 | #ifdef DEBUG | 1568 | #ifdef DEBUG |
1586 | #define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \ | 1569 | #define dbg(format, arg...) \ |
1587 | __FILE__ , ## arg) | 1570 | printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg) |
1588 | #else | 1571 | #else |
1589 | #define dbg(format, arg...) do {} while (0) | 1572 | #define dbg(format, arg...) \ |
1573 | do { \ | ||
1574 | if (0) \ | ||
1575 | printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ | ||
1576 | } while (0) | ||
1590 | #endif | 1577 | #endif |
1591 | 1578 | ||
1592 | #define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ | 1579 | #define err(format, arg...) \ |
1593 | format "\n" , ## arg) | 1580 | printk(KERN_ERR KBUILD_MODNAME ": " format "\n", ##arg) |
1594 | 1581 | ||
1595 | /* debugfs stuff */ | 1582 | /* debugfs stuff */ |
1596 | extern struct dentry *usb_debug_root; | 1583 | extern struct dentry *usb_debug_root; |
diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index 54c446309a2a..29fd73b0bffc 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild | |||
@@ -5,4 +5,3 @@ header-y += gadgetfs.h | |||
5 | header-y += midi.h | 5 | header-y += midi.h |
6 | header-y += g_printer.h | 6 | header-y += g_printer.h |
7 | header-y += tmc.h | 7 | header-y += tmc.h |
8 | header-y += vstusb.h | ||
diff --git a/include/linux/usb/atmel_usba_udc.h b/include/linux/usb/atmel_usba_udc.h index 6311fa2d9f82..baf41c8616e9 100644 --- a/include/linux/usb/atmel_usba_udc.h +++ b/include/linux/usb/atmel_usba_udc.h | |||
@@ -15,6 +15,7 @@ struct usba_ep_data { | |||
15 | 15 | ||
16 | struct usba_platform_data { | 16 | struct usba_platform_data { |
17 | int vbus_pin; | 17 | int vbus_pin; |
18 | int vbus_pin_inverted; | ||
18 | int num_ep; | 19 | int num_ep; |
19 | struct usba_ep_data ep[0]; | 20 | struct usba_ep_data ep[0]; |
20 | }; | 21 | }; |
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index 94012e649d86..e58369ff8168 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h | |||
@@ -775,7 +775,7 @@ enum usb_device_speed { | |||
775 | USB_SPEED_UNKNOWN = 0, /* enumerating */ | 775 | USB_SPEED_UNKNOWN = 0, /* enumerating */ |
776 | USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ | 776 | USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ |
777 | USB_SPEED_HIGH, /* usb 2.0 */ | 777 | USB_SPEED_HIGH, /* usb 2.0 */ |
778 | USB_SPEED_VARIABLE, /* wireless (usb 2.5) */ | 778 | USB_SPEED_WIRELESS, /* wireless (usb 2.5) */ |
779 | USB_SPEED_SUPER, /* usb 3.0 */ | 779 | USB_SPEED_SUPER, /* usb 3.0 */ |
780 | }; | 780 | }; |
781 | 781 | ||
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index 5dc2f227a0f1..7acef0234c0e 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h | |||
@@ -30,26 +30,26 @@ struct musb_hdrc_eps_bits { | |||
30 | struct musb_hdrc_config { | 30 | struct musb_hdrc_config { |
31 | /* MUSB configuration-specific details */ | 31 | /* MUSB configuration-specific details */ |
32 | unsigned multipoint:1; /* multipoint device */ | 32 | unsigned multipoint:1; /* multipoint device */ |
33 | unsigned dyn_fifo:1; /* supports dynamic fifo sizing */ | 33 | unsigned dyn_fifo:1 __deprecated; /* supports dynamic fifo sizing */ |
34 | unsigned soft_con:1; /* soft connect required */ | 34 | unsigned soft_con:1 __deprecated; /* soft connect required */ |
35 | unsigned utm_16:1; /* utm data witdh is 16 bits */ | 35 | unsigned utm_16:1 __deprecated; /* utm data witdh is 16 bits */ |
36 | unsigned big_endian:1; /* true if CPU uses big-endian */ | 36 | unsigned big_endian:1; /* true if CPU uses big-endian */ |
37 | unsigned mult_bulk_tx:1; /* Tx ep required for multbulk pkts */ | 37 | unsigned mult_bulk_tx:1; /* Tx ep required for multbulk pkts */ |
38 | unsigned mult_bulk_rx:1; /* Rx ep required for multbulk pkts */ | 38 | unsigned mult_bulk_rx:1; /* Rx ep required for multbulk pkts */ |
39 | unsigned high_iso_tx:1; /* Tx ep required for HB iso */ | 39 | unsigned high_iso_tx:1; /* Tx ep required for HB iso */ |
40 | unsigned high_iso_rx:1; /* Rx ep required for HD iso */ | 40 | unsigned high_iso_rx:1; /* Rx ep required for HD iso */ |
41 | unsigned dma:1; /* supports DMA */ | 41 | unsigned dma:1 __deprecated; /* supports DMA */ |
42 | unsigned vendor_req:1; /* vendor registers required */ | 42 | unsigned vendor_req:1 __deprecated; /* vendor registers required */ |
43 | 43 | ||
44 | u8 num_eps; /* number of endpoints _with_ ep0 */ | 44 | u8 num_eps; /* number of endpoints _with_ ep0 */ |
45 | u8 dma_channels; /* number of dma channels */ | 45 | u8 dma_channels __deprecated; /* number of dma channels */ |
46 | u8 dyn_fifo_size; /* dynamic size in bytes */ | 46 | u8 dyn_fifo_size; /* dynamic size in bytes */ |
47 | u8 vendor_ctrl; /* vendor control reg width */ | 47 | u8 vendor_ctrl __deprecated; /* vendor control reg width */ |
48 | u8 vendor_stat; /* vendor status reg witdh */ | 48 | u8 vendor_stat __deprecated; /* vendor status reg witdh */ |
49 | u8 dma_req_chan; /* bitmask for required dma channels */ | 49 | u8 dma_req_chan __deprecated; /* bitmask for required dma channels */ |
50 | u8 ram_bits; /* ram address size */ | 50 | u8 ram_bits; /* ram address size */ |
51 | 51 | ||
52 | struct musb_hdrc_eps_bits *eps_bits; | 52 | struct musb_hdrc_eps_bits *eps_bits __deprecated; |
53 | #ifdef CONFIG_BLACKFIN | 53 | #ifdef CONFIG_BLACKFIN |
54 | /* A GPIO controlling VRSEL in Blackfin */ | 54 | /* A GPIO controlling VRSEL in Blackfin */ |
55 | unsigned int gpio_vrsel; | 55 | unsigned int gpio_vrsel; |
@@ -76,6 +76,9 @@ struct musb_hdrc_platform_data { | |||
76 | /* (HOST or OTG) msec/2 after VBUS on till power good */ | 76 | /* (HOST or OTG) msec/2 after VBUS on till power good */ |
77 | u8 potpgt; | 77 | u8 potpgt; |
78 | 78 | ||
79 | /* (HOST or OTG) program PHY for external Vbus */ | ||
80 | unsigned extvbus:1; | ||
81 | |||
79 | /* Power the device on or off */ | 82 | /* Power the device on or off */ |
80 | int (*set_power)(int state); | 83 | int (*set_power)(int state); |
81 | 84 | ||
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index fef0972c8146..f8302d036a76 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef __LINUX_USB_OTG_H | 9 | #ifndef __LINUX_USB_OTG_H |
10 | #define __LINUX_USB_OTG_H | 10 | #define __LINUX_USB_OTG_H |
11 | 11 | ||
12 | #include <linux/notifier.h> | ||
13 | |||
12 | /* OTG defines lots of enumeration states before device reset */ | 14 | /* OTG defines lots of enumeration states before device reset */ |
13 | enum usb_otg_state { | 15 | enum usb_otg_state { |
14 | OTG_STATE_UNDEFINED = 0, | 16 | OTG_STATE_UNDEFINED = 0, |
@@ -33,6 +35,14 @@ enum usb_otg_state { | |||
33 | OTG_STATE_A_VBUS_ERR, | 35 | OTG_STATE_A_VBUS_ERR, |
34 | }; | 36 | }; |
35 | 37 | ||
38 | enum usb_xceiv_events { | ||
39 | USB_EVENT_NONE, /* no events or cable disconnected */ | ||
40 | USB_EVENT_VBUS, /* vbus valid event */ | ||
41 | USB_EVENT_ID, /* id was grounded */ | ||
42 | USB_EVENT_CHARGER, /* usb dedicated charger */ | ||
43 | USB_EVENT_ENUMERATED, /* gadget driver enumerated */ | ||
44 | }; | ||
45 | |||
36 | #define USB_OTG_PULLUP_ID (1 << 0) | 46 | #define USB_OTG_PULLUP_ID (1 << 0) |
37 | #define USB_OTG_PULLDOWN_DP (1 << 1) | 47 | #define USB_OTG_PULLDOWN_DP (1 << 1) |
38 | #define USB_OTG_PULLDOWN_DM (1 << 2) | 48 | #define USB_OTG_PULLDOWN_DM (1 << 2) |
@@ -70,6 +80,9 @@ struct otg_transceiver { | |||
70 | struct otg_io_access_ops *io_ops; | 80 | struct otg_io_access_ops *io_ops; |
71 | void __iomem *io_priv; | 81 | void __iomem *io_priv; |
72 | 82 | ||
83 | /* for notification of usb_xceiv_events */ | ||
84 | struct blocking_notifier_head notifier; | ||
85 | |||
73 | /* to pass extra port status to the root hub */ | 86 | /* to pass extra port status to the root hub */ |
74 | u16 port_status; | 87 | u16 port_status; |
75 | u16 port_change; | 88 | u16 port_change; |
@@ -213,6 +226,18 @@ otg_start_srp(struct otg_transceiver *otg) | |||
213 | return otg->start_srp(otg); | 226 | return otg->start_srp(otg); |
214 | } | 227 | } |
215 | 228 | ||
229 | /* notifiers */ | ||
230 | static inline int | ||
231 | otg_register_notifier(struct otg_transceiver *otg, struct notifier_block *nb) | ||
232 | { | ||
233 | return blocking_notifier_chain_register(&otg->notifier, nb); | ||
234 | } | ||
235 | |||
236 | static inline void | ||
237 | otg_unregister_notifier(struct otg_transceiver *otg, struct notifier_block *nb) | ||
238 | { | ||
239 | blocking_notifier_chain_unregister(&otg->notifier, nb); | ||
240 | } | ||
216 | 241 | ||
217 | /* for OTG controller drivers (and maybe other stuff) */ | 242 | /* for OTG controller drivers (and maybe other stuff) */ |
218 | extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); | 243 | extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); |
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index 2526f3bbd273..0a555dd131fc 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h | |||
@@ -19,4 +19,7 @@ | |||
19 | /* device can't handle its Configuration or Interface strings */ | 19 | /* device can't handle its Configuration or Interface strings */ |
20 | #define USB_QUIRK_CONFIG_INTF_STRINGS 0x00000008 | 20 | #define USB_QUIRK_CONFIG_INTF_STRINGS 0x00000008 |
21 | 21 | ||
22 | /*device will morph if reset, don't use reset for handling errors */ | ||
23 | #define USB_QUIRK_RESET_MORPHS 0x00000010 | ||
24 | |||
22 | #endif /* __LINUX_USB_QUIRKS_H */ | 25 | #endif /* __LINUX_USB_QUIRKS_H */ |
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 1819396ed501..0a458b861933 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -351,14 +351,11 @@ static inline void usb_serial_debug_data(int debug, | |||
351 | 351 | ||
352 | /* Use our own dbg macro */ | 352 | /* Use our own dbg macro */ |
353 | #undef dbg | 353 | #undef dbg |
354 | #define dbg(format, arg...) \ | 354 | #define dbg(format, arg...) \ |
355 | do { \ | 355 | do { \ |
356 | if (debug) \ | 356 | if (debug) \ |
357 | printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , \ | 357 | printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ |
358 | ## arg); \ | 358 | } while (0) |
359 | } while (0) | ||
360 | |||
361 | |||
362 | 359 | ||
363 | #endif /* __LINUX_USB_SERIAL_H */ | 360 | #endif /* __LINUX_USB_SERIAL_H */ |
364 | 361 | ||
diff --git a/include/linux/usb/vstusb.h b/include/linux/usb/vstusb.h deleted file mode 100644 index 1cfac67191ff..000000000000 --- a/include/linux/usb/vstusb.h +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /***************************************************************************** | ||
2 | * File: drivers/usb/misc/vstusb.h | ||
3 | * | ||
4 | * Purpose: Support for the bulk USB Vernier Spectrophotometers | ||
5 | * | ||
6 | * Author: EQware Engineering, Inc. | ||
7 | * Oregon City, OR, USA 97045 | ||
8 | * | ||
9 | * Copyright: 2007, 2008 | ||
10 | * Vernier Software & Technology | ||
11 | * Beaverton, OR, USA 97005 | ||
12 | * | ||
13 | * Web: www.vernier.com | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License version 2 as | ||
17 | * published by the Free Software Foundation. | ||
18 | * | ||
19 | *****************************************************************************/ | ||
20 | /***************************************************************************** | ||
21 | * | ||
22 | * The vstusb module is a standard usb 'client' driver running on top of the | ||
23 | * standard usb host controller stack. | ||
24 | * | ||
25 | * In general, vstusb supports standard bulk usb pipes. It supports multiple | ||
26 | * devices and multiple pipes per device. | ||
27 | * | ||
28 | * The vstusb driver supports two interfaces: | ||
29 | * 1 - ioctl SEND_PIPE/RECV_PIPE - a general bulk write/read msg | ||
30 | * interface to any pipe with timeout support; | ||
31 | * 2 - standard read/write with ioctl config - offers standard read/write | ||
32 | * interface with ioctl configured pipes and timeouts. | ||
33 | * | ||
34 | * Both interfaces can be signal from other process and will abort its i/o | ||
35 | * operation. | ||
36 | * | ||
37 | * A timeout of 0 means NO timeout. The user can still terminate the read via | ||
38 | * signal. | ||
39 | * | ||
40 | * If using multiple threads with this driver, the user should ensure that | ||
41 | * any reads, writes, or ioctls are complete before closing the device. | ||
42 | * Changing read/write timeouts or pipes takes effect on next read/write. | ||
43 | * | ||
44 | *****************************************************************************/ | ||
45 | |||
46 | struct vstusb_args { | ||
47 | union { | ||
48 | /* this struct is used for IOCTL_VSTUSB_SEND_PIPE, * | ||
49 | * IOCTL_VSTUSB_RECV_PIPE, and read()/write() fops */ | ||
50 | struct { | ||
51 | void __user *buffer; | ||
52 | size_t count; | ||
53 | unsigned int timeout_ms; | ||
54 | int pipe; | ||
55 | }; | ||
56 | |||
57 | /* this one is used for IOCTL_VSTUSB_CONFIG_RW */ | ||
58 | struct { | ||
59 | int rd_pipe; | ||
60 | int rd_timeout_ms; | ||
61 | int wr_pipe; | ||
62 | int wr_timeout_ms; | ||
63 | }; | ||
64 | }; | ||
65 | }; | ||
66 | |||
67 | #define VST_IOC_MAGIC 'L' | ||
68 | #define VST_IOC_FIRST 0x20 | ||
69 | #define IOCTL_VSTUSB_SEND_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST) | ||
70 | #define IOCTL_VSTUSB_RECV_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 1) | ||
71 | #define IOCTL_VSTUSB_CONFIG_RW _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 2) | ||