📄 usb-eth.c
字号:
/* * usb.c : Ethernet-over-USB for BLOB * * Copyright (c) 2003, Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#ifdef HAVE_CONFIG_H# include <blob/config.h>#endif#include <blob/arch.h>#include <blob/types.h>#include <blob/serial.h>#include <blob/util.h>#include <blob/init.h>#include <pxa_usb.h>#include <net.h>/* USB eth MAC address */unsigned char eth_mac_addr[6] = {0x0, 0x0, 0x0, 0x0, 0xf, 0xe};static int usb_rsize=64;static int usb_wsize=64;static struct mybuf* cur_tx_buf;static struct mybuf* next_tx_buf;static struct mybuf* rx_buf;#define MIN(a,b) ((a)<(b) ? (a): (b))#define ETHERNET_VENDOR_ID 0x8086#define ETHERNET_PRODUCT_ID 0x7d3static void usb_eth_send_callback(int flag, int size){ /* FIXME: assert cur_tx_buf */ if( cur_tx_buf ) { cur_tx_buf->len = 0; cur_tx_buf = 0; } else { SerialOutputString("Oops: cur_tx_buf is NULL \n"); return; } if( next_tx_buf ) { cur_tx_buf = next_tx_buf; next_tx_buf = 0; ep1_send(cur_tx_buf->buf, cur_tx_buf->len, usb_eth_send_callback); }}static void usb_eth_recv_callback(int flag, int size){ int done=1; //SerialOutputString("in usb_eth_recv_callback\n"); if( flag != 0 ) return; /* end-of-packet */ if(size == usb_rsize) { done = 0; } rx_buf->len += size; if( !done ) { if(rx_buf->len >= (BUFSZ-usb_rsize)) { SerialOutputString("Out of buffer\n"); return; } ep2_recv(rx_buf->buf+rx_buf->len, MIN(BUFSZ-rx_buf->len, usb_rsize), usb_eth_recv_callback); return; } /* SerialOutputDec(rx_buf->len); SerialOutputString(" bytes recved\n"); */ /* let's handle this */ net_rx(); /* reset buffer */ rx_buf->len = 0; memset(rx_buf->buf, 0, BUFSZ ); ep2_recv(rx_buf->buf, usb_rsize, usb_eth_recv_callback); return;}int eth_xmit(struct mybuf *out) { if( out->len < usb_wsize ) { out->len = usb_wsize + 1; } else if ( 0 == (out->len % usb_wsize) ) { out->len ++; } if( cur_tx_buf ) { if ( next_tx_buf ) { SerialOutputString("Droping\n"); return; } else next_tx_buf = out; } else { cur_tx_buf = out; ep1_send(out->buf, out->len , usb_eth_send_callback); } return 0;}void usb_driver_reset(){ desc_t * pdesc = pxa_usb_get_descriptor_ptr(); config_desc_t *cfg; intf_desc_t *intf; ep_desc_t *ep; /* setup device descriptor */ pdesc->dev.idVendor = ETHERNET_VENDOR_ID; pdesc->dev.idProduct = ETHERNET_PRODUCT_ID; pdesc->dev.bNumConfigurations = 1; cfg = (config_desc_t*) (pdesc->cdb); cfg->bLength = sizeof( config_desc_t ); cfg->bDescriptorType = USB_DESC_CONFIG; cfg->wTotalLength = make_word_c( sizeof(config_desc_t) + sizeof(intf_desc_t) * 1+ sizeof(ep_desc_t) * 2); cfg->bNumInterfaces = 1; cfg->bConfigurationValue = 1; cfg->iConfiguration = 0; cfg->bmAttributes = USB_CONFIG_BUSPOWERED; cfg->MaxPower = USB_POWER( 500 ); intf = (intf_desc_t *) ( cfg + 1); intf->bLength = sizeof( intf_desc_t ); intf->bDescriptorType = USB_DESC_INTERFACE; intf->bInterfaceNumber = 0; intf->bAlternateSetting = 0; intf->bNumEndpoints = 2; intf->bInterfaceClass = 0xFF; intf->bInterfaceSubClass = 0; intf->bInterfaceProtocol = 0; intf->iInterface = 0; ep = (ep_desc_t *) (intf + 1); ep[0].bLength = sizeof( ep_desc_t ); ep[0].bDescriptorType = USB_DESC_ENDPOINT; ep[0].bEndpointAddress = USB_EP_ADDRESS( 1, USB_IN ); ep[0].bmAttributes = USB_EP_BULK; ep[0].wMaxPacketSize = make_word( 64 ); ep[0].bInterval = 0; ep[1].bLength = sizeof( ep_desc_t ); ep[1].bDescriptorType = USB_DESC_ENDPOINT; ep[1].bEndpointAddress = USB_EP_ADDRESS( 2, USB_OUT ); ep[1].bmAttributes = USB_EP_BULK; ep[1].wMaxPacketSize = make_word( 64 ); ep[1].bInterval = 0; /* resetting */ net_reset(); rx_buf = bget(0); rx_buf->len = 0; cur_tx_buf = 0; next_tx_buf = 0; ep2_recv(rx_buf->buf, usb_rsize, usb_eth_recv_callback);}int eth_rx(){ if ( ICPR & 0x800 ) { udc_int_hndlr(0x11, 0); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -