lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:	Thu, 19 Feb 2015 13:53:40 +0100
From:	Shahin Ghazinouri <shahin.ghazinouri@...agicore.com>
To:	netdev@...r.kernel.org
Subject: Possible to support usbnet device with two IN endpoints?

Hi,
I'm developing a driver for a USB network device that filters received
network packets into two separate USB IN endpoints. This means a
second rx urb has to be allocated and submitted.

Right now, the implementation relies on patching usbnet.c (see below),
so that a second urb is allocated and rx_submit_fixup is called in
addition to rx_submit. This function is a copy of rx_submit, except it
submits an urb to receive data from the second endpoint.

Since I don't think this patch is a good idea, I would appreciate any
ideas on how to support a usbnet device with two IN endpoints within
the current framework.

Kind regards,
Shahin

diff -Naur a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
--- a/drivers/net/usb/usbnet.c 2014-11-03 21:49:29.000000000 +0100
+++ b/drivers/net/usb/usbnet.c 2014-11-05 11:13:37.824809365 +0100
@@ -1068,30 +1070,65 @@
  }
  }

- /* tasklet could resubmit itself forever if memory is tight */
- if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
- struct urb *urb = NULL;
- int resched = 1;
-
- if (netif_running (dev->net))
- urb = usb_alloc_urb (0, GFP_KERNEL);
- else
- clear_bit (EVENT_RX_MEMORY, &dev->flags);
- if (urb != NULL) {
- clear_bit (EVENT_RX_MEMORY, &dev->flags);
- status = usb_autopm_get_interface(dev->intf);
- if (status < 0) {
- usb_free_urb(urb);
- goto fail_lowmem;
- }
- if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK)
- resched = 0;
- usb_autopm_put_interface(dev->intf);
+    if(!dev->driver_info->rx_submit_fixup)
+    {
+        /* tasklet could resubmit itself forever if memory is tight */
+        if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
+            struct urb *urb = NULL;
+            int resched = 1;
+
+            if (netif_running (dev->net))
+                urb = usb_alloc_urb (0, GFP_KERNEL);
+            else
+                clear_bit (EVENT_RX_MEMORY, &dev->flags);
+            if (urb != NULL) {
+                clear_bit (EVENT_RX_MEMORY, &dev->flags);
+                status = usb_autopm_get_interface(dev->intf);
+                if (status < 0) {
+                    usb_free_urb(urb);
+                    goto fail_lowmem;
+                }
+                if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK)
+                    resched = 0;
+                usb_autopm_put_interface(dev->intf);
 fail_lowmem:
- if (resched)
- tasklet_schedule (&dev->bh);
- }
- }
+                if (resched)
+                    tasklet_schedule (&dev->bh);
+            }
+        }
+    }
+    else
+    {
+        /* tasklet could resubmit itself forever if memory is tight */
+        if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
+            struct urb *urb = NULL;
+            int resched = 1;
+            struct urb *aux_urb = NULL;
+            if (netif_running (dev->net))
+            {
+                urb = usb_alloc_urb (0, GFP_KERNEL);
+                aux_urb = usb_alloc_urb (0, GFP_KERNEL);
+            }
+            else
+                clear_bit (EVENT_RX_MEMORY, &dev->flags);
+            if ( (urb != NULL) && (aux_urb != NULL) ) {
+                clear_bit (EVENT_RX_MEMORY, &dev->flags);
+                status = usb_autopm_get_interface(dev->intf);
+                if (status < 0) {
+                    usb_free_urb(urb);
+                    usb_free_urb(aux_urb);
+                    goto fail_lowmem_1;
+                }
+                if ( (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK)
+                        || (dev->driver_info->rx_submit_fixup (dev,
aux_urb, GFP_KERNEL) == -ENOLINK) )
+                    resched = 0;
+                usb_autopm_put_interface(dev->intf);
+fail_lowmem_1:
+                if (resched)
+                    tasklet_schedule (&dev->bh);
+            }
+        }
+    }

  if (test_bit (EVENT_LINK_RESET, &dev->flags)) {
  struct driver_info *info = dev->driver_info;
@@ -1313,6 +1350,7 @@
  struct urb *urb;
  int i;
  int ret = 0;
+    struct urb *aux_urb;

  /* don't refill the queue all at once */
  for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) {
@@ -1325,6 +1363,18 @@
  ret = -ENOMEM;
  goto err;
  }
+        if(dev->driver_info->rx_submit_fixup)
+        {
+            aux_urb = usb_alloc_urb(0, flags);
+            if (aux_urb != NULL) {
+                ret = dev->driver_info->rx_submit_fixup(dev, aux_urb, flags);
+                if (ret)
+                    goto err;
+            } else {
+                ret = -ENOMEM;
+                goto err;
+            }
+        }
  }
 err:
  return ret;
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ