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,
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




[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