On Mon, Nov 29, 2010 at 5:17 PM, sugnan prabhu <sugnan.prabhu@xxxxxxxxx> wrote: > > Hello, > I am trying to write a kernel module which is the combination of the > usb driver and a network driver, now whenever the data is recieved by the > usb driver it will be in struct urb, but the data that is required by the > net driver is sk_buff, now how do i convert a urb to sk_buff, My reply is not a direct answer of your question but it might help you to understand. In USB driver the read and write is done via making calls to file operations which are same for character drivers. I.e. the USB end points is some thing you need to understand. For a USB driver the device will be reading and writing to the endpoints. Hence you need to have char driver which can create all this for you. >i found > something similar is being done in the phonet protocol, but i couldnt > understand, howexactly this is being done. Can someone explain this code. > drivers/net/usb/cdc-phonet.c > ------------------------------------------------------------------ > static void rx_complete(struct urb *req) > { > struct net_device *dev = req->context; > struct usbpn_dev *pnd = netdev_priv(dev); > struct page *page = virt_to_page(req->transfer_buffer); > struct sk_buff *skb; > unsigned long flags; > int status = req->status; > switch (status) { > case 0: > spin_lock_irqsave(&pnd->rx_lock, flags); > skb = pnd->rx_skb; > if (!skb) { > skb = pnd->rx_skb = netdev_alloc_skb(dev, 12); > if (likely(skb)) { > /* Can't use pskb_pull() on page in IRQ */ > memcpy(skb_put(skb, 1), page_address(page), 1); > skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, > page, 1, req->actual_length); > page = NULL; > } The above is for receiving end (usually rx functions are for receive) > } else { > skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, > page, 0, req->actual_length); > page = NULL; > } > if (req->actual_length < PAGE_SIZE) > pnd->rx_skb = NULL; /* Last fragment */ > else > skb = NULL; > spin_unlock_irqrestore(&pnd->rx_lock, flags); > if (skb) { > skb->protocol = htons(ETH_P_PHONET); > skb_reset_mac_header(skb); > __skb_pull(skb, 1); > skb->dev = dev; > dev->stats.rx_packets++; > dev->stats.rx_bytes += skb->len; > netif_rx(skb); > } > goto resubmit; > case -ENOENT: > case -ECONNRESET: > case -ESHUTDOWN: > req = NULL; > break; > case -EOVERFLOW: > dev->stats.rx_over_errors++; > dev_dbg(&dev->dev, "RX overflow\n"); > break; > case -EILSEQ: > dev->stats.rx_crc_errors++; > break; > } > dev->stats.rx_errors++; > resubmit: > if (page) > netdev_free_page(dev, page); > if (req) > rx_submit(pnd, req, GFP_ATOMIC); > } > > I don't think what you are asking is actually linked to the code you posted. -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ