drivers/net/can/usb/ems_usb.c
Source file repositories/reference/linux-study-clean/drivers/net/can/usb/ems_usb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/usb/ems_usb.c- Extension
.c- Size
- 26254 bytes
- Lines
- 1108
- 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 cpc_can_msgstruct cpc_sja1000_paramsstruct cpc_can_paramsstruct cpc_confirmstruct cpc_overrunstruct cpc_sja1000_can_errorstruct cpc_can_errorstruct cpc_can_err_counterstruct ems_usbstruct ems_tx_urb_contextstruct ems_usbfunction ems_usb_read_interrupt_callbackfunction ems_usb_rx_can_msgfunction ems_usb_rx_errfunction ems_usb_read_bulk_callbackfunction ems_usb_write_bulk_callbackfunction ems_usb_command_msgfunction ems_usb_write_modefunction ems_usb_control_cmdfunction ems_usb_startfunction unlink_all_urbsfunction ems_usb_openfunction ems_usb_start_xmitfunction allowedfunction ems_usb_closefunction ems_usb_set_modefunction ems_usb_set_bittimingfunction init_params_sja1000function ems_usb_probefunction ems_usb_disconnect
Annotated Snippet
static const struct net_device_ops ems_usb_netdev_ops = {
.ndo_open = ems_usb_open,
.ndo_stop = ems_usb_close,
.ndo_start_xmit = ems_usb_start_xmit,
};
static const struct ethtool_ops ems_usb_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct can_bittiming_const ems_usb_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,
};
static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode)
{
struct ems_usb *dev = netdev_priv(netdev);
switch (mode) {
case CAN_MODE_START:
if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL))
netdev_warn(netdev, "couldn't start device");
if (netif_queue_stopped(netdev))
netif_wake_queue(netdev);
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
static int ems_usb_set_bittiming(struct net_device *netdev)
{
struct ems_usb *dev = netdev_priv(netdev);
struct can_bittiming *bt = &dev->can.bittiming;
u8 btr0, btr1;
btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
(((bt->phase_seg2 - 1) & 0x7) << 4);
if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
btr1 |= 0x80;
netdev_info(netdev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0;
dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1;
return ems_usb_command_msg(dev, &dev->active_params);
}
static void init_params_sja1000(struct ems_cpc_msg *msg)
{
struct cpc_sja1000_params *sja1000 =
&msg->msg.can_params.cc_params.sja1000;
msg->type = CPC_CMD_TYPE_CAN_PARAMS;
msg->length = sizeof(struct cpc_can_params);
msg->msgid = 0;
msg->msg.can_params.cc_type = CPC_CC_TYPE_SJA1000;
/* Acceptance filter open */
sja1000->acc_code0 = 0x00;
sja1000->acc_code1 = 0x00;
sja1000->acc_code2 = 0x00;
sja1000->acc_code3 = 0x00;
/* Acceptance filter open */
sja1000->acc_mask0 = 0xFF;
sja1000->acc_mask1 = 0xFF;
sja1000->acc_mask2 = 0xFF;
sja1000->acc_mask3 = 0xFF;
sja1000->btr0 = 0;
sja1000->btr1 = 0;
sja1000->outp_contr = SJA1000_DEFAULT_OUTPUT_CONTROL;
sja1000->mode = SJA1000_MOD_RM;
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 cpc_can_msg`, `struct cpc_sja1000_params`, `struct cpc_can_params`, `struct cpc_confirm`, `struct cpc_overrun`, `struct cpc_sja1000_can_error`, `struct cpc_can_error`, `struct cpc_can_err_counter`, `struct ems_usb`, `struct ems_tx_urb_context`.
- 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.