drivers/usb/serial/safe_serial.c

Source file repositories/reference/linux-study-clean/drivers/usb/serial/safe_serial.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/serial/safe_serial.c
Extension
.c
Size
10230 bytes
Lines
312
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0+
/*
 * Safe Encapsulated USB Serial Driver
 *
 *      Copyright (C) 2010 Johan Hovold <jhovold@gmail.com>
 *      Copyright (C) 2001 Lineo
 *      Copyright (C) 2001 Hewlett-Packard
 *
 * By:
 *      Stuart Lynne <sl@lineo.com>, Tom Rushworth <tbr@lineo.com>
 */

/*
 * The encapsultaion is designed to overcome difficulties with some USB
 * hardware.
 *
 * While the USB protocol has a CRC over the data while in transit, i.e. while
 * being carried over the bus, there is no end to end protection. If the
 * hardware has any problems getting the data into or out of the USB transmit
 * and receive FIFO's then data can be lost.
 *
 * This protocol adds a two byte trailer to each USB packet to specify the
 * number of bytes of valid data and a 10 bit CRC that will allow the receiver
 * to verify that the entire USB packet was received without error.
 *
 * Because in this case the sender and receiver are the class and function
 * drivers there is now end to end protection.
 *
 * There is an additional option that can be used to force all transmitted
 * packets to be padded to the maximum packet size. This provides a work
 * around for some devices which have problems with small USB packets.
 *
 * Assuming a packetsize of N:
 *
 *      0..N-2  data and optional padding
 *
 *      N-2     bits 7-2 - number of bytes of valid data
 *              bits 1-0 top two bits of 10 bit CRC
 *      N-1     bottom 8 bits of 10 bit CRC
 *
 *
 *      | Data Length       | 10 bit CRC                                |
 *      + 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 | 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 +
 *
 * The 10 bit CRC is computed across the sent data, followed by the trailer
 * with the length set and the CRC set to zero. The CRC is then OR'd into
 * the trailer.
 *
 * When received a 10 bit CRC is computed over the entire frame including
 * the trailer and should be equal to zero.
 *
 * Two module parameters are used to control the encapsulation, if both are
 * turned of the module works as a simple serial device with NO
 * encapsulation.
 *
 * See linux/drivers/usbd/serial_fd for a device function driver
 * implementation of this.
 *
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/gfp.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>

static bool safe = true;
static bool padded = IS_ENABLED(CONFIG_USB_SERIAL_SAFE_PADDED);

#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com, Johan Hovold <jhovold@gmail.com>"
#define DRIVER_DESC "USB Safe Encapsulated Serial"

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

module_param(safe, bool, 0);
MODULE_PARM_DESC(safe, "Turn Safe Encapsulation On/Off");

module_param(padded, bool, 0);
MODULE_PARM_DESC(padded, "Pad to full wMaxPacketSize On/Off");

Annotation

Implementation Notes