drivers/net/usb/ch9200.c

Source file repositories/reference/linux-study-clean/drivers/net/usb/ch9200.c

File Facts

System
Linux kernel
Corpus path
drivers/net/usb/ch9200.c
Extension
.c
Size
9800 bytes
Lines
430
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!buf) {
			err = -ENOMEM;
			goto err_out;
		}
	}

	err = usb_control_msg(dev->udev,
			      usb_sndctrlpipe(dev->udev, 0),
			      request, request_type, value, index, buf, size,
			      timeout);
	if (err >= 0 && err < size)
		err = -EINVAL;
	kfree(buf);

	return 0;

err_out:
	return err;
}

static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc)
{
	struct usbnet *dev = netdev_priv(netdev);
	unsigned char buff[2];
	int ret;

	netdev_dbg(netdev, "%s phy_id:%02x loc:%02x\n",
		   __func__, phy_id, loc);

	if (phy_id != 0)
		return -ENODEV;

	ret = control_read(dev, REQUEST_READ, 0, loc * 2, buff, 0x02,
			   CONTROL_TIMEOUT_MS);
	if (ret < 0)
		return ret;

	return (buff[0] | buff[1] << 8);
}

static void ch9200_mdio_write(struct net_device *netdev,
			      int phy_id, int loc, int val)
{
	struct usbnet *dev = netdev_priv(netdev);
	unsigned char buff[2];

	netdev_dbg(netdev, "%s() phy_id=%02x loc:%02x\n",
		   __func__, phy_id, loc);

	if (phy_id != 0)
		return;

	buff[0] = (unsigned char)val;
	buff[1] = (unsigned char)(val >> 8);

	control_write(dev, REQUEST_WRITE, 0, loc * 2, buff, 0x02,
		      CONTROL_TIMEOUT_MS);
}

static int ch9200_link_reset(struct usbnet *dev)
{
	struct ethtool_cmd ecmd;

	mii_check_media(&dev->mii, 1, 1);
	mii_ethtool_gset(&dev->mii, &ecmd);

	netdev_dbg(dev->net, "%s() speed:%d duplex:%d\n",
		   __func__, ecmd.speed, ecmd.duplex);

	return 0;
}

static void ch9200_status(struct usbnet *dev, struct urb *urb)
{
	int link;
	unsigned char *buf;

	if (urb->actual_length < 16)
		return;

	buf = urb->transfer_buffer;
	link = !!(buf[0] & 0x01);

	if (link) {
		netif_carrier_on(dev->net);
		usbnet_defer_kevent(dev, EVENT_LINK_RESET);
	} else {
		netif_carrier_off(dev->net);
	}
}

Annotation

Implementation Notes