drivers/net/can/usb/f81604.c
Source file repositories/reference/linux-study-clean/drivers/net/can/usb/f81604.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/usb/f81604.c- Extension
.c- Size
- 28598 bytes
- Lines
- 1240
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/netdevice.hlinux/units.hlinux/usb.hlinux/can.hlinux/can/dev.hlinux/can/error.hlinux/can/platform/sja1000.hlinux/unaligned.h
Detected Declarations
struct f81604_privstruct f81604_port_privstruct f81604_int_datastruct f81604_sffstruct f81604_effstruct f81604_can_framefunction f81604_writefunction f81604_readfunction f81604_update_bitsfunction f81604_sja1000_writefunction f81604_sja1000_readfunction f81604_set_reset_modefunction f81604_set_normal_modefunction f81604_chipset_initfunction f81604_process_rx_packetfunction f81604_read_bulk_callbackfunction f81604_handle_txfunction f81604_handle_can_bus_errorsfunction f81604_read_int_callbackfunction f81604_unregister_urbsfunction f81604_register_urbsfunction f81604_startfunction f81604_set_bittimingfunction f81604_set_modefunction f81604_write_bulk_callbackfunction f81604_clear_reg_workfunction f81604_start_xmitfunction f81604_get_berr_counterfunction f81604_openfunction f81604_closefunction f81604_disconnectfunction __f81604_set_terminationfunction f81604_set_terminationfunction f81604_probe
Annotated Snippet
static const struct net_device_ops f81604_netdev_ops = {
.ndo_open = f81604_open,
.ndo_stop = f81604_close,
.ndo_start_xmit = f81604_start_xmit,
};
static const struct can_bittiming_const f81604_bittiming_const = {
.name = KBUILD_MODNAME,
.tseg1_min = 1,
.tseg1_max = 16,
.tseg2_min = 1,
.tseg2_max = 8,
.sjw_max = 4,
.brp_min = 1,
.brp_max = 64,
.brp_inc = 1,
};
/* Called by the usb core when driver is unloaded or device is removed */
static void f81604_disconnect(struct usb_interface *intf)
{
struct f81604_priv *priv = usb_get_intfdata(intf);
int i;
for (i = 0; i < ARRAY_SIZE(priv->netdev); ++i) {
if (!priv->netdev[i])
continue;
unregister_netdev(priv->netdev[i]);
free_candev(priv->netdev[i]);
}
}
static int __f81604_set_termination(struct usb_device *dev, int idx, u16 term)
{
u8 mask, data = 0;
if (idx == 0)
mask = F81604_CAN0_TERM;
else
mask = F81604_CAN1_TERM;
if (term)
data = mask;
return f81604_update_bits(dev, F81604_TERMINATOR_REG, mask, data);
}
static int f81604_set_termination(struct net_device *netdev, u16 term)
{
struct f81604_port_priv *port_priv = netdev_priv(netdev);
ASSERT_RTNL();
return __f81604_set_termination(port_priv->dev, netdev->dev_port,
term);
}
static int f81604_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct net_device *netdev;
struct f81604_priv *priv;
int i, ret;
priv = devm_kzalloc(&intf->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
usb_set_intfdata(intf, priv);
for (i = 0; i < ARRAY_SIZE(priv->netdev); ++i) {
ret = __f81604_set_termination(dev, i, 0);
if (ret) {
dev_err(&intf->dev,
"Setting termination of CH#%d failed: %pe\n",
i, ERR_PTR(ret));
return ret;
}
}
for (i = 0; i < ARRAY_SIZE(priv->netdev); ++i) {
struct f81604_port_priv *port_priv;
netdev = alloc_candev(sizeof(*port_priv), 1);
if (!netdev) {
dev_err(&intf->dev, "Couldn't alloc candev: %d\n", i);
ret = -ENOMEM;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/netdevice.h`, `linux/units.h`, `linux/usb.h`, `linux/can.h`, `linux/can/dev.h`, `linux/can/error.h`, `linux/can/platform/sja1000.h`.
- Detected declarations: `struct f81604_priv`, `struct f81604_port_priv`, `struct f81604_int_data`, `struct f81604_sff`, `struct f81604_eff`, `struct f81604_can_frame`, `function f81604_write`, `function f81604_read`, `function f81604_update_bits`, `function f81604_sja1000_write`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
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.