^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * USB Debug cable driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006 Greg Kroah-Hartman <greg@kroah.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define USB_DEBUG_MAX_PACKET_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define USB_DEBUG_BRK_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static const char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 0xfe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 0xfe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) { USB_DEVICE(0x0525, 0x127a) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static const struct usb_device_id dbc_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { USB_DEVICE(0x1d6b, 0x0010) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { USB_DEVICE(0x1d6b, 0x0011) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static const struct usb_device_id id_table_combined[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) { USB_DEVICE(0x0525, 0x127a) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) { USB_DEVICE(0x1d6b, 0x0010) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) { USB_DEVICE(0x1d6b, 0x0011) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MODULE_DEVICE_TABLE(usb, id_table_combined);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* This HW really does not support a serial break, so one will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * emulated when ever the break state is set to true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static void usb_debug_break_ctl(struct tty_struct *tty, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (!break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static void usb_debug_process_read_urb(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (urb->actual_length == USB_DEBUG_BRK_SIZE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) memcmp(urb->transfer_buffer, USB_DEBUG_BRK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) USB_DEBUG_BRK_SIZE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) usb_serial_handle_break(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) usb_serial_generic_process_read_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static struct usb_serial_driver debug_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .name = "debug",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .break_ctl = usb_debug_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .process_read_urb = usb_debug_process_read_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static struct usb_serial_driver dbc_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .name = "xhci_dbc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .id_table = dbc_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .break_ctl = usb_debug_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .process_read_urb = usb_debug_process_read_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) &debug_device, &dbc_device, NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) module_usb_serial_driver(serial_drivers, id_table_combined);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MODULE_LICENSE("GPL v2");