Re: Convert urb to skbuff

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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, 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;
> }
> } 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);
> }
>
The URB struct doesn't contain the actual transfered data rather it
contains a pointer to the data, the transfer_buffer element.

The code basically copies data from the transfer buffer to the sk
buff. The virt_to_page / page_address will return the virtual address
of the start of the transfer_buffer page.
-- 
James Bond

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ




[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux