From: sashiko-bot@kernel.org
To: "Michael Zaidman" <michael.zaidman@gmail.com>
Cc: linux-input@vger.kernel.org, linux-serial@vger.kernel.org,
linux-gpio@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH v2 02/15] HID: ft260: uart: fix the serial driver
Date: Fri, 30 Oct 2026 23:03:13 +0000 [thread overview]
Message-ID: <sashiko-outbox-191615@kernel.org> (raw)
In-Reply-To: <20261030223637.86907-3-michael.zaidman@gmail.com>
Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider:
- [High] HID: ft260: invalid report ID 0xFF in ft260_uart_transmit_chars()
- [High] HID: ft260: race and infinite loop in ft260_uart_transmit_chars()
- [High] HID: ft260: wakeup timer and work teardown race in ft260_remove()
- [High] HID: ft260: broken index allocation and bounds check in ft260_uart_add_port()
- [High] HID: ft260: UAF and double free when ft260_get_interface_type() returns 0
- [High] HID: ft260: missing iface_type check for UART reports in ft260_raw_event()
- [Medium] HID: ft260: unconditional wakeup timer in ft260_uart_port_activate()
- [Medium] HID: ft260: ft260_uart_probe() registers TTY device before configuring UART
- [Low] HID: ft260: unneeded ft260_uart_wakeup() prototype and changelog mismatches
--
commit 120d1c2c1f711fdf1a272089095a3cbf1a2d1d34
Author: Michael Zaidman <michael.zaidman@gmail.com>
HID: ft260: uart: fix the serial driver
This commit updates the FT260 serial driver to separate the UART and I2C TX
buffers, adjust the power-save wakeup timer logic, validate HID input report
lengths against the received report size, and clean up interface detection and
FIFO handling.
> HID: ft260: uart: fix the serial driver
>
> Fix the serial driver added by the previous patch, a port of
> Christina Quast's v4, so that it works reliably on hardware.
>
> The UART and I2C paths shared write_buf without proper separation,
> so concurrent use could corrupt transfers on both channels. Give
> UART its own TX buffer. The write request report is now built in
> that fixed per-port buffer, so its payload member becomes a fixed
> FT260_WR_UART_DATA_MAX (62) array rather than a __counted_by()
> flexible array, which describes a runtime-counted allocation this
> path no longer makes.
>
> The FT260 enters power-save after ~5s idle, which drops RX data at
> higher baud rates. Keep a timed dummy wakeup, but only when needed:
> skip it below 4800 baud and when EEPROM disables power-save; wake
> earlier before RX; avoid configuring baud or disabling the workaround
> twice; and arm the timer when a tty session starts.
>
> The received report length was validated against the actual HID report
> size only on the I2C path. The UART path instead bounded the
> device-supplied length against FT260_RD_DATA_MAX (180), which is the
> maximum I2C read payload, not a bound on the report buffer. As a UART
> payload cannot exceed FT260_WR_UART_DATA_MAX (62) bytes, a report
> claiming more would make ft260_uart_receive_chars() push data past the
> end of the report buffer into the tty flip buffer. Validate the length
> against the received report size once, before dispatching on the report
> type, and drop the two now-redundant FT260_RD_DATA_MAX checks.
>
> Also fix RX data loss after reopening the device, improve TX
> throughput, simplify HID interface-type detection, use kfifo_avail
> for write-room, and ignore spurious UART interrupt status (0xb1)
> reports instead of treating them as errors.
>
> Also includes UART cleanup and refactoring to match the rest of the
> driver style: replace the kfifo_*_locked aliases with
> kfifo_*_spinlocked, and drop the parentheses around single-value
> defines, which coding-style asks for only when the value is an
> expression.
>
> This replaces the UART bring-up fix series:
> https://lore.kernel.org/all/20240210215147.77629-1-michael.zaidman@gmail.com/
>
> Do not treat UART interrupt status (0xB1) as a payload length. When
> re-enabling the power-save wakeup workaround after a baud change,
> re-arm the timer (reported by Sashiko).
>
> Report 0xE1 is defined as FT260_UART_RI_DCD_STATUS, but AN_394 section
> 4.3 lists 0xE2 for "UART RI and DCD Status". Correct the value. The
> macro has no user, because the DCD and RI levels arrive in the 0xB1
> interrupt report, which ft260_raw_event() handles.
>
> Signed-off-by: Michael Zaidman <michael.zaidman@gmail.com>
[Severity: Low]
This isn't a bug in the code, but does the commit message match what the patch
does here?
The changelog mentions waking earlier before RX, but
FT260_WAKEUP_NEEDED_AFTER_MS remains 4800 ms and ft260_uart_wakeup() is only
called from the periodic ft260_uart_do_wakeup() work handler.
The last paragraph also states that DCD and RI levels arrive in the 0xB1
interrupt report, which ft260_raw_event() handles, whereas ft260_raw_event()
ignores FT260_UART_INTERRUPT_STATUS (0xB1) and returns 0.
> diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
> index 982e2ca7a2de6..c859486cb28c8 100644
> --- a/drivers/hid/hid-ft260.c
> +++ b/drivers/hid/hid-ft260.c
[ ... ]
> @@ -38,11 +34,14 @@ MODULE_PARM_DESC(debug, "Toggle FT260 debugging messages");
> pr_info("%s: " format, __func__, ##arg); \
> } while (0)
>
> -#define FT260_REPORT_MAX_LENGTH (64)
> -#define FT260_I2C_DATA_REPORT_ID(len) (FT260_I2C_REPORT_MIN + (len - 1) / 4)
> -#define FT260_UART_DATA_REPORT_ID(len) (FT260_UART_REPORT_MIN + (len - 1) / 4)
> +#define FT260_REPORT_MAX_LEN 64
> +#define FT260_DATA_REPORT_ID(min, len) (min + (len - 1) / 4)
> +#define FT260_I2C_DATA_REPORT_ID(len) \
> + FT260_DATA_REPORT_ID(FT260_I2C_REPORT_MIN, len)
> +#define FT260_UART_DATA_REPORT_ID(len) \
> + FT260_DATA_REPORT_ID(FT260_UART_REPORT_MIN, len)
>
> -#define FT260_WAKEUP_NEEDED_AFTER_MS (4800) /* 5s minus 200ms margin */
> +#define FT260_WAKEUP_NEEDED_AFTER_MS 4800 /* 5s minus 200ms margin */
>
> /*
> * The ft260 input report format defines 62 bytes for the data payload, but
> @@ -55,8 +54,9 @@ MODULE_PARM_DESC(debug, "Toggle FT260 debugging messages");
> * of I2C for potentially troublesome amounts of time, we select the maximum
> * read payload length to be 180 bytes.
> */
> -#define FT260_RD_DATA_MAX (180)
> -#define FT260_WR_DATA_MAX (60)
> +#define FT260_RD_DATA_MAX 180
> +#define FT260_WR_I2C_DATA_MAX 60
> +#define FT260_WR_UART_DATA_MAX 62
[Severity: High]
When ft260_uart_write() calls ft260_uart_transmit_chars() with 61 or more
bytes in xmit_fifo, len is clamped to FT260_WR_UART_DATA_MAX (62):
len = min(data_len, FT260_WR_UART_DATA_MAX);
rep->report = FT260_UART_DATA_REPORT_ID(len);
For len = 61 or 62, (len - 1) / 4 evaluates to 15, so
FT260_UART_DATA_REPORT_ID(len) produces 0xF0 + 15 = 0xFF.
Since the valid UART data report IDs end at FT260_UART_REPORT_MAX (0xFE, which
carries 57 to 62 payload bytes), won't setting rep->report to 0xFF cause
transfers of 61 or 62 bytes to fail with an invalid HID report ID?
[ ... ]
> @@ -937,27 +951,25 @@ static int ft260_get_interface_type(struct hid_device *hdev, struct ft260_device
> ft260_dbg("i2c_enable: 0x%02x\n", cfg.i2c_enable);
> ft260_dbg("uart_mode: 0x%02x\n", cfg.uart_mode);
>
> - dev->ft260_is_serial = false;
> + dev->power_saving_en = cfg.power_saving_en;
>
> switch (cfg.chip_mode) {
> case FT260_MODE_ALL:
> case FT260_MODE_BOTH:
> - if (interface == 1) {
> + if (interface == 1)
> ret = FT260_IFACE_UART;
> - dev->ft260_is_serial = true;
> - } else {
> + else
> ret = FT260_IFACE_I2C;
> - }
> break;
> case FT260_MODE_UART:
> ret = FT260_IFACE_UART;
> - dev->ft260_is_serial = true;
> break;
> case FT260_MODE_I2C:
> ret = FT260_IFACE_I2C;
> break;
> }
>
> + dev->iface_type = ret;
> return ret;
> }
[Severity: High]
If cfg.chip_mode does not match any of the four cases in
ft260_get_interface_type(), ret remains 0 (from ft260_get_system_config()),
which equals FT260_IFACE_NONE.
In ft260_probe(), hid_set_drvdata(hdev, dev) is called before
ft260_get_interface_type(), and the check:
ret = ft260_get_interface_type(hdev, dev);
if (ret <= FT260_IFACE_NONE)
goto err_hid_close;
jumps to err_hid_close with ret == 0. That error path frees dev via kfree(dev)
and returns 0 from ft260_probe().
Won't returning 0 cause the driver core to treat probe as successful, leading
to a use-after-free and double free of dev when ft260_remove() later retrieves
dev from hid_get_drvdata(hdev)?
[ ... ]
> @@ -1101,12 +1113,36 @@ static const struct attribute_group ft260_attr_group = {
> }
> };
>
> -/***
> - * START Serial dev part
> - */
> static DEFINE_MUTEX(ft260_uart_list_lock);
> static LIST_HEAD(ft260_uart_device_list);
>
> +static void ft260_uart_wakeup(struct ft260_device *dev);
[Severity: Low]
This isn't a bug, but is this forward declaration of ft260_uart_wakeup()
needed? Its only caller is ft260_uart_do_wakeup(), which is defined right
below ft260_uart_wakeup().
[ ... ]
> @@ -1123,8 +1159,8 @@ static int ft260_uart_add_port(struct ft260_device *port)
> int index = 0, ret = 0;
> struct ft260_device *dev;
>
> - spin_lock_init(&port->write_lock);
> - if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))
> + spin_lock_init(&port->xmit_fifo_lock);
> + if (kfifo_alloc(&port->xmit_fifo, XMIT_FIFO_SIZE, GFP_KERNEL))
> return -ENOMEM;
>
> mutex_lock(&ft260_uart_list_lock);
[Severity: High]
In ft260_uart_add_port(), the minor index search assumes
ft260_uart_device_list is sorted by index, but new ports are appended to the
tail of the list without checking UART_COUNT_MAX:
mutex_lock(&ft260_uart_list_lock);
list_for_each_entry(dev, &ft260_uart_device_list, device_list) {
if (dev->index != index)
break;
index++;
}
port->index = index;
list_add_tail(&port->device_list, &ft260_uart_device_list);
mutex_unlock(&ft260_uart_list_lock);
If ports 0 and 1 are added, port 0 is removed, and a new port A is probed,
port A gets index 0 and is placed at the tail (making the list order [1, 0]).
If another port B is then probed, the first entry has dev->index == 1 != 0, so
the loop breaks immediately and assigns index 0 to port B as well.
When ft260_uart_probe() then calls tty_port_register_device_attr(),
tty_port_link_device() overwrites ft260_tty_driver->ports[0] with &devB->port
before tty_register_device_attr() fails with -EEXIST and frees devB, leaving
ft260_tty_driver->ports[0] dangling for ft260_uart_install() ->
tty_standard_install(). Also, if more than UART_COUNT_MAX (4) ports are
probed, index >= UART_COUNT_MAX triggers WARN_ON(index >= driver->num) in
tty_port_link_device().
Should ft260_uart_add_port() insert before dev->device_list to keep the list
sorted and return an error when index >= UART_COUNT_MAX?
[ ... ]
> @@ -1217,30 +1253,24 @@ static int ft260_uart_transmit_chars(struct ft260_device *port)
> goto tty_out;
> }
>
> - rep = (struct ft260_uart_write_request_report *)port->write_buf;
> + rep = (struct ft260_uart_write_request_report *)port->uart_wr_buf;
>
> do {
> - len = min(data_len, FT260_WR_DATA_MAX);
> + len = min(data_len, FT260_WR_UART_DATA_MAX);
>
> rep->report = FT260_UART_DATA_REPORT_ID(len);
> rep->length = len;
>
> - len = kfifo_out_locked(xmit, rep->data, len, &port->write_lock);
> + len = kfifo_out_spinlocked(xmit, rep->data, len, &port->xmit_fifo_lock);
>
> - ret = ft260_hid_output_report(hdev, (u8 *)rep, len + sizeof(*rep));
> - if (ret < 0) {
> - hid_err(hdev, "Failed to start transfer, ret %d\n", ret);
> + ret = ft260_hid_output_report(hdev, (u8 *)rep, len + 2);
> + if (ret < 0)
> goto tty_out;
> - }
>
> data_len -= len;
> port->icount.tx += len;
> } while (data_len > 0);
>
> - len = kfifo_len(xmit);
> - if ((FIFO_SIZE - len) > TTY_WAKEUP_WATERMARK)
> - tty_wakeup(tty);
> -
> ret = 0;
>
> tty_out:
[Severity: High]
As reported by Sashiko on v1 [1], ft260_uart_transmit_chars() builds outgoing
reports in the shared per-port buffer port->uart_wr_buf without holding a lock
across the loop while ft260_hid_output_report() sleeps.
If two threads enter ft260_uart_write() -> ft260_uart_transmit_chars()
concurrently (or if kfifo_reset() runs in ft260_uart_port_activate()):
1. Both threads can overwrite port->uart_wr_buf concurrently before kmemdup()
in ft260_hid_output_report() copies it.
2. Because rep->report and rep->length are set from data_len before
kfifo_out_spinlocked(), a racing thread draining xmit_fifo can cause
kfifo_out_spinlocked() to return fewer bytes than rep->length, or 0 bytes.
3. If kfifo_out_spinlocked() returns 0, ft260_hid_output_report() sends a
2-byte report with a non-zero rep->length and data_len -= 0 never
terminates the while (data_len > 0) loop.
Also, with tty_wakeup(tty) removed here, what wakes up a writer waiting for
write room after xmit_fifo fills up?
[ ... ]
> @@ -1503,53 +1537,68 @@ static void ft260_uart_start_wakeup(struct timer_list *t)
[ ... ]
> +static int ft260_uart_port_activate(struct tty_port *tport, struct tty_struct *tty)
> +{
> + int ret;
> + int baudrate;
> + struct ft260_get_uart_settings_report cfg;
> + struct ft260_device *port = container_of(tport, struct ft260_device, port);
> +
> set_bit(TTY_IO_ERROR, &tty->flags);
>
> - spin_lock(&port->write_lock);
> + spin_lock(&port->xmit_fifo_lock);
> kfifo_reset(&port->xmit_fifo);
> - spin_unlock(&port->write_lock);
> + spin_unlock(&port->xmit_fifo_lock);
>
> - ft260_uart_change_speed(port, &tty->termios, NULL);
> clear_bit(TTY_IO_ERROR, &tty->flags);
>
> - if (port->reschedule_work) {
> - mod_timer(&port->wakeup_timer, jiffies +
> - msecs_to_jiffies(FT260_WAKEUP_NEEDED_AFTER_MS));
> - }
> + /*
> + * The port setting may remain intact after session termination.
> + * Then, when reopening the port without configuring the port
> + * setting, we need to retrieve the baud rate from the device to
> + * reactivate the wakeup workaround if needed.
> + */
> + ret = ft260_get_uart_settings(port->hdev, &cfg);
> + if (ret)
> + return ret;
> +
> + baudrate = get_unaligned_le32(&cfg.baudrate);
> + if (baudrate > FT260_UART_EN_PW_SAVE_BAUD)
> + ft260_uart_wakeup_workaraund_enable(port, true);
> +
> + ft260_dbg("configured baudrate = %d", baudrate);
> +
> + mod_timer(&port->wakeup_timer, jiffies +
> + msecs_to_jiffies(FT260_WAKEUP_NEEDED_AFTER_MS));
>
> return 0;
> }
[Severity: Medium]
In ft260_uart_port_activate(), mod_timer(&port->wakeup_timer, ...) is now
called unconditionally rather than only when port->reschedule_work is true.
Also, if baudrate <= FT260_UART_EN_PW_SAVE_BAUD on the first open after
ft260_uart_probe() enabled the workaround, port->reschedule_work remains true.
Should ft260_uart_port_activate() pass baudrate > FT260_UART_EN_PW_SAVE_BAUD
directly to ft260_uart_wakeup_workaraund_enable() and guard mod_timer() with
if (port->reschedule_work), as in ft260_uart_change_speed()?
[ ... ]
> @@ -1641,10 +1689,10 @@ static int ft260_uart_probe(struct hid_device *hdev, struct ft260_device *dev)
> ret = PTR_ERR(devt);
> goto err_register_tty;
> }
> - hid_info(hdev, "Registering device /dev/%s%d\n",
> + hid_info(hdev, "registering device /dev/%s%d\n",
> ft260_tty_driver->name, dev->index);
>
> - /* Send Feature Report to Configure FT260 as UART 9600-8-N-1 */
> + /* Configure UART to 9600n8 */
> req.report = FT260_SYSTEM_SETTINGS;
> req.request = FT260_SET_UART_CONFIG;
> req.flow_ctrl = FT260_UART_CFG_FLOW_CTRL_NONE;
> @@ -1656,8 +1704,7 @@ static int ft260_uart_probe(struct hid_device *hdev, struct ft260_device *dev)
>
> ret = ft260_hid_feature_report_set(hdev, (u8 *)&req, sizeof(req));
> if (ret < 0) {
> - hid_err(hdev, "ft260_hid_feature_report_set failed: %d\n",
> - ret);
> + hid_err(hdev, "failed to configure uart: %d\n", ret);
> goto err_hid_report;
> }
[Severity: Medium]
In ft260_uart_probe(), tty_port_register_device_attr() exposes /dev/ttyFT* to
userspace before ft260_hid_feature_report_set() configures the UART to 9600n8.
Since ft260_uart_port_activate() now reads the active UART settings from the
chip via ft260_get_uart_settings() instead of calling
ft260_uart_change_speed(), can a userspace process opening the port
immediately after registration read uninitialized UART settings or have its
termios changes overwritten by the 9600n8 feature report in
ft260_uart_probe()?
[ ... ]
> @@ -1765,7 +1812,7 @@ static void ft260_remove(struct hid_device *hdev)
> if (!dev)
> return;
>
> - if (dev->ft260_is_serial) {
> + if (dev->iface_type == FT260_IFACE_UART) {
> timer_delete_sync(&dev->wakeup_timer);
> cancel_work_sync(&dev->wakeup_work);
> tty_port_unregister_device(&dev->port, ft260_tty_driver,
> @@ -1779,7 +1826,7 @@ static void ft260_remove(struct hid_device *hdev)
> hid_hw_close(hdev);
> hid_hw_stop(hdev);
>
> - if (dev->ft260_is_serial)
> + if (dev->iface_type == FT260_IFACE_UART)
> ft260_uart_port_put(dev);
> else
> kfree(dev);
[Severity: High]
As reported by Sashiko on v1 [2], is the teardown ordering of wakeup_timer and
wakeup_work safe against concurrent TTY operations during removal?
In ft260_remove() and ft260_uart_port_remove():
ft260_remove()
timer_delete_sync(&dev->wakeup_timer);
cancel_work_sync(&dev->wakeup_work);
tty_port_unregister_device(&dev->port, ft260_tty_driver, dev->index);
ft260_uart_port_remove(dev)
timer_delete_sync(&port->wakeup_timer);
list_del(&port->device_list);
tty_port_tty_vhangup(&port->port);
Because port->reschedule_work is only cleared when tty_port_tty_vhangup()
invokes ft260_uart_port_shutdown():
1. If wakeup_timer fires between cancel_work_sync() in ft260_remove() and
timer_delete_sync() in ft260_uart_port_remove(), ft260_uart_start_wakeup()
schedules wakeup_work, which is never cancelled afterwards (and the
err_hid_report error path in ft260_uart_probe() never calls
cancel_work_sync() at all).
2. Until list_del() and tty_port_tty_vhangup() complete, a concurrent
ft260_uart_change_speed() or ft260_uart_port_activate() can set
port->reschedule_work = true and re-arm wakeup_timer via mod_timer() after
timer_delete_sync() has already run, leaving the timer or work active after
hid_hw_stop() and ft260_uart_port_put() free dev.
Should timer_delete_sync(&port->wakeup_timer) and
cancel_work_sync(&port->wakeup_work) happen after list_del() and
tty_port_tty_vhangup() have finished shutting down the port?
> @@ -1797,6 +1844,13 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
[ ... ]
> @@ -1837,12 +1884,11 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
>
> return 0;
>
> - } else if (xfer->length > FT260_RD_DATA_MAX) {
> - hid_err(hdev, "received data too long (%d)\n", xfer->length);
> - return -EBADR;
> } else if (xfer->report >= FT260_UART_REPORT_MIN &&
> xfer->report <= FT260_UART_REPORT_MAX) {
> return ft260_uart_receive_chars(dev, xfer->data, xfer->length);
> + } else if (xfer->report == FT260_UART_INTERRUPT_STATUS) {
> + return 0;
> }
> hid_err(hdev, "unhandled report %#02x\n", xfer->report);
[Severity: High]
In ft260_probe(), tty_port_init(&dev->port) is only called on the UART path in
ft260_uart_probe(). When dev->iface_type == FT260_IFACE_I2C, dev->port is left
zero-initialized with dev->port.buf.tail == NULL.
If an input report in the range FT260_UART_REPORT_MIN..FT260_UART_REPORT_MAX
arrives on an I2C interface, ft260_raw_event() calls
ft260_uart_receive_chars() -> tty_insert_flip_string(&port->port, ...), which
dereferences port->port.buf.tail in __tty_buffer_request_room().
Should ft260_raw_event() check that dev->iface_type == FT260_IFACE_UART before
dispatching UART reports to ft260_uart_receive_chars()?
[1] https://lore.kernel.org/r/20260822215615.2D8541F000E9@smtp.kernel.org
[2] https://lore.kernel.org/r/20260822215615.2D8541F000E9@smtp.kernel.org
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261030223637.86907-1-michael.zaidman@gmail.com?part=2
next prev parent reply other threads:[~2026-10-30 23:03 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 22:36 [PATCH v2 00/15] HID: ft260: add UART and GPIO support, plus I2C fixes Michael Zaidman
2026-10-30 22:36 ` [PATCH v2 01/15] HID: ft260: add serial driver Michael Zaidman
2026-10-30 23:00 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 02/15] HID: ft260: uart: fix the " Michael Zaidman
2026-10-30 23:03 ` sashiko-bot [this message]
2026-10-30 22:36 ` [PATCH v2 03/15] HID: ft260: add GPIO support Michael Zaidman
2026-10-30 22:53 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 04/15] HID: ft260: i2c: reduce driver module loading time Michael Zaidman
2026-10-30 22:44 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 05/15] HID: ft260: i2c: silence sysfs store big-numbers Michael Zaidman
2026-10-30 22:47 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 06/15] HID: ft260: i2c: reduce bus-error message severity Michael Zaidman
2026-10-30 22:44 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 07/15] HID: ft260: uart: enable flow control Michael Zaidman
2026-10-30 22:47 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 08/15] HID: ft260: uart: add modem pins control via ioctl Michael Zaidman
2026-10-30 22:55 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 09/15] HID: ft260: group sysfs attrs per HID interface Michael Zaidman
2026-10-30 22:48 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 10/15] HID: ft260: i2c: fix large write transaction failure Michael Zaidman
2026-10-30 22:43 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 11/15] HID: ft260: workaround for TN_189 errata endpoint STALL after enumeration Michael Zaidman
2026-10-30 22:59 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 12/15] HID: ft260: i2c: abort in-flight transfers with STOP before reset Michael Zaidman
2026-10-30 22:49 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 13/15] HID: ft260: i2c: reject an I2C clock outside the supported range Michael Zaidman
2026-10-30 22:47 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 14/15] HID: ft260: i2c: fix i2c_reset sysfs store return value Michael Zaidman
2026-10-30 22:48 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 15/15] HID: ft260: i2c: recover a bus held by a slave Michael Zaidman
2026-10-30 22:59 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-191615@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=michael.zaidman@gmail.com \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.