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

📄 ecos_usbeth.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                   usbeth->tx_buffer[i+4], usbeth->tx_buffer[i+5], usbeth->tx_buffer[i+6], usbeth->tx_buffer[i+7]);        }        printk("--------------------------------------------------------------\n");    }#endif    res = usb_submit_urb(&(usbeth->tx_urb));    if (0 == res) {        netif_stop_queue(net);        net->trans_start        = jiffies;        usbeth->stats.tx_packets++;        usbeth->stats.tx_bytes  += skb->len;    } else {                printk("ecos_usbeth: failed to start USB packet transmission, %d\n", res);        usbeth->stats.tx_errors++;    }        spin_unlock(&usbeth->usb_lock);    dev_kfree_skb(skb);    return 0;}// set_rx_mode()// Invoked by the network stack to enable/disable promiscuous mode or// for multicasting. The latter is not yet supported on the target// side. The former involves a USB control message. The main call// is not allowed to block.static voidecos_usbeth_set_rx_mode_callback(struct urb* urb){    kfree(urb->setup_packet);    usb_free_urb(urb);}static voidecos_usbeth_set_rx_mode(struct net_device* net){    ecos_usbeth* usbeth         = (ecos_usbeth*) net->priv;    __u16        promiscuous    = net->flags & IFF_PROMISC;    int          res;        if (promiscuous != usbeth->target_promiscuous) {        devrequest*     req;        urb_t*          urb;        urb = usb_alloc_urb(0);        if ((urb_t*)0 == urb) {            return;        }        req = kmalloc(sizeof(devrequest), GFP_KERNEL);        if ((devrequest*)0 == req) {            usb_free_urb(urb);            return;        }        req->requesttype        = USB_TYPE_CLASS | USB_RECIP_DEVICE;        req->request            = ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE;        req->value              = cpu_to_le16p(&promiscuous);        req->index              = 0;        req->length             = 0;        FILL_CONTROL_URB(urb,                         usbeth->usb_dev,                         usb_sndctrlpipe(usbeth->usb_dev, 0),                         (unsigned char*) req,                         (void*) 0,                         0,                         &ecos_usbeth_set_rx_mode_callback,                         (void*) usbeth);        res = usb_submit_urb(urb);        if (0 != res) {            kfree(req);            usb_free_urb(urb);        } else {            usbeth->target_promiscuous = promiscuous;        }    }}// netdev_stats()// Supply the current network statistics. These are held in// the stats field of the ecos_usbeth structurestatic struct net_device_stats*ecos_usbeth_netdev_stats(struct net_device* net){    ecos_usbeth* usbeth = (ecos_usbeth*) net->priv;    return &(usbeth->stats);}// ioctl()// Currently none of the network ioctl()'s are supportedstatic intecos_usbeth_ioctl(struct net_device* net, struct ifreq* request, int command){    return -EINVAL;}// probe().// This is invoked by the generic USB code when a new device has// been detected and its configuration details have been extracted// and stored in the usbdev structure. The interface_id specifies// a specific USB interface, to cope with multifunction peripherals.//// FIXME; right now this code only copes with simple enumeration data.// OK, to be really honest it just looks for the vendor and device ids// in the simple test cases and ignores everything else.//// On success it should return a non-NULL pointer, which happens to be// a newly allocated ecos_usbeth structure. This will get passed to// the disconnect function. Filling in the ecos_usbeth structure will,// amongst other things, register this as a network device driver.// The MAC address is obtained from the peripheral via a control// request.static void*ecos_usbeth_probe(struct usb_device* usbdev, unsigned int interface_id){    struct net_device*  net;    ecos_usbeth*        usbeth;    int                 res;    unsigned char       MAC[6];    unsigned char       dummy[1];    int                 tx_endpoint = -1;    int                 rx_endpoint = -1;    const ecos_usbeth_impl*   impl;    int                 found_impl = 0;    // See if this is the correct driver for this USB peripheral.    impl = ecos_usbeth_implementations;    while (impl->name != NULL) {        if ((usbdev->descriptor.idVendor  != impl->vendor) ||            (usbdev->descriptor.idProduct != impl->id)) {            found_impl = 1;            break;        }        impl++;    }    if (! found_impl) {        return (void*) 0;    }    // For now only support USB-ethernet peripherals consisting of a single    // configuration, with a single interface, with two bulk endpoints.    if ((1 != usbdev->descriptor.bNumConfigurations)  ||        (1 != usbdev->config[0].bNumInterfaces) ||        (2 != usbdev->config[0].interface[0].altsetting->bNumEndpoints)) {        return (void*) 0;    }    if ((0 == (usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress & USB_DIR_IN)) &&        (0 != (usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress & USB_DIR_IN))) {        tx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress;        rx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress & ~USB_DIR_IN;    }    if ((0 != (usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress & USB_DIR_IN)) &&        (0 == (usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress & USB_DIR_IN))) {        tx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[1].bEndpointAddress;        rx_endpoint = usbdev->config[0].interface[0].altsetting->endpoint[0].bEndpointAddress & ~USB_DIR_IN;    }    if (-1 == tx_endpoint) {        return (void*) 0;    }               res = usb_set_configuration(usbdev, usbdev->config[0].bConfigurationValue);    if (0 != res) {        printk("ecos_usbeth: failed to set configuration, %d\n", res);        return (void*) 0;    }    res = usb_control_msg(usbdev,                          usb_rcvctrlpipe(usbdev, 0),                          ECOS_USBETH_CONTROL_GET_MAC_ADDRESS,                          USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_DIR_IN,                          0,                          0,                          (void*) MAC,                          6,                          5 * HZ);    if (6 != res) {        printk("ecos_usbeth: failed to get MAC address, %d\n", res);        return (void*) 0;    }        res = usb_control_msg(usbdev,                          usb_sndctrlpipe(usbdev, 0),                           // pipe                          ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE,             // request                          USB_TYPE_CLASS | USB_RECIP_DEVICE,                    // requesttype                          0,                                                    // value                          0,                                                    // index                          (void*) dummy,                                        // data                          0,                                                    // size                          5 * HZ);                                              // timeout    if (0 != res) {        printk("ecos_usbeth: failed to disable promiscous mode, %d\n", res);    }               usbeth = (ecos_usbeth*) kmalloc(sizeof(ecos_usbeth), GFP_KERNEL);    if ((ecos_usbeth*)0 == usbeth) {        printk("ecos_usbeth: failed to allocate memory for usbeth data structure\n");        return (void*) 0;    }    memset(usbeth, 0, sizeof(ecos_usbeth));        net                 = init_etherdev(0, 0);    if ((struct net_device*) 0 == net) {        kfree(usbeth);        printk("ecos_usbeth: failed to allocate memory for net data structure\n");        return (void*) 0;    }    usbeth->usb_lock    = SPIN_LOCK_UNLOCKED;    usbeth->usb_dev     = usbdev;    FILL_BULK_URB(&(usbeth->tx_urb), usbdev, usb_sndbulkpipe(usbdev, tx_endpoint),                  usbeth->tx_buffer, ECOS_USBETH_MAXTU, &ecos_usbeth_tx_callback, (void*) usbeth);    FILL_BULK_URB(&(usbeth->rx_urb), usbdev, usb_rcvbulkpipe(usbdev, rx_endpoint),                  usbeth->rx_buffer, ECOS_USBETH_MAXTU, &ecos_usbeth_rx_callback, (void*) usbeth);        usbeth->net_dev             = net;    usbeth->target_promiscuous  = 0;        net->priv                   = (void*) usbeth;    net->open                   = &ecos_usbeth_open;    net->stop                   = &ecos_usbeth_close;    net->do_ioctl               = &ecos_usbeth_ioctl;    net->hard_start_xmit        = &ecos_usbeth_start_tx;    net->set_multicast_list     = &ecos_usbeth_set_rx_mode;    net->get_stats              = &ecos_usbeth_netdev_stats;    net->mtu                    = 1500; // ECOS_USBETH_MAXTU - 2;    memcpy(net->dev_addr, MAC, 6);        printk("eCos-based USB ethernet peripheral active at %s\n", net->name);    MOD_INC_USE_COUNT;    return (void*) usbeth;}// disconnect().// Invoked after probe() has recognized a device but that device// has gone away. static voidecos_usbeth_disconnect(struct usb_device* usbdev, void* data){    ecos_usbeth* usbeth = (ecos_usbeth*) data;    if (!usbeth) {        printk("ecos_usbeth: warning, disconnecting unconnected device\n");        return;    }    if (0 != netif_running(usbeth->net_dev)) {        ecos_usbeth_close(usbeth->net_dev);    }    unregister_netdev(usbeth->net_dev);    if (-EINPROGRESS == usbeth->rx_urb.status) {        usb_unlink_urb(&(usbeth->rx_urb));    }    if (-EINPROGRESS == usbeth->tx_urb.status) {        usb_unlink_urb(&(usbeth->tx_urb));    }    kfree(usbeth);    MOD_DEC_USE_COUNT;}static struct usb_driver ecos_usbeth_driver = {    name:       "ecos_usbeth",    probe:      ecos_usbeth_probe,    disconnect: ecos_usbeth_disconnect,};// init()// Called when the module is loaded. It just registers the device with// the generic USB code. Nothing else can really be done until// the USB code detects that a device has been attached.int __initecos_usbeth_init(void){    printk("eCos USB-ethernet device driver\n");    return usb_register(&ecos_usbeth_driver);}// exit()// Called when the module is unloaded. disconnect() will be// invoked if appropriate.void __exitecos_usbeth_exit(void){    usb_deregister(&ecos_usbeth_driver);}module_init(ecos_usbeth_init);module_exit(ecos_usbeth_exit);

⌨️ 快捷键说明

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