drivers/net/can/usb/usb_8dev.c
Source file repositories/reference/linux-study-clean/drivers/net/can/usb/usb_8dev.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/usb/usb_8dev.c- Extension
.c- Size
- 24287 bytes
- Lines
- 1022
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/ethtool.hlinux/signal.hlinux/slab.hlinux/module.hlinux/netdevice.hlinux/usb.hlinux/can.hlinux/can/dev.hlinux/can/error.h
Detected Declarations
struct usb_8dev_tx_urb_contextstruct usb_8dev_privenum usb_8dev_endpointenum usb_8dev_cmdfunction usb_8dev_send_cmd_msgfunction usb_8dev_wait_cmd_msgfunction usb_8dev_send_cmdfunction usb_8dev_cmd_openfunction usb_8dev_cmd_closefunction usb_8dev_cmd_versionfunction usb_8dev_set_modefunction usb_8dev_rx_err_msgfunction usb_8dev_rx_can_msgfunction usb_8dev_read_bulk_callbackfunction usb_8dev_write_bulk_callbackfunction usb_8dev_start_xmitfunction usb_8dev_get_berr_counterfunction usb_8dev_startfunction usb_8dev_openfunction unlink_all_urbsfunction usb_8dev_closefunction usb_8dev_probefunction usb_8dev_disconnect
Annotated Snippet
static const struct net_device_ops usb_8dev_netdev_ops = {
.ndo_open = usb_8dev_open,
.ndo_stop = usb_8dev_close,
.ndo_start_xmit = usb_8dev_start_xmit,
};
static const struct ethtool_ops usb_8dev_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct can_bittiming_const usb_8dev_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 = 1024,
.brp_inc = 1,
};
/* Probe USB device
*
* Check device and firmware.
* Set supported modes and bittiming constants.
* Allocate some memory.
*/
static int usb_8dev_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct net_device *netdev;
struct usb_8dev_priv *priv;
int i, err = -ENOMEM;
u32 version;
char buf[18];
struct usb_device *usbdev = interface_to_usbdev(intf);
/* product id looks strange, better we also check iProduct string */
if (usb_string(usbdev, usbdev->descriptor.iProduct, buf,
sizeof(buf)) > 0 && strcmp(buf, "USB2CAN converter")) {
dev_info(&usbdev->dev, "ignoring: not an USB2CAN converter\n");
return -ENODEV;
}
netdev = alloc_candev(sizeof(struct usb_8dev_priv), MAX_TX_URBS);
if (!netdev) {
dev_err(&intf->dev, "Couldn't alloc candev\n");
return -ENOMEM;
}
priv = netdev_priv(netdev);
priv->udev = usbdev;
priv->netdev = netdev;
priv->can.state = CAN_STATE_STOPPED;
priv->can.clock.freq = USB_8DEV_ABP_CLOCK;
priv->can.bittiming_const = &usb_8dev_bittiming_const;
priv->can.do_set_mode = usb_8dev_set_mode;
priv->can.do_get_berr_counter = usb_8dev_get_berr_counter;
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_ONE_SHOT |
CAN_CTRLMODE_CC_LEN8_DLC;
netdev->netdev_ops = &usb_8dev_netdev_ops;
netdev->ethtool_ops = &usb_8dev_ethtool_ops;
netdev->flags |= IFF_ECHO; /* we support local echo */
init_usb_anchor(&priv->rx_submitted);
init_usb_anchor(&priv->tx_submitted);
atomic_set(&priv->active_tx_urbs, 0);
for (i = 0; i < MAX_TX_URBS; i++)
priv->tx_contexts[i].echo_index = MAX_TX_URBS;
priv->cmd_msg_buffer = devm_kzalloc(&intf->dev, sizeof(struct usb_8dev_cmd_msg),
GFP_KERNEL);
if (!priv->cmd_msg_buffer)
goto cleanup_candev;
usb_set_intfdata(intf, priv);
SET_NETDEV_DEV(netdev, &intf->dev);
mutex_init(&priv->usb_8dev_cmd_lock);
Annotation
- Immediate include surface: `linux/ethtool.h`, `linux/signal.h`, `linux/slab.h`, `linux/module.h`, `linux/netdevice.h`, `linux/usb.h`, `linux/can.h`, `linux/can/dev.h`.
- Detected declarations: `struct usb_8dev_tx_urb_context`, `struct usb_8dev_priv`, `enum usb_8dev_endpoint`, `enum usb_8dev_cmd`, `function usb_8dev_send_cmd_msg`, `function usb_8dev_wait_cmd_msg`, `function usb_8dev_send_cmd`, `function usb_8dev_cmd_open`, `function usb_8dev_cmd_close`, `function usb_8dev_cmd_version`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.