Конвертировать урб в скбафф

Я пытаюсь написать модуль ядра, который представляет собой комбинацию драйвера USB и сетевого драйвера, теперь всякий раз, когда данные получены драйвером USB, он будет в структуре urb, но данные, которые требуются сетевому драйверу, sk_buff , теперь как мне преобразовать urb в sk_buff, я нашел что-то подобное делается в протоколе phonet, но я не мог понять, как именно это делается. Может кто-нибудь объяснить этот код.

драйверы/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);
}

person reality displays    schedule 30.11.2010    source источник


Ответы (1)


Структура URB не содержит фактически переданных данных, а содержит указатель на данные, элемент transfer_buffer.

Код в основном копирует данные из буфера передачи в буфер sk. virt_to_page/page_address вернет виртуальный адрес начала страницы transfer_buffer.

person Andrew Roca    schedule 30.11.2010