Re: [PATCH v3 5/6] ARM: dts: omap: update usb_otg_hs data
Hi, On Thursday 21 March 2013 02:29 AM, Stephen Warren wrote: On 03/20/2013 03:12 AM, Kishon Vijay Abraham I wrote: Updated the usb_otg_hs dt data to include the *phy* and *phy-names* binding in order for the driver to use the new generic PHY framework. Also updated the Documentation to include the binding information. diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index abce256..3d6f9f6 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -19,6 +19,9 @@ OMAP MUSB GLUE - power : Should be 50. This signifies the controller can supply upto 100mA when operating in host mode. - usb-phy : the phandle for the PHY device + - phy : the phandle for the PHY device (used by generic PHY framework) + - phy-names : the names of the PHY corresponding to the PHYs present in the + *phy* phandle. If the intent is for those properties to be generic and used by any DT binding that refers to a PHY node, I think you'd want to define those properties in e.g. Documentation/devicetree/bindings/phy/phy.txt, just like common clock/GPIO/... properties are defined in standalone common files. Ok. Will add it. I think you want to require that DT nodes that represent PHYs have a #phy-cells property, and that the format of the phy property be phy_phandle phy_specifier*, where #phy-cells in the referenced node defines how many cells are part of phy_specifier*, just like (almost) any other DT property that references another node by phandle. That way, if a single DT node represents a HW block that implements e.g. 3 PHYs, it can use #phy-cells = 1, and the referencing phy property can include a cell that indicates which of those 3 PHYs is being referenced. Currently, if a single phandle have reference to multiple PHYs, we can get PHY by passing index or by name as give in phy-names. I'm not sure if we have phy_phandle phy_specifier*, what could that phy_specifier be? Maybe phy_type? Thanks Kishon -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb host: Faraday FUSBH200 HCD driver.
Hi, On Wed, Mar 20, 2013 at 10:26 PM, Alan Stern st...@rowland.harvard.edu wrote: On Wed, 20 Mar 2013, Yuan-Hsin Chen wrote: Hi, On Tue, Mar 19, 2013 at 11:48 PM, Alan Stern st...@rowland.harvard.edu wrote: On Tue, 19 Mar 2013, Yuan-Hsin Chen wrote: What about the port_status registers? They're not between command and async_next. If they aren't consistent with EHCI, it makes things a lot more complicated. fusbh200 has only one port_status register with different offset, 0x30, and the position of some bits are different from EHCI. How about adding kernel configuration to adjust offset for FUSBH200 in ehci_def.h? So port_status would be in offset 0x20 from ehci_regs. For example, /* ASYNCLISTADDR: offset 0x18 */ u32 async_next; /* address of next async queue head */ #ifndef CONFIG_USB_EHCI_HCD_FUSBH200 u32 reserved1[2]; /* TXFILLTUNING: offset 0x24 */ u32 txfill_tuning; /* TX FIFO Tuning register */ #define TXFIFO_DEFAULT (816) /* FIFO burst threshold 8 */ u32 reserved2[6]; /* CONFIGFLAG: offset 0x40 */ u32 configured_flag; #define FLAG_CF (10) /* true: we'll support high speed */ #else u32 reserved1; #endif /* PORTSC: offset 0x44 */ u32 port_status[0]; /* up to N_PORTS */ This is acceptable _only_ if it is not possible to use an FUSBH200 controller in the same computer as a normal EHCI controller. Furthermore, there are PORT_POWER, PORT_OWNER, PORT_LED_XXX, PORT_TEST, PORT_WKCONN_E, PORT_WKDISC_E, PORT_WKOC_E absent in port_status of FUSBH200. Also PORT_OC and PORT_OCC are in another register. Is it ok to use quirk flag also? Yes, those can be handled by a quirk flag. Does the FUSBH200 have a built-in Transaction Translator? Yes, the FUSBH200 has built-in Transaction Translator. I will modify the driver based on what we discussed before and re-submit it. Thank you for your time. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] usb: xhci: Fix TRB transfer length macro used for Event TRB.
Use proper macro while extracting TRB transfer length from Transfer event TRBs. Adding a macro EVENT_TRB_LEN (bits 0:23) for the same, and use it instead of TRB_LEN (bits 0:16) in case of event TRBs. Signed-off-by: Vivek gautam gautam.vi...@samsung.com --- Hi Sarah, Updated the patch as suggested. There are two 80 characters warnings although ;-) Thanks! drivers/usb/host/xhci-ring.c | 24 drivers/usb/host/xhci.h |4 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8828754..30a2489 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2027,8 +2027,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, if (event_trb != ep_ring-dequeue event_trb != td-last_trb) td-urb-actual_length = - td-urb-transfer_buffer_length - - TRB_LEN(le32_to_cpu(event-transfer_len)); + td-urb-transfer_buffer_length - + EVENT_TRB_LEN(le32_to_cpu(event-transfer_len)); else td-urb-actual_length = 0; @@ -2060,7 +2060,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, /* Maybe the event was for the data stage? */ td-urb-actual_length = td-urb-transfer_buffer_length - - TRB_LEN(le32_to_cpu(event-transfer_len)); + EVENT_TRB_LEN(le32_to_cpu(event-transfer_len)); xhci_dbg(xhci, Waiting for status stage event\n); return 0; @@ -2096,7 +2096,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, /* handle completion code */ switch (trb_comp_code) { case COMP_SUCCESS: - if (TRB_LEN(le32_to_cpu(event-transfer_len)) == 0) { + if (EVENT_TRB_LEN(le32_to_cpu(event-transfer_len)) == 0) { frame-status = 0; break; } @@ -2141,7 +2141,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, len += TRB_LEN(le32_to_cpu(cur_trb-generic.field[2])); } len += TRB_LEN(le32_to_cpu(cur_trb-generic.field[2])) - - TRB_LEN(le32_to_cpu(event-transfer_len)); + EVENT_TRB_LEN(le32_to_cpu(event-transfer_len)); if (trb_comp_code != COMP_STOP_INVAL) { frame-actual_length = len; @@ -2199,7 +2199,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, case COMP_SUCCESS: /* Double check that the HW transferred everything. */ if (event_trb != td-last_trb || - TRB_LEN(le32_to_cpu(event-transfer_len)) != 0) { + EVENT_TRB_LEN(le32_to_cpu(event-transfer_len)) != 0) { xhci_warn(xhci, WARN Successful completion on short TX\n); if (td-urb-transfer_flags URB_SHORT_NOT_OK) @@ -2227,18 +2227,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, %d bytes untransferred\n, td-urb-ep-desc.bEndpointAddress, td-urb-transfer_buffer_length, - TRB_LEN(le32_to_cpu(event-transfer_len))); + EVENT_TRB_LEN(le32_to_cpu(event-transfer_len))); /* Fast path - was this the last TRB in the TD for this URB? */ if (event_trb == td-last_trb) { - if (TRB_LEN(le32_to_cpu(event-transfer_len)) != 0) { + if (EVENT_TRB_LEN(le32_to_cpu(event-transfer_len)) != 0) { td-urb-actual_length = td-urb-transfer_buffer_length - - TRB_LEN(le32_to_cpu(event-transfer_len)); + EVENT_TRB_LEN(le32_to_cpu(event-transfer_len)); if (td-urb-transfer_buffer_length td-urb-actual_length) { xhci_warn(xhci, HC gave bad length of %d bytes left\n, - TRB_LEN(le32_to_cpu(event-transfer_len))); + EVENT_TRB_LEN(le32_to_cpu(event-transfer_len))); td-urb-actual_length = 0; if (td-urb-transfer_flags URB_SHORT_NOT_OK) *status = -EREMOTEIO;
[RFC PATCH] usb: register usb port to usb_bus_type
Usb port isn't assigned to any bus_type. This seems not good from Greg's comments. http://marc.info/?l=linux-usbm=136200364929942w=2 This patch is to register usb port to usb_bus_type. The usb port's original name is portX. This will cause name confilct after adding usb port to usb_bus_type since the usb ports with same port num under different hub have the same name. So change the usb port's name format to port + (hub dev name) + '.' + (port num) for non-root hub and port + (usb bus num) + '-' + (port num) for root hub. ls /sys/bus/usb/devices 1-0:1.02-0:1.0 port1-1 port1-1.3 port2-1.2 port2-2 port4-3 1-12-1 port1-1.1port1-1.4 port2-1.3 port3-1 port4-4 1-1.1 2-1:1.0 port1-1.2port1-1.5 port2-1.4 port3-2 usb1 1-1:1.03-0:1.0 port1-1.2.1 port1-1.6 port2-1.5 port3-3 usb2 1-1.1:1.0 3-1 port1-1.2.2 port1-2port2-1.6 port3-4 usb3 1-1.2 3-1:1.0 port1-1.2.3 port2-1port2-1.7 port4-1 usb4 1-1.2:1.0 4-0:1.0 port1-1.2.4 port2-1.1 port2-1.8 port4-2 Signed-off-by: Lan Tianyu tianyu@intel.com --- Documentation/ABI/testing/sysfs-bus-usb |6 +++--- drivers/usb/core/port.c | 10 +- drivers/usb/core/usb-acpi.c |7 +-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index c8baaf5..842e8b8 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -221,14 +221,14 @@ Description: The file will be present for all speeds of USB devices, and will always read no for USB 1.1 and USB 2.0 devices. -What: /sys/bus/usb/devices/.../(hub interface)/portX +What: /sys/bus/usb/devices/.../(hub interface)/portX-X Date: August 2012 Contact: Lan Tianyu tianyu@intel.com Description: - The /sys/bus/usb/devices/.../(hub interface)/portX + The /sys/bus/usb/devices/.../(hub interface)/portX-X is usb port device's sysfs directory. -What: /sys/bus/usb/devices/.../(hub interface)/portX/connect_type +What: /sys/bus/usb/devices/.../(hub interface)/portX-X/connect_type Date: January 2013 Contact: Lan Tianyu tianyu@intel.com Description: diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 797f9d5..4d37984 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -155,6 +155,7 @@ struct device_type usb_port_device_type = { int usb_hub_create_port_device(struct usb_hub *hub, int port1) { struct usb_port *port_dev = NULL; + struct usb_device *hdev = hub-hdev; int retval; port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); @@ -169,7 +170,14 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1) port_dev-dev.parent = hub-intfdev; port_dev-dev.groups = port_dev_group; port_dev-dev.type = usb_port_device_type; - dev_set_name(port_dev-dev, port%d, port1); + port_dev-dev.bus = usb_bus_type; + + if (!hdev-parent) + dev_set_name(port_dev-dev, port%d-%d, + hdev-bus-busnum, port1); + else + dev_set_name(port_dev-dev, port%s.%d, + dev_name(hdev-dev), port1); retval = device_register(port_dev-dev); if (retval) diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index b6f4bad..1cc55c9 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -17,7 +17,7 @@ #include linux/pci.h #include acpi/acpi_bus.h -#include usb.h +#include hub.h /** * usb_acpi_power_manageable - check whether usb port has @@ -178,7 +178,10 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) return -ENODEV; return 0; } else if (is_usb_port(dev)) { - sscanf(dev_name(dev), port%d, port_num); + struct usb_port *port_dev = to_usb_port(dev); + + port_num = port_dev-portnum; + /* Get the struct usb_device point of port's hub */ udev = to_usb_device(dev-parent-parent); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [BUG] bisected: PandaBoard smsc95xx ethernet driver error from USB timeout
Hi Frank, On Thu, Mar 21, 2013 at 11:29 AM, Frank Rowand frank.row...@am.sony.com wrote: I found the problem on 3.6.11, but have not replicated it on 3.9-rcX yet because my config fails to build on 3.9-rc1 and 3.9-rc2. I'll try to work on that issue tomorrow. I play upstream kernel on Pandaboard A1 frequently, looks not see the failure problem before. Maybe the problem is config dependent. If you may share your config file, I'd like to do the test too. Thanks, -- Ming Lei -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] usb: otg: mv_otg: remove unused clock
On Wed, Mar 20, 2013 at 9:09 PM, Felipe Balbi ba...@ti.com wrote: On Mon, Mar 18, 2013 at 03:55:29AM -0400, Chao Xie wrote: The origianl understanding of clock is wrong. The OTG controller only have one clock input. Passing clock name by pdata is wrong. The clock is defined by device iteself. Signed-off-by: Chao Xie chao@marvell.com please rebase against my 'next' branch. -- balbi hi Do you mean git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git - branch usb-next? Or some other git? -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] usb: otg: mv_otg: remove unused clock
On Thu, Mar 21, 2013 at 05:16:15PM +0800, Chao Xie wrote: On Wed, Mar 20, 2013 at 9:09 PM, Felipe Balbi ba...@ti.com wrote: On Mon, Mar 18, 2013 at 03:55:29AM -0400, Chao Xie wrote: The origianl understanding of clock is wrong. The OTG controller only have one clock input. Passing clock name by pdata is wrong. The clock is defined by device iteself. Signed-off-by: Chao Xie chao@marvell.com please rebase against my 'next' branch. -- balbi hi Do you mean git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git - branch usb-next? Or some other git? from MAINTAINERS: 8293 USB GADGET/PERIPHERAL SUBSYSTEM 8294 M: Felipe Balbi ba...@ti.com 8295 L: linux-usb@vger.kernel.org 8296 W: http://www.linux-usb.org/gadget 8297 T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git 8298 S: Maintained 8299 F: drivers/usb/gadget/ 8300 F: include/linux/usb/gadget* -- balbi signature.asc Description: Digital signature
[PATCH] usb: gadget: net2272: fix sparse warnings
Fix the following sparse warnings: drivers/usb/gadget/net2272.c:916:13: warning: Using plain integer as NULL pointer drivers/usb/gadget/net2272.c:1624:9: warning: Using plain integer as NULL pointer drivers/usb/gadget/net2272.c:1552:30: warning: right shift by bigger than source value Note that the last warning is an actual bug, since ep-dma is a one bit value which is shifted by one bit in code. Signed-off-by: Felipe Balbi ba...@ti.com --- Hi Alan, found this when building drivers/usb/gadget/ with sparse checks. I'm only concerned about the second hunk. Do you think it's correct ? I don't have HW to test neither do I have documentation to read. drivers/usb/gadget/net2272.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 32524b63..9cc3ca8 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -913,7 +913,7 @@ net2272_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) } } } - if (likely(req != 0)) + if (likely(req)) list_add_tail(req-queue, ep-queue); if (likely(!list_empty(ep-queue))) @@ -1549,7 +1549,7 @@ net2272_handle_dma(struct net2272_ep *ep) | (ep-dev-dma_eot_polarity EOT_POLARITY) | (ep-dev-dma_dack_polarity DACK_POLARITY) | (ep-dev-dma_dreq_polarity DREQ_POLARITY) - | ((ep-dma 1) DMA_ENDPOINT_SELECT)); + | (ep-dma DMA_ENDPOINT_SELECT)); ep-dev-dma_busy = 0; @@ -1622,7 +1622,7 @@ net2272_handle_ep(struct net2272_ep *ep) ep-irqs++; dev_vdbg(ep-dev-dev, %s ack ep_stat0 %02x, ep_stat1 %02x, req %p\n, - ep-ep.name, stat0, stat1, req ? req-req : 0); + ep-ep.name, stat0, stat1, req ? req-req : NULL); net2272_ep_write(ep, EP_STAT0, stat0 ~((1 NAK_OUT_PACKETS) -- 1.8.2 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL] usb: fixes for v3.9-rc4
Hi Greg, Hopefully, this is my last round of fixes for v3.9-rc. Things seem to be calming down. Patches have been in my fixes branch for quite a while and I haven't heard anything from Fengguang's 0-day kernel build. I have also built this branch with the following defconfigs: omap2plus_defconfig omap1_defconfig tegra_defconfig allnoconfig randconfig (5 iterations) allmodconfig allyesconfig And nothing bad has showed up. Please consider merging this tag into your usb-linus branch. Let me know if you want me to change anything. cheers The following changes since commit 66e4afc77f76653460d7eb31ec793506ada1ad33: usb: gadget: pxa25x: fix disconnect reporting (2013-03-11 12:40:31 +0200) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git tags/fixes-for-v3.9-rc4 for you to fetch changes up to eda81bea894e5cd945e30f85b00546caf80fbecc: usb: gadget: net2272: finally convert CONFIG_USB_GADGET_NET2272_DMA (2013-03-21 12:14:05 +0200) usb: fixes for v3.9-rc4 udc-core learned that it shouldn't use invalid pointers when unloading a gadget driver. net2272 and net2280 got a fix for a regression caused by the udc_start/udc_stop conversion. We're defining a static inline no-op for otg_ulpi_create() to prevent build errors when that driver isn't enabled. FunctionFS got a fix for an off-by-one error when binding and unbinding instances of FunctionFS. MUSB learned that it shouldn't try to unmap buffers which weren't previously mapped. f_rndis got a fix for a possible NULL pointer dereference in a debugging message code. MUSB's DA8xx glue layer got a build fix due to a typo. Alan Stern (2): usb: gadget: udc-core: fix a regression during gadget driver unbinding USB: gadget: net2280: remove leftover driver-unbind call in error pathway Andrzej Pietrasiewicz (1): usb: gadget: ffs: fix enable multiple instances Bo Shen (1): usb: gadget: u_serial: fix typo which cause build warning Fabio Estevam (1): usb: ulpi: Define a *otg_ulpi_create no-op Felipe Balbi (1): usb: gadget: net22xx: fix -disconnect reporting Kishon Vijay Abraham I (1): usb: musb: gadget: do *unmap_dma_buffer* only for valid DMA addr Mikhail Kshevetskiy (1): usb: musb: da8xx: Fix build breakage due to typo Paul Bolle (1): usb: gadget: net2272: finally convert CONFIG_USB_GADGET_NET2272_DMA Truls Bengtsson (1): usb: gadget: f_rndis: Avoid to use ERROR macro if cdev can be null drivers/usb/gadget/f_rndis.c | 3 +-- drivers/usb/gadget/g_ffs.c | 4 ++-- drivers/usb/gadget/net2272.c | 9 - drivers/usb/gadget/net2280.c | 8 +++- drivers/usb/gadget/u_serial.c | 2 +- drivers/usb/gadget/udc-core.c | 2 +- drivers/usb/musb/da8xx.c | 2 +- drivers/usb/musb/musb_gadget.c | 9 +++-- include/linux/usb/ulpi.h | 8 9 files changed, 36 insertions(+), 11 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 07/94] USB: serial: remove redundant comments
Remove redundant comments and fix some minor coding style issues. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 20 +--- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a5e8a7b..1318630 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -14,7 +14,6 @@ * * See Documentation/usb/usb-serial.txt for more information on using this * driver - * */ #define pr_fmt(fmt) KBUILD_MODNAME : fmt @@ -49,7 +48,6 @@ drivers depend on it. */ -/* initially all NULL */ static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; static DEFINE_MUTEX(table_lock); static LIST_HEAD(usb_serial_driver_list); @@ -342,7 +340,6 @@ static int serial_write(struct tty_struct *tty, const unsigned char *buf, dev_dbg(tty-dev, %s - port %d, %d byte(s)\n, __func__, port-number, count); - /* pass on to the driver specific version of this function */ retval = port-serial-type-write(tty, port, buf, count); if (retval 0) retval = usb_translate_errors(retval); @@ -355,7 +352,7 @@ static int serial_write_room(struct tty_struct *tty) struct usb_serial_port *port = tty-driver_data; dev_dbg(tty-dev, %s - port %d\n, __func__, port-number); - /* pass on to the driver specific version of this function */ + return port-serial-type-write_room(tty); } @@ -385,7 +382,6 @@ static void serial_throttle(struct tty_struct *tty) dev_dbg(tty-dev, %s - port %d\n, __func__, port-number); - /* pass on to the driver specific version of this function */ if (port-serial-type-throttle) port-serial-type-throttle(tty); } @@ -396,7 +392,6 @@ static void serial_unthrottle(struct tty_struct *tty) dev_dbg(tty-dev, %s - port %d\n, __func__, port-number); - /* pass on to the driver specific version of this function */ if (port-serial-type-unthrottle) port-serial-type-unthrottle(tty); } @@ -410,12 +405,11 @@ static int serial_ioctl(struct tty_struct *tty, dev_dbg(tty-dev, %s - port %d, cmd 0x%.4x\n, __func__, port-number, cmd); - /* pass on to the driver specific version of this function - if it is available */ - if (port-serial-type-ioctl) { + if (port-serial-type-ioctl) retval = port-serial-type-ioctl(tty, cmd, arg); - } else + else retval = -ENOIOCTLCMD; + return retval; } @@ -425,8 +419,6 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old) dev_dbg(tty-dev, %s - port %d\n, __func__, port-number); - /* pass on to the driver specific version of this function - if it is available */ if (port-serial-type-set_termios) port-serial-type-set_termios(tty, port, old); else @@ -439,10 +431,9 @@ static int serial_break(struct tty_struct *tty, int break_state) dev_dbg(tty-dev, %s - port %d\n, __func__, port-number); - /* pass on to the driver specific version of this function - if it is available */ if (port-serial-type-break_ctl) port-serial-type-break_ctl(tty, break_state); + return 0; } @@ -1470,7 +1461,6 @@ void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_driver } EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers); -/* Module information */ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE(GPL); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 05/94] USB: pl2303: make set_control_lines a port operation
Pass usb-serial port rather than usb device to set_control_lines, and make sure port device is used for all port related debugging. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/pl2303.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 5b2e62f..e7e407b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -248,14 +248,15 @@ static int pl2303_port_remove(struct usb_serial_port *port) return 0; } -static int set_control_lines(struct usb_device *dev, u8 value) +static int pl2303_set_control_lines(struct usb_serial_port *port, u8 value) { + struct usb_device *dev = port-serial-dev; int retval; retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE, value, 0, NULL, 0, 100); - dev_dbg(dev-dev, %s - value = %d, retval = %d\n, __func__, + dev_dbg(port-dev, %s - value = %d, retval = %d\n, __func__, value, retval); return retval; } @@ -437,7 +438,7 @@ static void pl2303_set_termios(struct tty_struct *tty, if (control != priv-line_control) { control = priv-line_control; spin_unlock_irqrestore(priv-lock, flags); - set_control_lines(serial-dev, control); + pl2303_set_control_lines(port, control); } else { spin_unlock_irqrestore(priv-lock, flags); } @@ -480,7 +481,7 @@ static void pl2303_dtr_rts(struct usb_serial_port *port, int on) priv-line_control = ~(CONTROL_DTR | CONTROL_RTS); control = priv-line_control; spin_unlock_irqrestore(priv-lock, flags); - set_control_lines(port-serial-dev, control); + pl2303_set_control_lines(port, control); } static void pl2303_close(struct usb_serial_port *port) @@ -550,7 +551,7 @@ static int pl2303_tiocmset(struct tty_struct *tty, mutex_lock(serial-disc_mutex); if (!serial-disconnected) - ret = set_control_lines(serial-dev, control); + ret = pl2303_set_control_lines(port, control); else ret = -ENODEV; mutex_unlock(serial-disc_mutex); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 00/94] USB: serial: disconnect-related patches for 3.10
This is v3 of the USB-disconnect series rebased on Linus tree of last week (c41b3810c09) and the recently submitted fixes-series: USB: fixes for 3.9-final I retained Alan's ACK on the urb-poison patch. This series fixes a bunch of issues related to device disconnect. As the diffstat shows: 35 files changed, 601 insertions(+), 1576 deletions(-) a lot of boilerplate and broken code is removed in the process. I've tried to group related patches and the empty lines in the patch list below are supposed to indicate this. The first set contains various clean-ups and minor fixes. The second set removes legacy disconnect tests which are both broken and unnecessary. The third set cleans up disconnect handling in usb-serial core. It also reimplements the stopping of I/O at disconnect and suspend using URB- poisoning, which, it turns out, appears to have broken since first added to USB core. The included fix is not marked for stable as the bug did not affect any in-kernel drivers (until now). The fourth set adds generic icount and TIOCMIWAIT support to usb-serial, and replaces most current implementations with the generic one, thereby fixing a bunch of races and other odd behaviour as well. Some drivers with incomplete icount-support are simply moved over to use the new tiocmiwait usb-serial operation, while TIOCMIWAIT is removed from the two drivers which appeared to support the required interrupts but in fact did not (copy-paste, I guess). I basically rewrote parts of spcp8x5 (and fixed its modem-status handling) in the process. This version of the series also make sure that the custom TIOCMIWAIT-implementations are woken up at disconnect. The fifth set gets rid of the no longer needed disconnect checks in subdriver close and tiocmset callbacks. This can be done as the tty-port implementation guarantees (and has for some time) that close is never called after tty_vhangup returns (as long as we prevent new activations, which we do). This has the added benefit of allowing us to do clean shutdowns and put devices in any low-power modes also on driver unbind. The sixth set removes another unnecessary and broken legacy disconnect test from two drivers. The final patch updates some copyright information. All patches have been compile tested, while the usb-serial, ftdi_sio and pl2303 ones have been tested on actual hardware. Johan v3: - rebase on USB: fixes for 3.9-final - reuse tty-port wait queue to implement TIOCMIWAIT - make sure generic TIOCMIWAIT handles all hangups - incorporate disconnect fix series for custom TIOCMIWAIT - add two patches that remove unused, private MSR-wait queues - fix indentation of kl5kusb105-close patch v2: - rebase on c41b3810c09 and two previously posted series - expand usb-serial-bus-remove patch commit message - fix typo in visor patch (already posted once) Johan Hovold (94): USB: ftdi_sio: remove obsolete port data refcounting USB: kl5kusb105: remove unnecessary urb kill on close USB: iuu_phoenix: remove unnecessary urb kill on close USB: pl2303: use interface device for debug USB: pl2303: make set_control_lines a port operation USB: serial: rename tty-port callbacks USB: serial: remove redundant comments USB: serial: clean up debug info USB: serial: remove redundant allocation error messages USB: serial: remove port number from generic-driver debug USB: ark3116: remove bogus disconnect test in close USB: cyberjack: remove bogus disconnect test in close USB: digi_acceleport: remove bogus disconnect test in close USB: iuu_phoenix: remove bogus disconnect test in close USB: keyspan: remove bogus disconnect test in close USB: keyspan_pda: remove bogus disconnect test from dtr_rts USB: keyspan_pda: remove bogus disconnect test in close USB: mos7840: remove bogus disconnect test in close USB: sierra: remove bogus disconnect test in close USB: usb_wwan: remove bogus disconnect test in close USB: serial: remove bogus disconnect test in cleanup USB: ssu100: remove explicit initialisation of disconnect USB: ssu100: remove custom close operation USB: serial: fix generic disconnect implementation USB: serial: remove generic disconnect callback USB: serial: remove generic release callback USB: serial: clean up generic-operation handling USB: cyberjack: fix disconnect handling USB: serial: fix port release USB: serial: rename port release USB: fix urb-poison imbalance USB: serial: use urb poison to reliably kill traffic USB: serial: clean up usb-serial bus device removal USB: serial: add tiocmiwait subdriver operation USB: serial: add generic TIOCMIWAIT implementation USB: serial: wake up MSR-wait queue on disconnect USB: serial: add generic get_icount implementation USB: ftdi_sio: use port icount USB: ftdi_sio: switch to generic TIOCMIWAIT implementation USB: ftdi_sio: switch to generic get_icount implementation USB: ark3116: switch to generic get_icount implementation
[PATCH v3 88/94] USB: pl2303: remove disconnect test from tiocmset
Remove unnecessary disconnect test in tiocmset. No ioctls will be made after disconnect returns. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/pl2303.c | 15 --- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 4dff179..7151659 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -531,7 +531,6 @@ static int pl2303_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty-driver_data; - struct usb_serial *serial = port-serial; struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; u8 control; @@ -549,17 +548,11 @@ static int pl2303_tiocmset(struct tty_struct *tty, control = priv-line_control; spin_unlock_irqrestore(priv-lock, flags); - mutex_lock(serial-disc_mutex); - if (!serial-disconnected) { - ret = pl2303_set_control_lines(port, control); - if (ret) - ret = usb_translate_errors(ret); - } else { - ret = -ENODEV; - } - mutex_unlock(serial-disc_mutex); + ret = pl2303_set_control_lines(port, control); + if (ret) + return usb_translate_errors(ret); - return ret; + return 0; } static int pl2303_tiocmget(struct tty_struct *tty) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 82/94] USB: kl5kusb105: always disable uart on close
Always try to disable the uart on close. Since the switch to tty ports, close will be called as part of shutdown before disconnect returns. Hence there is no need to check the disconnected flag, and we can put devices in disabled states also on driver unbind. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/kl5kusb105.c | 27 +++ 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 57fd001..1b4054f 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -341,22 +341,17 @@ static void klsi_105_close(struct usb_serial_port *port) { int rc; - mutex_lock(port-serial-disc_mutex); - if (!port-serial-disconnected) { - /* send READ_OFF */ - rc = usb_control_msg(port-serial-dev, -usb_sndctrlpipe(port-serial-dev, 0), -KL5KUSB105A_SIO_CONFIGURE, -USB_TYPE_VENDOR | USB_DIR_OUT, -KL5KUSB105A_SIO_CONFIGURE_READ_OFF, -0, /* index */ -NULL, 0, -KLSI_TIMEOUT); - if (rc 0) - dev_err(port-dev, - Disabling read failed (error = %d)\n, rc); - } - mutex_unlock(port-serial-disc_mutex); + /* send READ_OFF */ + rc = usb_control_msg(port-serial-dev, +usb_sndctrlpipe(port-serial-dev, 0), +KL5KUSB105A_SIO_CONFIGURE, +USB_TYPE_VENDOR | USB_DIR_OUT, +KL5KUSB105A_SIO_CONFIGURE_READ_OFF, +0, /* index */ +NULL, 0, +KLSI_TIMEOUT); + if (rc 0) + dev_err(port-dev, failed to disable read: %d\n, rc); /* shutdown our bulk reads and writes */ usb_serial_generic_close(port); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 84/94] USB: mos7720: always disable uart on close
Always try to disable the uart on close. Since the switch to tty ports, close will be called as part of shutdown before disconnect returns. Hence there is no need to check the disconnected flag, and we can put devices in disabled states also on driver unbind. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mos7720.c | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index d1e2bf3..fc506bb 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1140,16 +1140,9 @@ static void mos7720_close(struct usb_serial_port *port) usb_kill_urb(port-write_urb); usb_kill_urb(port-read_urb); - mutex_lock(serial-disc_mutex); - /* these commands must not be issued if the device has -* been disconnected */ - if (!serial-disconnected) { - write_mos_reg(serial, port-number - port-serial-minor, - MCR, 0x00); - write_mos_reg(serial, port-number - port-serial-minor, - IER, 0x00); - } - mutex_unlock(serial-disc_mutex); + write_mos_reg(serial, port-number - port-serial-minor, MCR, 0x00); + write_mos_reg(serial, port-number - port-serial-minor, IER, 0x00); + mos7720_port-open = 0; } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 06/94] USB: serial: rename tty-port callbacks
Rename the tty-port callbacks using a common prefix to more clearly separate them from the tty and usb driver callbacks. Rename serial_down to serial_port_shutdown to match the callback name. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2e70efa..a5e8a7b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -225,7 +225,7 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) return retval; } -static int serial_activate(struct tty_port *tport, struct tty_struct *tty) +static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty) { struct usb_serial_port *port = container_of(tport, struct usb_serial_port, port); @@ -254,7 +254,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp) } /** - * serial_down - shut down hardware + * serial_port_shutdown - shut down hardware * @tport: tty port to shut down * * Shut down a USB serial port unless it is the console. We never @@ -262,7 +262,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp) * against activate by the tport mutex and kept to matching open/close pairs * of calls by the ASYNCB_INITIALIZED flag. */ -static void serial_down(struct tty_port *tport) +static void serial_port_shutdown(struct tty_port *tport) { struct usb_serial_port *port = container_of(tport, struct usb_serial_port, port); @@ -681,7 +681,7 @@ static struct usb_serial_driver *search_serial_device( return NULL; } -static int serial_carrier_raised(struct tty_port *port) +static int serial_port_carrier_raised(struct tty_port *port) { struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); struct usb_serial_driver *drv = p-serial-type; @@ -692,7 +692,7 @@ static int serial_carrier_raised(struct tty_port *port) return 1; } -static void serial_dtr_rts(struct tty_port *port, int on) +static void serial_port_dtr_rts(struct tty_port *port, int on) { struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); struct usb_serial *serial = p-serial; @@ -712,10 +712,10 @@ static void serial_dtr_rts(struct tty_port *port, int on) } static const struct tty_port_operations serial_port_ops = { - .carrier_raised = serial_carrier_raised, - .dtr_rts = serial_dtr_rts, - .activate = serial_activate, - .shutdown = serial_down, + .carrier_raised = serial_port_carrier_raised, + .dtr_rts= serial_port_dtr_rts, + .activate = serial_port_activate, + .shutdown = serial_port_shutdown, }; static int usb_serial_probe(struct usb_interface *interface, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 81/94] USB: io_ti: always disable uart on close
Always try to disable the uart on close. Since the switch to tty ports, close will be called as part of shutdown before disconnect returns. Hence there is no need to check the disconnected flag, and we can put devices in disabled states also on driver unbind. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/io_ti.c | 15 ++- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 8914002..0ccc422 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1907,21 +1907,10 @@ static void edge_close(struct usb_serial_port *port) kfifo_reset_out(edge_port-write_fifo); spin_unlock_irqrestore(edge_port-ep_lock, flags); - /* assuming we can still talk to the device, -* send a close port command to it */ dev_dbg(port-dev, %s - send umpc_close_port\n, __func__); port_number = port-number - port-serial-minor; - - mutex_lock(serial-disc_mutex); - if (!serial-disconnected) { - send_cmd(serial-dev, -UMPC_CLOSE_PORT, -(__u8)(UMPM_UART1_PORT + port_number), -0, -NULL, -0); - } - mutex_unlock(serial-disc_mutex); + send_cmd(serial-dev, UMPC_CLOSE_PORT, +(__u8)(UMPM_UART1_PORT + port_number), 0, NULL, 0); mutex_lock(edge_serial-es_lock); --edge_port-edge_serial-num_ports_open; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 83/94] USB: metro-usb: always disable uart on close
Always try to disable the uart on close. Since the switch to tty ports, close will be called as part of shutdown before disconnect returns. Hence there is no need to check the disconnected flag, and we can put devices in disabled states also on driver unbind. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/metro-usb.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index bf3c7a2..47e2477 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -177,10 +177,7 @@ static void metrousb_cleanup(struct usb_serial_port *port) usb_unlink_urb(port-interrupt_in_urb); usb_kill_urb(port-interrupt_in_urb); - mutex_lock(port-serial-disc_mutex); - if (!port-serial-disconnected) - metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); - mutex_unlock(port-serial-disc_mutex); + metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); } static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 53/94] USB: io_ti: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation which does not suffer from the races involved when using the deprecated sleep_on functions. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/io_ti.c | 34 -- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index fb9e664..8914002 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -86,6 +86,7 @@ struct edgeport_port { int baud_rate; int close_pending; int lsr_event; + struct edgeport_serial *edge_serial; struct usb_serial_port *port; __u8 bUartMode; /* Port type, 0: RS232, etc. */ @@ -1455,7 +1456,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) icount-dcd++; if (msr EDGEPORT_MSR_DELTA_RI) icount-rng++; - wake_up_interruptible(edge_port-port-delta_msr_wait); + wake_up_interruptible(edge_port-port-port.delta_msr_wait); } /* Save the new modem status */ @@ -2392,8 +2393,6 @@ static int edge_ioctl(struct tty_struct *tty, { struct usb_serial_port *port = tty-driver_data; struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount cnow; - struct async_icount cprev; dev_dbg(port-dev, %s - port %d, cmd = 0x%x\n, __func__, port-number, cmd); @@ -2402,32 +2401,6 @@ static int edge_ioctl(struct tty_struct *tty, dev_dbg(port-dev, %s - TIOCGSERIAL\n, __func__); return get_serial_info(edge_port, (struct serial_struct __user *) arg); - case TIOCMIWAIT: - dev_dbg(port-dev, %s - TIOCMIWAIT\n, __func__); - cprev = edge_port-port-icount; - while (1) { - interruptible_sleep_on(port-delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - cnow = port-icount; - if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr - cnow.dcd == cprev.dcd cnow.cts == cprev.cts) - return -EIO; /* no change = error */ - if (((arg TIOCM_RNG) (cnow.rng != cprev.rng)) || - ((arg TIOCM_DSR) (cnow.dsr != cprev.dsr)) || - ((arg TIOCM_CD) (cnow.dcd != cprev.dcd)) || - ((arg TIOCM_CTS) (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* not reached */ - break; } return -ENOIOCTLCMD; } @@ -2522,7 +2495,6 @@ static int edge_port_remove(struct usb_serial_port *port) struct edgeport_port *edge_port; edge_port = usb_get_serial_port_data(port); - edge_remove_sysfs_attrs(port); kfifo_free(edge_port-write_fifo); kfree(edge_port); @@ -2594,6 +2566,7 @@ static struct usb_serial_driver edgeport_1port_device = { .set_termios= edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, .write_room = edge_write_room, @@ -2625,6 +2598,7 @@ static struct usb_serial_driver edgeport_2port_device = { .set_termios= edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, .write_room = edge_write_room, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 15/94] USB: keyspan: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Remove some out-commented bogus code while at it. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/keyspan.c | 26 +++--- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 1fd1935..6abe8a4 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -1115,7 +1115,6 @@ static void keyspan_dtr_rts(struct usb_serial_port *port, int on) static void keyspan_close(struct usb_serial_port *port) { int i; - struct usb_serial *serial = port-serial; struct keyspan_port_private *p_priv; p_priv = usb_get_serial_port_data(port); @@ -1123,28 +1122,17 @@ static void keyspan_close(struct usb_serial_port *port) p_priv-rts_state = 0; p_priv-dtr_state = 0; - if (serial-dev) { - keyspan_send_setup(port, 2); - /* pilot-xfer seems to work best with this delay */ - mdelay(100); - /* keyspan_set_termios(port, NULL); */ - } - - /*while (p_priv-outcont_urb-status == -EINPROGRESS) { - dev_dbg(port-dev, %s - urb in progress\n, __func__); - }*/ + keyspan_send_setup(port, 2); + /* pilot-xfer seems to work best with this delay */ + mdelay(100); p_priv-out_flip = 0; p_priv-in_flip = 0; - if (serial-dev) { - /* Stop reading/writing urbs */ - stop_urb(p_priv-inack_urb); - /* stop_urb(p_priv-outcont_urb); */ - for (i = 0; i 2; i++) { - stop_urb(p_priv-in_urbs[i]); - stop_urb(p_priv-out_urbs[i]); - } + stop_urb(p_priv-inack_urb); + for (i = 0; i 2; i++) { + stop_urb(p_priv-in_urbs[i]); + stop_urb(p_priv-out_urbs[i]); } } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 03/94] USB: iuu_phoenix: remove unnecessary urb kill on close
Remove kill of interrupt-in urb on close as it has never been submitted. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/iuu_phoenix.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index ff77027..a3bfcb3 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -957,7 +957,6 @@ static void iuu_close(struct usb_serial_port *port) dev_dbg(port-dev, %s - shutting down urbs\n, __func__); usb_kill_urb(port-write_urb); usb_kill_urb(port-read_urb); - usb_kill_urb(port-interrupt_in_urb); iuu_led(port, 0, 0, 0xF000, 0xFF); } } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 02/94] USB: kl5kusb105: remove unnecessary urb kill on close
Remove kill of interrupt-in urb on close as it has never been submitted. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/kl5kusb105.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 769d910..57fd001 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -360,9 +360,6 @@ static void klsi_105_close(struct usb_serial_port *port) /* shutdown our bulk reads and writes */ usb_serial_generic_close(port); - - /* wgg - do I need this? I think so. */ - usb_kill_urb(port-interrupt_in_urb); } /* We need to write a complete 64-byte data block and encode the -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 04/94] USB: pl2303: use interface device for debug
Use interface rather than usb-serial device for debugging interface related operations. This gives more descriptive messages, such as [ 905.669436] pl2303 1-4.1:1.0: 0x40:0x1:0x8:0x0 0 rather than [ 341.943535] usb 1-4.1: 0x40:0x1:0x8:0x0 0 Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/pl2303.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 3b10018..5b2e62f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -149,7 +149,7 @@ static int pl2303_vendor_read(__u16 value, __u16 index, int res = usb_control_msg(serial-dev, usb_rcvctrlpipe(serial-dev, 0), VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, value, index, buf, 1, 100); - dev_dbg(serial-dev-dev, 0x%x:0x%x:0x%x:0x%x %d - %x\n, + dev_dbg(serial-interface-dev, 0x%x:0x%x:0x%x:0x%x %d - %x\n, VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, value, index, res, buf[0]); return res; @@ -161,7 +161,7 @@ static int pl2303_vendor_write(__u16 value, __u16 index, int res = usb_control_msg(serial-dev, usb_sndctrlpipe(serial-dev, 0), VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, value, index, NULL, 0, 100); - dev_dbg(serial-dev-dev, 0x%x:0x%x:0x%x:0x%x %d\n, + dev_dbg(serial-interface-dev, 0x%x:0x%x:0x%x:0x%x %d\n, VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, value, index, res); return res; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 09/94] USB: serial: remove redundant allocation error messages
Failed allocations already get an OOM message and a stack dump. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 37 + 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 0e6fd53..578072d 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -607,10 +607,8 @@ static struct usb_serial *create_serial(struct usb_device *dev, struct usb_serial *serial; serial = kzalloc(sizeof(*serial), GFP_KERNEL); - if (!serial) { - dev_err(dev-dev, %s - out of memory\n, __func__); + if (!serial) return NULL; - } serial-dev = usb_get_dev(dev); serial-type = driver; serial-interface = usb_get_intf(interface); @@ -754,7 +752,6 @@ static int usb_serial_probe(struct usb_interface *interface, serial = create_serial(dev, interface, type); if (!serial) { module_put(type-driver.owner); - dev_err(ddev, %s - out of memory\n, __func__); return -ENOMEM; } @@ -918,16 +915,12 @@ static int usb_serial_probe(struct usb_interface *interface, for (j = 0; j ARRAY_SIZE(port-read_urbs); ++j) { set_bit(j, port-read_urbs_free); port-read_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); - if (!port-read_urbs[j]) { - dev_err(ddev, No free urbs available\n); + if (!port-read_urbs[j]) goto probe_error; - } port-bulk_in_buffers[j] = kmalloc(buffer_size, GFP_KERNEL); - if (!port-bulk_in_buffers[j]) { - dev_err(ddev, Couldn't allocate bulk_in_buffer\n); + if (!port-bulk_in_buffers[j]) goto probe_error; - } usb_fill_bulk_urb(port-read_urbs[j], dev, usb_rcvbulkpipe(dev, endpoint-bEndpointAddress), @@ -954,16 +947,12 @@ static int usb_serial_probe(struct usb_interface *interface, for (j = 0; j ARRAY_SIZE(port-write_urbs); ++j) { set_bit(j, port-write_urbs_free); port-write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); - if (!port-write_urbs[j]) { - dev_err(ddev, No free urbs available\n); + if (!port-write_urbs[j]) goto probe_error; - } port-bulk_out_buffers[j] = kmalloc(buffer_size, GFP_KERNEL); - if (!port-bulk_out_buffers[j]) { - dev_err(ddev, Couldn't allocate bulk_out_buffer\n); + if (!port-bulk_out_buffers[j]) goto probe_error; - } usb_fill_bulk_urb(port-write_urbs[j], dev, usb_sndbulkpipe(dev, endpoint-bEndpointAddress), @@ -981,19 +970,15 @@ static int usb_serial_probe(struct usb_interface *interface, endpoint = interrupt_in_endpoint[i]; port = serial-port[i]; port-interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port-interrupt_in_urb) { - dev_err(ddev, No free urbs available\n); + if (!port-interrupt_in_urb) goto probe_error; - } buffer_size = usb_endpoint_maxp(endpoint); port-interrupt_in_endpointAddress = endpoint-bEndpointAddress; port-interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!port-interrupt_in_buffer) { - dev_err(ddev, Couldn't allocate interrupt_in_buffer\n); + if (!port-interrupt_in_buffer) goto probe_error; - } usb_fill_int_urb(port-interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint-bEndpointAddress), @@ -1010,20 +995,16 @@ static int usb_serial_probe(struct usb_interface *interface, endpoint = interrupt_out_endpoint[i];
[PATCH v3 34/94] USB: serial: add tiocmiwait subdriver operation
Add tiocmiwait operation to struct usb_serial_driver. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 15 +++ include/linux/usb/serial.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index c481a80..c17becb 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -406,10 +406,17 @@ static int serial_ioctl(struct tty_struct *tty, dev_dbg(tty-dev, %s - cmd 0x%.4x\n, __func__, cmd); - if (port-serial-type-ioctl) - retval = port-serial-type-ioctl(tty, cmd, arg); - else - retval = -ENOIOCTLCMD; + switch (cmd) { + case TIOCMIWAIT: + if (port-serial-type-tiocmiwait) + retval = port-serial-type-tiocmiwait(tty, arg); + break; + default: + if (port-serial-type-ioctl) + retval = port-serial-type-ioctl(tty, cmd, arg); + else + retval = -ENOIOCTLCMD; + } return retval; } diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 3f8f5e3..9c8b53f 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -272,6 +272,7 @@ struct usb_serial_driver { int (*tiocmget)(struct tty_struct *tty); int (*tiocmset)(struct tty_struct *tty, unsigned int set, unsigned int clear); + int (*tiocmiwait)(struct tty_struct *tty, unsigned long arg); int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount); /* Called by the tty layer for port level work. There may or may not -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 91/94] USB: garmin_gps: remove bogus disconnect test in close
Remove bogus disconnect test for serial device being NULL in close. This can never happen as close is guaranteed to be called before the last tty reference is dropped (and port-serial is cleared). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/garmin_gps.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 81caf56..1ade6cf2 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -946,16 +946,12 @@ static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port) static void garmin_close(struct usb_serial_port *port) { - struct usb_serial *serial = port-serial; struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); dev_dbg(port-dev, %s - port %d - mode=%d state=%d flags=0x%X\n, __func__, port-number, garmin_data_p-mode, garmin_data_p-state, garmin_data_p-flags); - if (!serial) - return; - garmin_clear(garmin_data_p); /* shutdown our urbs */ -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 51/94] USB: io_edgeport: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/io_edgeport.c | 35 +-- drivers/usb/serial/io_tables.h | 4 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 16ef8f3..ff9a6ef 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1618,8 +1618,6 @@ static int edge_ioctl(struct tty_struct *tty, struct usb_serial_port *port = tty-driver_data; DEFINE_WAIT(wait); struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount cnow; - struct async_icount cprev; dev_dbg(port-dev, %s - port %d, cmd = 0x%x\n, __func__, port-number, cmd); @@ -1631,37 +1629,6 @@ static int edge_ioctl(struct tty_struct *tty, case TIOCGSERIAL: dev_dbg(port-dev, %s (%d) TIOCGSERIAL\n, __func__, port-number); return get_serial_info(edge_port, (struct serial_struct __user *) arg); - - case TIOCMIWAIT: - dev_dbg(port-dev, %s (%d) TIOCMIWAIT\n, __func__, port-number); - cprev = port-icount; - while (1) { - prepare_to_wait(port-delta_msr_wait, - wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(port-delta_msr_wait, wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - cnow = port-icount; - if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr - cnow.dcd == cprev.dcd cnow.cts == cprev.cts) - return -EIO; /* no change = error */ - if (((arg TIOCM_RNG) (cnow.rng != cprev.rng)) || - ((arg TIOCM_DSR) (cnow.dsr != cprev.dsr)) || - ((arg TIOCM_CD) (cnow.dcd != cprev.dcd)) || - ((arg TIOCM_CTS) (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - break; - } return -ENOIOCTLCMD; } @@ -2022,7 +1989,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr) icount-dcd++; if (newMsr EDGEPORT_MSR_DELTA_RI) icount-rng++; - wake_up_interruptible(edge_port-port-delta_msr_wait); + wake_up_interruptible(edge_port-port-port.delta_msr_wait); } /* Save the new modem status */ diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 35fe9ad..ae5fac5 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -116,6 +116,7 @@ static struct usb_serial_driver edgeport_2port_device = { .set_termios= edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, .write_room = edge_write_room, @@ -147,6 +148,7 @@ static struct usb_serial_driver edgeport_4port_device = { .set_termios= edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, .write_room = edge_write_room, @@ -178,6 +180,7 @@ static struct usb_serial_driver edgeport_8port_device = { .set_termios= edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .write = edge_write, .write_room = edge_write_room, @@ -209,6 +212,7 @@ static struct usb_serial_driver epic_device = { .set_termios= edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount,
[PATCH v3 72/94] USB: spcp8x5: reimplement device type detection
Reimplement device type detection using the device id table and quirks. Device type was used to detect one device type which did not support to control functions. Add quirks to the device table and store them in the private port data at probe instead. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/spcp8x5.c | 70 +--- 1 file changed, 21 insertions(+), 49 deletions(-) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index e0093dd..a454a3f 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -28,6 +28,9 @@ #define DRIVER_DESCSPCP8x5 USB to serial adaptor driver +#define SPCP825_QUIRK_NO_UART_STATUS 0x01 +#define SPCP825_QUIRK_NO_WORK_MODE 0x02 + #define SPCP8x5_007_VID0x04FC #define SPCP8x5_007_PID0x0201 #define SPCP8x5_008_VID0x04fc @@ -44,7 +47,9 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)}, { USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)}, { USB_DEVICE(SPCP8x5_008_VID, SPCP8x5_008_PID)}, - { USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID)}, + { USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID), + .driver_info = SPCP825_QUIRK_NO_UART_STATUS | + SPCP825_QUIRK_NO_WORK_MODE }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); @@ -136,47 +141,32 @@ struct spcp8x5_usb_ctrl_arg { #define UART_OVERRUN_ERROR 0x40 #define UART_CTS 0x80 -enum spcp8x5_type { - SPCP825_007_TYPE, - SPCP825_008_TYPE, - SPCP825_PHILIP_TYPE, - SPCP825_INTERMATIC_TYPE, - SPCP835_TYPE, -}; - struct spcp8x5_private { + unsignedquirks; spinlock_t lock; - enum spcp8x5_type type; u8 line_control; u8 line_status; }; +static int spcp8x5_probe(struct usb_serial *serial, + const struct usb_device_id *id) +{ + usb_set_serial_data(serial, (void *)id); + + return 0; +} + static int spcp8x5_port_probe(struct usb_serial_port *port) { - struct usb_serial *serial = port-serial; + const struct usb_device_id *id = usb_get_serial_data(port-serial); struct spcp8x5_private *priv; - enum spcp8x5_type type = SPCP825_007_TYPE; - u16 product = le16_to_cpu(serial-dev-descriptor.idProduct); - - if (product == 0x0201) - type = SPCP825_007_TYPE; - else if (product == 0x0231) - type = SPCP835_TYPE; - else if (product == 0x0235) - type = SPCP825_008_TYPE; - else if (product == 0x0204) - type = SPCP825_INTERMATIC_TYPE; - else if (product == 0x0471 -serial-dev-descriptor.idVendor == cpu_to_le16(0x081e)) - type = SPCP825_PHILIP_TYPE; - dev_dbg(serial-dev-dev, device type = %d\n, (int)type); priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; spin_lock_init(priv-lock); - priv-type = type; + priv-quirks = id-driver_info; usb_set_serial_port_data(port, priv); @@ -193,18 +183,13 @@ static int spcp8x5_port_remove(struct usb_serial_port *port) return 0; } -/* - * Set the modem control line of the device. - * - * NOTE: not supported by spcp825-007 - */ static int spcp8x5_set_ctrl_line(struct usb_serial_port *port, u8 mcr) { struct spcp8x5_private *priv = usb_get_serial_port_data(port); struct usb_device *dev = port-serial-dev; int retval; - if (priv-type == SPCP825_007_TYPE) + if (priv-quirks SPCP825_QUIRK_NO_UART_STATUS) return -EPERM; retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -217,11 +202,6 @@ static int spcp8x5_set_ctrl_line(struct usb_serial_port *port, u8 mcr) return retval; } -/* - * Get the modem status register of the device. - * - * NOTE: not supported by spcp825-007 - */ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) { struct spcp8x5_private *priv = usb_get_serial_port_data(port); @@ -229,9 +209,7 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) u8 *buf; int ret; - /* I return Permited not support here but seem inval device -* is more fix */ - if (priv-type == SPCP825_007_TYPE) + if (priv-quirks SPCP825_QUIRK_NO_UART_STATUS) return -EPERM; buf = kzalloc(1, GFP_KERNEL); @@ -251,11 +229,6 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) return ret; } -/* - * Select the work mode. - * - * NOTE: not supported by spcp825-007 - */ static void
[PATCH v3 46/94] USB: cypress_m8: fix TIOCMIWAIT and disconnect
Use tty-port modem-status-change wait queue on which processes are woken up at hangup and disconnect. Currently a process waiting on modem-status changes will not be woken on device disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/cypress_m8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index cdbb096..e4a62cf 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -861,7 +861,7 @@ static int cypress_tiocmiwait(struct tty_struct *tty, unsigned long arg) char diff; for (;;) { - interruptible_sleep_on(port-delta_msr_wait); + interruptible_sleep_on(port-port.delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; @@ -1176,7 +1176,7 @@ static void cypress_read_int_callback(struct urb *urb) if (priv-current_status != priv-prev_status) { priv-diff_status |= priv-current_status ^ priv-prev_status; - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); priv-prev_status = priv-current_status; } spin_unlock_irqrestore(priv-lock, flags); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 63/94] USB: pl2303: add custom tiocmiwait operation
Break out TIOCMIWAIT handling from custom ioctl operation and use tiocmiwait operation field instead. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/pl2303.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index e7e407b..1f7fd1a 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -593,8 +593,9 @@ static int pl2303_carrier_raised(struct usb_serial_port *port) return 0; } -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) +static int pl2303_tiocmiwait(struct tty_struct *tty, unsigned long arg) { + struct usb_serial_port *port = tty-driver_data; struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int prevstatus; @@ -652,10 +653,6 @@ static int pl2303_ioctl(struct tty_struct *tty, return -EFAULT; return 0; - - case TIOCMIWAIT: - dev_dbg(port-dev, %s TIOCMIWAIT\n, __func__); - return wait_modem_info(port, arg); default: dev_dbg(port-dev, %s not supported = 0x%04x\n, __func__, cmd); break; @@ -836,6 +833,7 @@ static struct usb_serial_driver pl2303_device = { .set_termios = pl2303_set_termios, .tiocmget = pl2303_tiocmget, .tiocmset = pl2303_tiocmset, + .tiocmiwait = pl2303_tiocmiwait, .process_read_urb = pl2303_process_read_urb, .read_int_callback =pl2303_read_int_callback, .attach = pl2303_startup, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 40/94] USB: ftdi_sio: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ftdi_sio.c | 24 +--- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index fa3077f..1199dc5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -917,8 +917,6 @@ static void ftdi_set_termios(struct tty_struct *tty, static int ftdi_tiocmget(struct tty_struct *tty); static int ftdi_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int ftdi_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void ftdi_break_ctl(struct tty_struct *tty, int break_state); @@ -955,7 +953,7 @@ static struct usb_serial_driver ftdi_sio_device = { .tiocmget = ftdi_tiocmget, .tiocmset = ftdi_tiocmset, .tiocmiwait = usb_serial_generic_tiocmiwait, - .get_icount = ftdi_get_icount, + .get_icount = usb_serial_generic_get_icount, .ioctl =ftdi_ioctl, .set_termios = ftdi_set_termios, .break_ctl =ftdi_break_ctl, @@ -2351,26 +2349,6 @@ static int ftdi_tiocmset(struct tty_struct *tty, return update_mctrl(port, set, clear); } -static int ftdi_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct async_icount *ic = port-icount; - - icount-cts = ic-cts; - icount-dsr = ic-dsr; - icount-rng = ic-rng; - icount-dcd = ic-dcd; - icount-tx = ic-tx; - icount-rx = ic-rx; - icount-frame = ic-frame; - icount-parity = ic-parity; - icount-overrun = ic-overrun; - icount-brk = ic-brk; - icount-buf_overrun = ic-buf_overrun; - return 0; -} - static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 36/94] USB: serial: wake up MSR-wait queue on disconnect
Make sure processes waiting for modem-status changes are woken up at disconnect. This is needed for custom subdriver TIOCMIWAIT-implementations which do not yet handle hangup. Even though processes on the tty-port wait queue are woken up at hangup the wake-up call in usb-serial disconnect is still needed if a woken-up process may go back to sleep (e.g. due to an incomplete TIOCMIWAIT-implementation). If a disconnect occurs after a hangup, any process waiting for changes will not be woken up a second time by the tty-layer as the port will then have been disassociated from the tty. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index c17becb..96cfe43 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1097,6 +1097,7 @@ static void usb_serial_disconnect(struct usb_interface *interface) tty_kref_put(tty); } usb_serial_port_poison_urbs(port); + wake_up_interruptible(port-port.delta_msr_wait); cancel_work_sync(port-work); if (device_is_registered(port-dev)) device_del(port-dev); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 69/94] USB: spcp8x5: clean up code
Clean up this driver somewhat. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/spcp8x5.c | 72 +++- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index f34930c..a5c3a36 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -13,8 +13,6 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * - * */ #include linux/kernel.h #include linux/errno.h @@ -28,7 +26,7 @@ #include linux/usb.h #include linux/usb/serial.h -#define DRIVER_DESCSPCP8x5 USB to serial adaptor driver +#define DRIVER_DESCSPCP8x5 USB to serial adaptor driver #define SPCP8x5_007_VID0x04FC #define SPCP8x5_007_PID0x0201 @@ -52,7 +50,7 @@ static const struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); struct spcp8x5_usb_ctrl_arg { - u8 type; + u8 type; u8 cmd; u8 cmd_type; u16 value; @@ -147,10 +145,10 @@ enum spcp8x5_type { }; struct spcp8x5_private { - spinlock_t lock; + spinlock_t lock; enum spcp8x5_type type; - u8 line_control; - u8 line_status; + u8 line_control; + u8 line_status; }; static int spcp8x5_port_probe(struct usb_serial_port *port) @@ -180,7 +178,7 @@ static int spcp8x5_port_probe(struct usb_serial_port *port) spin_lock_init(priv-lock); priv-type = type; - usb_set_serial_port_data(port , priv); + usb_set_serial_port_data(port, priv); return 0; } @@ -195,13 +193,16 @@ static int spcp8x5_port_remove(struct usb_serial_port *port) return 0; } -/* set the modem control line of the device. - * NOTE spcp825-007 not supported this */ -static int spcp8x5_set_ctrlLine(struct usb_device *dev, u8 value, +/* + * Set the modem control line of the device. + * + * NOTE: not supported by spcp825-007 + */ +static int spcp8x5_set_ctrl_line(struct usb_device *dev, u8 value, enum spcp8x5_type type) { int retval; - u8 mcr = 0 ; + u8 mcr = 0; if (type == SPCP825_007_TYPE) return -EPERM; @@ -215,8 +216,11 @@ static int spcp8x5_set_ctrlLine(struct usb_device *dev, u8 value, return retval; } -/* get the modem status register of the device - * NOTE spcp825-007 not supported this */ +/* + * Get the modem status register of the device. + * + * NOTE: not supported by spcp825-007 + */ static int spcp8x5_get_msr(struct usb_device *dev, u8 *status, enum spcp8x5_type type) { @@ -249,9 +253,12 @@ static int spcp8x5_get_msr(struct usb_device *dev, u8 *status, return ret; } -/* select the work mode. - * NOTE this function not supported by spcp825-007 */ -static void spcp8x5_set_workMode(struct usb_device *dev, u16 value, +/* + * Select the work mode. + * + * NOTE: not supported by spcp825-007 + */ +static void spcp8x5_set_work_mode(struct usb_device *dev, u16 value, u16 index, enum spcp8x5_type type) { int ret; @@ -273,8 +280,10 @@ static void spcp8x5_set_workMode(struct usb_device *dev, u16 value, static int spcp8x5_carrier_raised(struct usb_serial_port *port) { struct spcp8x5_private *priv = usb_get_serial_port_data(port); + if (priv-line_status MSR_STATUS_LINE_DCD) return 1; + return 0; } @@ -293,20 +302,17 @@ static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on) | MCR_CONTROL_LINE_RTS); control = priv-line_control; spin_unlock_irqrestore(priv-lock, flags); - spcp8x5_set_ctrlLine(port-serial-dev, control , priv-type); + spcp8x5_set_ctrl_line(port-serial-dev, control, priv-type); } static void spcp8x5_init_termios(struct tty_struct *tty) { - /* for the 1st time call this function */ tty-termios = tty_std_termios; tty-termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; tty-termios.c_ispeed = 115200; tty-termios.c_ospeed = 115200; } -/* set the serial param for transfer. we should check if we really need to - * transfer. if we set flow control we should do this too. */ static void spcp8x5_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { @@ -321,7 +327,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty, int i; u8 control; - /* check that they really want us to change something */ if (!tty_termios_hw_change(tty-termios, old_termios)) return;
[PATCH v3 76/94] USB: ti_usb_3410_5052: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ti_usb_3410_5052.c | 44 ++- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 73deb02..9997725 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -73,7 +73,6 @@ struct ti_port { unsigned inttp_uart_base_addr; int tp_flags; int tp_closing_wait;/* in .01 secs */ - struct async_icount tp_icount; wait_queue_head_t tp_write_wait; struct ti_device*tp_tdev; struct usb_serial_port *tp_port; @@ -108,8 +107,6 @@ static void ti_throttle(struct tty_struct *tty); static void ti_unthrottle(struct tty_struct *tty); static int ti_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); -static int ti_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); static void ti_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios); static int ti_tiocmget(struct tty_struct *tty); @@ -235,7 +232,7 @@ static struct usb_serial_driver ti_1port_device = { .set_termios= ti_set_termios, .tiocmget = ti_tiocmget, .tiocmset = ti_tiocmset, - .get_icount = ti_get_icount, + .get_icount = usb_serial_generic_get_icount, .break_ctl = ti_break, .read_int_callback = ti_interrupt_callback, .read_bulk_callback = ti_bulk_in_callback, @@ -265,7 +262,7 @@ static struct usb_serial_driver ti_2port_device = { .set_termios= ti_set_termios, .tiocmget = ti_tiocmget, .tiocmset = ti_tiocmset, - .get_icount = ti_get_icount, + .get_icount = usb_serial_generic_get_icount, .break_ctl = ti_break, .read_int_callback = ti_interrupt_callback, .read_bulk_callback = ti_bulk_in_callback, @@ -480,8 +477,6 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) port_number = port-number - port-serial-minor; - memset((tport-tp_icount), 0x00, sizeof(tport-tp_icount)); - tport-tp_msr = 0; tport-tp_shadow_mcr |= (TI_MCR_RTS | TI_MCR_DTR); @@ -731,31 +726,6 @@ static void ti_unthrottle(struct tty_struct *tty) } } -static int ti_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - struct async_icount cnow = tport-tp_icount; - - dev_dbg(port-dev, %s - TIOCGICOUNT RX=%d, TX=%d\n, __func__, - cnow.rx, cnow.tx); - - icount-cts = cnow.cts; - icount-dsr = cnow.dsr; - icount-rng = cnow.rng; - icount-dcd = cnow.dcd; - icount-rx = cnow.rx; - icount-tx = cnow.tx; - icount-frame = cnow.frame; - icount-overrun = cnow.overrun; - icount-parity = cnow.parity; - icount-brk = cnow.brk; - icount-buf_overrun = cnow.buf_overrun; - - return 0; -} - static int ti_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -780,7 +750,7 @@ static int ti_ioctl(struct tty_struct *tty, (struct serial_struct __user *)arg); case TIOCMIWAIT: dev_dbg(port-dev, %s - TIOCMIWAIT\n, __func__); - cprev = tport-tp_icount; + cprev = port-icount; while (1) { interruptible_sleep_on(port-delta_msr_wait); if (signal_pending(current)) @@ -789,7 +759,7 @@ static int ti_ioctl(struct tty_struct *tty, if (port-serial-disconnected) return -EIO; - cnow = tport-tp_icount; + cnow = port-icount; if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr cnow.dcd == cprev.dcd cnow.cts == cprev.cts) return -EIO; /* no change = error */ @@ -1156,7 +1126,7 @@ static void ti_bulk_in_callback(struct urb *urb) else ti_recv(port, urb-transfer_buffer, urb-actual_length); spin_lock(tport-tp_lock); - tport-tp_icount.rx += urb-actual_length; + port-icount.rx += urb-actual_length; spin_unlock(tport-tp_lock); } @@ -1265,7 +1235,7 @@ static void ti_send(struct ti_port *tport) /* TODO: reschedule ti_send */ } else {
[PATCH v3 61/94] USB: oti6858: replace custom ioctl operation with tiocmiwait
Replace custom ioctl operation with tiocmiwait. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/oti6858.c | 26 -- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 87c71cc..fd5dcb8 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -124,8 +124,6 @@ static void oti6858_close(struct usb_serial_port *port); static void oti6858_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static void oti6858_init_termios(struct tty_struct *tty); -static int oti6858_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); static void oti6858_read_int_callback(struct urb *urb); static void oti6858_read_bulk_callback(struct urb *urb); static void oti6858_write_bulk_callback(struct urb *urb); @@ -136,6 +134,7 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty); static int oti6858_tiocmget(struct tty_struct *tty); static int oti6858_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); +static int oti6858_tiocmiwait(struct tty_struct *tty, unsigned long arg); static int oti6858_port_probe(struct usb_serial_port *port); static int oti6858_port_remove(struct usb_serial_port *port); @@ -150,11 +149,11 @@ static struct usb_serial_driver oti6858_device = { .open = oti6858_open, .close =oti6858_close, .write =oti6858_write, - .ioctl =oti6858_ioctl, .set_termios = oti6858_set_termios, .init_termios = oti6858_init_termios, .tiocmget = oti6858_tiocmget, .tiocmset = oti6858_tiocmset, + .tiocmiwait = oti6858_tiocmiwait, .read_bulk_callback = oti6858_read_bulk_callback, .read_int_callback =oti6858_read_int_callback, .write_bulk_callback = oti6858_write_bulk_callback, @@ -650,8 +649,9 @@ static int oti6858_tiocmget(struct tty_struct *tty) return result; } -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) +static int oti6858_tiocmiwait(struct tty_struct *tty, unsigned long arg) { + struct usb_serial_port *port = tty-driver_data; struct oti6858_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int prev, status; @@ -689,24 +689,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return 0; } -static int oti6858_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty-driver_data; - - dev_dbg(port-dev, %s(cmd = 0x%04x, arg = 0x%08lx)\n, __func__, cmd, arg); - - switch (cmd) { - case TIOCMIWAIT: - dev_dbg(port-dev, %s(): TIOCMIWAIT\n, __func__); - return wait_modem_info(port, arg); - default: - dev_dbg(port-dev, %s(): 0x%04x not supported\n, __func__, cmd); - break; - } - return -ENOIOCTLCMD; -} - static void oti6858_read_int_callback(struct urb *urb) { struct usb_serial_port *port = urb-context; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 17/94] USB: keyspan_pda: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/keyspan_pda.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 0d992ba..da3b29e 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -649,13 +649,8 @@ error: } static void keyspan_pda_close(struct usb_serial_port *port) { - struct usb_serial *serial = port-serial; - - if (serial-dev) { - /* shutdown our bulk reads and writes */ - usb_kill_urb(port-write_urb); - usb_kill_urb(port-interrupt_in_urb); - } + usb_kill_urb(port-write_urb); + usb_kill_urb(port-interrupt_in_urb); } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 56/94] USB: mct_u232: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mct_u232.c | 58 ++- 1 file changed, 2 insertions(+), 56 deletions(-) diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 6f4303c..3353c9e 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -35,7 +35,6 @@ #include linux/usb.h #include linux/usb/serial.h #include linux/serial.h -#include linux/ioctl.h #include mct_u232.h #define DRIVER_AUTHOR Wolfgang Grandegger wolfg...@ces.ch @@ -57,8 +56,6 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); static int mct_u232_tiocmget(struct tty_struct *tty); static int mct_u232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int mct_u232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); static void mct_u232_throttle(struct tty_struct *tty); static void mct_u232_unthrottle(struct tty_struct *tty); @@ -93,10 +90,10 @@ static struct usb_serial_driver mct_u232_device = { .break_ctl = mct_u232_break_ctl, .tiocmget = mct_u232_tiocmget, .tiocmset = mct_u232_tiocmset, + .tiocmiwait =usb_serial_generic_tiocmiwait, .attach =mct_u232_startup, .port_probe =mct_u232_port_probe, .port_remove = mct_u232_port_remove, - .ioctl = mct_u232_ioctl, .get_icount =usb_serial_generic_get_icount, }; @@ -595,7 +592,7 @@ static void mct_u232_read_int_callback(struct urb *urb) tty_kref_put(tty); } #endif - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); spin_unlock_irqrestore(priv-lock, flags); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -783,57 +780,6 @@ static void mct_u232_unthrottle(struct tty_struct *tty) } } -static int mct_u232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - DEFINE_WAIT(wait); - struct usb_serial_port *port = tty-driver_data; - struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); - struct async_icount cnow, cprev; - unsigned long flags; - - dev_dbg(port-dev, %s - cmd = 0x%x\n, __func__, cmd); - - switch (cmd) { - - case TIOCMIWAIT: - - dev_dbg(port-dev, %s TIOCMIWAIT, __func__); - - spin_lock_irqsave(mct_u232_port-lock, flags); - cprev = port-icount; - spin_unlock_irqrestore(mct_u232_port-lock, flags); - for ( ; ; ) { - prepare_to_wait(port-delta_msr_wait, - wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(port-delta_msr_wait, wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - spin_lock_irqsave(mct_u232_port-lock, flags); - cnow = port-icount; - spin_unlock_irqrestore(mct_u232_port-lock, flags); - if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr - cnow.dcd == cprev.dcd cnow.cts == cprev.cts) - return -EIO; /* no change = error */ - if (((arg TIOCM_RNG) (cnow.rng != cprev.rng)) || - ((arg TIOCM_DSR) (cnow.dsr != cprev.dsr)) || - ((arg TIOCM_CD) (cnow.dcd != cprev.dcd)) || - ((arg TIOCM_CTS) (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - - } - return -ENOIOCTLCMD; -} - module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 74/94] USB: ssu100: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ssu100.c | 55 + 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 45b8c29..8d94a5a 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -61,7 +61,6 @@ struct ssu100_port_private { spinlock_t status_lock; u8 shadowLSR; u8 shadowMSR; - struct async_icount icount; }; static inline int ssu100_control_msg(struct usb_device *dev, @@ -345,16 +344,16 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) unsigned long flags; spin_lock_irqsave(priv-status_lock, flags); - prev = priv-icount; + prev = port-icount; spin_unlock_irqrestore(priv-status_lock, flags); while (1) { wait_event_interruptible(port-delta_msr_wait, (port-serial-disconnected || - (priv-icount.rng != prev.rng) || - (priv-icount.dsr != prev.dsr) || - (priv-icount.dcd != prev.dcd) || - (priv-icount.cts != prev.cts))); + (port-icount.rng != prev.rng) || + (port-icount.dsr != prev.dsr) || + (port-icount.dcd != prev.dcd) || + (port-icount.cts != prev.cts))); if (signal_pending(current)) return -ERESTARTSYS; @@ -363,7 +362,7 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return -EIO; spin_lock_irqsave(priv-status_lock, flags); - cur = priv-icount; + cur = port-icount; spin_unlock_irqrestore(priv-status_lock, flags); if ((prev.rng == cur.rng) @@ -381,30 +380,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return 0; } -static int ssu100_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct ssu100_port_private *priv = usb_get_serial_port_data(port); - struct async_icount cnow = priv-icount; - - icount-cts = cnow.cts; - icount-dsr = cnow.dsr; - icount-rng = cnow.rng; - icount-dcd = cnow.dcd; - icount-rx = cnow.rx; - icount-tx = cnow.tx; - icount-frame = cnow.frame; - icount-overrun = cnow.overrun; - icount-parity = cnow.parity; - icount-brk = cnow.brk; - icount-buf_overrun = cnow.buf_overrun; - - return 0; -} - - - static int ssu100_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -527,13 +502,13 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) if (msr UART_MSR_ANY_DELTA) { /* update input line counters */ if (msr UART_MSR_DCTS) - priv-icount.cts++; + port-icount.cts++; if (msr UART_MSR_DDSR) - priv-icount.dsr++; + port-icount.dsr++; if (msr UART_MSR_DDCD) - priv-icount.dcd++; + port-icount.dcd++; if (msr UART_MSR_TERI) - priv-icount.rng++; + port-icount.rng++; wake_up_interruptible(port-delta_msr_wait); } } @@ -553,22 +528,22 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, /* we always want to update icount, but we only want to * update tty_flag for one case */ if (lsr UART_LSR_BI) { - priv-icount.brk++; + port-icount.brk++; *tty_flag = TTY_BREAK; usb_serial_handle_break(port); } if (lsr UART_LSR_PE) { - priv-icount.parity++; + port-icount.parity++; if (*tty_flag == TTY_NORMAL) *tty_flag = TTY_PARITY; } if (lsr UART_LSR_FE) { - priv-icount.frame++; + port-icount.frame++; if (*tty_flag == TTY_NORMAL) *tty_flag = TTY_FRAME; } if (lsr UART_LSR_OE){ - priv-icount.overrun++; + port-icount.overrun++; if (*tty_flag == TTY_NORMAL)
[PATCH v3 13/94] USB: digi_acceleport: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/digi_acceleport.c | 92 ++-- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index ebe45fa..76a8c20 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1149,53 +1149,51 @@ static void digi_close(struct usb_serial_port *port) if (port-serial-disconnected) goto exit; - if (port-serial-dev) { - /* FIXME: Transmit idle belongs in the wait_unti_sent path */ - digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); - - /* disable input flow control */ - buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; - buf[1] = priv-dp_port_num; - buf[2] = DIGI_DISABLE; - buf[3] = 0; - - /* disable output flow control */ - buf[4] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; - buf[5] = priv-dp_port_num; - buf[6] = DIGI_DISABLE; - buf[7] = 0; - - /* disable reading modem signals automatically */ - buf[8] = DIGI_CMD_READ_INPUT_SIGNALS; - buf[9] = priv-dp_port_num; - buf[10] = DIGI_DISABLE; - buf[11] = 0; - - /* disable receive */ - buf[12] = DIGI_CMD_RECEIVE_ENABLE; - buf[13] = priv-dp_port_num; - buf[14] = DIGI_DISABLE; - buf[15] = 0; - - /* flush fifos */ - buf[16] = DIGI_CMD_IFLUSH_FIFO; - buf[17] = priv-dp_port_num; - buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; - buf[19] = 0; - - ret = digi_write_oob_command(port, buf, 20, 0); - if (ret != 0) - dev_dbg(port-dev, digi_close: write oob failed, ret=%d\n, ret); - - /* wait for final commands on oob port to complete */ - prepare_to_wait(priv-dp_flush_wait, wait, - TASK_INTERRUPTIBLE); - schedule_timeout(DIGI_CLOSE_TIMEOUT); - finish_wait(priv-dp_flush_wait, wait); - - /* shutdown any outstanding bulk writes */ - usb_kill_urb(port-write_urb); - } + /* FIXME: Transmit idle belongs in the wait_unti_sent path */ + digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); + + /* disable input flow control */ + buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; + buf[1] = priv-dp_port_num; + buf[2] = DIGI_DISABLE; + buf[3] = 0; + + /* disable output flow control */ + buf[4] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; + buf[5] = priv-dp_port_num; + buf[6] = DIGI_DISABLE; + buf[7] = 0; + + /* disable reading modem signals automatically */ + buf[8] = DIGI_CMD_READ_INPUT_SIGNALS; + buf[9] = priv-dp_port_num; + buf[10] = DIGI_DISABLE; + buf[11] = 0; + + /* disable receive */ + buf[12] = DIGI_CMD_RECEIVE_ENABLE; + buf[13] = priv-dp_port_num; + buf[14] = DIGI_DISABLE; + buf[15] = 0; + + /* flush fifos */ + buf[16] = DIGI_CMD_IFLUSH_FIFO; + buf[17] = priv-dp_port_num; + buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; + buf[19] = 0; + + ret = digi_write_oob_command(port, buf, 20, 0); + if (ret != 0) + dev_dbg(port-dev, digi_close: write oob failed, ret=%d\n, + ret); + /* wait for final commands on oob port to complete */ + prepare_to_wait(priv-dp_flush_wait, wait, + TASK_INTERRUPTIBLE); + schedule_timeout(DIGI_CLOSE_TIMEOUT); + finish_wait(priv-dp_flush_wait, wait); + + /* shutdown any outstanding bulk writes */ + usb_kill_urb(port-write_urb); exit: spin_lock_irq(priv-dp_port_lock); priv-dp_write_urb_in_use = 0; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 16/94] USB: keyspan_pda: remove bogus disconnect test from dtr_rts
Remove bogus (and unnecessary) test for serial-dev being NULL in dtr_rts. The device is never cleared, and disconnect is handled for dtr_rts in usb-serial core anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/keyspan_pda.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 3b17d5d..0d992ba 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -595,12 +595,10 @@ static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on) { struct usb_serial *serial = port-serial; - if (serial-dev) { - if (on) - keyspan_pda_set_modem_info(serial, (17) | (1 2)); - else - keyspan_pda_set_modem_info(serial, 0); - } + if (on) + keyspan_pda_set_modem_info(serial, (1 7) | (1 2)); + else + keyspan_pda_set_modem_info(serial, 0); } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 49/94] USB: f81232: fix TIOCMIWAIT and disconnect
Use tty-port modem-status-change wait queue on which processes are woken up at hangup and disconnect. Currently a process waiting on modem-status changes will not be woken on device disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/f81232.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index d1fdd8d..090b411 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -110,7 +110,7 @@ static void f81232_process_read_urb(struct urb *urb) line_status = priv-line_status; priv-line_status = ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(priv-lock, flags); - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); if (!urb-actual_length) return; @@ -256,7 +256,7 @@ static int f81232_tiocmiwait(struct tty_struct *tty, unsigned long arg) spin_unlock_irqrestore(priv-lock, flags); while (1) { - interruptible_sleep_on(port-delta_msr_wait); + interruptible_sleep_on(port-port.delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 64/94] USB: pl2303: fix TIOCMIWAIT and disconnect
Use tty-port modem-status-change wait queue on which processes are woken up at hangup and disconnect. Currently a process waiting on modem-status changes will not be woken on device disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/pl2303.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 1f7fd1a..997eba4 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -607,7 +607,7 @@ static int pl2303_tiocmiwait(struct tty_struct *tty, unsigned long arg) spin_unlock_irqrestore(priv-lock, flags); while (1) { - interruptible_sleep_on(port-delta_msr_wait); + interruptible_sleep_on(port-port.delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; @@ -718,7 +718,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, spin_unlock_irqrestore(priv-lock, flags); if (priv-line_status UART_BREAK_ERROR) usb_serial_handle_break(port); - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); tty = tty_port_tty_get(port-port); if (!tty) @@ -782,7 +782,7 @@ static void pl2303_process_read_urb(struct urb *urb) line_status = priv-line_status; priv-line_status = ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(priv-lock, flags); - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); if (!urb-actual_length) return; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 67/94] USB: spcp8x5: remove broken TIOCMIWAIT support
Remove broken TIOCMIWAIT support. This drivers appears to implement TIOCMIWAIT but has no means of receiving modem-status interrupts. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/spcp8x5.c | 68 1 file changed, 68 deletions(-) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 549ef68..e24d23b 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -472,8 +472,6 @@ static void spcp8x5_process_read_urb(struct urb *urb) status = priv-line_status; priv-line_status = ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(priv-lock, flags); - /* wake up the wait for termios */ - wake_up_interruptible(port-delta_msr_wait); if (!urb-actual_length) return; @@ -509,71 +507,6 @@ static void spcp8x5_process_read_urb(struct urb *urb) tty_flip_buffer_push(port-port); } -static int spcp8x5_wait_modem_info(struct usb_serial_port *port, - unsigned int arg) -{ - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int prevstatus; - unsigned int status; - unsigned int changed; - - spin_lock_irqsave(priv-lock, flags); - prevstatus = priv-line_status; - spin_unlock_irqrestore(priv-lock, flags); - - while (1) { - /* wake up in bulk read */ - interruptible_sleep_on(port-delta_msr_wait); - - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - spin_lock_irqsave(priv-lock, flags); - status = priv-line_status; - spin_unlock_irqrestore(priv-lock, flags); - - changed = prevstatus^status; - - if (((arg TIOCM_RNG) (changed MSR_STATUS_LINE_RI)) || - ((arg TIOCM_DSR) (changed MSR_STATUS_LINE_DSR)) || - ((arg TIOCM_CD) (changed MSR_STATUS_LINE_DCD)) || - ((arg TIOCM_CTS) (changed MSR_STATUS_LINE_CTS))) - return 0; - - prevstatus = status; - } - /* NOTREACHED */ - return 0; -} - -static int spcp8x5_ioctl(struct tty_struct *tty, -unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty-driver_data; - - dev_dbg(port-dev, %s (%d) cmd = 0x%04x\n, __func__, - port-number, cmd); - - switch (cmd) { - case TIOCMIWAIT: - dev_dbg(port-dev, %s (%d) TIOCMIWAIT\n, __func__, - port-number); - return spcp8x5_wait_modem_info(port, arg); - - default: - dev_dbg(port-dev, %s not supported = 0x%04x, __func__, - cmd); - break; - } - - return -ENOIOCTLCMD; -} - static int spcp8x5_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { @@ -634,7 +567,6 @@ static struct usb_serial_driver spcp8x5_device = { .carrier_raised = spcp8x5_carrier_raised, .set_termios= spcp8x5_set_termios, .init_termios = spcp8x5_init_termios, - .ioctl = spcp8x5_ioctl, .tiocmget = spcp8x5_tiocmget, .tiocmset = spcp8x5_tiocmset, .port_probe = spcp8x5_port_probe, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 80/94] USB: cypress_m8: remove bogus disconnect test from close
Remove disconnected test from close which did not protect any device IO at all. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/cypress_m8.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index e4a62cf..d341555 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -632,12 +632,6 @@ static void cypress_close(struct usb_serial_port *port) struct cypress_private *priv = usb_get_serial_port_data(port); unsigned long flags; - /* writing is potentially harmful, lock must be taken */ - mutex_lock(port-serial-disc_mutex); - if (port-serial-disconnected) { - mutex_unlock(port-serial-disc_mutex); - return; - } spin_lock_irqsave(priv-lock, flags); kfifo_reset_out(priv-write_fifo); spin_unlock_irqrestore(priv-lock, flags); @@ -649,7 +643,6 @@ static void cypress_close(struct usb_serial_port *port) if (stats) dev_info(port-dev, Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n, priv-bytes_in, priv-bytes_out, priv-cmd_count); - mutex_unlock(port-serial-disc_mutex); } /* cypress_close */ -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 62/94] USB: oti6858: fix TIOCMIWAIT and disconnect
Use tty-port modem-status-change wait queue on which processes are woken up at hangup and disconnect. Currently a process waiting on modem-status changes will not be woken on device disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/oti6858.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index fd5dcb8..7e3e078 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -662,7 +662,7 @@ static int oti6858_tiocmiwait(struct tty_struct *tty, unsigned long arg) spin_unlock_irqrestore(priv-lock, flags); while (1) { - wait_event_interruptible(port-delta_msr_wait, + wait_event_interruptible(port-port.delta_msr_wait, port-serial-disconnected || priv-status.pin_state != prev); if (signal_pending(current)) @@ -747,7 +747,7 @@ static void oti6858_read_int_callback(struct urb *urb) if (!priv-transient) { if (xs-pin_state != priv-status.pin_state) - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); memcpy(priv-status, xs, OTI6858_CTRL_PKT_SIZE); } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 66/94] USB: quatech2: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/quatech2.c | 50 ++- 1 file changed, 2 insertions(+), 48 deletions(-) diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 6d1faab..71fdc09 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -492,49 +492,6 @@ static int get_serial_info(struct usb_serial_port *port, return 0; } -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) -{ - struct qt2_port_private *priv = usb_get_serial_port_data(port); - struct async_icount prev, cur; - unsigned long flags; - - spin_lock_irqsave(priv-lock, flags); - prev = port-icount; - spin_unlock_irqrestore(priv-lock, flags); - - while (1) { - wait_event_interruptible(port-delta_msr_wait, -(port-serial-disconnected || - (port-icount.rng != prev.rng) || - (port-icount.dsr != prev.dsr) || - (port-icount.dcd != prev.dcd) || - (port-icount.cts != prev.cts))); - - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - spin_lock_irqsave(priv-lock, flags); - cur = port-icount; - spin_unlock_irqrestore(priv-lock, flags); - - if ((prev.rng == cur.rng) - (prev.dsr == cur.dsr) - (prev.dcd == cur.dcd) - (prev.cts == cur.cts)) - return -EIO; - - if ((arg TIOCM_RNG (prev.rng != cur.rng)) || - (arg TIOCM_DSR (prev.dsr != cur.dsr)) || - (arg TIOCM_CD (prev.dcd != cur.dcd)) || - (arg TIOCM_CTS (prev.cts != cur.cts))) - return 0; - } - return 0; -} - static int qt2_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -544,10 +501,6 @@ static int qt2_ioctl(struct tty_struct *tty, case TIOCGSERIAL: return get_serial_info(port, (struct serial_struct __user *)arg); - - case TIOCMIWAIT: - return wait_modem_info(port, arg); - default: break; } @@ -945,7 +898,7 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) if (newMSR UART_MSR_TERI) port-icount.rng++; - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); } } @@ -1075,6 +1028,7 @@ static struct usb_serial_driver qt2_device = { .break_ctl = qt2_break_ctl, .tiocmget= qt2_tiocmget, .tiocmset= qt2_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .ioctl = qt2_ioctl, .set_termios = qt2_set_termios, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 59/94] USB: mos7840: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Note that the interrupt counters will no longer be reset at open which is in accordance with which how the other drivers work. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mos7840.c | 56 +++- 1 file changed, 9 insertions(+), 47 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 794e972..5c2c79b 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -220,7 +220,6 @@ struct moschip_port { char open_ports; wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ int delta_msr_cond; - struct async_icount icount; struct usb_serial_port *port; /* loop back to the owner of this object */ /* Offsets */ @@ -399,11 +398,10 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) struct moschip_port *mos7840_port; struct async_icount *icount; mos7840_port = port; - icount = mos7840_port-icount; if (new_msr (MOS_MSR_DELTA_CTS | MOS_MSR_DELTA_DSR | MOS_MSR_DELTA_RI | MOS_MSR_DELTA_CD)) { - icount = mos7840_port-icount; + icount = mos7840_port-port-icount; /* update input line counters */ if (new_msr MOS_MSR_DELTA_CTS) @@ -434,7 +432,7 @@ static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) } /* update input line counters */ - icount = port-icount; + icount = port-port-icount; if (new_lsr SERIAL_LSR_BI) icount-brk++; if (new_lsr SERIAL_LSR_OE) @@ -761,8 +759,8 @@ static void mos7840_bulk_in_callback(struct urb *urb) struct tty_port *tport = mos7840_port-port-port; tty_insert_flip_string(tport, data, urb-actual_length); tty_flip_buffer_push(tport); - mos7840_port-icount.rx += urb-actual_length; - dev_dbg(port-dev, mos7840_port-icount.rx is %d:\n, mos7840_port-icount.rx); + port-icount.rx += urb-actual_length; + dev_dbg(port-dev, icount.rx is %d:\n, port-icount.rx); } if (!mos7840_port-read_urb) { @@ -1113,17 +,12 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) /* initialize our wait queues */ init_waitqueue_head(mos7840_port-wait_chase); - /* initialize our icount structure */ - memset((mos7840_port-icount), 0x00, sizeof(mos7840_port-icount)); - /* initialize our port settings */ /* Must set to enable ints! */ mos7840_port-shadowMCR = MCR_MASTER_IE; /* send a open port command */ mos7840_port-open = 1; /* mos7840_change_port_settings(mos7840_port,old_termios); */ - mos7840_port-icount.tx = 0; - mos7840_port-icount.rx = 0; return 0; } @@ -1490,8 +1483,8 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, goto exit; } bytes_sent = transfer_size; - mos7840_port-icount.tx += transfer_size; - dev_dbg(port-dev, mos7840_port-icount.tx is %d:\n, mos7840_port-icount.tx); + port-icount.tx += transfer_size; + dev_dbg(port-dev, icount.tx is %d:\n, port-icount.tx); exit: return bytes_sent; @@ -2110,37 +2103,6 @@ static int mos7840_get_serial_info(struct moschip_port *mos7840_port, return 0; } -static int mos7840_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct moschip_port *mos7840_port; - struct async_icount cnow; - unsigned long flags; - - mos7840_port = mos7840_get_port_private(port); - - spin_lock_irqsave(port-lock, flags); - cnow = mos7840_port-icount; - spin_unlock_irqrestore(port-lock, flags); - - icount-cts = cnow.cts; - icount-dsr = cnow.dsr; - icount-rng = cnow.rng; - icount-dcd = cnow.dcd; - icount-rx = cnow.rx; - icount-tx = cnow.tx; - icount-frame = cnow.frame; - icount-overrun = cnow.overrun; - icount-parity = cnow.parity; - icount-brk = cnow.brk; - icount-buf_overrun = cnow.buf_overrun; - - dev_dbg(port-dev, %s TIOCGICOUNT RX=%d, TX=%d\n, __func__, - icount-rx, icount-tx); - return 0; -} - /* * SerialIoctl * this function handles any ioctl calls to the driver @@ -2184,7 +2146,7 @@ static int mos7840_ioctl(struct tty_struct *tty, case TIOCMIWAIT: dev_dbg(port-dev, %s TIOCMIWAIT\n, __func__); spin_lock_irqsave(port-lock, flags); - cprev = mos7840_port-icount; +
[PATCH v3 24/94] USB: serial: fix generic disconnect implementation
There is no need for the generic disconnect callback to stop the read and write urbs a second time as this has already been taken care of by close (which is called from hangup as part of disconnect). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/generic.c | 12 +--- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 131d6cb..a6d0ac6 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -102,7 +102,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port } EXPORT_SYMBOL_GPL(usb_serial_generic_open); -static void generic_cleanup(struct usb_serial_port *port) +void usb_serial_generic_close(struct usb_serial_port *port) { unsigned long flags; int i; @@ -120,11 +120,6 @@ static void generic_cleanup(struct usb_serial_port *port) usb_kill_urb(port-read_urbs[i]); } } - -void usb_serial_generic_close(struct usb_serial_port *port) -{ - generic_cleanup(port); -} EXPORT_SYMBOL_GPL(usb_serial_generic_close); int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, @@ -507,11 +502,6 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_resume); void usb_serial_generic_disconnect(struct usb_serial *serial) { - int i; - - /* stop reads and writes on all ports */ - for (i = 0; i serial-num_ports; ++i) - generic_cleanup(serial-port[i]); } EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 79/94] USB: cp210x: always disable uart on close
Always try to disable the uart on close. Since the switch to tty ports, close will be called as part of shutdown before disconnect returns. Hence there is no need to check the disconnected flag, and we can put devices in disabled states also on driver unbind. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/cp210x.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 4747d1c..2c65955 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -462,11 +462,7 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) static void cp210x_close(struct usb_serial_port *port) { usb_serial_generic_close(port); - - mutex_lock(port-serial-disc_mutex); - if (!port-serial-disconnected) - cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE); - mutex_unlock(port-serial-disc_mutex); + cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE); } /* -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 50/94] USB: io_edgeport: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Note that the interrupt counters will no longer be reset at open which is in accordance with which how the other drivers work. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/io_edgeport.c | 45 +++- drivers/usb/serial/io_tables.h | 8 +++ 2 files changed, 11 insertions(+), 42 deletions(-) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index efd8b97..16ef8f3 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -111,7 +111,6 @@ struct edgeport_port { wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */ wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */ - struct async_icount icount; struct usb_serial_port *port; /* loop back to the owner of this object */ }; @@ -215,8 +214,6 @@ static void edge_break(struct tty_struct *tty, int break_state); static int edge_tiocmget(struct tty_struct *tty); static int edge_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int edge_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); static int edge_startup(struct usb_serial *serial); static void edge_disconnect(struct usb_serial *serial); static void edge_release(struct usb_serial *serial); @@ -885,9 +882,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) init_waitqueue_head(edge_port-wait_chase); init_waitqueue_head(edge_port-wait_command); - /* initialize our icount structure */ - memset((edge_port-icount), 0x00, sizeof(edge_port-icount)); - /* initialize our port settings */ edge_port-txCredits = 0; /* Can't send any data yet */ /* Must always set this bit to enable ints! */ @@ -1314,7 +1308,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, /* decrement the number of credits we have by the number we just sent */ edge_port-txCredits -= count; - edge_port-icount.tx += count; + edge_port-port-icount.tx += count; status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { @@ -1326,7 +1320,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, /* revert the credits as something bad happened. */ edge_port-txCredits += count; - edge_port-icount.tx -= count; + edge_port-port-icount.tx -= count; } dev_dbg(dev, %s wrote %d byte(s) TxCredit %d, Fifo %d\n, __func__, count, edge_port-txCredits, fifo-count); @@ -1588,31 +1582,6 @@ static int edge_tiocmget(struct tty_struct *tty) return result; } -static int edge_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount cnow; - cnow = edge_port-icount; - - icount-cts = cnow.cts; - icount-dsr = cnow.dsr; - icount-rng = cnow.rng; - icount-dcd = cnow.dcd; - icount-rx = cnow.rx; - icount-tx = cnow.tx; - icount-frame = cnow.frame; - icount-overrun = cnow.overrun; - icount-parity = cnow.parity; - icount-brk = cnow.brk; - icount-buf_overrun = cnow.buf_overrun; - - dev_dbg(port-dev, %s (%d) TIOCGICOUNT RX=%d, TX=%d\n, __func__, - port-number, icount-rx, icount-tx); - return 0; -} - static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct __user *retinfo) { @@ -1665,7 +1634,7 @@ static int edge_ioctl(struct tty_struct *tty, case TIOCMIWAIT: dev_dbg(port-dev, %s (%d) TIOCMIWAIT\n, __func__, port-number); - cprev = edge_port-icount; + cprev = port-icount; while (1) { prepare_to_wait(port-delta_msr_wait, wait, TASK_INTERRUPTIBLE); @@ -1678,7 +1647,7 @@ static int edge_ioctl(struct tty_struct *tty, if (port-serial-disconnected) return -EIO; - cnow = edge_port-icount; + cnow = port-icount; if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr cnow.dcd == cprev.dcd cnow.cts == cprev.cts) return -EIO; /* no change = error */ @@ -1866,7 +1835,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
[PATCH v3 57/94] USB: mos7720: remove broken get_icount and TIOCMIWAIT
Remove broken get_icount and TIOCMIWAIT support. The driver has an icount structure but it is never been updated which makes get_icount rather pointless and causes TIOCMIWAIT to always return -EIO. Note that the TIOCMIWAIT implementation has always been broken and would not work even if icount support was added as it does not wait for the modem status to change (does not use a work queue at all). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mos7720.c | 55 1 file changed, 55 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e0ebec3..d1e2bf3 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -62,7 +62,6 @@ struct moschip_port { __u8shadowMCR; /* last MCR value received */ __u8shadowMSR; /* last MSR value received */ charopen; - struct async_icount icount; struct usb_serial_port *port; /* loop back to the owner */ struct urb *write_urb_pool[NUM_URBS]; }; @@ -1075,9 +1074,6 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) dev_err(port-dev, %s - Error %d submitting read urb\n, __func__, response); - /* initialize our icount structure */ - memset((mos7720_port-icount), 0x00, sizeof(mos7720_port-icount)); - /* initialize our port settings */ mos7720_port-shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */ @@ -1803,33 +1799,6 @@ static int mos7720_tiocmset(struct tty_struct *tty, return 0; } -static int mos7720_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct moschip_port *mos7720_port; - struct async_icount cnow; - - mos7720_port = usb_get_serial_port_data(port); - cnow = mos7720_port-icount; - - icount-cts = cnow.cts; - icount-dsr = cnow.dsr; - icount-rng = cnow.rng; - icount-dcd = cnow.dcd; - icount-rx = cnow.rx; - icount-tx = cnow.tx; - icount-frame = cnow.frame; - icount-overrun = cnow.overrun; - icount-parity = cnow.parity; - icount-brk = cnow.brk; - icount-buf_overrun = cnow.buf_overrun; - - dev_dbg(port-dev, %s TIOCGICOUNT RX=%d, TX=%d\n, __func__, - icount-rx, icount-tx); - return 0; -} - static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, unsigned int __user *value) { @@ -1905,8 +1874,6 @@ static int mos7720_ioctl(struct tty_struct *tty, { struct usb_serial_port *port = tty-driver_data; struct moschip_port *mos7720_port; - struct async_icount cnow; - struct async_icount cprev; mos7720_port = usb_get_serial_port_data(port); if (mos7720_port == NULL) @@ -1931,27 +1898,6 @@ static int mos7720_ioctl(struct tty_struct *tty, dev_dbg(port-dev, %s TIOCGSERIAL\n, __func__); return get_serial_info(mos7720_port, (struct serial_struct __user *)arg); - - case TIOCMIWAIT: - dev_dbg(port-dev, %s TIOCMIWAIT\n, __func__); - cprev = mos7720_port-icount; - while (1) { - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = mos7720_port-icount; - if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr - cnow.dcd == cprev.dcd cnow.cts == cprev.cts) - return -EIO; /* no change = error */ - if (((arg TIOCM_RNG) (cnow.rng != cprev.rng)) || - ((arg TIOCM_DSR) (cnow.dsr != cprev.dsr)) || - ((arg TIOCM_CD) (cnow.dcd != cprev.dcd)) || - ((arg TIOCM_CTS) (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - break; } return -ENOIOCTLCMD; @@ -2107,7 +2053,6 @@ static struct usb_serial_driver moschip7720_2port_driver = { .ioctl = mos7720_ioctl, .tiocmget = mos7720_tiocmget, .tiocmset = mos7720_tiocmset, - .get_icount = mos7720_get_icount, .set_termios= mos7720_set_termios, .write = mos7720_write, .write_room = mos7720_write_room, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at
[PATCH v3 71/94] USB: spcp8x5: clean up modem status retrieval
Clean up modem status retrieval. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/spcp8x5.c | 18 +++--- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 5779dd8..e0093dd 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -226,31 +226,27 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) { struct spcp8x5_private *priv = usb_get_serial_port_data(port); struct usb_device *dev = port-serial-dev; - u8 *status_buffer; + u8 *buf; int ret; /* I return Permited not support here but seem inval device * is more fix */ if (priv-type == SPCP825_007_TYPE) return -EPERM; - if (status == NULL) - return -EINVAL; - status_buffer = kmalloc(1, GFP_KERNEL); - if (!status_buffer) + buf = kzalloc(1, GFP_KERNEL); + if (!buf) return -ENOMEM; - status_buffer[0] = status[0]; ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_UART_STATUS, GET_UART_STATUS_TYPE, - 0, GET_UART_STATUS_MSR, status_buffer, 1, 100); + 0, GET_UART_STATUS_MSR, buf, 1, 100); if (ret 0) dev_err(port-dev, failed to get modem status: %d, ret); - dev_dbg(port-dev, 0xc0:0x22:0:6 %d - 0x02%x, ret, *status_buffer); - - status[0] = status_buffer[0]; - kfree(status_buffer); + dev_dbg(port-dev, 0xc0:0x22:0:6 %d - 0x02%x, ret, *buf); + *status = *buf; + kfree(buf); return ret; } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 89/94] USB: quatech2: always disable uart on close
Always try to disable the uart on close. Since the switch to tty ports, close will be called as part of shutdown before disconnect returns. Hence there is no need to check the disconnected flag, and we can put devices in disabled states also on driver unbind. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/quatech2.c | 8 1 file changed, 8 deletions(-) diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 71fdc09..264dd72 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -422,12 +422,6 @@ static void qt2_close(struct usb_serial_port *port) port_priv-urb_in_use = false; spin_unlock_irqrestore(port_priv-urb_lock, flags); - mutex_lock(port-serial-disc_mutex); - if (port-serial-disconnected) { - mutex_unlock(port-serial-disc_mutex); - return; - } - /* flush the port transmit buffer */ i = usb_control_msg(serial-dev, usb_rcvctrlpipe(serial-dev, 0), @@ -458,8 +452,6 @@ static void qt2_close(struct usb_serial_port *port) if (i 0) dev_err(port-dev, %s - close port failed %i\n, __func__, i); - - mutex_unlock(port-serial-disc_mutex); } static void qt2_disconnect(struct usb_serial *serial) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 94/94] USB: serial: update copyright information
Update copyright information. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ftdi_sio.c | 2 +- drivers/usb/serial/generic.c| 2 +- drivers/usb/serial/usb-serial.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1199dc5..9a5295e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1,7 +1,7 @@ /* * USB FTDI SIO driver * - * Copyright (C) 2009 - 2010 + * Copyright (C) 2009 - 2013 * Johan Hovold (jhov...@gmail.com) * Copyright (C) 1999 - 2001 * Greg Kroah-Hartman (g...@kroah.com) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 5e55761..297665f 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -1,7 +1,7 @@ /* * USB Serial Converter Generic functions * - * Copyright (C) 2010 - 2011 Johan Hovold (jhov...@gmail.com) + * Copyright (C) 2010 - 2013 Johan Hovold (jhov...@gmail.com) * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (g...@kroah.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 96cfe43..40e9a4f 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1,6 +1,7 @@ /* * USB Serial Converter driver * + * Copyright (C) 2009 - 2013 Johan Hovold (jhov...@gmail.com) * Copyright (C) 1999 - 2012 Greg Kroah-Hartman (g...@kroah.com) * Copyright (C) 2000 Peter Berger (pber...@brimson.com) * Copyright (C) 2000 Al Borchers (borch...@steinerpoint.com) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 43/94] USB: ch341: replace custom ioctl operation with tiocmiwait
Replace custom ioctl operation with tiocmiwait. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ch341.c | 25 +++-- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 07d4650..1a97985 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -500,8 +500,9 @@ exit: __func__, status); } -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) +static int ch341_tiocmiwait(struct tty_struct *tty, unsigned long arg) { + struct usb_serial_port *port = tty-driver_data; struct ch341_private *priv = usb_get_serial_port_data(port); unsigned long flags; u8 prevstatus; @@ -542,26 +543,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return 0; } -static int ch341_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty-driver_data; - - dev_dbg(port-dev, %s (%d) cmd = 0x%04x\n, __func__, port-number, cmd); - - switch (cmd) { - case TIOCMIWAIT: - dev_dbg(port-dev, %s (%d) TIOCMIWAIT\n, __func__, port-number); - return wait_modem_info(port, arg); - - default: - dev_dbg(port-dev, %s not supported = 0x%04x\n, __func__, cmd); - break; - } - - return -ENOIOCTLCMD; -} - static int ch341_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty-driver_data; @@ -611,11 +592,11 @@ static struct usb_serial_driver ch341_device = { .dtr_rts = ch341_dtr_rts, .carrier_raised= ch341_carrier_raised, .close = ch341_close, - .ioctl = ch341_ioctl, .set_termios = ch341_set_termios, .break_ctl = ch341_break_ctl, .tiocmget = ch341_tiocmget, .tiocmset = ch341_tiocmset, + .tiocmiwait= ch341_tiocmiwait, .read_int_callback = ch341_read_int_callback, .port_probe= ch341_port_probe, .port_remove = ch341_port_remove, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 93/94] USB: iuu_phoenix: remove bogus disconnect test in close
Remove bogus disconnect test for serial device being NULL in close. This can never happen as close is guaranteed to be called before the last tty reference is dropped (and port-serial is cleared). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/iuu_phoenix.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 1ccf9e4..9d74c27 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -942,11 +942,6 @@ static void iuu_set_termios(struct tty_struct *tty, static void iuu_close(struct usb_serial_port *port) { /* iuu_led (port,255,0,0,0); */ - struct usb_serial *serial; - - serial = port-serial; - if (!serial) - return; iuu_uart_off(port); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 39/94] USB: ftdi_sio: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation which does not suffer from the races involved when using the deprecated sleep_on functions. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ftdi_sio.c | 36 ++-- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ea7433e..fa3077f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -954,6 +954,7 @@ static struct usb_serial_driver ftdi_sio_device = { .prepare_write_buffer = ftdi_prepare_write_buffer, .tiocmget = ftdi_tiocmget, .tiocmset = ftdi_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = ftdi_get_icount, .ioctl =ftdi_ioctl, .set_termios = ftdi_set_termios, @@ -1824,8 +1825,6 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) { struct ftdi_private *priv = usb_get_serial_port_data(port); - wake_up_interruptible(port-delta_msr_wait); - remove_sysfs_attrs(port); kfree(priv); @@ -1953,7 +1952,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, if (diff_status FTDI_RS0_RLSD) port-icount.dcd++; - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); priv-prev_status = status; } @@ -2376,8 +2375,6 @@ static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty-driver_data; - struct async_icount cnow; - struct async_icount cprev; dev_dbg(port-dev, %s cmd 0x%04x\n, __func__, cmd); @@ -2391,35 +2388,6 @@ static int ftdi_ioctl(struct tty_struct *tty, case TIOCSSERIAL: /* sets serial port data */ return set_serial_info(tty, port, (struct serial_struct __user *) arg); - - /* -* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change -* - mask passed in arg for lines of interest -* (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) -* Caller should use TIOCGICOUNT to see which one it was. -* -* This code is borrowed from linux/drivers/char/serial.c -*/ - case TIOCMIWAIT: - cprev = port-icount; - for (;;) { - interruptible_sleep_on(port-delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - cnow = port-icount; - if (((arg TIOCM_RNG) (cnow.rng != cprev.rng)) || - ((arg TIOCM_DSR) (cnow.dsr != cprev.dsr)) || - ((arg TIOCM_CD) (cnow.dcd != cprev.dcd)) || - ((arg TIOCM_CTS) (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } case TIOCSERGETLSR: return get_lsr_info(port, (struct serial_struct __user *)arg); break; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 58/94] USB: mos7840: remove smp barriers from icount handling
Remove SMP memory barriers from icount handling and rely on the barriers implied by wait_event, sleep and locks, while using the port lock to guarantee atomicity. This is a step in moving over to the generic icount implementations. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mos7840.c | 48 ++-- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 8da1921..794e972 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -406,22 +406,14 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) icount = mos7840_port-icount; /* update input line counters */ - if (new_msr MOS_MSR_DELTA_CTS) { + if (new_msr MOS_MSR_DELTA_CTS) icount-cts++; - smp_wmb(); - } - if (new_msr MOS_MSR_DELTA_DSR) { + if (new_msr MOS_MSR_DELTA_DSR) icount-dsr++; - smp_wmb(); - } - if (new_msr MOS_MSR_DELTA_CD) { + if (new_msr MOS_MSR_DELTA_CD) icount-dcd++; - smp_wmb(); - } - if (new_msr MOS_MSR_DELTA_RI) { + if (new_msr MOS_MSR_DELTA_RI) icount-rng++; - smp_wmb(); - } mos7840_port-delta_msr_cond = 1; wake_up_interruptible(port-port-delta_msr_wait); @@ -443,22 +435,14 @@ static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) /* update input line counters */ icount = port-icount; - if (new_lsr SERIAL_LSR_BI) { + if (new_lsr SERIAL_LSR_BI) icount-brk++; - smp_wmb(); - } - if (new_lsr SERIAL_LSR_OE) { + if (new_lsr SERIAL_LSR_OE) icount-overrun++; - smp_wmb(); - } - if (new_lsr SERIAL_LSR_PE) { + if (new_lsr SERIAL_LSR_PE) icount-parity++; - smp_wmb(); - } - if (new_lsr SERIAL_LSR_FE) { + if (new_lsr SERIAL_LSR_FE) icount-frame++; - smp_wmb(); - } } // @@ -778,7 +762,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) tty_insert_flip_string(tport, data, urb-actual_length); tty_flip_buffer_push(tport); mos7840_port-icount.rx += urb-actual_length; - smp_wmb(); dev_dbg(port-dev, mos7840_port-icount.rx is %d:\n, mos7840_port-icount.rx); } @@ -1508,7 +1491,6 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, } bytes_sent = transfer_size; mos7840_port-icount.tx += transfer_size; - smp_wmb(); dev_dbg(port-dev, mos7840_port-icount.tx is %d:\n, mos7840_port-icount.tx); exit: return bytes_sent; @@ -2134,11 +2116,14 @@ static int mos7840_get_icount(struct tty_struct *tty, struct usb_serial_port *port = tty-driver_data; struct moschip_port *mos7840_port; struct async_icount cnow; + unsigned long flags; mos7840_port = mos7840_get_port_private(port); + + spin_lock_irqsave(port-lock, flags); cnow = mos7840_port-icount; + spin_unlock_irqrestore(port-lock, flags); - smp_rmb(); icount-cts = cnow.cts; icount-dsr = cnow.dsr; icount-rng = cnow.rng; @@ -2167,7 +2152,7 @@ static int mos7840_ioctl(struct tty_struct *tty, struct usb_serial_port *port = tty-driver_data; void __user *argp = (void __user *)arg; struct moschip_port *mos7840_port; - + unsigned long flags; struct async_icount cnow; struct async_icount cprev; @@ -2198,7 +2183,9 @@ static int mos7840_ioctl(struct tty_struct *tty, case TIOCMIWAIT: dev_dbg(port-dev, %s TIOCMIWAIT\n, __func__); + spin_lock_irqsave(port-lock, flags); cprev = mos7840_port-icount; + spin_unlock_irqrestore(port-lock, flags); while (1) { /* interruptible_sleep_on(mos7840_port-delta_msr_wait); */ mos7840_port-delta_msr_cond = 0; @@ -2214,11 +2201,14 @@ static int mos7840_ioctl(struct tty_struct *tty, if (port-serial-disconnected) return -EIO; + spin_lock_irqsave(port-lock, flags); cnow = mos7840_port-icount; - smp_rmb(); + spin_unlock_irqrestore(port-lock, flags); + if (cnow.rng == cprev.rng cnow.dsr
[PATCH v3 38/94] USB: ftdi_sio: use port icount
Use the port-data icount for interrupt counters. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ftdi_sio.c | 31 ++- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c575738..ea7433e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -67,7 +67,6 @@ struct ftdi_private { */ int flags; /* some ASYNC_ flags are supported */ unsigned long last_dtr_rts; /* saved modem control outputs */ - struct async_icount icount; char prev_status;/* Used for TIOCMIWAIT */ char transmit_empty;/* If transmitter is empty or not */ __u16 interface;/* FT2232C, FT2232H or FT4232H port interface @@ -1909,7 +1908,7 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, c = kfifo_out(port-write_fifo, buffer[i + 1], len); if (!c) break; - priv-icount.tx += c; + port-icount.tx += c; buffer[i] = (c 2) + 1; count += c + 1; } @@ -1917,7 +1916,7 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, } else { count = kfifo_out_locked(port-write_fifo, dest, size, port-lock); - priv-icount.tx += count; + port-icount.tx += count; } return count; @@ -1946,13 +1945,13 @@ static int ftdi_process_packet(struct usb_serial_port *port, char diff_status = status ^ priv-prev_status; if (diff_status FTDI_RS0_CTS) - priv-icount.cts++; + port-icount.cts++; if (diff_status FTDI_RS0_DSR) - priv-icount.dsr++; + port-icount.dsr++; if (diff_status FTDI_RS0_RI) - priv-icount.rng++; + port-icount.rng++; if (diff_status FTDI_RS0_RLSD) - priv-icount.dcd++; + port-icount.dcd++; wake_up_interruptible(port-delta_msr_wait); priv-prev_status = status; @@ -1964,18 +1963,18 @@ static int ftdi_process_packet(struct usb_serial_port *port, * over framing errors */ if (packet[1] FTDI_RS_BI) { flag = TTY_BREAK; - priv-icount.brk++; + port-icount.brk++; usb_serial_handle_break(port); } else if (packet[1] FTDI_RS_PE) { flag = TTY_PARITY; - priv-icount.parity++; + port-icount.parity++; } else if (packet[1] FTDI_RS_FE) { flag = TTY_FRAME; - priv-icount.frame++; + port-icount.frame++; } /* Overrun is special, not associated with a char */ if (packet[1] FTDI_RS_OE) { - priv-icount.overrun++; + port-icount.overrun++; tty_insert_flip_char(port-port, 0, TTY_OVERRUN); } } @@ -1989,7 +1988,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, len -= 2; if (!len) return 0; /* status only */ - priv-icount.rx += len; + port-icount.rx += len; ch = packet + 2; if (port-port.console port-sysrq) { @@ -2357,8 +2356,7 @@ static int ftdi_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount) { struct usb_serial_port *port = tty-driver_data; - struct ftdi_private *priv = usb_get_serial_port_data(port); - struct async_icount *ic = priv-icount; + struct async_icount *ic = port-icount; icount-cts = ic-cts; icount-dsr = ic-dsr; @@ -2378,7 +2376,6 @@ static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty-driver_data; - struct ftdi_private *priv = usb_get_serial_port_data(port); struct async_icount cnow; struct async_icount cprev; @@ -2404,7 +2401,7 @@ static int ftdi_ioctl(struct tty_struct *tty, * This code is borrowed from linux/drivers/char/serial.c */ case TIOCMIWAIT: - cprev = priv-icount; + cprev = port-icount; for (;;) { interruptible_sleep_on(port-delta_msr_wait); /* see if a signal did it */ @@ -2414,7 +2411,7 @@
[PATCH v3 86/94] USB: opticon: remove disconnect test from tiocmset
Remove unnecessary disconnect test in tiocmset. No ioctls will be made after disconnect returns. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/opticon.c | 16 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 6af5bb8..5f4b0cd 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -309,7 +309,6 @@ static int opticon_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty-driver_data; - struct usb_serial *serial = port-serial; struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; bool rts; @@ -330,18 +329,11 @@ static int opticon_tiocmset(struct tty_struct *tty, if (!changed) return 0; - /* Send the new RTS state to the connected device */ - mutex_lock(serial-disc_mutex); - if (!serial-disconnected) { - ret = send_control_msg(port, CONTROL_RTS, !rts); - if (ret) - ret = usb_translate_errors(ret); - } else { - ret = -ENODEV; - } - mutex_unlock(serial-disc_mutex); + ret = send_control_msg(port, CONTROL_RTS, !rts); + if (ret) + return usb_translate_errors(ret); - return ret; + return 0; } static int get_serial_info(struct usb_serial_port *port, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 54/94] USB: iuu_phoenix: remove unused MSR-wait queue
Remove unused, private modem-status wait queue from driver. If TIOCMIWAIT is ever implemented it must not rely on a private wait queue which may have been released when woken up. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/iuu_phoenix.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 8eeefe3..1ccf9e4 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -55,7 +55,6 @@ static void read_rxcmd_callback(struct urb *urb); struct iuu_private { spinlock_t lock;/* store irq state */ - wait_queue_head_t delta_msr_wait; u8 line_status; int tiostatus; /* store IUART SIGNAL for tiocmget call */ u8 reset; /* if 1 reset is needed */ @@ -94,7 +93,6 @@ static int iuu_port_probe(struct usb_serial_port *port) priv-vcc = vcc_default; spin_lock_init(priv-lock); - init_waitqueue_head(priv-delta_msr_wait); usb_set_serial_port_data(port, priv); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 60/94] USB: mos7840: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mos7840.c | 48 ++-- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 5c2c79b..5417aac 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -219,7 +219,6 @@ struct moschip_port { char open; char open_ports; wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ - int delta_msr_cond; struct usb_serial_port *port; /* loop back to the owner of this object */ /* Offsets */ @@ -413,8 +412,7 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) if (new_msr MOS_MSR_DELTA_RI) icount-rng++; - mos7840_port-delta_msr_cond = 1; - wake_up_interruptible(port-port-delta_msr_wait); + wake_up_interruptible(port-port-port.delta_msr_wait); } } @@ -2114,9 +2112,6 @@ static int mos7840_ioctl(struct tty_struct *tty, struct usb_serial_port *port = tty-driver_data; void __user *argp = (void __user *)arg; struct moschip_port *mos7840_port; - unsigned long flags; - struct async_icount cnow; - struct async_icount cprev; if (mos7840_port_paranoia_check(port, __func__)) return -1; @@ -2142,46 +2137,6 @@ static int mos7840_ioctl(struct tty_struct *tty, case TIOCSSERIAL: dev_dbg(port-dev, %s TIOCSSERIAL\n, __func__); break; - - case TIOCMIWAIT: - dev_dbg(port-dev, %s TIOCMIWAIT\n, __func__); - spin_lock_irqsave(port-lock, flags); - cprev = port-icount; - spin_unlock_irqrestore(port-lock, flags); - while (1) { - /* interruptible_sleep_on(mos7840_port-delta_msr_wait); */ - mos7840_port-delta_msr_cond = 0; - wait_event_interruptible(port-delta_msr_wait, -(port-serial-disconnected || - mos7840_port- - delta_msr_cond == 1)); - - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - spin_lock_irqsave(port-lock, flags); - cnow = port-icount; - spin_unlock_irqrestore(port-lock, flags); - - if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr - cnow.dcd == cprev.dcd cnow.cts == cprev.cts) - return -EIO;/* no change = error */ - - if (((arg TIOCM_RNG) (cnow.rng != cprev.rng)) || - ((arg TIOCM_DSR) (cnow.dsr != cprev.dsr)) || - ((arg TIOCM_CD) (cnow.dcd != cprev.dcd)) || - ((arg TIOCM_CTS) (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - break; - default: break; } @@ -2528,6 +2483,7 @@ static struct usb_serial_driver moschip7840_4port_device = { .break_ctl = mos7840_break, .tiocmget = mos7840_tiocmget, .tiocmset = mos7840_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .port_probe = mos7840_port_probe, .port_remove = mos7840_port_remove, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 55/94] USB: mct_u232: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mct_u232.c | 40 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 06d5a60..6f4303c 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -59,8 +59,6 @@ static int mct_u232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int mct_u232_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); -static int mct_u232_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); static void mct_u232_throttle(struct tty_struct *tty); static void mct_u232_unthrottle(struct tty_struct *tty); @@ -99,7 +97,7 @@ static struct usb_serial_driver mct_u232_device = { .port_probe =mct_u232_port_probe, .port_remove = mct_u232_port_remove, .ioctl = mct_u232_ioctl, - .get_icount =mct_u232_get_icount, + .get_icount =usb_serial_generic_get_icount, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -113,7 +111,6 @@ struct mct_u232_private { unsigned charlast_lsr; /* Line Status Register */ unsigned charlast_msr; /* Modem Status Register */ unsigned int rx_flags; /* Throttling flags */ - struct async_icount icount; }; #define THROTTLED 0x01 @@ -570,7 +567,7 @@ static void mct_u232_read_int_callback(struct urb *urb) /* Record Control Line states */ mct_u232_msr_to_state(port, priv-control_state, priv-last_msr); - mct_u232_msr_to_icount(priv-icount, priv-last_msr); + mct_u232_msr_to_icount(port-icount, priv-last_msr); #if 0 /* Not yet handled. See belkin_sa.c for further information */ @@ -804,7 +801,7 @@ static int mct_u232_ioctl(struct tty_struct *tty, dev_dbg(port-dev, %s TIOCMIWAIT, __func__); spin_lock_irqsave(mct_u232_port-lock, flags); - cprev = mct_u232_port-icount; + cprev = port-icount; spin_unlock_irqrestore(mct_u232_port-lock, flags); for ( ; ; ) { prepare_to_wait(port-delta_msr_wait, @@ -819,7 +816,7 @@ static int mct_u232_ioctl(struct tty_struct *tty, return -EIO; spin_lock_irqsave(mct_u232_port-lock, flags); - cnow = mct_u232_port-icount; + cnow = port-icount; spin_unlock_irqrestore(mct_u232_port-lock, flags); if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr cnow.dcd == cprev.dcd cnow.cts == cprev.cts) @@ -837,35 +834,6 @@ static int mct_u232_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } -static int mct_u232_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); - struct async_icount *ic = mct_u232_port-icount; - unsigned long flags; - - spin_lock_irqsave(mct_u232_port-lock, flags); - - icount-cts = ic-cts; - icount-dsr = ic-dsr; - icount-rng = ic-rng; - icount-dcd = ic-dcd; - icount-rx = ic-rx; - icount-tx = ic-tx; - icount-frame = ic-frame; - icount-overrun = ic-overrun; - icount-parity = ic-parity; - icount-brk = ic-brk; - icount-buf_overrun = ic-buf_overrun; - - spin_unlock_irqrestore(mct_u232_port-lock, flags); - - dev_dbg(port-dev, %s TIOCGICOUNT RX=%d, TX=%d\n, - __func__, icount-rx, icount-tx); - return 0; -} - module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 42/94] USB: ark3116: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation which does not suffer from the races involved when using the deprecated sleep_on functions. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ark3116.c | 30 ++ 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index ed3f6b8..3b16118 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -426,33 +426,6 @@ static int ark3116_ioctl(struct tty_struct *tty, if (copy_from_user(serstruct, user_arg, sizeof(serstruct))) return -EFAULT; return 0; - case TIOCMIWAIT: - for (;;) { - struct async_icount prev = port-icount; - interruptible_sleep_on(port-delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - if ((prev.rng == port-icount.rng) - (prev.dsr == port-icount.dsr) - (prev.dcd == port-icount.dcd) - (prev.cts == port-icount.cts)) - return -EIO; - if ((arg TIOCM_RNG -(prev.rng != port-icount.rng)) || - (arg TIOCM_DSR -(prev.dsr != port-icount.dsr)) || - (arg TIOCM_CD -(prev.dcd != port-icount.dcd)) || - (arg TIOCM_CTS -(prev.cts != port-icount.cts))) - return 0; - } - break; } return -ENOIOCTLCMD; @@ -557,7 +530,7 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr) port-icount.dcd++; if (msr UART_MSR_TERI) port-icount.rng++; - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); } } @@ -697,6 +670,7 @@ static struct usb_serial_driver ark3116_device = { .ioctl =ark3116_ioctl, .tiocmget = ark3116_tiocmget, .tiocmset = ark3116_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .open = ark3116_open, .close =ark3116_close, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 14/94] USB: iuu_phoenix: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/iuu_phoenix.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index a3bfcb3..8eeefe3 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -951,14 +951,11 @@ static void iuu_close(struct usb_serial_port *port) return; iuu_uart_off(port); - if (serial-dev) { - /* free writebuf */ - /* shutdown our urbs */ - dev_dbg(port-dev, %s - shutting down urbs\n, __func__); - usb_kill_urb(port-write_urb); - usb_kill_urb(port-read_urb); - iuu_led(port, 0, 0, 0xF000, 0xFF); - } + + usb_kill_urb(port-write_urb); + usb_kill_urb(port-read_urb); + + iuu_led(port, 0, 0, 0xF000, 0xFF); } static void iuu_init_termios(struct tty_struct *tty) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 25/94] USB: serial: remove generic disconnect callback
Remove the now empty generic disconnect callback and make the disconnect callback non-mandatory. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/generic.c| 6 -- drivers/usb/serial/usb-serial.c | 4 ++-- include/linux/usb/serial.h | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index a6d0ac6..4d421f3 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -45,7 +45,6 @@ struct usb_serial_driver usb_serial_generic_device = { }, .id_table = generic_device_ids, .num_ports =1, - .disconnect = usb_serial_generic_disconnect, .release = usb_serial_generic_release, .throttle = usb_serial_generic_throttle, .unthrottle = usb_serial_generic_unthrottle, @@ -500,11 +499,6 @@ int usb_serial_generic_resume(struct usb_serial *serial) } EXPORT_SYMBOL_GPL(usb_serial_generic_resume); -void usb_serial_generic_disconnect(struct usb_serial *serial) -{ -} -EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect); - void usb_serial_generic_release(struct usb_serial *serial) { } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 578072d..a7b6651 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1099,7 +1099,8 @@ static void usb_serial_disconnect(struct usb_interface *interface) device_del(port-dev); } } - serial-type-disconnect(serial); + if (serial-type-disconnect) + serial-type-disconnect(serial); /* let the last holder of this object cause it to be cleaned up */ usb_serial_put(serial); @@ -1303,7 +1304,6 @@ static void fixup_generic(struct usb_serial_driver *device) set_to_generic_if_null(device, chars_in_buffer); set_to_generic_if_null(device, read_bulk_callback); set_to_generic_if_null(device, write_bulk_callback); - set_to_generic_if_null(device, disconnect); set_to_generic_if_null(device, release); set_to_generic_if_null(device, process_read_urb); set_to_generic_if_null(device, prepare_write_buffer); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 1819b59..437dfd6 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -329,7 +329,6 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void usb_serial_generic_unthrottle(struct tty_struct *tty); -extern void usb_serial_generic_disconnect(struct usb_serial *serial); extern void usb_serial_generic_release(struct usb_serial *serial); extern int usb_serial_generic_register(void); extern void usb_serial_generic_deregister(void); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 47/94] USB: digi_acceleport: remove unused MSR-wait queue
Remove unused, private modem-status wait queue from driver. If TIOCMIWAIT is ever implemented it must not rely on a private wait queue which may have been released when woken up. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/digi_acceleport.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 76a8c20..32873b4 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -196,7 +196,6 @@ struct digi_port { unsigned char dp_out_buf[DIGI_OUT_BUF_SIZE]; int dp_write_urb_in_use; unsigned int dp_modem_signals; - wait_queue_head_t dp_modem_change_wait; int dp_transmit_idle; wait_queue_head_t dp_transmit_idle_wait; int dp_throttled; @@ -1250,7 +1249,6 @@ static int digi_port_init(struct usb_serial_port *port, unsigned port_num) spin_lock_init(priv-dp_port_lock); priv-dp_port_num = port_num; - init_waitqueue_head(priv-dp_modem_change_wait); init_waitqueue_head(priv-dp_transmit_idle_wait); init_waitqueue_head(priv-dp_flush_wait); init_waitqueue_head(priv-dp_close_wait); @@ -1541,7 +1539,6 @@ static int digi_read_oob_callback(struct urb *urb) else priv-dp_modem_signals = ~TIOCM_CD; - wake_up_interruptible(priv-dp_modem_change_wait); spin_unlock(priv-dp_port_lock); } else if (opcode == DIGI_CMD_TRANSMIT_IDLE) { spin_lock(priv-dp_port_lock); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 87/94] USB: pl2303: fix return value of tiocmset
Make sure we return 0 or a negative error number appropriate for userspace on errors. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/pl2303.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 997eba4..4dff179 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -550,10 +550,13 @@ static int pl2303_tiocmset(struct tty_struct *tty, spin_unlock_irqrestore(priv-lock, flags); mutex_lock(serial-disc_mutex); - if (!serial-disconnected) + if (!serial-disconnected) { ret = pl2303_set_control_lines(port, control); - else + if (ret) + ret = usb_translate_errors(ret); + } else { ret = -ENODEV; + } mutex_unlock(serial-disc_mutex); return ret; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 35/94] USB: serial: add generic TIOCMIWAIT implementation
Add generic TIOCMIWAIT implementation which correctly handles hangup, USB-device disconnect, does not rely on the deprecated sleep_on functions and hence does not suffer from the races currently affecting several usb-serial drivers. This makes it much easier to add TIOCMIWAIT support to subdrivers as the tricky details related to hangup and disconnect (e.g. atomicity, that the private port data may have been freed when woken up, and waking up processes at disconnect) have been handled once and for all. To add support to a subdriver, simply set the tiocmiwait-port-operation field, update the port icount fields and wake up any process sleeping on the tty-port modem-status-change wait queue on changes. Note that the tty-port initialised flag can be used to detect disconnected as the port will be hung up as part of disconnect (and cannot be reactivated due to the disconnected flag). However, as the tty-port implementation currently wakes up processes before calling port shutdown, the tty-hupping flag must also be checked to detect hangup for now. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/generic.c | 58 include/linux/usb/serial.h | 5 2 files changed, 63 insertions(+) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index aa71f6e..18bc74e 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -418,6 +418,64 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) } EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); +static bool usb_serial_generic_msr_changed(struct tty_struct *tty, + unsigned long arg, struct async_icount *cprev) +{ + struct usb_serial_port *port = tty-driver_data; + struct async_icount cnow; + unsigned long flags; + bool ret; + + /* +* Use tty-port initialised flag to detect all hangups including the +* one generated at USB-device disconnect. +* +* FIXME: Remove hupping check once tty_port_hangup calls shutdown +*(which clears the initialised flag) before wake up. +*/ + if (test_bit(TTY_HUPPING, tty-flags)) + return true; + if (!test_bit(ASYNCB_INITIALIZED, port-port.flags)) + return true; + + spin_lock_irqsave(port-lock, flags); + cnow = port-icount;/* atomic copy*/ + spin_unlock_irqrestore(port-lock, flags); + + ret = ((arg TIOCM_RNG) (cnow.rng != cprev-rng)) || + ((arg TIOCM_DSR) (cnow.dsr != cprev-dsr)) || + ((arg TIOCM_CD) (cnow.dcd != cprev-dcd)) || + ((arg TIOCM_CTS) (cnow.cts != cprev-cts)); + + *cprev = cnow; + + return ret; +} + +int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg) +{ + struct usb_serial_port *port = tty-driver_data; + struct async_icount cnow; + unsigned long flags; + int ret; + + spin_lock_irqsave(port-lock, flags); + cnow = port-icount;/* atomic copy */ + spin_unlock_irqrestore(port-lock, flags); + + ret = wait_event_interruptible(port-port.delta_msr_wait, + usb_serial_generic_msr_changed(tty, arg, cnow)); + if (!ret) { + if (test_bit(TTY_HUPPING, tty-flags)) + ret = -EIO; + if (!test_bit(ASYNCB_INITIALIZED, port-port.flags)) + ret = -EIO; + } + + return ret; +} +EXPORT_SYMBOL_GPL(usb_serial_generic_tiocmiwait); + #ifdef CONFIG_MAGIC_SYSRQ int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) { diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 9c8b53f..47c8d2c 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -15,6 +15,7 @@ #include linux/kref.h #include linux/mutex.h +#include linux/serial.h #include linux/sysrq.h #include linux/kfifo.h @@ -61,6 +62,7 @@ * @bulk_out_buffers: pointers to the bulk out buffers for this port * @write_urbs: pointers to the bulk out urbs for this port * @write_urbs_free: status bitmap the for bulk out urbs + * @icount: interrupt counters * @tx_bytes: number of bytes currently in host stack queues * @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this * port. @@ -109,6 +111,7 @@ struct usb_serial_port { unsigned long write_urbs_free; __u8bulk_out_endpointAddress; + struct async_icount icount; int tx_bytes; unsigned long flags; @@ -330,6 +333,8 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void
[PATCH v3 18/94] USB: mos7840: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Simplify urb killing, and remove some related debug and dead code while at it. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/mos7840.c | 28 ++-- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index b8051fa..8da1921 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1223,25 +1223,10 @@ static void mos7840_close(struct usb_serial_port *port) } } - /* While closing port, shutdown all bulk read, write * -* and interrupt read if they exists */ - if (serial-dev) { - if (mos7840_port-write_urb) { - dev_dbg(port-dev, %s, Shutdown bulk write\n); - usb_kill_urb(mos7840_port-write_urb); - } - if (mos7840_port-read_urb) { - dev_dbg(port-dev, %s, Shutdown bulk read\n); - usb_kill_urb(mos7840_port-read_urb); - mos7840_port-read_urb_busy = false; - } - if ((mos7840_port-control_urb)) { - dev_dbg(port-dev, %s, Shutdown control read\n); - /*/ usb_kill_urb (mos7840_port-control_urb); */ - } - } -/* if(mos7840_port-ctrl_buf != NULL) */ -/* kfree(mos7840_port-ctrl_buf); */ + usb_kill_urb(mos7840_port-write_urb); + usb_kill_urb(mos7840_port-read_urb); + mos7840_port-read_urb_busy = false; + port0-open_ports--; dev_dbg(port-dev, %s in close%d:in port%d\n, __func__, port0-open_ports, port-number); if (port0-open_ports == 0) { @@ -1331,9 +1316,8 @@ static void mos7840_break(struct tty_struct *tty, int break_state) if (mos7840_port == NULL) return; - if (serial-dev) - /* flush and block until tx is empty */ - mos7840_block_until_chase_response(tty, mos7840_port); + /* flush and block until tx is empty */ + mos7840_block_until_chase_response(tty, mos7840_port); if (break_state == -1) data = mos7840_port-shadowLCR | LCR_SET_BREAK; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 44/94] USB: ch341: fix TIOCMIWAIT and disconnect
Use tty-port modem-status-change wait queue on which processes are woken up at hangup and disconnect. Currently a process waiting on modem-status changes will not be woken on device disconnect as wake up was only done in dtr_rts which isn't guaranteed to be called (e.g. if HUPCL is not set). Also remove the redundant wake-up call from dtr_rts. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ch341.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 1a97985..c2a4171 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -296,7 +296,6 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on) priv-line_control = ~(CH341_BIT_RTS | CH341_BIT_DTR); spin_unlock_irqrestore(priv-lock, flags); ch341_set_handshake(port-serial-dev, priv-line_control); - wake_up_interruptible(port-delta_msr_wait); } static void ch341_close(struct usb_serial_port *port) @@ -489,7 +488,7 @@ static void ch341_read_int_callback(struct urb *urb) tty_kref_put(tty); } - wake_up_interruptible(port-delta_msr_wait); + wake_up_interruptible(port-port.delta_msr_wait); } exit: @@ -516,7 +515,7 @@ static int ch341_tiocmiwait(struct tty_struct *tty, unsigned long arg) spin_unlock_irqrestore(priv-lock, flags); while (!multi_change) { - interruptible_sleep_on(port-delta_msr_wait); + interruptible_sleep_on(port-port.delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 65/94] USB: quatech2: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/quatech2.c | 51 ++- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 75f125d..6d1faab 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -128,8 +128,6 @@ struct qt2_port_private { u8 shadowLSR; u8 shadowMSR; - struct async_icount icount; - struct usb_serial_port *port; }; @@ -501,16 +499,16 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) unsigned long flags; spin_lock_irqsave(priv-lock, flags); - prev = priv-icount; + prev = port-icount; spin_unlock_irqrestore(priv-lock, flags); while (1) { wait_event_interruptible(port-delta_msr_wait, (port-serial-disconnected || - (priv-icount.rng != prev.rng) || - (priv-icount.dsr != prev.dsr) || - (priv-icount.dcd != prev.dcd) || - (priv-icount.cts != prev.cts))); + (port-icount.rng != prev.rng) || + (port-icount.dsr != prev.dsr) || + (port-icount.dcd != prev.dcd) || + (port-icount.cts != prev.cts))); if (signal_pending(current)) return -ERESTARTSYS; @@ -519,7 +517,7 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return -EIO; spin_lock_irqsave(priv-lock, flags); - cur = priv-icount; + cur = port-icount; spin_unlock_irqrestore(priv-lock, flags); if ((prev.rng == cur.rng) @@ -537,28 +535,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return 0; } -static int qt2_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct qt2_port_private *priv = usb_get_serial_port_data(port); - struct async_icount cnow = priv-icount; - - icount-cts = cnow.cts; - icount-dsr = cnow.dsr; - icount-rng = cnow.rng; - icount-dcd = cnow.dcd; - icount-rx = cnow.rx; - icount-tx = cnow.tx; - icount-frame = cnow.frame; - icount-overrun = cnow.overrun; - icount-parity = cnow.parity; - icount-brk = cnow.brk; - icount-buf_overrun = cnow.buf_overrun; - - return 0; -} - static int qt2_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -961,16 +937,13 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) if (newMSR UART_MSR_ANY_DELTA) { /* update input line counters */ if (newMSR UART_MSR_DCTS) - port_priv-icount.cts++; - + port-icount.cts++; if (newMSR UART_MSR_DDSR) - port_priv-icount.dsr++; - + port-icount.dsr++; if (newMSR UART_MSR_DDCD) - port_priv-icount.dcd++; - + port-icount.dcd++; if (newMSR UART_MSR_TERI) - port_priv-icount.rng++; + port-icount.rng++; wake_up_interruptible(port-delta_msr_wait); } @@ -992,7 +965,7 @@ static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch) port_priv-shadowLSR = newLSR; spin_unlock_irqrestore(port_priv-lock, flags); - icount = port_priv-icount; + icount = port-icount; if (newLSR UART_LSR_BRK_ERROR_BITS) { @@ -1102,7 +1075,7 @@ static struct usb_serial_driver qt2_device = { .break_ctl = qt2_break_ctl, .tiocmget= qt2_tiocmget, .tiocmset= qt2_tiocmset, - .get_icount = qt2_get_icount, + .get_icount = usb_serial_generic_get_icount, .ioctl = qt2_ioctl, .set_termios = qt2_set_termios, }; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 26/94] USB: serial: remove generic release callback
Remove empty generic release implementation and make the release callback non-mandatory (like attach, probe and disconnect). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/generic.c| 5 - drivers/usb/serial/usb-serial.c | 3 +-- include/linux/usb/serial.h | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 4d421f3..aa71f6e 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -45,7 +45,6 @@ struct usb_serial_driver usb_serial_generic_device = { }, .id_table = generic_device_ids, .num_ports =1, - .release = usb_serial_generic_release, .throttle = usb_serial_generic_throttle, .unthrottle = usb_serial_generic_unthrottle, .resume = usb_serial_generic_resume, @@ -498,7 +497,3 @@ int usb_serial_generic_resume(struct usb_serial *serial) return c ? -EIO : 0; } EXPORT_SYMBOL_GPL(usb_serial_generic_resume); - -void usb_serial_generic_release(struct usb_serial *serial) -{ -} diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a7b6651..628a386 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -137,7 +137,7 @@ static void destroy_serial(struct kref *kref) if (serial-minor != SERIAL_TTY_NO_MINOR) return_serial(serial); - if (serial-attached) + if (serial-attached serial-type-release) serial-type-release(serial); /* Now that nothing is using the ports, they can be freed */ @@ -1304,7 +1304,6 @@ static void fixup_generic(struct usb_serial_driver *device) set_to_generic_if_null(device, chars_in_buffer); set_to_generic_if_null(device, read_bulk_callback); set_to_generic_if_null(device, write_bulk_callback); - set_to_generic_if_null(device, release); set_to_generic_if_null(device, process_read_urb); set_to_generic_if_null(device, prepare_write_buffer); } diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 437dfd6..3f8f5e3 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -329,7 +329,6 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void usb_serial_generic_unthrottle(struct tty_struct *tty); -extern void usb_serial_generic_release(struct usb_serial *serial); extern int usb_serial_generic_register(void); extern void usb_serial_generic_deregister(void); extern int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 70/94] USB: spcp8x5: pass usb-serial port to control functions
Pass usb-serial port to the control functions for uart status and work mode. Use port device for debugging and use dev_err to report errors. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/spcp8x5.c | 54 +++- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index a5c3a36..5779dd8 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -198,21 +198,22 @@ static int spcp8x5_port_remove(struct usb_serial_port *port) * * NOTE: not supported by spcp825-007 */ -static int spcp8x5_set_ctrl_line(struct usb_device *dev, u8 value, - enum spcp8x5_type type) +static int spcp8x5_set_ctrl_line(struct usb_serial_port *port, u8 mcr) { + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + struct usb_device *dev = port-serial-dev; int retval; - u8 mcr = 0; - if (type == SPCP825_007_TYPE) + if (priv-type == SPCP825_007_TYPE) return -EPERM; - mcr = (unsigned short)value; retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_UART_STATUS_TYPE, SET_UART_STATUS, mcr, 0x04, NULL, 0, 100); - if (retval != 0) - dev_dbg(dev-dev, usb_control_msg return %#x\n, retval); + if (retval != 0) { + dev_err(port-dev, failed to set control lines: %d\n, + retval); + } return retval; } @@ -221,15 +222,16 @@ static int spcp8x5_set_ctrl_line(struct usb_device *dev, u8 value, * * NOTE: not supported by spcp825-007 */ -static int spcp8x5_get_msr(struct usb_device *dev, u8 *status, - enum spcp8x5_type type) +static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) { + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + struct usb_device *dev = port-serial-dev; u8 *status_buffer; int ret; /* I return Permited not support here but seem inval device * is more fix */ - if (type == SPCP825_007_TYPE) + if (priv-type == SPCP825_007_TYPE) return -EPERM; if (status == NULL) return -EINVAL; @@ -243,10 +245,10 @@ static int spcp8x5_get_msr(struct usb_device *dev, u8 *status, GET_UART_STATUS, GET_UART_STATUS_TYPE, 0, GET_UART_STATUS_MSR, status_buffer, 1, 100); if (ret 0) - dev_dbg(dev-dev, Get MSR = 0x%p failed (error = %d), - status_buffer, ret); + dev_err(port-dev, failed to get modem status: %d, ret); + + dev_dbg(port-dev, 0xc0:0x22:0:6 %d - 0x02%x, ret, *status_buffer); - dev_dbg(dev-dev, 0xc0:0x22:0:6 %d - 0x%p , ret, status_buffer); status[0] = status_buffer[0]; kfree(status_buffer); @@ -258,23 +260,24 @@ static int spcp8x5_get_msr(struct usb_device *dev, u8 *status, * * NOTE: not supported by spcp825-007 */ -static void spcp8x5_set_work_mode(struct usb_device *dev, u16 value, -u16 index, enum spcp8x5_type type) +static void spcp8x5_set_work_mode(struct usb_serial_port *port, u16 value, +u16 index) { + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + struct usb_device *dev = port-serial-dev; int ret; /* I return Permited not support here but seem inval device * is more fix */ - if (type == SPCP825_007_TYPE) + if (priv-type == SPCP825_007_TYPE) return; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_WORKING_MODE_TYPE, SET_WORKING_MODE, value, index, NULL, 0, 100); - dev_dbg(dev-dev, value = %#x , index = %#x\n, value, index); + dev_dbg(port-dev, value = %#x , index = %#x\n, value, index); if (ret 0) - dev_dbg(dev-dev, - RTSCTS usb_control_msg(enable flowctrl) = %d\n, ret); + dev_err(port-dev, failed to set work mode: %d\n, ret); } static int spcp8x5_carrier_raised(struct usb_serial_port *port) @@ -302,7 +305,7 @@ static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on) | MCR_CONTROL_LINE_RTS); control = priv-line_control; spin_unlock_irqrestore(priv-lock, flags); - spcp8x5_set_ctrl_line(port-serial-dev, control, priv-type); + spcp8x5_set_ctrl_line(port, control); } static void spcp8x5_init_termios(struct tty_struct *tty) @@ -342,7 +345,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, if (control != priv-line_control) { control
[PATCH v3 28/94] USB: cyberjack: fix disconnect handling
Make sure the interrupt urb submitted in port_probe is killed in port_remove. The interrupt-urb completion handler references the port and may get called after port_remove has returned and the port has been unregistered (although this is currently prevented by usb-serial core as we are using a non-private urb). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/cyberjack.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index de9253d..7814262 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -51,7 +51,6 @@ #define CYBERJACK_PRODUCT_ID 0x0100 /* Function prototypes */ -static void cyberjack_disconnect(struct usb_serial *serial); static int cyberjack_port_probe(struct usb_serial_port *port); static int cyberjack_port_remove(struct usb_serial_port *port); static int cyberjack_open(struct tty_struct *tty, @@ -79,7 +78,6 @@ static struct usb_serial_driver cyberjack_device = { .description = Reiner SCT Cyberjack USB card reader, .id_table = id_table, .num_ports =1, - .disconnect = cyberjack_disconnect, .port_probe = cyberjack_port_probe, .port_remove = cyberjack_port_remove, .open = cyberjack_open, @@ -130,20 +128,14 @@ static int cyberjack_port_remove(struct usb_serial_port *port) { struct cyberjack_private *priv; + usb_kill_urb(port-interrupt_in_urb); + priv = usb_get_serial_port_data(port); kfree(priv); return 0; } -static void cyberjack_disconnect(struct usb_serial *serial) -{ - int i; - - for (i = 0; i serial-num_ports; ++i) - usb_kill_urb(serial-port[i]-interrupt_in_urb); -} - static int cyberjack_open(struct tty_struct *tty, struct usb_serial_port *port) { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/94] USB: ark3116: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ark3116.c | 17 +++-- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 4775f82..3b811fe 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -341,18 +341,15 @@ static void ark3116_close(struct usb_serial_port *port) { struct usb_serial *serial = port-serial; - if (serial-dev) { - /* disable DMA */ - ark3116_write_reg(serial, UART_FCR, 0); - - /* deactivate interrupts */ - ark3116_write_reg(serial, UART_IER, 0); + /* disable DMA */ + ark3116_write_reg(serial, UART_FCR, 0); - usb_serial_generic_close(port); - if (serial-num_interrupt_in) - usb_kill_urb(port-interrupt_in_urb); - } + /* deactivate interrupts */ + ark3116_write_reg(serial, UART_IER, 0); + usb_serial_generic_close(port); + if (serial-num_interrupt_in) + usb_kill_urb(port-interrupt_in_urb); } static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 77/94] USB: ti_usb_3410_5052: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation which does not suffer from the races involved when using the deprecated sleep_on functions. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ti_usb_3410_5052.c | 29 +++-- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 9997725..0726859 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -232,6 +232,7 @@ static struct usb_serial_driver ti_1port_device = { .set_termios= ti_set_termios, .tiocmget = ti_tiocmget, .tiocmset = ti_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .break_ctl = ti_break, .read_int_callback = ti_interrupt_callback, @@ -262,6 +263,7 @@ static struct usb_serial_driver ti_2port_device = { .set_termios= ti_set_termios, .tiocmget = ti_tiocmget, .tiocmset = ti_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, .break_ctl = ti_break, .read_int_callback = ti_interrupt_callback, @@ -731,8 +733,6 @@ static int ti_ioctl(struct tty_struct *tty, { struct usb_serial_port *port = tty-driver_data; struct ti_port *tport = usb_get_serial_port_data(port); - struct async_icount cnow; - struct async_icount cprev; dev_dbg(port-dev, %s - cmd = 0x%04X\n, __func__, cmd); @@ -748,29 +748,6 @@ static int ti_ioctl(struct tty_struct *tty, dev_dbg(port-dev, %s - TIOCSSERIAL\n, __func__); return ti_set_serial_info(tty, tport, (struct serial_struct __user *)arg); - case TIOCMIWAIT: - dev_dbg(port-dev, %s - TIOCMIWAIT\n, __func__); - cprev = port-icount; - while (1) { - interruptible_sleep_on(port-delta_msr_wait); - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - cnow = port-icount; - if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr - cnow.dcd == cprev.dcd cnow.cts == cprev.cts) - return -EIO; /* no change = error */ - if (((arg TIOCM_RNG) (cnow.rng != cprev.rng)) || - ((arg TIOCM_DSR) (cnow.dsr != cprev.dsr)) || - ((arg TIOCM_CD) (cnow.dcd != cprev.dcd)) || - ((arg TIOCM_CTS) (cnow.cts != cprev.cts))) - return 0; - cprev = cnow; - } - break; } return -ENOIOCTLCMD; } @@ -1364,7 +1341,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) icount-dcd++; if (msr TI_MSR_DELTA_RI) icount-rng++; - wake_up_interruptible(tport-tp_port-delta_msr_wait); + wake_up_interruptible(tport-tp_port-port.delta_msr_wait); spin_unlock_irqrestore(tport-tp_lock, flags); } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 29/94] USB: serial: fix port release
We should not call kill_traffic (and usb_kill_urb) once disconnect returns. Any pending urbs are killed at disconnect and new submissions are prevented by usb_unbind_interface (and usb_disable_interface). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b9f460b..2c32f84 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -576,13 +576,6 @@ static void port_release(struct device *dev) dev_dbg(dev, %s\n, __func__); - /* -* Stop all the traffic before cancelling the work, so that -* nobody will restart it by calling usb_serial_port_softint. -*/ - kill_traffic(port); - cancel_work_sync(port-work); - usb_free_urb(port-interrupt_in_urb); usb_free_urb(port-interrupt_out_urb); for (i = 0; i ARRAY_SIZE(port-read_urbs); ++i) { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 20/94] USB: usb_wwan: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb_wwan.c | 25 - 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 571965a..ece326e 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -421,20 +421,19 @@ void usb_wwan_close(struct usb_serial_port *port) portdata = usb_get_serial_port_data(port); - if (serial-dev) { - /* Stop reading/writing urbs */ - spin_lock_irq(intfdata-susp_lock); - portdata-opened = 0; - spin_unlock_irq(intfdata-susp_lock); + /* Stop reading/writing urbs */ + spin_lock_irq(intfdata-susp_lock); + portdata-opened = 0; + spin_unlock_irq(intfdata-susp_lock); - for (i = 0; i N_IN_URB; i++) - usb_kill_urb(portdata-in_urbs[i]); - for (i = 0; i N_OUT_URB; i++) - usb_kill_urb(portdata-out_urbs[i]); - /* balancing - important as an error cannot be handled*/ - usb_autopm_get_interface_no_resume(serial-interface); - serial-interface-needs_remote_wakeup = 0; - } + for (i = 0; i N_IN_URB; i++) + usb_kill_urb(portdata-in_urbs[i]); + for (i = 0; i N_OUT_URB; i++) + usb_kill_urb(portdata-out_urbs[i]); + + /* balancing - important as an error cannot be handled*/ + usb_autopm_get_interface_no_resume(serial-interface); + serial-interface-needs_remote_wakeup = 0; } EXPORT_SYMBOL(usb_wwan_close); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 21/94] USB: serial: remove bogus disconnect test in cleanup
Remove bogus (and unnecessary) test for serial-dev being NULL in cleanup. The device is never cleared, and cleanup is never called after a completed disconnect anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/generic.c | 24 ++-- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 927c5d6..131d6cb 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -104,24 +104,20 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_open); static void generic_cleanup(struct usb_serial_port *port) { - struct usb_serial *serial = port-serial; unsigned long flags; int i; - if (serial-dev) { - /* shutdown any bulk transfers that might be going on */ - if (port-bulk_out_size) { - for (i = 0; i ARRAY_SIZE(port-write_urbs); ++i) - usb_kill_urb(port-write_urbs[i]); + if (port-bulk_out_size) { + for (i = 0; i ARRAY_SIZE(port-write_urbs); ++i) + usb_kill_urb(port-write_urbs[i]); - spin_lock_irqsave(port-lock, flags); - kfifo_reset_out(port-write_fifo); - spin_unlock_irqrestore(port-lock, flags); - } - if (port-bulk_in_size) { - for (i = 0; i ARRAY_SIZE(port-read_urbs); ++i) - usb_kill_urb(port-read_urbs[i]); - } + spin_lock_irqsave(port-lock, flags); + kfifo_reset_out(port-write_fifo); + spin_unlock_irqrestore(port-lock, flags); + } + if (port-bulk_in_size) { + for (i = 0; i ARRAY_SIZE(port-read_urbs); ++i) + usb_kill_urb(port-read_urbs[i]); } } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 22/94] USB: ssu100: remove explicit initialisation of disconnect
The disconnect callback is set to the generic implementation by usb-serial core if NULL. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ssu100.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 4b2a197..97aca3f 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -641,7 +641,6 @@ static struct usb_serial_driver ssu100_device = { .get_icount = ssu100_get_icount, .ioctl = ssu100_ioctl, .set_termios = ssu100_set_termios, - .disconnect = usb_serial_generic_disconnect, }; static struct usb_serial_driver * const serial_drivers[] = { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 33/94] USB: serial: clean up usb-serial bus device removal
Make sure to unregister the tty-device before calling subdriver port_remove. This way remove will reverse probe, and specifically any port data released in port_remove will be available throughout tty unregister. Note that the order currently does not matter as the tty-layer can make callbacks also after the device has been unregistered. This is handled in usb-serial core using the disconnected flag, which is already set when usb-serial bus device remove is called. Cc: Peter Hurley pe...@hurleysoftware.com Reported-by: Peter Hurley pe...@hurleysoftware.com Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/bus.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 37decb1..3c4db6d 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -106,14 +106,15 @@ static int usb_serial_device_remove(struct device *dev) /* make sure suspend/resume doesn't race against port_remove */ usb_autopm_get_interface(port-serial-interface); + minor = port-number; + tty_unregister_device(usb_serial_tty_driver, minor); + device_remove_file(port-dev, dev_attr_port_number); driver = port-serial-type; if (driver-port_remove) retval = driver-port_remove(port); - minor = port-number; - tty_unregister_device(usb_serial_tty_driver, minor); dev_info(dev, %s converter now disconnected from ttyUSB%d\n, driver-description, minor); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 31/94] USB: fix urb-poison imbalance
The calls to usb_poison_urb and usb_unpoison_urb are expected to be balanced. However, if an urb that has not yet been submitted is poisoned, its reject counter will not be increased as its ep-field is NULL. A consecutive call to unpoison will thus in fact poison the urb as its reject counter will be decremented to a negative value, effectively preventing the urb from being submitted. Note that there are currently no in-kernel drivers affected by this. Cc: Alan Stern st...@rowland.harvard.edu Acked-by: Alan Stern st...@rowland.harvard.edu Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/core/urb.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index e0d9d94..16927fa 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -683,10 +683,13 @@ EXPORT_SYMBOL_GPL(usb_kill_urb); void usb_poison_urb(struct urb *urb) { might_sleep(); - if (!(urb urb-dev urb-ep)) + if (!urb) return; atomic_inc(urb-reject); + if (!urb-dev || !urb-ep) + return; + usb_hcd_unlink_urb(urb, -ENOENT); wait_event(usb_kill_urb_queue, atomic_read(urb-use_count) == 0); } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 48/94] USB: f81232: add custom tiocmiwait operation
Break out TIOCMIWAIT handling from custom ioctl operation and use tiocmiwait operation field instead. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/f81232.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index a172ad5..d1fdd8d 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -242,8 +242,9 @@ static int f81232_carrier_raised(struct usb_serial_port *port) return 0; } -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) +static int f81232_tiocmiwait(struct tty_struct *tty, unsigned long arg) { + struct usb_serial_port *port = tty-driver_data; struct f81232_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int prevstatus; @@ -302,11 +303,6 @@ static int f81232_ioctl(struct tty_struct *tty, return -EFAULT; return 0; - - case TIOCMIWAIT: - dev_dbg(port-dev, %s (%d) TIOCMIWAIT\n, __func__, - port-number); - return wait_modem_info(port, arg); default: dev_dbg(port-dev, %s not supported = 0x%04x\n, __func__, cmd); @@ -358,6 +354,7 @@ static struct usb_serial_driver f81232_device = { .set_termios = f81232_set_termios, .tiocmget = f81232_tiocmget, .tiocmset = f81232_tiocmset, + .tiocmiwait = f81232_tiocmiwait, .process_read_urb = f81232_process_read_urb, .read_int_callback =f81232_read_int_callback, .port_probe = f81232_port_probe, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 68/94] USB: spcp8x5: remove broken uart-error handling
Remove broken uart-error handling. This driver appears to implement uart-error handling but does not receive status interrupts or status information with bulk in transfers. Instead status was retrieved at open and used to flag only the first bulk in transfer. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/spcp8x5.c | 52 1 file changed, 52 deletions(-) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index e24d23b..f34930c 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -456,57 +456,6 @@ static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) return usb_serial_generic_open(tty, port); } -static void spcp8x5_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb-context; - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - unsigned char *data = urb-transfer_buffer; - unsigned long flags; - u8 status; - char tty_flag; - - /* get tty_flag from status */ - tty_flag = TTY_NORMAL; - - spin_lock_irqsave(priv-lock, flags); - status = priv-line_status; - priv-line_status = ~UART_STATE_TRANSIENT_MASK; - spin_unlock_irqrestore(priv-lock, flags); - - if (!urb-actual_length) - return; - - - if (status UART_STATE_TRANSIENT_MASK) { - /* break takes precedence over parity, which takes precedence -* over framing errors */ - if (status UART_BREAK_ERROR) - tty_flag = TTY_BREAK; - else if (status UART_PARITY_ERROR) - tty_flag = TTY_PARITY; - else if (status UART_FRAME_ERROR) - tty_flag = TTY_FRAME; - dev_dbg(port-dev, tty_flag = %d\n, tty_flag); - - /* overrun is special, not associated with a char */ - if (status UART_OVERRUN_ERROR) - tty_insert_flip_char(port-port, 0, TTY_OVERRUN); - - if (status UART_DCD) { - struct tty_struct *tty = tty_port_tty_get(port-port); - if (tty) { - usb_serial_handle_dcd_change(port, tty, - priv-line_status MSR_STATUS_LINE_DCD); - tty_kref_put(tty); - } - } - } - - tty_insert_flip_string_fixed_flag(port-port, data, tty_flag, - urb-actual_length); - tty_flip_buffer_push(port-port); -} - static int spcp8x5_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { @@ -571,7 +520,6 @@ static struct usb_serial_driver spcp8x5_device = { .tiocmset = spcp8x5_tiocmset, .port_probe = spcp8x5_port_probe, .port_remove= spcp8x5_port_remove, - .process_read_urb = spcp8x5_process_read_urb, }; static struct usb_serial_driver * const serial_drivers[] = { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 41/94] USB: ark3116: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ark3116.c | 58 ++-- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 3b811fe..ed3f6b8 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -62,7 +62,6 @@ static int is_irda(struct usb_serial *serial) } struct ark3116_private { - struct async_icount icount; int irda; /* 1 for irda device */ /* protects hw register updates */ @@ -402,31 +401,10 @@ err_out: return result; } -static int ark3116_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct ark3116_private *priv = usb_get_serial_port_data(port); - struct async_icount cnow = priv-icount; - icount-cts = cnow.cts; - icount-dsr = cnow.dsr; - icount-rng = cnow.rng; - icount-dcd = cnow.dcd; - icount-rx = cnow.rx; - icount-tx = cnow.tx; - icount-frame = cnow.frame; - icount-overrun = cnow.overrun; - icount-parity = cnow.parity; - icount-brk = cnow.brk; - icount-buf_overrun = cnow.buf_overrun; - return 0; -} - static int ark3116_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty-driver_data; - struct ark3116_private *priv = usb_get_serial_port_data(port); struct serial_struct serstruct; void __user *user_arg = (void __user *)arg; @@ -450,7 +428,7 @@ static int ark3116_ioctl(struct tty_struct *tty, return 0; case TIOCMIWAIT: for (;;) { - struct async_icount prev = priv-icount; + struct async_icount prev = port-icount; interruptible_sleep_on(port-delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) @@ -459,19 +437,19 @@ static int ark3116_ioctl(struct tty_struct *tty, if (port-serial-disconnected) return -EIO; - if ((prev.rng == priv-icount.rng) - (prev.dsr == priv-icount.dsr) - (prev.dcd == priv-icount.dcd) - (prev.cts == priv-icount.cts)) + if ((prev.rng == port-icount.rng) + (prev.dsr == port-icount.dsr) + (prev.dcd == port-icount.dcd) + (prev.cts == port-icount.cts)) return -EIO; if ((arg TIOCM_RNG -(prev.rng != priv-icount.rng)) || +(prev.rng != port-icount.rng)) || (arg TIOCM_DSR -(prev.dsr != priv-icount.dsr)) || +(prev.dsr != port-icount.dsr)) || (arg TIOCM_CD -(prev.dcd != priv-icount.dcd)) || +(prev.dcd != port-icount.dcd)) || (arg TIOCM_CTS -(prev.cts != priv-icount.cts))) +(prev.cts != port-icount.cts))) return 0; } break; @@ -572,13 +550,13 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr) if (msr UART_MSR_ANY_DELTA) { /* update input line counters */ if (msr UART_MSR_DCTS) - priv-icount.cts++; + port-icount.cts++; if (msr UART_MSR_DDSR) - priv-icount.dsr++; + port-icount.dsr++; if (msr UART_MSR_DDCD) - priv-icount.dcd++; + port-icount.dcd++; if (msr UART_MSR_TERI) - priv-icount.rng++; + port-icount.rng++; wake_up_interruptible(port-delta_msr_wait); } } @@ -595,13 +573,13 @@ static void ark3116_update_lsr(struct usb_serial_port *port, __u8 lsr) if (lsrUART_LSR_BRK_ERROR_BITS) { if (lsr UART_LSR_BI) - priv-icount.brk++; + port-icount.brk++; if (lsr UART_LSR_FE) - priv-icount.frame++; + port-icount.frame++; if (lsr UART_LSR_PE) - priv-icount.parity++; + port-icount.parity++; if (lsr UART_LSR_OE) -
[PATCH v3 90/94] USB: visor: always disable uart on close
Always try to disable the uart on close. Since the switch to tty ports, close will be called as part of shutdown before disconnect returns. Hence there is no need to check the disconnected flag, and we can put devices in disabled states also on driver unbind. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/visor.c | 16 +--- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 1129aa7..7573ec8 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -257,24 +257,18 @@ static void visor_close(struct usb_serial_port *port) { unsigned char *transfer_buffer; - /* shutdown our urbs */ usb_serial_generic_close(port); usb_kill_urb(port-interrupt_in_urb); - mutex_lock(port-serial-disc_mutex); - if (!port-serial-disconnected) { - /* Try to send shutdown message, unless the device is gone */ - transfer_buffer = kmalloc(0x12, GFP_KERNEL); - if (transfer_buffer) { - usb_control_msg(port-serial-dev, + transfer_buffer = kmalloc(0x12, GFP_KERNEL); + if (!transfer_buffer) + return; + usb_control_msg(port-serial-dev, usb_rcvctrlpipe(port-serial-dev, 0), VISOR_CLOSE_NOTIFICATION, 0xc2, 0x, 0x, transfer_buffer, 0x12, 300); - kfree(transfer_buffer); - } - } - mutex_unlock(port-serial-disc_mutex); + kfree(transfer_buffer); } static void visor_read_int_callback(struct urb *urb) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 85/94] USB: opticon: fix return value of tiocmset
Make sure we return 0 or a negative error number appropriate for userspace on errors. Currently 1 rather than 0 is returned on successful operation. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/opticon.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index e13e1a4..6af5bb8 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -120,7 +120,10 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, 0, 0, buffer, 1, 0); kfree(buffer); - return retval; + if (retval 0) + return retval; + + return 0; } static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -329,10 +332,13 @@ static int opticon_tiocmset(struct tty_struct *tty, /* Send the new RTS state to the connected device */ mutex_lock(serial-disc_mutex); - if (!serial-disconnected) + if (!serial-disconnected) { ret = send_control_msg(port, CONTROL_RTS, !rts); - else + if (ret) + ret = usb_translate_errors(ret); + } else { ret = -ENODEV; + } mutex_unlock(serial-disc_mutex); return ret; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 32/94] USB: serial: use urb poison to reliably kill traffic
Use usb_poison_urb to reliably kill all urbs on disconnect and suspend. This way there will be no question that the urbs cannot be resubmitted by buggy subdrivers. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 55 +++-- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b73c1cd..c481a80 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -546,27 +546,30 @@ static void usb_serial_port_work(struct work_struct *work) tty_kref_put(tty); } -static void kill_traffic(struct usb_serial_port *port) +static void usb_serial_port_poison_urbs(struct usb_serial_port *port) { int i; for (i = 0; i ARRAY_SIZE(port-read_urbs); ++i) - usb_kill_urb(port-read_urbs[i]); + usb_poison_urb(port-read_urbs[i]); for (i = 0; i ARRAY_SIZE(port-write_urbs); ++i) - usb_kill_urb(port-write_urbs[i]); - /* -* This is tricky. -* Some drivers submit the read_urb in the -* handler for the write_urb or vice versa -* this order determines the order in which -* usb_kill_urb() must be used to reliably -* kill the URBs. As it is unknown here, -* both orders must be used in turn. -* The call below is not redundant. -*/ - usb_kill_urb(port-read_urb); - usb_kill_urb(port-interrupt_in_urb); - usb_kill_urb(port-interrupt_out_urb); + usb_poison_urb(port-write_urbs[i]); + + usb_poison_urb(port-interrupt_in_urb); + usb_poison_urb(port-interrupt_out_urb); +} + +static void usb_serial_port_unpoison_urbs(struct usb_serial_port *port) +{ + int i; + + for (i = 0; i ARRAY_SIZE(port-read_urbs); ++i) + usb_unpoison_urb(port-read_urbs[i]); + for (i = 0; i ARRAY_SIZE(port-write_urbs); ++i) + usb_unpoison_urb(port-write_urbs[i]); + + usb_unpoison_urb(port-interrupt_in_urb); + usb_unpoison_urb(port-interrupt_out_urb); } static void usb_serial_port_release(struct device *dev) @@ -1086,7 +1089,7 @@ static void usb_serial_disconnect(struct usb_interface *interface) tty_vhangup(tty); tty_kref_put(tty); } - kill_traffic(port); + usb_serial_port_poison_urbs(port); cancel_work_sync(port-work); if (device_is_registered(port-dev)) device_del(port-dev); @@ -1119,7 +1122,7 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) for (i = 0; i serial-num_ports; ++i) { port = serial-port[i]; if (port) - kill_traffic(port); + usb_serial_port_poison_urbs(port); } err_out: @@ -1127,11 +1130,25 @@ err_out: } EXPORT_SYMBOL(usb_serial_suspend); +static void usb_serial_unpoison_port_urbs(struct usb_serial *serial) +{ + struct usb_serial_port *port; + int i; + + for (i = 0; i serial-num_ports; ++i) { + port = serial-port[i]; + if (port) + usb_serial_port_unpoison_urbs(port); + } +} + int usb_serial_resume(struct usb_interface *intf) { struct usb_serial *serial = usb_get_intfdata(intf); int rv; + usb_serial_unpoison_port_urbs(serial); + serial-suspending = 0; if (serial-type-resume) rv = serial-type-resume(serial); @@ -1147,6 +1164,8 @@ static int usb_serial_reset_resume(struct usb_interface *intf) struct usb_serial *serial = usb_get_intfdata(intf); int rv; + usb_serial_unpoison_port_urbs(serial); + serial-suspending = 0; if (serial-type-reset_resume) rv = serial-type-reset_resume(serial); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 92/94] USB: garmin_gps: remove bogus disconnect test in bulk callback
Remove bogus disconnect test for serial device being NULL in read bulk callback. This can never happen as the port read urb is killed (and poisoned) at close, which in turn is guaranteed to be called before the last tty reference is dropped (and port-serial is cleared). Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/garmin_gps.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 1ade6cf2..b110c57 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1181,17 +1181,11 @@ static void garmin_read_bulk_callback(struct urb *urb) { unsigned long flags; struct usb_serial_port *port = urb-context; - struct usb_serial *serial = port-serial; struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); unsigned char *data = urb-transfer_buffer; int status = urb-status; int retval; - if (!serial) { - dev_dbg(urb-dev-dev, %s - bad serial pointer, exiting\n, __func__); - return; - } - if (status) { dev_dbg(urb-dev-dev, %s - nonzero read bulk status received: %d\n, __func__, status); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 27/94] USB: serial: clean up generic-operation handling
Most USB serial drivers are, and should be, using as much of the generic implementation as possible. Rename the fixup_generic function to a more descriptive name. Reword the related debug message in a more neutral tone (and remember to add the missing newline). Finally, move the operations initialisation to after the initial sanity checks. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 628a386..b9f460b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1290,12 +1290,12 @@ module_exit(usb_serial_exit); do {\ if (!type-function) { \ type-function = usb_serial_generic_##function; \ - pr_debug(Had to override the #function \ -usb serial operation with the generic one.);\ - } \ + pr_debug(%s: using generic #function \n, \ + type-driver.name); \ + } \ } while (0) -static void fixup_generic(struct usb_serial_driver *device) +static void usb_serial_operations_init(struct usb_serial_driver *device) { set_to_generic_if_null(device, open); set_to_generic_if_null(device, write); @@ -1315,8 +1315,6 @@ static int usb_serial_register(struct usb_serial_driver *driver) if (usb_disabled()) return -ENODEV; - fixup_generic(driver); - if (!driver-description) driver-description = driver-driver.name; if (!driver-usb_driver) { @@ -1325,6 +1323,8 @@ static int usb_serial_register(struct usb_serial_driver *driver) return -EINVAL; } + usb_serial_operations_init(driver); + /* Add this device to our list of devices */ mutex_lock(table_lock); list_add(driver-driver_list, usb_serial_driver_list); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 78/94] USB: serial: remove unused MSR-wait queue
Remove the port MSR-wait queue now that all drivers have been migrated to the tty-port queue. Signed-off-by: Johan Hovold jhov...@gmail.com --- include/linux/usb/serial.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index c786ee7..b9b0f7b4 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -68,7 +68,6 @@ * port. * @flags: usb serial port flags * @write_wait: a wait_queue_head_t used by the port. - * @delta_msr_wait: modem-status-change wait queue * @work: work queue entry for the line discipline waking up. * @throttled: nonzero if the read urb is inactive to throttle the device * @throttle_req: nonzero if the tty wants to throttle us @@ -116,7 +115,6 @@ struct usb_serial_port { unsigned long flags; wait_queue_head_t write_wait; - wait_queue_head_t delta_msr_wait; struct work_struct work; charthrottled; charthrottle_req; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 12/94] USB: cyberjack: remove bogus disconnect test in close
Remove bogus (and unnecessary) test for serial-dev being NULL in close. The device is never cleared, and close is never called after a completed disconnect anyway. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/cyberjack.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 629bd28..de9253d 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -166,11 +166,8 @@ static int cyberjack_open(struct tty_struct *tty, static void cyberjack_close(struct usb_serial_port *port) { - if (port-serial-dev) { - /* shutdown any bulk reads that might be going on */ - usb_kill_urb(port-write_urb); - usb_kill_urb(port-read_urb); - } + usb_kill_urb(port-write_urb); + usb_kill_urb(port-read_urb); } static int cyberjack_write(struct tty_struct *tty, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 45/94] USB: cypress_m8: replace custom ioctl operation with tiocmiwait
Replace custom ioctl operation with tiocmiwait. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/cypress_m8.c | 85 + 1 file changed, 36 insertions(+), 49 deletions(-) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index ba7352e..cdbb096 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -129,13 +129,12 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static void cypress_send(struct usb_serial_port *port); static int cypress_write_room(struct tty_struct *tty); -static int cypress_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); static void cypress_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static int cypress_tiocmget(struct tty_struct *tty); static int cypress_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); +static int cypress_tiocmiwait(struct tty_struct *tty, unsigned long arg); static int cypress_chars_in_buffer(struct tty_struct *tty); static void cypress_throttle(struct tty_struct *tty); static void cypress_unthrottle(struct tty_struct *tty); @@ -158,10 +157,10 @@ static struct usb_serial_driver cypress_earthmate_device = { .dtr_rts = cypress_dtr_rts, .write =cypress_write, .write_room = cypress_write_room, - .ioctl =cypress_ioctl, .set_termios = cypress_set_termios, .tiocmget = cypress_tiocmget, .tiocmset = cypress_tiocmset, + .tiocmiwait = cypress_tiocmiwait, .chars_in_buffer = cypress_chars_in_buffer, .throttle = cypress_throttle, .unthrottle = cypress_unthrottle, @@ -184,10 +183,10 @@ static struct usb_serial_driver cypress_hidcom_device = { .dtr_rts = cypress_dtr_rts, .write =cypress_write, .write_room = cypress_write_room, - .ioctl =cypress_ioctl, .set_termios = cypress_set_termios, .tiocmget = cypress_tiocmget, .tiocmset = cypress_tiocmset, + .tiocmiwait = cypress_tiocmiwait, .chars_in_buffer = cypress_chars_in_buffer, .throttle = cypress_throttle, .unthrottle = cypress_unthrottle, @@ -210,10 +209,10 @@ static struct usb_serial_driver cypress_ca42v2_device = { .dtr_rts = cypress_dtr_rts, .write =cypress_write, .write_room = cypress_write_room, - .ioctl =cypress_ioctl, .set_termios = cypress_set_termios, .tiocmget = cypress_tiocmget, .tiocmset = cypress_tiocmset, + .tiocmiwait = cypress_tiocmiwait, .chars_in_buffer = cypress_chars_in_buffer, .throttle = cypress_throttle, .unthrottle = cypress_unthrottle, @@ -855,55 +854,43 @@ static int cypress_tiocmset(struct tty_struct *tty, } -static int cypress_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) +static int cypress_tiocmiwait(struct tty_struct *tty, unsigned long arg) { struct usb_serial_port *port = tty-driver_data; struct cypress_private *priv = usb_get_serial_port_data(port); - - dev_dbg(port-dev, %s - port %d, cmd 0x%.4x\n, __func__, port-number, cmd); - - switch (cmd) { - /* This code comes from drivers/char/serial.c and ftdi_sio.c */ - case TIOCMIWAIT: - for (;;) { - interruptible_sleep_on(port-delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port-serial-disconnected) - return -EIO; - - { - char diff = priv-diff_status; - if (diff == 0) - return -EIO; /* no change = error */ - - /* consume all events */ - priv-diff_status = 0; - - /* return 0 if caller wanted to know about - these bits */ -
[PATCH v3 37/94] USB: serial: add generic get_icount implementation
Add generic get_icount implementation that subdrivers relying on the port interrupt counters can use. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/generic.c | 27 +++ include/linux/usb/serial.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 18bc74e..5e55761 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -476,6 +476,33 @@ int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg) } EXPORT_SYMBOL_GPL(usb_serial_generic_tiocmiwait); +int usb_serial_generic_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct usb_serial_port *port = tty-driver_data; + struct async_icount cnow; + unsigned long flags; + + spin_lock_irqsave(port-lock, flags); + cnow = port-icount;/* atomic copy */ + spin_unlock_irqrestore(port-lock, flags); + + icount-cts = cnow.cts; + icount-dsr = cnow.dsr; + icount-rng = cnow.rng; + icount-dcd = cnow.dcd; + icount-tx = cnow.tx; + icount-rx = cnow.rx; + icount-frame = cnow.frame; + icount-parity = cnow.parity; + icount-overrun = cnow.overrun; + icount-brk = cnow.brk; + icount-buf_overrun = cnow.buf_overrun; + + return 0; +} +EXPORT_SYMBOL_GPL(usb_serial_generic_get_icount); + #ifdef CONFIG_MAGIC_SYSRQ int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) { diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 47c8d2c..c786ee7 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -335,6 +335,8 @@ extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void usb_serial_generic_unthrottle(struct tty_struct *tty); extern int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg); +extern int usb_serial_generic_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount); extern int usb_serial_generic_register(void); extern void usb_serial_generic_deregister(void); extern int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 73/94] USB: spcp8x5: add proper modem-status support
Fetch modem status on carrier_raised and tiocmget. This driver appeared to support modem-status but only read the modem status registers once at open and then used that cached value for all further enquires. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/spcp8x5.c | 27 ++- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index a454a3f..cf3df79 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -1,7 +1,7 @@ /* * spcp8x5 USB to serial adaptor driver * - * Copyright (C) 2010 Johan Hovold (jhov...@gmail.com) + * Copyright (C) 2010-2013 Johan Hovold (jhov...@gmail.com) * Copyright (C) 2006 Linxb (xubin@worldplus.com.cn) * Copyright (C) 2006 S1 Corp. * @@ -145,7 +145,6 @@ struct spcp8x5_private { unsignedquirks; spinlock_t lock; u8 line_control; - u8 line_status; }; static int spcp8x5_probe(struct usb_serial *serial, @@ -249,9 +248,11 @@ static void spcp8x5_set_work_mode(struct usb_serial_port *port, u16 value, static int spcp8x5_carrier_raised(struct usb_serial_port *port) { - struct spcp8x5_private *priv = usb_get_serial_port_data(port); + u8 msr; + int ret; - if (priv-line_status MSR_STATUS_LINE_DCD) + ret = spcp8x5_get_msr(port, msr); + if (ret || msr MSR_STATUS_LINE_DCD) return 1; return 0; @@ -397,9 +398,6 @@ static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) struct usb_serial *serial = port-serial; struct spcp8x5_private *priv = usb_get_serial_port_data(port); int ret; - unsigned long flags; - u8 status = 0x30; - /* status 0x30 means DSR and CTS = 1 other CDC RI and delta = 0 */ usb_clear_halt(serial-dev, port-write_urb-pipe); usb_clear_halt(serial-dev, port-read_urb-pipe); @@ -412,17 +410,9 @@ static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) spcp8x5_set_ctrl_line(port, priv-line_control); - /* Setup termios */ if (tty) spcp8x5_set_termios(tty, port, tmp_termios); - spcp8x5_get_msr(port, status); - - /* may be we should update uart status here but now we did not do */ - spin_lock_irqsave(priv-lock, flags); - priv-line_status = status 0xf0 ; - spin_unlock_irqrestore(priv-lock, flags); - port-port.drain_delay = 256; return usb_serial_generic_open(tty, port); @@ -457,12 +447,15 @@ static int spcp8x5_tiocmget(struct tty_struct *tty) struct spcp8x5_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int mcr; - unsigned int status; + u8 status; unsigned int result; + result = spcp8x5_get_msr(port, status); + if (result) + return result; + spin_lock_irqsave(priv-lock, flags); mcr = priv-line_control; - status = priv-line_status; spin_unlock_irqrestore(priv-lock, flags); result = ((mcr MCR_DTR) ? TIOCM_DTR : 0) -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 52/94] USB: io_ti: switch to generic get_icount implementation
Switch to the generic get_icount implementation. Note that the interrupt counters will no longer be reset at open which is in accordance with which how the other drivers work. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/io_ti.c | 40 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 172..fb9e664 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -86,7 +86,6 @@ struct edgeport_port { int baud_rate; int close_pending; int lsr_event; - struct async_icount icount; struct edgeport_serial *edge_serial; struct usb_serial_port *port; __u8 bUartMode; /* Port type, 0: RS232, etc. */ @@ -1445,7 +1444,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) if (msr (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) { - icount = edge_port-icount; + icount = edge_port-port-icount; /* update input line counters */ if (msr EDGEPORT_MSR_DELTA_CTS) @@ -1498,7 +1497,7 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, edge_tty_recv(edge_port-port, data, 1); /* update input line counters */ - icount = edge_port-icount; + icount = edge_port-port-icount; if (new_lsr LSR_BREAK) icount-brk++; if (new_lsr LSR_OVER_ERR) @@ -1657,7 +1656,7 @@ static void edge_bulk_in_callback(struct urb *urb) else edge_tty_recv(edge_port-port, data, urb-actual_length); - edge_port-icount.rx += urb-actual_length; + edge_port-port-icount.rx += urb-actual_length; } exit: @@ -1750,8 +1749,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) dev = port-serial-dev; - memset((edge_port-icount), 0x00, sizeof(edge_port-icount)); - /* turn off loopback */ status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0); if (status) { @@ -1999,7 +1996,7 @@ static void edge_send(struct tty_struct *tty) edge_port-ep_write_urb_in_use = 0; /* TODO: reschedule edge_send */ } else - edge_port-icount.tx += count; + edge_port-port-icount.tx += count; /* wakeup any process waiting for writes to complete */ /* there is now more room in the buffer for new writes */ @@ -2360,27 +2357,6 @@ static int edge_tiocmget(struct tty_struct *tty) return result; } -static int edge_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty-driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount *ic = edge_port-icount; - - icount-cts = ic-cts; - icount-dsr = ic-dsr; - icount-rng = ic-rng; - icount-dcd = ic-dcd; - icount-tx = ic-tx; -icount-rx = ic-rx; -icount-frame = ic-frame; -icount-parity = ic-parity; -icount-overrun = ic-overrun; -icount-brk = ic-brk; -icount-buf_overrun = ic-buf_overrun; - return 0; -} - static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct __user *retinfo) { @@ -2428,7 +2404,7 @@ static int edge_ioctl(struct tty_struct *tty, (struct serial_struct __user *) arg); case TIOCMIWAIT: dev_dbg(port-dev, %s - TIOCMIWAIT\n, __func__); - cprev = edge_port-icount; + cprev = edge_port-port-icount; while (1) { interruptible_sleep_on(port-delta_msr_wait); /* see if a signal did it */ @@ -2438,7 +2414,7 @@ static int edge_ioctl(struct tty_struct *tty, if (port-serial-disconnected) return -EIO; - cnow = edge_port-icount; + cnow = port-icount; if (cnow.rng == cprev.rng cnow.dsr == cprev.dsr cnow.dcd == cprev.dcd cnow.cts == cprev.cts) return -EIO; /* no change = error */ @@ -2618,7 +2594,7 @@ static struct usb_serial_driver edgeport_1port_device = { .set_termios= edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, - .get_icount = edge_get_icount, + .get_icount = usb_serial_generic_get_icount, .write = edge_write, .write_room
[PATCH v3 23/94] USB: ssu100: remove custom close operation
The generic close operation will be used if the close field is left uninitialised. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/ssu100.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 97aca3f..45b8c29 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -315,11 +315,6 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) return usb_serial_generic_open(tty, port); } -static void ssu100_close(struct usb_serial_port *port) -{ - usb_serial_generic_close(port); -} - static int get_serial_info(struct usb_serial_port *port, struct serial_struct __user *retinfo) { @@ -630,7 +625,6 @@ static struct usb_serial_driver ssu100_device = { .id_table= id_table, .num_ports = 1, .open= ssu100_open, - .close = ssu100_close, .attach = ssu100_attach, .port_probe = ssu100_port_probe, .port_remove = ssu100_port_remove, -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 30/94] USB: serial: rename port release
Rename port_release so that all usb_serial_port functions have a common prefix. Signed-off-by: Johan Hovold jhov...@gmail.com --- drivers/usb/serial/usb-serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2c32f84..b73c1cd 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -569,7 +569,7 @@ static void kill_traffic(struct usb_serial_port *port) usb_kill_urb(port-interrupt_out_urb); } -static void port_release(struct device *dev) +static void usb_serial_port_release(struct device *dev) { struct usb_serial_port *port = to_usb_serial_port(dev); int i; @@ -892,7 +892,7 @@ static int usb_serial_probe(struct usb_interface *interface, port-dev.parent = interface-dev; port-dev.driver = NULL; port-dev.bus = usb_serial_bus_type; - port-dev.release = port_release; + port-dev.release = usb_serial_port_release; device_initialize(port-dev); } -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Newbie question: how the kernel determine usb device has been connected - handling some interrupt or pooling loop?
Hi, On Thu, Mar 21, 2013 at 03:43:16PM +0400, Dmitry Bolshakov wrote: Where could I read about it? and where is the code? I've found something looks like a pooling loop - drivers/usb/core/hub.c in the hub_events function is this it? the entry point is always an interrupt handler in one of the host controller drivers. grep for irqreturn_t under drivers/usb/host and you will find what you want. Hint: the interrupt handlers wakes up HUB kthread. -- balbi signature.asc Description: Digital signature