⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kaweth.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			      KAWETH_CONTROL_TIMEOUT);}/**************************************************************** *     kaweth_trigger_firmware ****************************************************************/static int kaweth_trigger_firmware(struct kaweth_device *kaweth,				   __u8 interrupt){	kaweth->firmware_buf[0] = 0xB6;	kaweth->firmware_buf[1] = 0xC3;	kaweth->firmware_buf[2] = 0x01;	kaweth->firmware_buf[3] = 0x00;	kaweth->firmware_buf[4] = 0x06;	kaweth->firmware_buf[5] = interrupt;	kaweth->firmware_buf[6] = 0x00;	kaweth->firmware_buf[7] = 0x00;	kaweth_dbg("Triggering firmware");	return kaweth_control(kaweth,			      usb_sndctrlpipe(kaweth->dev, 0),			      KAWETH_COMMAND_SCAN,			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,			      0,			      0,			      (void *)kaweth->firmware_buf,			      8,			      KAWETH_CONTROL_TIMEOUT);}/**************************************************************** *     kaweth_reset ****************************************************************/static int kaweth_reset(struct kaweth_device *kaweth){	int result;	kaweth_dbg("kaweth_reset(%p)", kaweth);	result = kaweth_control(kaweth,				usb_sndctrlpipe(kaweth->dev, 0),				USB_REQ_SET_CONFIGURATION,				0,				kaweth->dev->config[0].bConfigurationValue,				0,				NULL,				0,				KAWETH_CONTROL_TIMEOUT);	udelay(10000);	kaweth_dbg("kaweth_reset() returns %d.",result);	return result;}static void kaweth_usb_receive(struct urb *);static void kaweth_resubmit_rx_urb(struct kaweth_device *);/****************************************************************	int_callback*****************************************************************/static void int_callback(struct urb *u){	struct kaweth_device *kaweth = u->context;	int act_state;	/* we abuse the interrupt urb for rebsubmitting under low memory saving a timer */	if (kaweth->suspend_lowmem)		kaweth_resubmit_rx_urb(kaweth);	/* we check the link state to report changes */	if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) {		if (!act_state)			netif_carrier_on(kaweth->net);		else			netif_carrier_off(kaweth->net);		kaweth->linkstate = act_state;	}}/**************************************************************** *     kaweth_resubmit_rx_urb ****************************************************************/static void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth){	int result;	long flags;	FILL_BULK_URB(kaweth->rx_urb,		      kaweth->dev,		      usb_rcvbulkpipe(kaweth->dev, 1),		      kaweth->rx_buf,		      KAWETH_BUF_SIZE,		      kaweth_usb_receive,		      kaweth);	spin_lock_irqsave(&kaweth->device_lock, flags);	if (!kaweth->removed) { /* no resubmit if disconnecting */		if((result = usb_submit_urb(kaweth->rx_urb))) {			if (result == -ENOMEM)				kaweth->suspend_lowmem = 1;			kaweth_err("resubmitting rx_urb %d failed", result);		} else {			kaweth->suspend_lowmem = 0;		}	}	spin_unlock_irqrestore(&kaweth->device_lock, flags);}static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth);/**************************************************************** *     kaweth_usb_receive ****************************************************************/static void kaweth_usb_receive(struct urb *urb){	struct kaweth_device *kaweth = urb->context;	struct net_device *net = kaweth->net;	int count = urb->actual_length;	int count2 = urb->transfer_buffer_length;	__u16 pkt_len = le16_to_cpup((u16 *)kaweth->rx_buf);	struct sk_buff *skb;	if(urb->status == -ECONNRESET || urb->status == -ECONNABORTED)	/* we are killed - set a flag and wake the disconnect handler */	{		kaweth->end = 1;		wake_up(&kaweth->term_wait);		return;	}	if (kaweth->status & KAWETH_STATUS_CLOSING)		return;	if(urb->status && urb->status != -EREMOTEIO && count != 1) {		kaweth_err("%s RX status: %d count: %d packet_len: %d",                           net->name,			   urb->status,			   count,			   (int)pkt_len);		kaweth_resubmit_rx_urb(kaweth);                return;	}	if(kaweth->net && (count > 2)) {		if(pkt_len > (count - 2)) {			kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);			kaweth_err("Packet len & 2047: %x", pkt_len & 2047);			kaweth_err("Count 2: %x", count2);		        kaweth_resubmit_rx_urb(kaweth);                        return;                }		if(!(skb = dev_alloc_skb(pkt_len+2))) {		        kaweth_resubmit_rx_urb(kaweth);                        return;		}		skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */		skb->dev = net;		eth_copy_and_sum(skb, kaweth->rx_buf + 2, pkt_len, 0);		skb_put(skb, pkt_len);		skb->protocol = eth_type_trans(skb, net);		netif_rx(skb);		kaweth->stats.rx_packets++;		kaweth->stats.rx_bytes += pkt_len;	}	kaweth_resubmit_rx_urb(kaweth);}/**************************************************************** *     kaweth_open ****************************************************************/static int kaweth_open(struct net_device *net){	struct kaweth_device *kaweth = (struct kaweth_device *)net->priv;	kaweth_dbg("Dev usage: %d", kaweth->dev->refcnt.counter);	kaweth_dbg("Opening network device.");	MOD_INC_USE_COUNT;	kaweth_resubmit_rx_urb(kaweth);	FILL_INT_URB(		kaweth->irq_urb,		kaweth->dev,		usb_rcvintpipe(kaweth->dev, 3),		kaweth->intbuffer,		INTBUFFERSIZE,		int_callback,		kaweth,		HZ/4);	usb_submit_urb(kaweth->irq_urb);	netif_start_queue(net);	kaweth_async_set_rx_mode(kaweth);	return 0;}/**************************************************************** *     kaweth_close ****************************************************************/static int kaweth_close(struct net_device *net){	struct kaweth_device *kaweth = net->priv;	netif_stop_queue(net);		spin_lock_irq(&kaweth->device_lock);	kaweth->status |= KAWETH_STATUS_CLOSING;	spin_unlock_irq(&kaweth->device_lock);	usb_unlink_urb(kaweth->irq_urb);	usb_unlink_urb(kaweth->rx_urb);	kaweth->status &= ~KAWETH_STATUS_CLOSING;	MOD_DEC_USE_COUNT;	printk("Dev usage: %d", kaweth->dev->refcnt.counter);	return 0;}static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr){	u32 ethcmd;		if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))		return -EFAULT;		switch (ethcmd) {	case ETHTOOL_GDRVINFO: {		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};		strncpy(info.driver, "kaweth", sizeof(info.driver)-1);		if (copy_to_user(useraddr, &info, sizeof(info)))			return -EFAULT;		return 0;	}	}		return -EOPNOTSUPP;}/**************************************************************** *     kaweth_ioctl ****************************************************************/static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd){	switch (cmd) {	case SIOCETHTOOL:		return netdev_ethtool_ioctl(net, (void *) rq->ifr_data);	}	return -EOPNOTSUPP;}/**************************************************************** *     kaweth_usb_transmit_complete ****************************************************************/static void kaweth_usb_transmit_complete(struct urb *urb){	struct kaweth_device *kaweth = urb->context;	struct sk_buff *skb = kaweth->tx_skb;	if (urb->status != 0)		kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);	netif_wake_queue(kaweth->net);	dev_kfree_skb(skb);}/**************************************************************** *     kaweth_start_xmit ****************************************************************/static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net){	struct kaweth_device *kaweth = net->priv;	char *private_header;	int res;	spin_lock(&kaweth->device_lock);	if (kaweth->removed) {	/* our device is undergoing disconnection - we bail out */		spin_unlock(&kaweth->device_lock);		dev_kfree_skb(skb);		return 0;	}	kaweth_async_set_rx_mode(kaweth);	netif_stop_queue(net);	/* We now decide whether we can put our special header into the sk_buff */	if (skb_cloned(skb) || skb_headroom(skb) < 2) {		/* no such luck - we make our own */		struct sk_buff *copied_skb;		copied_skb = skb_copy_expand(skb, 2, 0, GFP_ATOMIC);		dev_kfree_skb_any(skb);		skb = copied_skb;		if (!copied_skb) {			kaweth->stats.tx_errors++;			netif_start_queue(net);			spin_unlock(&kaweth->device_lock);			return 0;		}	}	private_header = __skb_push(skb, 2);	*private_header = cpu_to_le16(skb->len);	kaweth->tx_skb = skb;	FILL_BULK_URB(kaweth->tx_urb,		      kaweth->dev,		      usb_sndbulkpipe(kaweth->dev, 2),		      private_header,		      skb->len,		      kaweth_usb_transmit_complete,		      kaweth);	kaweth->end = 0;	kaweth->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;	if((res = usb_submit_urb(kaweth->tx_urb)))	{		kaweth_warn("kaweth failed tx_urb %d", res);		kaweth->stats.tx_errors++;		netif_start_queue(net);		dev_kfree_skb(skb);	}	else	{		kaweth->stats.tx_packets++;		kaweth->stats.tx_bytes += skb->len;		net->trans_start = jiffies;	}	spin_unlock(&kaweth->device_lock);	return 0;}/**************************************************************** *     kaweth_set_rx_mode ****************************************************************/static void kaweth_set_rx_mode(struct net_device *net){	struct kaweth_device *kaweth = net->priv;	__u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED |                                     KAWETH_PACKET_FILTER_BROADCAST |		                     KAWETH_PACKET_FILTER_MULTICAST;	kaweth_dbg("Setting Rx mode to %d", packet_filter_bitmap);	netif_stop_queue(net);	if (net->flags & IFF_PROMISC) {		packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS;	}	else if ((net->mc_count) || (net->flags & IFF_ALLMULTI)) {		packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST;	}	kaweth->packet_filter_bitmap = packet_filter_bitmap;	netif_wake_queue(net);}/**************************************************************** *     kaweth_async_set_rx_mode ****************************************************************/static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth){	__u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;	kaweth->packet_filter_bitmap = 0;	if(packet_filter_bitmap == 0) return;	{	int result;	result = kaweth_control(kaweth,				usb_sndctrlpipe(kaweth->dev, 0),				KAWETH_COMMAND_SET_PACKET_FILTER,				USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,				packet_filter_bitmap,				0,				(void *)&kaweth->scratch,				0,				KAWETH_CONTROL_TIMEOUT);	if(result < 0) {		kaweth_err("Failed to set Rx mode: %d", result);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -