Re: [PATCH v4 4/4] phy: add phy-hi6220-usb
Hi Zhangfei, On 22/02/15 05:10, zhangfei wrote: > Hi, Balbi > > On 02/22/2015 12:21 AM, Felipe Balbi wrote: >> Hi, >> >> On Sat, Feb 21, 2015 at 11:03:05PM +0800, zhangfei wrote: >>> +static void hi6220_start_peripheral(struct hi6220_priv *priv, bool on) >>> +{ >>> +struct usb_otg *otg = priv->phy.otg; >>> + >>> +if (!otg->gadget) >>> +return; >>> + >>> +if (on) >>> +usb_gadget_connect(otg->gadget); >>> +else >>> +usb_gadget_disconnect(otg->gadget); >> >> why is the PHY fiddling with pullups ? > > We use this to enable/disable otg gadget mode. I got that, but the pullups don't belong to the PHY, they belong to the gadget. > The gpio_id & gpio_vbus are used to distinguish otg gadget mode or > host mode. > When micro usb or otg device attached to otg, gpio_vbus falling down. > And gpio_id = 1 is micro usb, gpio_id = 0 is otg device. all of that I understood clearly :-) > So when micro usb attached, we enable gadget mode; while micro usb > detached, we disable gadget mode, and dwc2 will automatically set to > host mode. that's all fine, I'm concerned about letting the PHY fiddle with something it doesn't own. If I am to change pullups rules in udc-core, this is likely to break down miserably and I don't want to have to go through that. >>> >>> Thanks for the clarifying. >> >> no problem. >> >>> How about using usb_gadget_vbus_connect/disconnect, which are used in many >>> files under drivers/usb/phy. >>> There is no vbus_session in dwc2/gadget.c, I thought it would be same as >>> pullup. >>> >>> However, usb_gadget_vbus_connect still need para gadget, where should we put >>> this file, drivers/usb/phy or drivers/phy >> >> drivers/phy, if the framework misses anything you need, it's a great >> opportunity to give back to the community by extending the framework. > > Sorry, I am a little confused. > I need some concrete suggestion for the next step of this patch, which is > required for the community board, hikey board. > > Do you mean in the future we need use hsotg->phy instead of hsotg->uphy. > struct phy *phy; > struct usb_phy *uphy; > usb_phy has many members that struct phy does not have, including otg. > struct usb_otg *otg; > Is that mean we need port such member from usb_phy to phy. In my opinion otg structure should belong to the USB core part that takes care of the OTG/DRD state machine. We still don't have a clear solution here and I'm currently investigating this. My current work is to get Dual role functionality working with DWC3 controller and TI platforms. Currently phy drivers take care of OTG operation themselves but there is an opportunity to share code and centralize USB role switching. The USB core should be the owner of the Host controller, Gadget controller and the OTG phy and should take care of the that. > > Besides, are you ok with using usb_gadget_vbus_connect/disconnect. I don't think PHY is the right place for this even though older drivers seem to be doing so. But at the same time there is nowhere else to add this at the moment. The right place should be the USB core that is aware of host/gadget, phy and the state of the bus. > >> >> Scratching one's own itch kinda thing... >> >>> +static void hi6220_detect_work(struct work_struct *work) >>> +{ >>> +struct hi6220_priv *priv = >>> +container_of(work, struct hi6220_priv, work.work); >>> +int gpio_id, gpio_vbus; >>> +enum usb_otg_state state; >>> + >>> +if (!gpio_is_valid(priv->gpio_id) || >>> !gpio_is_valid(priv->gpio_vbus)) >>> +return; >>> + >>> +gpio_id = gpio_get_value_cansleep(priv->gpio_id); >>> +gpio_vbus = gpio_get_value_cansleep(priv->gpio_vbus); >> >> looks like this should be using extcon > Not used extcon before. > However, we need gpio_vbus interrupt. > Checked phy-tahvo.c and phy-omap-otg.c, not find extcon related with > interrupt. > Will investigate tomorrow. drivers/extcon/extcon-gpio.c >>> I think there is no need to use extcon, gpio is clear enough. >>> extcon-gpio.c even do not support dt. >> >> well, add DT. The whole idea of free software is that we improve on >> things we already have. EXTCON is *the* API to handle such things. > I wrote the extcon-gpio-usb.c driver for exactly your use case. It is queued for v4.1 https://lkml.org/lkml/2015/2/2/187 It takes care of debouncing for you. Although currently it supports only ID gpio, it should be very easy to extend to VBUS sense GPIO. > I think I am still not understanding extcon-gpio, not sure why need use this > API here. several reasons. Let me list a few. 1) Code reuse. Every PHY driver doesn't need to implement GPIO/interrupt handling and debouncing. It just registers what cable events it wants to
[PATCH V7 11/11] USB: f81232: modify/add author
Add me to co-author and fix no '>' in greg kh's email Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index ee9a2a2..23f0a17 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -691,5 +691,6 @@ static struct usb_serial_driver * const serial_drivers[] = { module_usb_serial_driver(serial_drivers, id_table); MODULE_DESCRIPTION("Fintek F81232 USB to serial adaptor driver"); -MODULE_AUTHOR("Greg Kroah-Hartman "); +MODULE_AUTHOR("Peter Hong "); MODULE_LICENSE("GPL v2"); -- 1.9.1 -- 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 V7 09/11] USB: f81232: clarify f81232_ioctl() and fix
We extract TIOCGSERIAL section in f81232_ioctl() to f81232_get_serial_info() to make it clarify. Also we fix device type from 16654 to 16550A, and set it's baud_base to 115200 (1.8432MHz/16). Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 0c96b9a..3b0da70 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -603,24 +603,32 @@ static int f81232_carrier_raised(struct usb_serial_port *port) return 0; } +static int f81232_get_serial_info(struct usb_serial_port *port, + unsigned long arg) +{ + struct serial_struct ser; + + memset(&ser, 0, sizeof(ser)); + + ser.type = PORT_16550A; + ser.line = port->minor; + ser.port = port->port_number; + ser.baud_base = 115200; + + if (copy_to_user((void __user *)arg, &ser, sizeof(ser))) + return -EFAULT; + + return 0; +} + static int f81232_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct serial_struct ser; struct usb_serial_port *port = tty->driver_data; switch (cmd) { case TIOCGSERIAL: - memset(&ser, 0, sizeof ser); - ser.type = PORT_16654; - ser.line = port->minor; - ser.port = port->port_number; - ser.baud_base = 460800; - - if (copy_to_user((void __user *)arg, &ser, sizeof ser)) - return -EFAULT; - - return 0; + return f81232_get_serial_info(port, arg); default: break; } -- 1.9.1 -- 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 V7 10/11] USB: f81232: cleanup non-used define
We remove non-used define in this patch to avoid wrong usage. Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 14 -- 1 file changed, 14 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 3b0da70..ee9a2a2 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -47,20 +47,6 @@ MODULE_DEVICE_TABLE(usb, id_table); #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) -#define CONTROL_DTR0x01 -#define CONTROL_RTS0x02 - -#define UART_STATE 0x08 -#define UART_STATE_TRANSIENT_MASK 0x74 -#define UART_DCD 0x01 -#define UART_DSR 0x02 -#define UART_BREAK_ERROR 0x04 -#define UART_RING 0x08 -#define UART_FRAME_ERROR 0x10 -#define UART_PARITY_ERROR 0x20 -#define UART_OVERRUN_ERROR 0x40 -#define UART_CTS 0x80 - struct f81232_private { struct mutex lock; u8 modem_control; -- 1.9.1 -- 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 V7 07/11] USB: f81232: implement port_enable function
We put FCR/IER initial step to f81232_port_enable(). When port is open, it set MSR interrupt on. Otherwise set it off. Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 39 +++ 1 file changed, 39 insertions(+) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 21f606f..f5c9060 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -37,6 +37,8 @@ MODULE_DEVICE_TABLE(usb, id_table); #define F81232_SET_REGISTER0x40 #define SERIAL_BASE_ADDRESS0x0120 +#define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS) +#define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS) #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) @@ -367,6 +369,33 @@ static void f81232_break_ctl(struct tty_struct *tty, int break_state) */ } +static int f81232_port_enable(struct usb_serial_port *port, int enable) +{ + u8 data = 0; + int status; + + /* fifo on, trigger8, clear TX/RX*/ + data = UART_FCR_TRIGGER_8 | UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR + | UART_FCR_CLEAR_XMIT; + + status = f81232_set_register(port, FIFO_CONTROL_REGISTER, data); + if (status) { + dev_err(&port->dev, "%s failed to set FCR: %d\n", __func__, status); + return status; + } + + /* MSR Interrupt only, LSR will read from Bulk-in odd byte */ + data = enable ? UART_IER_MSI : 0; + + status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, data); + if (status) { + dev_err(&port->dev, "%s failed to set IER: %d\n", __func__, status); + return status; + } + + return 0; +} + static void f81232_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { @@ -418,6 +447,12 @@ static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) { int result; + result = f81232_port_enable(port, 1); + if (result) { + dev_err(&port->dev, "%s - init fail: %d\n", __func__, result); + return result; + } + /* Setup termios */ if (tty) f81232_set_termios(tty, port, NULL); @@ -440,6 +475,10 @@ static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) static void f81232_close(struct usb_serial_port *port) { + int result = f81232_port_enable(port, 0); + if (result) + dev_err(&port->dev, "%s - init fail: %d\n", __func__, result); + usb_serial_generic_close(port); usb_kill_urb(port->interrupt_in_urb); } -- 1.9.1 -- 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 V7 08/11] USB: f81232: implement set_termios()
The original driver had do not any h/w change in driver. This patch implements with configure H/W for baud/parity/word length/stop bits functional in f81232_set_termios(). This patch also implement DTR/RTS control when baudrate B0. We drop DTR/RTS when B0, otherwise enable it. Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 106 ++-- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index f5c9060..0c96b9a 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -31,14 +31,19 @@ static const struct usb_device_id id_table[] = { }; MODULE_DEVICE_TABLE(usb, id_table); +/* Maximum baudrate for F81232 */ +#define F81232_MAX_BAUDRATE115200 + /* USB Control EP parameter */ #define F81232_REGISTER_REQUEST0xA0 #define F81232_GET_REGISTER0xc0 #define F81232_SET_REGISTER0x40 #define SERIAL_BASE_ADDRESS0x0120 +#define RECEIVE_BUFFER_REGISTER(0x00 + SERIAL_BASE_ADDRESS) #define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS) #define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS) +#define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS) #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) @@ -64,6 +69,14 @@ struct f81232_private { struct usb_serial_port *port; }; +static int calc_baud_divisor(u32 baudrate) +{ + if (!baudrate) + return 0; + else + return DIV_ROUND_CLOSEST(F81232_MAX_BAUDRATE, baudrate); +} + static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *data) { int status; @@ -369,6 +382,52 @@ static void f81232_break_ctl(struct tty_struct *tty, int break_state) */ } +static void f81232_set_baudrate(struct usb_serial_port *port, int baudrate) +{ + u8 divisor, lcr; + int status = 0; + + if (!baudrate) + return; + + divisor = calc_baud_divisor(baudrate); + + status = f81232_get_register(port, LINE_CONTROL_REGISTER, +&lcr); /* get LCR */ + if (status) { + dev_err(&port->dev, "%s failed to get LCR: %d\n", + __func__, status); + } + + status = f81232_set_register(port, LINE_CONTROL_REGISTER, +lcr | UART_LCR_DLAB); /* Enable DLAB */ + if (status) { + dev_err(&port->dev, "%s failed to set DLAB: %d\n", + __func__, status); + } + + status = f81232_set_register(port, RECEIVE_BUFFER_REGISTER, +divisor & 0x00ff); /* low */ + if (status) { + dev_err(&port->dev, "%s failed to set baudrate MSB: %d\n", + __func__, status); + } + + status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, +(divisor & 0xff00) >> 8); /* high */ + if (status) { + dev_err(&port->dev, "%s failed to set baudrate LSB: %d\n", + __func__, status); + } + + status = f81232_set_register(port, LINE_CONTROL_REGISTER, + lcr & ~UART_LCR_DLAB); + if (status) { + dev_err(&port->dev, "%s failed to set DLAB: %d\n", + __func__, status); + } +} + static int f81232_port_enable(struct usb_serial_port *port, int enable) { u8 data = 0; @@ -399,15 +458,54 @@ static int f81232_port_enable(struct usb_serial_port *port, int enable) static void f81232_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { - /* FIXME - Stubbed out for now */ + u8 new_lcr = 0; + int status = 0; + /* Don't change anything if nothing has changed */ if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) return; - /* Do the real work here... */ - if (old_termios) - tty_termios_copy_hw(&tty->termios, old_termios); + if (C_BAUD(tty) == B0) + f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS); + else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) + f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0); + + f81232_set_baudrate(port, tty_get_baud_rate(tty)); + + if (C_PARENB(tty)) { + new_lcr |= UART_LCR_PARITY; + + if (!C_PARODD(tty)) + new_lcr |= UART_LCR_EPAR; + + if (C_CMSPAR(tty)) + new_lcr |= UART_LCR_SPAR; + } + + if (C_CSTOPB(tty)) + new_lcr |= UART_LCR_STOP; + + switch (C_CSIZE(tty)) { + case CS5: + new_lcr |= UART_LCR_WLEN5; + break; + case CS6: + new_lcr |= UART_LCR_WLEN6; + break; + case CS7:
[PATCH V7 05/11] USB: f81232: implement read IIR/MSR with endpoint
The interrupt endpoint will report current IIR. If we got IIR with MSR changed , We will do read MSR with interrupt_work worker to do f81232_read_msr() function. We also confirmd MSR strange delta value is not locking-issue. The issue is set MCR & get MSR before IIR notice with MSR changed (Loopback only). When we use RS232 loopback, assume doing RTS change will cause CTS change, DTR change will cause DCD/DSR change too. Sometimes we got 7~4 bits of MSR changed but the 3~0 bits of MSR(delta) maybe not changed when set & get MCR rapidly. So we add more check not only UART_MSR_ANY_DELTA but also with comparing DCD/RI/DSR/CTS change with old value. Because of the state bit is always correct, we direct save msr when read. The following step to reproduce this problem with while loop step 1~4: 1. ioctl(fd, TIOCMSET, &data) to set RTS or DTR 2. ioctl(fd, TIOCMGET, &data) to read CTS or DCD/DSR state 3. ioctl(fd, TIOCMSET, &data) to unset RTS or DTR 4. ioctl(fd, TIOCMGET, &data) to read CTS or DCD/DSR state Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 106 1 file changed, 98 insertions(+), 8 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index bf072fe..339be30 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -36,6 +36,9 @@ MODULE_DEVICE_TABLE(usb, id_table); #define F81232_GET_REGISTER0xc0 #define F81232_SET_REGISTER0x40 +#define SERIAL_BASE_ADDRESS0x0120 +#define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) + #define CONTROL_DTR0x01 #define CONTROL_RTS0x02 @@ -54,6 +57,8 @@ struct f81232_private { struct mutex lock; u8 line_control; u8 modem_status; + struct work_struct interrupt_work; + struct usb_serial_port *port; }; static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *data) @@ -130,17 +135,92 @@ static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 data) kfree(tmp); return status; } + +static void f81232_read_msr(struct usb_serial_port *port) +{ + int status; + u8 current_msr, prev_msr; + u8 msr_mask = ~UART_MSR_ANY_DELTA; + u8 msr_changed_bit; + struct tty_struct *tty; + struct f81232_private *priv = usb_get_serial_port_data(port); + + status = f81232_get_register(port, MODEM_STATUS_REGISTER, + ¤t_msr); + if (status) { + dev_err(&port->dev, "%s fail, status: %d\n", __func__, status); + return; + } + + /* + * The 7~4 bits of MSR will change but the 3~0 bits of MSR(delta) + * maybe not change when set MCR & get MSR rapidly. + * + * So we add more check with comparing DCD/RI/DSR/CTS + * change. and direct save msr when read. + */ + + mutex_lock(&priv->lock); + prev_msr = priv->modem_status; + priv->modem_status = current_msr; + mutex_unlock(&priv->lock); + + if (!(current_msr & UART_MSR_ANY_DELTA) && + !((prev_msr ^ current_msr) & msr_mask)) + return; + + /* find checked delta bits set */ + msr_changed_bit = + (current_msr & UART_MSR_ANY_DELTA) << 4; + + /* append with not delta but changed bits */ + msr_changed_bit |= (prev_msr ^ current_msr) & msr_mask; + + if (msr_changed_bit & UART_MSR_CTS) + port->icount.cts++; + if (msr_changed_bit & UART_MSR_DSR) + port->icount.dsr++; + if (msr_changed_bit & UART_MSR_RI) + port->icount.rng++; + if (msr_changed_bit & UART_MSR_DCD) { + + port->icount.dcd++; + tty = tty_port_tty_get(&port->port); + if (tty) { + + usb_serial_handle_dcd_change(port, tty, + current_msr & UART_MSR_DCD); + + tty_kref_put(tty); + } + } + + wake_up_interruptible(&port->port.delta_msr_wait); +} + static void f81232_update_line_status(struct usb_serial_port *port, unsigned char *data, - unsigned int actual_length) + size_t actual_length) { - /* -* FIXME: Update port->icount, and call -* -* wake_up_interruptible(&port->port.delta_msr_wait); -* -*on MSR changes. -*/ + struct f81232_private *priv = usb_get_serial_port_data(port); + + if (!actual_length) + return; + + switch (data[0] & 0x07) { + case 0x00: /* msr change */ + dev_dbg(&port->dev, "IIR: MSR Change: %02x\n", data[0]); + schedule_work(&priv->interrupt_work); + break; + case 0x02: /* tx-empty */ + break; + c
[PATCH V7 01/11] USB: f81232: rename private struct member name
Change private struct member name from line_status to modem_status. It will store MSR for some functions used Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index c5dc233..669a2f2 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -47,7 +47,7 @@ MODULE_DEVICE_TABLE(usb, id_table); struct f81232_private { spinlock_t lock; u8 line_control; - u8 line_status; + u8 modem_status; }; static void f81232_update_line_status(struct usb_serial_port *port, @@ -113,8 +113,8 @@ static void f81232_process_read_urb(struct urb *urb) /* update line status */ spin_lock_irqsave(&priv->lock, flags); - line_status = priv->line_status; - priv->line_status &= ~UART_STATE_TRANSIENT_MASK; + line_status = priv->modem_status; + priv->modem_status &= ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(&priv->lock, flags); if (!urb->actual_length) @@ -241,7 +241,7 @@ static void f81232_dtr_rts(struct usb_serial_port *port, int on) static int f81232_carrier_raised(struct usb_serial_port *port) { struct f81232_private *priv = usb_get_serial_port_data(port); - if (priv->line_status & UART_DCD) + if (priv->modem_status & UART_DCD) return 1; return 0; } -- 1.9.1 -- 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 V7 02/11] USB: f81232: add preparatory functions
We add f81232_get_register()/f81232_set_register() and necessary defines for future patch with communication with F81232 USB control endpoint. Because of this is a preparatory patch, there are unused function warning with compiling. The functions will used with following patches. Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 79 + 1 file changed, 79 insertions(+) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 669a2f2..1f29b95 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -30,6 +30,11 @@ static const struct usb_device_id id_table[] = { }; MODULE_DEVICE_TABLE(usb, id_table); +/* USB Control EP parameter */ +#define F81232_REGISTER_REQUEST0xA0 +#define F81232_GET_REGISTER0xc0 +#define F81232_SET_REGISTER0x40 + #define CONTROL_DTR0x01 #define CONTROL_RTS0x02 @@ -50,6 +55,80 @@ struct f81232_private { u8 modem_status; }; +static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *data) +{ + int status; + u8 *tmp; + struct usb_device *dev = port->serial->dev; + + if (!data) + return -EFAULT; + + tmp = kmalloc(sizeof(u8), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + status = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + F81232_REGISTER_REQUEST, + F81232_GET_REGISTER, + reg, + 0, + tmp, + sizeof(u8), + USB_CTRL_GET_TIMEOUT); + if (status <= 0) { + /* show something with failed */ + dev_err(&port->dev, "%s failed status: %d\n", __func__, status); + + if (status == 0) + status = -EIO; + else + status = usb_translate_errors(status); + } else { + status = 0; /* on success */ + memcpy((void*) data, (void*) tmp, sizeof(u8)); + } + + kfree(tmp); + return status; +} + +static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 data) +{ + int status; + u8 *tmp; + struct usb_device *dev = port->serial->dev; + + tmp = kmalloc(sizeof(u8), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + memcpy((void*) tmp, (void*) &data, sizeof(u8)); + + status = usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + F81232_REGISTER_REQUEST, + F81232_SET_REGISTER, + reg, + 0, + tmp, + sizeof(u8), + USB_CTRL_SET_TIMEOUT); + if (status <= 0) { + /* show something with failed */ + dev_err(&port->dev, "%s failed status: %d\n", __func__, status); + + if (status == 0) + status = -EIO; + else + status = usb_translate_errors(status); + } else + status = 0; /* on success */ + + kfree(tmp); + return status; +} static void f81232_update_line_status(struct usb_serial_port *port, unsigned char *data, unsigned int actual_length) -- 1.9.1 -- 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 V7 03/11] USB: f81232: implement RX bulk-in EP
The F81232 bulk-in is RX data + LSR channel, data format is [LSR+Data][LSR+Data]. , We had implemented in f81232_process_read_urb(). Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 69 +++-- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 1f29b95..419e2d6 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -23,6 +23,7 @@ #include #include #include +#include static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1934, 0x0706) }, @@ -183,44 +184,46 @@ exit: static void f81232_process_read_urb(struct urb *urb) { struct usb_serial_port *port = urb->context; - struct f81232_private *priv = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; - char tty_flag = TTY_NORMAL; - unsigned long flags; - u8 line_status; + char tty_flag; int i; + u8 lsr; - /* update line status */ - spin_lock_irqsave(&priv->lock, flags); - line_status = priv->modem_status; - priv->modem_status &= ~UART_STATE_TRANSIENT_MASK; - spin_unlock_irqrestore(&priv->lock, flags); - - if (!urb->actual_length) + if (urb->actual_length < 2) return; - /* break takes precedence over parity, */ - /* which takes precedence over framing errors */ - if (line_status & UART_BREAK_ERROR) - tty_flag = TTY_BREAK; - else if (line_status & UART_PARITY_ERROR) - tty_flag = TTY_PARITY; - else if (line_status & UART_FRAME_ERROR) - tty_flag = TTY_FRAME; - dev_dbg(&port->dev, "%s - tty_flag = %d\n", __func__, tty_flag); - - /* overrun is special, not associated with a char */ - if (line_status & UART_OVERRUN_ERROR) - tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); - - if (port->port.console && port->sysrq) { - for (i = 0; i < urb->actual_length; ++i) - if (!usb_serial_handle_sysrq_char(port, data[i])) - tty_insert_flip_char(&port->port, data[i], - tty_flag); - } else { - tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, - urb->actual_length); + /* bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]... */ + + for (i = 0; i < urb->actual_length; i += 2) { + tty_flag = TTY_NORMAL; + lsr = data[i + 0]; + + if (lsr & UART_LSR_BRK_ERROR_BITS) { + if (lsr & UART_LSR_BI) { + tty_flag = TTY_BREAK; + port->icount.brk++; + usb_serial_handle_break(port); + } else if (lsr & UART_LSR_PE) { + tty_flag = TTY_PARITY; + port->icount.parity++; + } else if (lsr & UART_LSR_FE) { + tty_flag = TTY_FRAME; + port->icount.frame++; + } + + if (lsr & UART_LSR_OE) { + port->icount.overrun++; + tty_insert_flip_char(&port->port, 0, + TTY_OVERRUN); + } + } + + if (port->port.console && port->sysrq) { + if (usb_serial_handle_sysrq_char(port, data[i + 1])) + continue; + } + + tty_insert_flip_char(&port->port, data[i + 1], tty_flag); } tty_flip_buffer_push(&port->port); -- 1.9.1 -- 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 V7 04/11] USB: f81232: change lock mechanism
The original driver lock with spin_lock_irqsave()/spin_unlock_irqrestore() because of it's maybe used in interrupt context f81232_process_read_urb(). We had remove it from previous patch "implement RX bulk-in EP", so we can change it from busying loop spin_lock to sleepable mutex_lock. Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 419e2d6..bf072fe 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -51,7 +51,7 @@ MODULE_DEVICE_TABLE(usb, id_table); #define UART_CTS 0x80 struct f81232_private { - spinlock_t lock; + struct mutex lock; u8 line_control; u8 modem_status; }; @@ -306,17 +306,16 @@ static void f81232_close(struct usb_serial_port *port) static void f81232_dtr_rts(struct usb_serial_port *port, int on) { struct f81232_private *priv = usb_get_serial_port_data(port); - unsigned long flags; u8 control; - spin_lock_irqsave(&priv->lock, flags); + mutex_lock(&priv->lock); /* Change DTR and RTS */ if (on) priv->line_control |= (CONTROL_DTR | CONTROL_RTS); else priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); + mutex_unlock(&priv->lock); set_control_lines(port->serial->dev, control); } @@ -360,7 +359,7 @@ static int f81232_port_probe(struct usb_serial_port *port) if (!priv) return -ENOMEM; - spin_lock_init(&priv->lock); + mutex_init(&priv->lock); usb_set_serial_port_data(port, priv); -- 1.9.1 -- 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 V7 06/11] USB: f81232: implement MCR/MSR function
This patch implement relative MCR/MSR function, such like tiocmget()/tiocmset()/dtr_rts()/carrier_raised() original f81232_carrier_raised() compared with wrong value UART_DCD. It's should compared with UART_MSR_DCD. Signed-off-by: Peter Hung --- drivers/usb/serial/f81232.c | 103 ++-- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 339be30..21f606f 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -37,6 +37,7 @@ MODULE_DEVICE_TABLE(usb, id_table); #define F81232_SET_REGISTER0x40 #define SERIAL_BASE_ADDRESS0x0120 +#define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) #define CONTROL_DTR0x01 @@ -55,7 +56,7 @@ MODULE_DEVICE_TABLE(usb, id_table); struct f81232_private { struct mutex lock; - u8 line_control; + u8 modem_control; u8 modem_status; struct work_struct interrupt_work; struct usb_serial_port *port; @@ -198,6 +199,52 @@ static void f81232_read_msr(struct usb_serial_port *port) wake_up_interruptible(&port->port.delta_msr_wait); } +static int f81232_set_mctrl(struct usb_serial_port *port, + unsigned int set, unsigned int clear) +{ + u8 urb_value; + int status; + struct f81232_private *priv = usb_get_serial_port_data(port); + + if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) + return 0; /* no change */ + + /* 'set' takes precedence over 'clear' */ + clear &= ~set; + + /* force enable interrupt with OUT2 */ + mutex_lock(&priv->lock); + urb_value = UART_MCR_OUT2 | priv->modem_control; + mutex_unlock(&priv->lock); + + if (clear & TIOCM_DTR) + urb_value &= ~UART_MCR_DTR; + + if (clear & TIOCM_RTS) + urb_value &= ~UART_MCR_RTS; + + if (set & TIOCM_DTR) + urb_value |= UART_MCR_DTR; + + if (set & TIOCM_RTS) + urb_value |= UART_MCR_RTS; + + dev_dbg(&port->dev, "%s new:%02x old:%02x\n", __func__, + urb_value, priv->modem_control); + + status = f81232_set_register(port, MODEM_CONTROL_REGISTER, urb_value); + if (status) { + dev_err(&port->dev, "%s set MCR status < 0\n", __func__); + return status; + } else { + mutex_lock(&priv->lock); + priv->modem_control = urb_value; + mutex_unlock(&priv->lock); + } + + return 0; +} + static void f81232_update_line_status(struct usb_serial_port *port, unsigned char *data, size_t actual_length) @@ -309,12 +356,6 @@ static void f81232_process_read_urb(struct urb *urb) tty_flip_buffer_push(&port->port); } -static int set_control_lines(struct usb_device *dev, u8 value) -{ - /* FIXME - Stubbed out for now */ - return 0; -} - static void f81232_break_ctl(struct tty_struct *tty, int break_state) { /* FIXME - Stubbed out for now */ @@ -342,15 +383,35 @@ static void f81232_set_termios(struct tty_struct *tty, static int f81232_tiocmget(struct tty_struct *tty) { - /* FIXME - Stubbed out for now */ - return 0; + int r; + struct usb_serial_port *port = tty->driver_data; + struct f81232_private *port_priv = usb_get_serial_port_data(port); + u8 mcr, msr; + + /* force get current MSR changed state */ + f81232_read_msr(port); + + mutex_lock(&port_priv->lock); + mcr = port_priv->modem_control; + msr = port_priv->modem_status; + mutex_unlock(&port_priv->lock); + + r = (mcr & UART_MCR_DTR ? TIOCM_DTR : 0) | + (mcr & UART_MCR_RTS ? TIOCM_RTS : 0) | + (msr & UART_MSR_CTS ? TIOCM_CTS : 0) | + (msr & UART_MSR_DCD ? TIOCM_CAR : 0) | + (msr & UART_MSR_RI ? TIOCM_RI : 0) | + (msr & UART_MSR_DSR ? TIOCM_DSR : 0); + + return r; } static int f81232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { - /* FIXME - Stubbed out for now */ - return 0; + struct usb_serial_port *port = tty->driver_data; + + return f81232_set_mctrl(port, set, clear); } static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -385,24 +446,22 @@ static void f81232_close(struct usb_serial_port *port) static void f81232_dtr_rts(struct usb_serial_port *port, int on) { - struct f81232_private *priv = usb_get_serial_port_data(port); - u8 control; - - mutex_lock(&priv->lock); - /* Change DTR and RTS */ if (on) - priv->line_control |= (CONTROL_DTR | CONTROL_RTS); + f81232_set_mctrl(port
[PATCH V7 00/11] USB: f81232: V7 patches
This series patch V7 is changed from V6 as following: 1. The buffer of usb_control_msg() in set_register()/get_register() are change from local variable to kmalloc(). (PATCH V7 02/11) 2. Change all set_register()/get_register() return value 0 is success, otherwise are failed. ( return 0 of usb_control_msg() treat as -EIO, PATCH V7 02/11) 3. tty_port_tty_get() called only when DCD has changed. (PATCH V7 05/11) 4. remove likely()/unlikely() branch prediction. 5. Implement DTR/RTS control when baudrate B0. We drop DTR/RTS when B0, otherwise enable it. (PATCH V7 08/11) 6. Change private struct line_control to modem_control with meanful. (PATCH V7 06/11) 7. We confirmd MSR strange delta value is not locking-issue. The issue maybe reproduce with set MCR & get MSR before IIR notice with MSR changed. V6 (old change): 1. transform all function not to use private data as parameter, using usb_serial_port instead. 2. process_read_urb() add process of Break/FrameError/ParityError/OE. (patch: 03/10) 3. fix calc_baud_divisor() will cause divide by zero with B0. (patch: 04/10) 4. Some init step we extract it from set_termios() to f81232_port_init() and run it when open port only. (patch: 04/10) 5. We'll force re-read msr in tiocmget() because the IIR with MSR change maybe delay received. (patch: 05/10) 6. fix MSR status bits changed but delta bits is 0 will cause read serial port malfunctional with update port status. (patch: 08/10) 7. Add MSR change statistic when MSR has been read. (patch: 09/10) 8. clarify a lot of code about Johan suggested. Peter Hung (11): USB: f81232: rename private struct member name USB: f81232: add preparatory functions USB: f81232: implement RX bulk-in EP USB: f81232: change lock mechanism USB: f81232: implement read IIR/MSR with endpoint USB: f81232: implement MCR/MSR function USB: f81232: implement port_enable function USB: f81232: implement set_termios() USB: f81232: clarify f81232_ioctl() and fix USB: f81232: cleanup non-used define USB: f81232: modify/add author drivers/usb/serial/f81232.c | 554 1 file changed, 458 insertions(+), 96 deletions(-) -- 1.9.1 -- 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: MUSB dual-role on AM335x behaving weirdly
On Thu, Feb 05, 2015 at 02:21:42PM +0100, Maxime Ripard wrote: > Hi, > > On Thu, Jan 22, 2015 at 08:37:45AM +0100, Yegor Yefremov wrote: > > I have the same experience with 3.15. The switching is working when > > CONFIG_USB_MUSB_DUAL_ROLE is set and dr_mode = "otg". But since 3.16 > > it seems to be broken. Still had no time to bisect this. > > I've been giving a few versions (from v3.15 to Tuesday's linux-next) a > try, and I always see the same behaviour now: > > - Booting as a gadget (ie, with a USB cable plugged in), and > swapping the cable for a (real, this time) USB OTG cable with a > USB key never works. When the device is plugged, all I get is > > [ 262.944846] usb 1-1: new high-speed USB device number 2 using musb-hdrc > [ 278.064748] usb 1-1: device descriptor read/64, error -110 > > Putting in back in gadget results with a load of continuous: > [ 315.258839] musb_bus_suspend 2484: trying to suspend as a_wait_vfall while > active > > - Booting as a host, or with nothing connected to it actually work, > up to a few plug-a-device-then-plug-a-host cycles, where you end > up with the following logs when disconnecting the device (somehow, > it always happens when it is set in host mode). > > [ 12.969075] CAUTION: musb: Babble Interrupt Occurred > [ 12.974445] CAUTION: musb: Babble Interrupt Occurred > [ 12.979637] musb_stage0_irq 789: unhandled DISCONNECT transition > (a_wait_bcon) > [ 12.988498] usb 1-1: USB disconnect, device number 2 > [ 13.071849] musb-hdrc musb-hdrc.0.auto: Restarting MUSB to recover from > Babble > > Plugging back our USB cable, with the AM335x acting as a device > work once. Then, when it switches to the host mode, we end up with > the same scenario than in the coldplug as gadget case: USB read > error, before then having all the a_wait_vfall messages. Guys, any ideas/hints? Thanks, Maxime -- Maxime Ripard, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com signature.asc Description: Digital signature
Re: XHCI, "brain-dead scanner", and microframe rounding
On Donnerstag, 19. Februar 2015 16:07:41 Mathias Nyman wrote: > On 18.02.2015 14:27, Hans-Peter Jansen wrote: > > Mathias Nyman writes: > >> On 27.01.2015 13:57, Hans-Peter Jansen wrote: > >>> What about a stable backport? Do you think, it's feasible, too much > >>> work, or too risky? > >> > >> This should definitely be backported to 3.18 stable, which should be > >> easy. > >> Older longterms kernels are a bit tricky as the halt and reset code > >> around > > > > this was > > > >> heavily modified in 3.18 > > > > Will this be included in 3.20? > > I'll send it once 3.20-rc1 is out. > > So yes, it should be in the final 3.20 Mathias, you need to adjust your filter to <4.0>, and I cannot see anything related moving onwards. Also 3.19-stable is still dangling.. Those people, that are bitten by this, still suffer big times. Cheers, Pete -- 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 v4] xhci: fix reporting of 0-sized URBs in control endpoint
When a control transfer has a short data stage, the xHCI controller generates two transfer events: a COMP_SHORT_TX event that specifies the untransferred amount, and a COMP_SUCCESS event. But when the data stage is not short, only the COMP_SUCCESS event occurs. Therefore, xhci-hcd must set urb->actual_length to urb->transfer_buffer_length while processing the COMP_SUCCESS event, unless urb->actual_length was set already by a previous COMP_SHORT_TX event. The driver checks this by seeing whether urb->actual_length == 0, but this alone is the wrong test, as it is entirely possible for a short transfer to have an urb->actual_length = 0. This patch changes the xhci driver to rely not only on the urb->actual_length, but also on a new td->urb_length_set flag, which is set to true when a COMP_SHORT_TX event is received and the URB length updated at that stage. This fixes a bug which affected the HSO plugin, which relies on URBs with urb->actual_length == 0 to halt re-submitting the RX URB in the control endpoint. Signed-off-by: Aleksander Morgado --- Hey Mathias, I have now updated the patch to avoid re-using the 'last_td_was_short' flag, and instead use a new 'urb_length_set' flag in the xhci_td struct. This new flag will be unique for each URB, and therefore the flag shouldn't affect other TDs that may come afterwards, as was the case when reusing the 'last_td_was_short' flag in 'ep_ring'. I was wondering whether the xhci_td struct is the best place to add this logic; maybe it isn't, given that this is control-transfer specific? Let me know what you think. Cheers! --- drivers/usb/host/xhci-ring.c | 9 +++-- drivers/usb/host/xhci.h | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 88da8d6..be9c560 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1955,12 +1955,17 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, /* Did we already see a short data * stage? */ *status = -EREMOTEIO; - } else { + } else if (!td->urb_length_set) { td->urb->actual_length = td->urb->transfer_buffer_length; } } else { - /* Maybe the event was for the data stage? */ + /* +* Maybe the event was for the data stage? If so, update already the +* actual_length of the URB and flag it as set, so that it is not +* overwritten in the event for the last TRB. +*/ + td->urb_length_set = true; td->urb->actual_length = td->urb->transfer_buffer_length - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9745147..bd868aa 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1,3 +1,4 @@ + /* * xHCI host controller driver * @@ -1288,6 +1289,8 @@ struct xhci_td { struct xhci_segment *start_seg; union xhci_trb *first_trb; union xhci_trb *last_trb; + /* actual_length of the URB has already been set */ + boolurb_length_set; }; /* xHCI command default timeout value */ -- 2.3.0 -- 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: MUSB dual-role on AM335x behaving weirdly
Hi, On Tue, Feb 24, 2015 at 11:39:11AM +0100, Maxime Ripard wrote: > On Thu, Feb 05, 2015 at 02:21:42PM +0100, Maxime Ripard wrote: > > Hi, > > > > On Thu, Jan 22, 2015 at 08:37:45AM +0100, Yegor Yefremov wrote: > > > I have the same experience with 3.15. The switching is working when > > > CONFIG_USB_MUSB_DUAL_ROLE is set and dr_mode = "otg". But since 3.16 > > > it seems to be broken. Still had no time to bisect this. > > > > I've been giving a few versions (from v3.15 to Tuesday's linux-next) a > > try, and I always see the same behaviour now: > > > > - Booting as a gadget (ie, with a USB cable plugged in), and > > swapping the cable for a (real, this time) USB OTG cable with a > > USB key never works. When the device is plugged, all I get is > > > > [ 262.944846] usb 1-1: new high-speed USB device number 2 using musb-hdrc > > [ 278.064748] usb 1-1: device descriptor read/64, error -110 > > > > Putting in back in gadget results with a load of continuous: > > [ 315.258839] musb_bus_suspend 2484: trying to suspend as a_wait_vfall > > while active > > > > - Booting as a host, or with nothing connected to it actually work, > > up to a few plug-a-device-then-plug-a-host cycles, where you end > > up with the following logs when disconnecting the device (somehow, > > it always happens when it is set in host mode). > > > > [ 12.969075] CAUTION: musb: Babble Interrupt Occurred > > [ 12.974445] CAUTION: musb: Babble Interrupt Occurred > > [ 12.979637] musb_stage0_irq 789: unhandled DISCONNECT transition > > (a_wait_bcon) > > [ 12.988498] usb 1-1: USB disconnect, device number 2 > > [ 13.071849] musb-hdrc musb-hdrc.0.auto: Restarting MUSB to recover from > > Babble > > > > Plugging back our USB cable, with the AM335x acting as a device > > work once. Then, when it switches to the host mode, we end up with > > the same scenario than in the coldplug as gadget case: USB read > > error, before then having all the a_wait_vfall messages. > > Guys, any ideas/hints? which platform are you using ? I guess the only way to move here would be to bisect between 3.15 and 3.16 to find the offending commit. cheers -- balbi signature.asc Description: Digital signature
Re: [PATCH 00/29] Equivalent of g_printer with configfs
On Tue, Feb 24, 2015 at 08:15:48AM +0100, Andrzej Pietrasiewicz wrote: > W dniu 23.02.2015 o 16:01, Andrzej Pietrasiewicz pisze: > >This series aims at integrating configfs into hid, the way > > Of course I meant printer. Sorry about confusion. no problem :-) -- balbi signature.asc Description: Digital signature
[PATCH] usb: storage: Fix trivial typo in isd200_log_config()
Change 'Supsend' to 'Suspend' Signed-off-by: Yannick Guerrini --- drivers/usb/storage/isd200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 599d8bf..0761786 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -737,7 +737,7 @@ static void isd200_log_config(struct us_data *us, struct isd200_info *info) info->ConfigData.ATAExtraConfig & ATACFGE_CONF_DESC2); usb_stor_dbg(us, " Skip Device Boot: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_SKIP_BOOT); - usb_stor_dbg(us, " ATA 3 State Supsend: 0x%x\n", + usb_stor_dbg(us, " ATA 3 State Suspend: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_STATE_SUSPEND); usb_stor_dbg(us, " Descriptor Override: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_DESC_OVERRIDE); -- 1.9.5.msysgit.0 -- 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 2/3] xhci: Allocate correct amount of scratchpad buffers
Include the high order bit fields for Max scratchpad buffers when calculating how many scratchpad buffers are needed. I'm suprised this hasn't caused more issues, we never allocated more than 32 buffers even if xhci needed more. Either we got lucky and xhci never really used past that area, or then we got enough zeroed dma memory anyway. Should be backported as far back as possible Signed-off-by: Mathias Nyman Cc: --- drivers/usb/host/xhci.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9745147..68956b1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -88,9 +88,10 @@ struct xhci_cap_regs { #define HCS_IST(p) (((p) >> 0) & 0xf) /* bits 4:7, max number of Event Ring segments */ #define HCS_ERST_MAX(p)(((p) >> 4) & 0xf) +/* bits 21:25 Hi 5 bits of Scratchpad buffers SW must allocate for the HW */ /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ -/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ -#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f) +/* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */ +#define HCS_MAX_SCRATCHPAD(p) p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f)) /* HCSPARAMS3 - hcs_params3 - bitmasks */ /* bits 0:7, Max U1 to U0 latency for the roothub ports */ -- 1.8.3.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
[PATCH 1/3] usb: XHCI: platform: Move the Marvell quirks after the enabling the clocks
From: Maxime Ripard The commit 973747928514 ("usb: host: xhci-plat: add support for the Armada 375/38x XHCI controllers") extended the xhci-plat driver to support the Armada 375/38x SoCs, mostly by adding a quirk configuring the MBUS window. However, that quirk was run before the clock the controllers needs has been enabled. This usually worked because the clock was first enabled by the bootloader, and left as such until the driver is probe, where it tries to access the MBUS configuration registers before enabling the clock. Things get messy when EPROBE_DEFER is involved during the probe, since as part of its error path, the driver will rightfully disable the clock. When the driver will be reprobed, it will retry to access the MBUS registers, but this time with the clock disabled, which hangs forever. Fix this by running the quirks after the clock has been enabled by the driver. Signed-off-by: Maxime Ripard Cc: # v3.16+ Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-plat.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 08d402b..0e11d61 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -83,16 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; - - if (of_device_is_compatible(pdev->dev.of_node, - "marvell,armada-375-xhci") || - of_device_is_compatible(pdev->dev.of_node, - "marvell,armada-380-xhci")) { - ret = xhci_mvebu_mbus_init_quirk(pdev); - if (ret) - return ret; - } - /* Initialize dma_mask and coherent_dma_mask to 32-bits */ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) @@ -127,6 +117,15 @@ static int xhci_plat_probe(struct platform_device *pdev) goto put_hcd; } + if (of_device_is_compatible(pdev->dev.of_node, + "marvell,armada-375-xhci") || + of_device_is_compatible(pdev->dev.of_node, + "marvell,armada-380-xhci")) { + ret = xhci_mvebu_mbus_init_quirk(pdev); + if (ret) + goto disable_clk; + } + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto disable_clk; -- 1.8.3.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
Re: XHCI, "brain-dead scanner", and microframe rounding
On 24.02.2015 12:41, Hans-Peter Jansen wrote: > On Donnerstag, 19. Februar 2015 16:07:41 Mathias Nyman wrote: >> On 18.02.2015 14:27, Hans-Peter Jansen wrote: >>> Mathias Nyman writes: On 27.01.2015 13:57, Hans-Peter Jansen wrote: > What about a stable backport? Do you think, it's feasible, too much > work, or too risky? This should definitely be backported to 3.18 stable, which should be easy. Older longterms kernels are a bit tricky as the halt and reset code around >>> >>> this was >>> heavily modified in 3.18 >>> >>> Will this be included in 3.20? >> >> I'll send it once 3.20-rc1 is out. >> >> So yes, it should be in the final 3.20 > > Mathias, you need to adjust your filter to <4.0>, and I cannot see anything > related moving onwards. > > Also 3.19-stable is still dangling.. > Just sent it to Greg, with stable CC tags. -Mathias -- 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 3/3] xhci: Clear the host side toggle manually when endpoint is 'soft reset'
Main benefit of this is to get xhci connected USB scanners to work. Some devices use a clear endpoint halt request as a 'soft reset' even if the endpoint is not halted. This will clear the toggle and sequence on the device side. xHCI however refuses to reset a non-halted endpoint, so instead we need to issue a configure endpoint command on xHCI to clear its host side toggle and sequence, and get it in sync with the device side. Cc: # v3.18 Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 100 +++ drivers/usb/host/xhci.h | 2 + 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 88da8d6..b46b5b9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, if (!command) return; - ep->ep_state |= EP_HALTED; + ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED; ep->stopped_stream = stream_id; xhci_queue_reset_ep(xhci, command, slot_id, ep_index); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ec8ac16..b06d1a5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1338,6 +1338,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto exit; } + /* Reject urb if endpoint is in soft reset, queue must stay empty */ + if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_CONFIG_PENDING) { + xhci_warn(xhci, "Can't enqueue URB while ep is in soft reset\n"); + ret = -EINVAL; + } + if (usb_endpoint_xfer_isoc(&urb->ep->desc)) size = urb->number_of_packets; else @@ -2948,23 +2954,36 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, } } -/* Called when clearing halted device. The core should have sent the control +/* Called after clearing a halted device. USB core should have sent the control * message to clear the device halt condition. The host side of the halt should - * already be cleared with a reset endpoint command issued when the STALL tx - * event was received. - * - * Context: in_interrupt + * already be cleared with a reset endpoint command issued immediately when the + * STALL tx event was received. */ void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; + struct usb_device *udev; + struct xhci_virt_device *virt_dev; + struct xhci_virt_ep *virt_ep; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_command *command; + unsigned int ep_index, ep_state; + unsigned long flags; + u32 ep_flag; xhci = hcd_to_xhci(hcd); + udev = (struct usb_device *) ep->hcpriv; + if (!ep->hcpriv) + return; + virt_dev = xhci->devs[udev->slot_id]; + ep_index = xhci_get_endpoint_index(&ep->desc); + virt_ep = &virt_dev->eps[ep_index]; + ep_state = virt_ep->ep_state; /* -* We might need to implement the config ep cmd in xhci 4.8.1 note: +* Implement the config ep command in xhci 4.6.8 additional note: * The Reset Endpoint Command may only be issued to endpoints in the * Halted state. If software wishes reset the Data Toggle or Sequence * Number of an endpoint that isn't in the Halted state, then software @@ -2972,9 +2991,72 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, * for the target endpoint. that is in the Stopped state. */ - /* For now just print debug to follow the situation */ - xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n", -ep->desc.bEndpointAddress); + if (ep_state & SET_DEQ_PENDING || ep_state & EP_RECENTLY_HALTED) { + virt_ep->ep_state &= ~EP_RECENTLY_HALTED; + xhci_dbg(xhci, "ep recently halted, no toggle reset needed\n"); + return; + } + + /* Only interrupt and bulk ep's use Data toggle, USB2 spec 5.5.4-> */ + if (usb_endpoint_xfer_control(&ep->desc) || + usb_endpoint_xfer_isoc(&ep->desc)) + return; + + ep_flag = xhci_get_endpoint_flag(&ep->desc); + + if (ep_flag == SLOT_FLAG || ep_flag == EP0_FLAG) + return; + + command = xhci_alloc_command(xhci, true, true, GFP_NOWAIT); + if (!command) { + xhci_err(xhci, "Could not allocate xHCI command structure.\n"); + return; + } + + spin_lock_irqsave(&xhci->lock, flags); + + /* block ringing ep doorbell */ + virt_ep->ep_state |= EP_CONFIG_PENDING; + + /* +* Make sure endpoint ring is empty before resetting the toggle/seq. +* Driver is required to synchronously canc
[PATCH 0/3] xhci fixes for 4.0-rc2
Hi Greg Three xhci patches for usb-linus this time. Fixing issues like allocating the correct amount of DMA memory for xhci controller (not less like it sometimes did), fix Armada 375/38x XHCI support by making sure clocks are on before touching the xhci controller, and finally fixing an issue where where some devices, mainly scanners, use 'endpoint reset' requests to soft reset the device endpoint, ending up getting the host and device out of sync. The last 'endpoint reset' issue for scanners has been around for some time, but 3.18 had some major changes in endpoint reset code, so backporting it to older versions than 3.18 will be diffcult. -Mathias Mathias Nyman (2): xhci: Allocate correct amount of scratchpad buffers xhci: Clear the host side toggle manually when endpoint is 'soft reset' Maxime Ripard (1): usb: XHCI: platform: Move the Marvell quirks after the enabling the clocks drivers/usb/host/xhci-plat.c | 19 drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 100 +++ drivers/usb/host/xhci.h | 7 ++- 4 files changed, 106 insertions(+), 22 deletions(-) -- 1.8.3.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
Re: [PATCH 0/3] xhci fixes for 4.0-rc2
On 24.02.2015 17:48, Mathias Nyman wrote: > Hi Greg > > Three xhci patches for usb-linus this time. And I just noticed they are missing the proper Tested-by and other credits, Sorry about that. I'll resend -Mathias -- 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 v4.0-rc2
Hi Greg, Here's my first set of fixes for this -rc. Let me know if you need anything to be changed. cheers The following changes since commit c517d838eb7d07bbe9507871fab3931deccff539: Linux 4.0-rc1 (2015-02-22 18:21:14 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git tags/fixes-for-v4.0-rc2 for you to fetch changes up to a0456399fb07155637a2b597b91cc1c63bc25141: usb: gadget: configfs: don't NUL-terminate (sub)compatible ids (2015-02-23 09:37:27 -0600) usb: fixes for v4.0-rc2 Not that many fixes this time. They have all been tested on platforms I have around and also passed my randconfig builds. Here's a quick summary of the changes: Phonet function learned to not disable a disabled endpoint. musb received a pm_runtime_irq_safe() call to fix a bug when calling musb_pullup() (via usb_gadget_{connect,disconnect}()) with irqs disabled. musb also got a really old fix for throughput with isochronous endpoints by pushing URB completion to a tasklet (by means of HCD_BH flag). musb now can properly get its phys on musb-dsps platforms (am335x as of now). musb learned how to read boolean OF properties. Old bug on how to disable dwc3-omap's IRQs got fixed finally. A few sparse warnings here and there. Renesas got a linkage fix. Signed-off-by: Felipe Balbi Andrzej Pietrasiewicz (1): usb: gadget: configfs: don't NUL-terminate (sub)compatible ids Arnd Bergmann (1): usb: renesas: fix extcon dependency Felipe Balbi (2): usb: gadget: function: phonet: balance usb_ep_disable calls usb: musb: core: add pm_runtime_irq_safe() George Cherian (2): usb: musb: musb_host: Enable HCD_BH flag to handle urb return in bottom half usb: dwc3: dwc3-omap: Fix disable IRQ Lad, Prabhakar (6): usb: gadget: function: f_hid: fix sparse warning usb: gadget: function: f_uac2: fix sparse warnings usb: gadget: function: f_sourcesink: fix sparse warning usb: gadget: function: uvc: fix sparse warnings usb: gadget: gadgetfs: fix sparse warnings usb: gadget: function: uvc_v4l2.c: fix sparse warnings Nicholas Mc Guire (1): usb: isp1760: use msecs_to_jiffies for time conversion Tony Lindgren (2): usb: musb: Fix use for of_property_read_bool for disabled multipoint usb: musb: Fix getting a generic phy for musb_dsps drivers/usb/dwc3/dwc3-omap.c | 30 -- drivers/usb/gadget/configfs.c | 2 -- drivers/usb/gadget/function/f_hid.c| 2 +- drivers/usb/gadget/function/f_phonet.c | 5 - drivers/usb/gadget/function/f_sourcesink.c | 4 ++-- drivers/usb/gadget/function/f_uac2.c | 34 +++--- drivers/usb/gadget/function/uvc_v4l2.c | 1 + drivers/usb/gadget/function/uvc_video.c| 1 + drivers/usb/gadget/legacy/g_ffs.c | 6 -- drivers/usb/isp1760/isp1760-hcd.c | 6 +++--- drivers/usb/musb/musb_core.c | 10 + drivers/usb/musb/musb_dsps.c | 32 +--- drivers/usb/musb/musb_host.c | 2 +- drivers/usb/musb/omap2430.c| 7 -- drivers/usb/renesas_usbhs/Kconfig | 1 + 15 files changed, 103 insertions(+), 40 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
Re: [PATCH 0/3] xhci fixes for 4.0-rc2
On Tue, Feb 24, 2015 at 06:17:10PM +0200, Mathias Nyman wrote: > On 24.02.2015 17:48, Mathias Nyman wrote: > > Hi Greg > > > > Three xhci patches for usb-linus this time. > > And I just noticed they are missing the proper Tested-by and other credits, > Sorry about that. > > I'll resend Thanks, I'll drop these. greg k-h -- 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 1/3] usb: XHCI: platform: Move the Marvell quirks after the enabling the clocks
From: Maxime Ripard The commit 973747928514 ("usb: host: xhci-plat: add support for the Armada 375/38x XHCI controllers") extended the xhci-plat driver to support the Armada 375/38x SoCs, mostly by adding a quirk configuring the MBUS window. However, that quirk was run before the clock the controllers needs has been enabled. This usually worked because the clock was first enabled by the bootloader, and left as such until the driver is probe, where it tries to access the MBUS configuration registers before enabling the clock. Things get messy when EPROBE_DEFER is involved during the probe, since as part of its error path, the driver will rightfully disable the clock. When the driver will be reprobed, it will retry to access the MBUS registers, but this time with the clock disabled, which hangs forever. Fix this by running the quirks after the clock has been enabled by the driver. Signed-off-by: Maxime Ripard Cc: # v3.16+ Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-plat.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 08d402b..0e11d61 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -83,16 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; - - if (of_device_is_compatible(pdev->dev.of_node, - "marvell,armada-375-xhci") || - of_device_is_compatible(pdev->dev.of_node, - "marvell,armada-380-xhci")) { - ret = xhci_mvebu_mbus_init_quirk(pdev); - if (ret) - return ret; - } - /* Initialize dma_mask and coherent_dma_mask to 32-bits */ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) @@ -127,6 +117,15 @@ static int xhci_plat_probe(struct platform_device *pdev) goto put_hcd; } + if (of_device_is_compatible(pdev->dev.of_node, + "marvell,armada-375-xhci") || + of_device_is_compatible(pdev->dev.of_node, + "marvell,armada-380-xhci")) { + ret = xhci_mvebu_mbus_init_quirk(pdev); + if (ret) + goto disable_clk; + } + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto disable_clk; -- 1.8.3.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
[PATCH v2 2/3] xhci: Allocate correct amount of scratchpad buffers
Include the high order bit fields for Max scratchpad buffers when calculating how many scratchpad buffers are needed. I'm suprised this hasn't caused more issues, we never allocated more than 32 buffers even if xhci needed more. Either we got lucky and xhci never really used past that area, or then we got enough zeroed dma memory anyway. Should be backported as far back as possible Reported-by: Tim Chen Tested-by: Tim Chen Signed-off-by: Mathias Nyman Cc: --- drivers/usb/host/xhci.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9745147..68956b1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -88,9 +88,10 @@ struct xhci_cap_regs { #define HCS_IST(p) (((p) >> 0) & 0xf) /* bits 4:7, max number of Event Ring segments */ #define HCS_ERST_MAX(p)(((p) >> 4) & 0xf) +/* bits 21:25 Hi 5 bits of Scratchpad buffers SW must allocate for the HW */ /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ -/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ -#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f) +/* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */ +#define HCS_MAX_SCRATCHPAD(p) p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f)) /* HCSPARAMS3 - hcs_params3 - bitmasks */ /* bits 0:7, Max U1 to U0 latency for the roothub ports */ -- 1.8.3.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
[PATCH v2 3/3] xhci: Clear the host side toggle manually when endpoint is 'soft reset'
Main benefit of this is to get xhci connected USB scanners to work. Some devices use a clear endpoint halt request as a 'soft reset' even if the endpoint is not halted. This will clear the toggle and sequence on the device side. xHCI however refuses to reset a non-halted endpoint, so instead we need to issue a configure endpoint command on xHCI to clear its host side toggle and sequence, and get it in sync with the device side. Tested-by: Mike Mammarella Cc: # v3.18 Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 100 +++ drivers/usb/host/xhci.h | 2 + 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 88da8d6..b46b5b9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, if (!command) return; - ep->ep_state |= EP_HALTED; + ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED; ep->stopped_stream = stream_id; xhci_queue_reset_ep(xhci, command, slot_id, ep_index); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ec8ac16..b06d1a5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1338,6 +1338,12 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto exit; } + /* Reject urb if endpoint is in soft reset, queue must stay empty */ + if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_CONFIG_PENDING) { + xhci_warn(xhci, "Can't enqueue URB while ep is in soft reset\n"); + ret = -EINVAL; + } + if (usb_endpoint_xfer_isoc(&urb->ep->desc)) size = urb->number_of_packets; else @@ -2948,23 +2954,36 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, } } -/* Called when clearing halted device. The core should have sent the control +/* Called after clearing a halted device. USB core should have sent the control * message to clear the device halt condition. The host side of the halt should - * already be cleared with a reset endpoint command issued when the STALL tx - * event was received. - * - * Context: in_interrupt + * already be cleared with a reset endpoint command issued immediately when the + * STALL tx event was received. */ void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; + struct usb_device *udev; + struct xhci_virt_device *virt_dev; + struct xhci_virt_ep *virt_ep; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_command *command; + unsigned int ep_index, ep_state; + unsigned long flags; + u32 ep_flag; xhci = hcd_to_xhci(hcd); + udev = (struct usb_device *) ep->hcpriv; + if (!ep->hcpriv) + return; + virt_dev = xhci->devs[udev->slot_id]; + ep_index = xhci_get_endpoint_index(&ep->desc); + virt_ep = &virt_dev->eps[ep_index]; + ep_state = virt_ep->ep_state; /* -* We might need to implement the config ep cmd in xhci 4.8.1 note: +* Implement the config ep command in xhci 4.6.8 additional note: * The Reset Endpoint Command may only be issued to endpoints in the * Halted state. If software wishes reset the Data Toggle or Sequence * Number of an endpoint that isn't in the Halted state, then software @@ -2972,9 +2991,72 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, * for the target endpoint. that is in the Stopped state. */ - /* For now just print debug to follow the situation */ - xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n", -ep->desc.bEndpointAddress); + if (ep_state & SET_DEQ_PENDING || ep_state & EP_RECENTLY_HALTED) { + virt_ep->ep_state &= ~EP_RECENTLY_HALTED; + xhci_dbg(xhci, "ep recently halted, no toggle reset needed\n"); + return; + } + + /* Only interrupt and bulk ep's use Data toggle, USB2 spec 5.5.4-> */ + if (usb_endpoint_xfer_control(&ep->desc) || + usb_endpoint_xfer_isoc(&ep->desc)) + return; + + ep_flag = xhci_get_endpoint_flag(&ep->desc); + + if (ep_flag == SLOT_FLAG || ep_flag == EP0_FLAG) + return; + + command = xhci_alloc_command(xhci, true, true, GFP_NOWAIT); + if (!command) { + xhci_err(xhci, "Could not allocate xHCI command structure.\n"); + return; + } + + spin_lock_irqsave(&xhci->lock, flags); + + /* block ringing ep doorbell */ + virt_ep->ep_state |= EP_CONFIG_PENDING; + + /* +* Make sure endpoint ring is empty before resetting the toggle/seq. +* Driver is re
[PATCH v2 0/3] xhci fixes for 4.0-rc2
Hi Greg Second try, only change is adding testing credits to commit messages. Three xhci patches for usb-linus this time. Fixing issues like allocating the correct amount of DMA memory for xhci controller (not less like it sometimes did), fix Armada 375/38x XHCI support by making sure clocks are on before touching the xhci controller, and finally fixing an issue where where some devices, mainly scanners, use 'endpoint reset' requests to soft reset the device endpoint, ending up getting the host and device out of sync. The last 'endpoint reset' issue for scanners has been around for some time, but 3.18 had some major changes in endpoint reset code, so backporting it to older versions than 3.18 will be diffcult. Mathias Nyman (2): xhci: Allocate correct amount of scratchpad buffers xhci: Clear the host side toggle manually when endpoint is 'soft reset' Maxime Ripard (1): usb: XHCI: platform: Move the Marvell quirks after the enabling the clocks drivers/usb/host/xhci-plat.c | 19 drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 100 +++ drivers/usb/host/xhci.h | 7 ++- 4 files changed, 106 insertions(+), 22 deletions(-) -- 1.8.3.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
Re: [GIT PULL] USB fixes for v4.0-rc2
On Tue, Feb 24, 2015 at 10:22:59AM -0600, Felipe Balbi wrote: > Hi Greg, > > Here's my first set of fixes for this -rc. Let me know if you > need anything to be changed. > > cheers > > The following changes since commit c517d838eb7d07bbe9507871fab3931deccff539: > > Linux 4.0-rc1 (2015-02-22 18:21:14 -0800) > > are available in the git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git > tags/fixes-for-v4.0-rc2 Pulled and pushed out, thanks. greg k-h -- 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: XHCI, "brain-dead scanner", and microframe rounding
On Dienstag, 24. Februar 2015 17:53:25 Mathias Nyman wrote: > On 24.02.2015 12:41, Hans-Peter Jansen wrote: > > On Donnerstag, 19. Februar 2015 16:07:41 Mathias Nyman wrote: > >> On 18.02.2015 14:27, Hans-Peter Jansen wrote: > >>> Mathias Nyman writes: > On 27.01.2015 13:57, Hans-Peter Jansen wrote: > > What about a stable backport? Do you think, it's feasible, too much > > work, or too risky? > > This should definitely be backported to 3.18 stable, which should be > easy. > Older longterms kernels are a bit tricky as the halt and reset code > around > >>> > >>> this was > >>> > heavily modified in 3.18 > >>> > >>> Will this be included in 3.20? > >> > >> I'll send it once 3.20-rc1 is out. > >> > >> So yes, it should be in the final 3.20 > > > > Mathias, you need to adjust your filter to <4.0>, and I cannot see > > anything > > related moving onwards. > > > > Also 3.19-stable is still dangling.. > > Just sent it to Greg, with stable CC tags. Thanks a lot, will test through 3.19 stable, when it is released. Pete -- 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: MUSB dual-role on AM335x behaving weirdly
Hi Felipe, On Tue, Feb 24, 2015 at 08:54:01AM -0600, Felipe Balbi wrote: > Hi, > > On Tue, Feb 24, 2015 at 11:39:11AM +0100, Maxime Ripard wrote: > > On Thu, Feb 05, 2015 at 02:21:42PM +0100, Maxime Ripard wrote: > > > Hi, > > > > > > On Thu, Jan 22, 2015 at 08:37:45AM +0100, Yegor Yefremov wrote: > > > > I have the same experience with 3.15. The switching is working when > > > > CONFIG_USB_MUSB_DUAL_ROLE is set and dr_mode = "otg". But since 3.16 > > > > it seems to be broken. Still had no time to bisect this. > > > > > > I've been giving a few versions (from v3.15 to Tuesday's linux-next) a > > > try, and I always see the same behaviour now: > > > > > > - Booting as a gadget (ie, with a USB cable plugged in), and > > > swapping the cable for a (real, this time) USB OTG cable with a > > > USB key never works. When the device is plugged, all I get is > > > > > > [ 262.944846] usb 1-1: new high-speed USB device number 2 using musb-hdrc > > > [ 278.064748] usb 1-1: device descriptor read/64, error -110 > > > > > > Putting in back in gadget results with a load of continuous: > > > [ 315.258839] musb_bus_suspend 2484: trying to suspend as a_wait_vfall > > > while active > > > > > > - Booting as a host, or with nothing connected to it actually work, > > > up to a few plug-a-device-then-plug-a-host cycles, where you end > > > up with the following logs when disconnecting the device (somehow, > > > it always happens when it is set in host mode). > > > > > > [ 12.969075] CAUTION: musb: Babble Interrupt Occurred > > > [ 12.974445] CAUTION: musb: Babble Interrupt Occurred > > > [ 12.979637] musb_stage0_irq 789: unhandled DISCONNECT transition > > > (a_wait_bcon) > > > [ 12.988498] usb 1-1: USB disconnect, device number 2 > > > [ 13.071849] musb-hdrc musb-hdrc.0.auto: Restarting MUSB to recover > > > from Babble > > > > > > Plugging back our USB cable, with the AM335x acting as a device > > > work once. Then, when it switches to the host mode, we end up with > > > the same scenario than in the coldplug as gadget case: USB read > > > error, before then having all the a_wait_vfall messages. > > > > Guys, any ideas/hints? > > which platform are you using ? I guess the only way to move here would > be to bisect between 3.15 and 3.16 to find the offending commit. 3.15 didn't work either unfortunately. I had the behaviour described above on all kernel between 3.15 and a 4.0-rc1-ish. This is on an custom design based on the am335x. Maxime -- Maxime Ripard, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com signature.asc Description: Digital signature
Re: MUSB dual-role on AM335x behaving weirdly
Hi, On Tue, Feb 24, 2015 at 05:50:50PM +0100, Maxime Ripard wrote: > Hi Felipe, > > On Tue, Feb 24, 2015 at 08:54:01AM -0600, Felipe Balbi wrote: > > Hi, > > > > On Tue, Feb 24, 2015 at 11:39:11AM +0100, Maxime Ripard wrote: > > > On Thu, Feb 05, 2015 at 02:21:42PM +0100, Maxime Ripard wrote: > > > > Hi, > > > > > > > > On Thu, Jan 22, 2015 at 08:37:45AM +0100, Yegor Yefremov wrote: > > > > > I have the same experience with 3.15. The switching is working when > > > > > CONFIG_USB_MUSB_DUAL_ROLE is set and dr_mode = "otg". But since 3.16 since 3.16 ? > > > > > it seems to be broken. Still had no time to bisect this. > > > > > > > > I've been giving a few versions (from v3.15 to Tuesday's linux-next) a > > > > try, and I always see the same behaviour now: > > > > > > > > - Booting as a gadget (ie, with a USB cable plugged in), and > > > > swapping the cable for a (real, this time) USB OTG cable with a > > > > USB key never works. When the device is plugged, all I get is > > > > > > > > [ 262.944846] usb 1-1: new high-speed USB device number 2 using > > > > musb-hdrc > > > > [ 278.064748] usb 1-1: device descriptor read/64, error -110 > > > > > > > > Putting in back in gadget results with a load of continuous: > > > > [ 315.258839] musb_bus_suspend 2484: trying to suspend as a_wait_vfall > > > > while active > > > > > > > > - Booting as a host, or with nothing connected to it actually work, > > > > up to a few plug-a-device-then-plug-a-host cycles, where you end > > > > up with the following logs when disconnecting the device (somehow, > > > > it always happens when it is set in host mode). > > > > > > > > [ 12.969075] CAUTION: musb: Babble Interrupt Occurred > > > > [ 12.974445] CAUTION: musb: Babble Interrupt Occurred > > > > [ 12.979637] musb_stage0_irq 789: unhandled DISCONNECT transition > > > > (a_wait_bcon) > > > > [ 12.988498] usb 1-1: USB disconnect, device number 2 > > > > [ 13.071849] musb-hdrc musb-hdrc.0.auto: Restarting MUSB to recover > > > > from Babble > > > > > > > > Plugging back our USB cable, with the AM335x acting as a device > > > > work once. Then, when it switches to the host mode, we end up with > > > > the same scenario than in the coldplug as gadget case: USB read > > > > error, before then having all the a_wait_vfall messages. > > > > > > Guys, any ideas/hints? > > > > which platform are you using ? I guess the only way to move here would > > be to bisect between 3.15 and 3.16 to find the offending commit. > > 3.15 didn't work either unfortunately. I had the behaviour described > above on all kernel between 3.15 and a 4.0-rc1-ish. > > This is on an custom design based on the am335x. has it ever worked ? I don't have a board here which can do dual role. BBB has a mini-B only on the peripheral port. -- balbi signature.asc Description: Digital signature
[PATCH] usb: isp1760: fix peripheral/device controller chip id
As per the ISP1761 data sheet, the DcChipID register represents the hardware version number (0015h) and the chip ID (8210h) for the Peripheral Controller. This patch fixes the chip ID value used to verify the controller. Cc: Felipe Balbi Cc: Laurent Pinchart Signed-off-by: Sudeep Holla --- drivers/usb/isp1760/isp1760-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Hi Laurent, I found that the chip ID is wrong when I tried testing OTG on vexpress platforms. As per Section 10.8.2 DcChipID register in [1], it should be 0x00158210. It's still not functional, I will follow up with the logs separately. Regards, Sudeep [1] http://ridl.cfd.rit.edu/products/manuals/Altera/DE3_v.1.7_CDROM/Datasheet/USB/ISP1761.pdf#G2148521 diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 9612d7990565..87a8dc044fce 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c @@ -1411,7 +1411,7 @@ static int isp1760_udc_init(struct isp1760_udc *udc) return -ENODEV; } - if (chipid != 0x00011582) { + if (chipid != 0x00158210) { dev_err(udc->isp->dev, "udc: invalid chip ID 0x%08x\n", chipid); return -ENODEV; } -- 1.9.1 -- 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 v2] extcon: otg_gpio: add driver for USB OTG port controlled by GPIO(s)
Hi, [snip] > Felipe suggested to "divide to conquer" instead of having a single > extcon driver to handle all these functions: > > - The mux functions would be controlled by a possible new pinctrl-gpio > driver (Linus, your input here would be nice :) > - The VBUS would be a fixed regulator > - The USB ID would make usage of existent extcon-gpio > > But the on fw side, this is a single ACPI device representing a virtual > device for USB OTG port, which is nothing but a bunch of independent > GPIOs. > > I could make a mfd driver to register devices for those simpler and more > generic drivers, but according to [1] community recognized it as a hack > with ACPI since I'd need to give them the GPIO without requesting on > mfd. I believe this case could be resumed in: Would be [1] acceptable for mfd drivers? - If yes, I can split this driver into more generic ones - If no, I see no other option but having this driver fully controlling the USB OTG port. BR, David [1] https://lkml.org/lkml/2014/12/18/82 -- 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