drivers/net/can/usb/gs_usb.c
Source file repositories/reference/linux-study-clean/drivers/net/can/usb/gs_usb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/usb/gs_usb.c- Extension
.c- Size
- 44343 bytes
- Lines
- 1679
- 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/bitfield.hlinux/clocksource.hlinux/ethtool.hlinux/init.hlinux/module.hlinux/netdevice.hlinux/signal.hlinux/timecounter.hlinux/units.hlinux/usb.hlinux/workqueue.hlinux/can.hlinux/can/dev.hlinux/can/error.hlinux/can/rx-offload.h
Detected Declarations
struct gs_host_configstruct gs_device_configstruct gs_device_modestruct gs_device_statestruct gs_device_bittimingstruct gs_identify_modestruct gs_device_termination_statestruct gs_device_bt_conststruct gs_device_bt_const_extendedstruct classic_canstruct classic_can_tsstruct classic_can_quirkstruct canfdstruct canfd_tsstruct canfd_quirkstruct gs_host_framestruct gs_tx_contextstruct gs_canstruct gs_usbenum gs_usb_breqenum gs_can_modeenum gs_can_stateenum gs_can_identify_modeenum gs_can_termination_statefunction gs_free_tx_contextfunction gs_cmd_resetfunction gs_usb_get_timestampfunction gs_usb_timestamp_readfunction gs_usb_timestamp_workfunction gs_usb_skb_set_timestampfunction gs_usb_timestamp_initfunction gs_usb_timestamp_stopfunction gs_update_statefunction gs_usb_set_timestampfunction gs_usb_rx_offloadfunction gs_usb_get_echo_skbfunction gs_usb_get_minimum_rx_lengthfunction gs_usb_receive_bulk_callbackfunction gs_usb_set_bittimingfunction gs_usb_set_data_bittimingfunction gs_usb_xmit_callbackfunction gs_can_start_xmitfunction gs_can_openfunction gs_usb_get_statefunction gs_usb_can_get_berr_counterfunction gs_can_closefunction gs_can_hwtstamp_getfunction gs_can_hwtstamp_set
Annotated Snippet
static const struct net_device_ops gs_usb_netdev_ops = {
.ndo_open = gs_can_open,
.ndo_stop = gs_can_close,
.ndo_start_xmit = gs_can_start_xmit,
.ndo_hwtstamp_get = gs_can_hwtstamp_get,
.ndo_hwtstamp_set = gs_can_hwtstamp_set,
};
static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
{
struct gs_can *dev = netdev_priv(netdev);
struct gs_identify_mode imode;
if (do_identify)
imode.mode = cpu_to_le32(GS_CAN_IDENTIFY_ON);
else
imode.mode = cpu_to_le32(GS_CAN_IDENTIFY_OFF);
return usb_control_msg_send(dev->udev, 0, GS_USB_BREQ_IDENTIFY,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
dev->channel, 0, &imode, sizeof(imode), 100,
GFP_KERNEL);
}
/* blink LED's for finding the this interface */
static int gs_usb_set_phys_id(struct net_device *netdev,
enum ethtool_phys_id_state state)
{
const struct gs_can *dev = netdev_priv(netdev);
int rc = 0;
if (!(dev->feature & GS_CAN_FEATURE_IDENTIFY))
return -EOPNOTSUPP;
switch (state) {
case ETHTOOL_ID_ACTIVE:
rc = gs_usb_set_identify(netdev, GS_CAN_IDENTIFY_ON);
break;
case ETHTOOL_ID_INACTIVE:
rc = gs_usb_set_identify(netdev, GS_CAN_IDENTIFY_OFF);
break;
default:
break;
}
return rc;
}
static int gs_usb_get_ts_info(struct net_device *netdev,
struct kernel_ethtool_ts_info *info)
{
struct gs_can *dev = netdev_priv(netdev);
/* report if device supports HW timestamps */
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
return can_ethtool_op_get_ts_info_hwts(netdev, info);
return ethtool_op_get_ts_info(netdev, info);
}
static const struct ethtool_ops gs_usb_ethtool_ops = {
.set_phys_id = gs_usb_set_phys_id,
.get_ts_info = gs_usb_get_ts_info,
};
static int gs_usb_get_termination(struct net_device *netdev, u16 *term)
{
struct gs_can *dev = netdev_priv(netdev);
struct gs_device_termination_state term_state;
int rc;
rc = usb_control_msg_recv(dev->udev, 0, GS_USB_BREQ_GET_TERMINATION,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
dev->channel, 0,
&term_state, sizeof(term_state), 1000,
GFP_KERNEL);
if (rc)
return rc;
if (term_state.state == cpu_to_le32(GS_CAN_TERMINATION_STATE_ON))
*term = GS_USB_TERMINATION_ENABLED;
else
*term = GS_USB_TERMINATION_DISABLED;
return 0;
}
static int gs_usb_set_termination(struct net_device *netdev, u16 term)
{
struct gs_can *dev = netdev_priv(netdev);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clocksource.h`, `linux/ethtool.h`, `linux/init.h`, `linux/module.h`, `linux/netdevice.h`, `linux/signal.h`, `linux/timecounter.h`.
- Detected declarations: `struct gs_host_config`, `struct gs_device_config`, `struct gs_device_mode`, `struct gs_device_state`, `struct gs_device_bittiming`, `struct gs_identify_mode`, `struct gs_device_termination_state`, `struct gs_device_bt_const`, `struct gs_device_bt_const_extended`, `struct classic_can`.
- 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.