drivers/net/can/can327.c
Source file repositories/reference/linux-study-clean/drivers/net/can/can327.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/can327.c- Extension
.c- Size
- 30909 bytes
- Lines
- 1143
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/module.hlinux/bitops.hlinux/ctype.hlinux/errno.hlinux/hex.hlinux/kernel.hlinux/list.hlinux/lockdep.hlinux/netdevice.hlinux/skbuff.hlinux/spinlock.hlinux/string.hlinux/tty.hlinux/tty_ldisc.hlinux/workqueue.huapi/linux/tty.hlinux/can.hlinux/can/dev.hlinux/can/error.hlinux/can/rx-offload.h
Detected Declarations
struct can327enum can327_tx_dofunction can327_sendfunction can327_kick_into_cmd_modefunction can327_send_framefunction can327_init_devicefunction can327_feed_frame_to_netdevfunction can327_uart_side_failurefunction can327_rxbuf_cmpfunction can327_parse_errorfunction can327_parse_framefunction can327_parse_linefunction can327_parse_framefunction can327_handle_promptfunction can327_is_ready_charfunction can327_drop_bytesfunction can327_parse_rxbuffunction can327_netdev_openfunction can327_netdev_closefunction can327_netdev_start_xmitfunction can_bus_offfunction can327_is_valid_rx_charfunction can327_ldisc_rxfunction can327_ldisc_tx_workerfunction can327_ldisc_tx_wakeupfunction can327_ldisc_openfunction can327_ldisc_closefunction can327_ldisc_ioctlfunction can327_initfunction can327_exitmodule init can327_init
Annotated Snippet
static const struct net_device_ops can327_netdev_ops = {
.ndo_open = can327_netdev_open,
.ndo_stop = can327_netdev_close,
.ndo_start_xmit = can327_netdev_start_xmit,
};
static const struct ethtool_ops can327_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static bool can327_is_valid_rx_char(u8 c)
{
static const bool lut_char_is_valid['z'] = {
['\r'] = true,
[' '] = true,
['.'] = true,
['0'] = true, true, true, true, true,
['5'] = true, true, true, true, true,
['<'] = true,
[CAN327_READY_CHAR] = true,
['?'] = true,
['A'] = true, true, true, true, true, true, true,
['H'] = true, true, true, true, true, true, true,
['O'] = true, true, true, true, true, true, true,
['V'] = true, true, true, true, true,
['a'] = true,
['b'] = true,
['v'] = true,
[CAN327_DUMMY_CHAR] = true,
};
BUILD_BUG_ON(CAN327_DUMMY_CHAR >= 'z');
return (c < ARRAY_SIZE(lut_char_is_valid) && lut_char_is_valid[c]);
}
/* Handle incoming ELM327 ASCII data.
* This will not be re-entered while running, but other ldisc
* functions may be called in parallel.
*/
static void can327_ldisc_rx(struct tty_struct *tty, const u8 *cp,
const u8 *fp, size_t count)
{
struct can327 *elm = tty->disc_data;
size_t first_new_char_idx;
if (elm->uart_side_failure)
return;
spin_lock_bh(&elm->lock);
/* Store old rxfill, so can327_parse_rxbuf() will have
* the option of skipping already checked characters.
*/
first_new_char_idx = elm->rxfill;
while (count--) {
if (elm->rxfill >= CAN327_SIZE_RXBUF) {
netdev_err(elm->dev,
"Receive buffer overflowed. Bad chip or wiring? count = %zu",
count);
goto uart_failure;
}
if (fp && *fp++) {
netdev_err(elm->dev,
"Error in received character stream. Check your wiring.");
goto uart_failure;
}
/* Ignore NUL characters, which the PIC microcontroller may
* inadvertently insert due to a known hardware bug.
* See ELM327 documentation, which refers to a Microchip PIC
* bug description.
*/
if (*cp) {
/* Check for stray characters on the UART line.
* Likely caused by bad hardware.
*/
if (!can327_is_valid_rx_char(*cp)) {
netdev_err(elm->dev,
"Received illegal character %02x.\n",
*cp);
goto uart_failure;
}
elm->rxbuf[elm->rxfill++] = *cp;
}
cp++;
}
Annotation
- Immediate include surface: `linux/init.h`, `linux/module.h`, `linux/bitops.h`, `linux/ctype.h`, `linux/errno.h`, `linux/hex.h`, `linux/kernel.h`, `linux/list.h`.
- Detected declarations: `struct can327`, `enum can327_tx_do`, `function can327_send`, `function can327_kick_into_cmd_mode`, `function can327_send_frame`, `function can327_init_device`, `function can327_feed_frame_to_netdev`, `function can327_uart_side_failure`, `function can327_rxbuf_cmp`, `function can327_parse_error`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.