Commit 964f3281 authored by Petko Manolov's avatar Petko Manolov Committed by Greg Kroah-Hartman

[PATCH] various pegasus and rtl8150 fixes and improvements

USB pegasus and rtl8150 fixes and improvements

pegasus:
	- using preallocated skb thus avoiding memcpy in the receive path;
	- tasklet used to handle failed skb allocations and Rx urb submission;
	- Lindent run on the result.

rtl8150:
	- better tasklet handling and a few races fixed;
	- introducing new flag for Rx urb resubmission;
	- GFP_KERNEL to GFP_ATOMIC flag change in Tx path.
parent 59985585
This diff is collapsed.
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
#define PEGASUS_II 0x80000000 #define PEGASUS_II 0x80000000
#define HAS_HOME_PNA 0x40000000 #define HAS_HOME_PNA 0x40000000
#define PEGASUS_MTU 1500 #define PEGASUS_MTU 1536
#define PEGASUS_MAX_MTU 1536
#define EPROM_WRITE 0x01 #define EPROM_WRITE 0x01
#define EPROM_READ 0x02 #define EPROM_READ 0x02
...@@ -45,6 +44,7 @@ ...@@ -45,6 +44,7 @@
#define CTRL_URB_RUNNING 0x00000010 #define CTRL_URB_RUNNING 0x00000010
#define CTRL_URB_SLEEP 0x00000020 #define CTRL_URB_SLEEP 0x00000020
#define PEGASUS_UNPLUG 0x00000040 #define PEGASUS_UNPLUG 0x00000040
#define PEGASUS_RX_URB_FAIL 0x00000080
#define ETH_REGS_CHANGE 0x40000000 #define ETH_REGS_CHANGE 0x40000000
#define ETH_REGS_CHANGED 0x80000000 #define ETH_REGS_CHANGED 0x80000000
...@@ -98,13 +98,14 @@ typedef struct pegasus { ...@@ -98,13 +98,14 @@ typedef struct pegasus {
unsigned features; unsigned features;
int dev_index; int dev_index;
int intr_interval; int intr_interval;
struct tasklet_struct rx_tl;
struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb; struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb;
struct sk_buff *rx_skb;
struct usb_ctrlrequest dr; struct usb_ctrlrequest dr;
wait_queue_head_t ctrl_wait; wait_queue_head_t ctrl_wait;
struct semaphore sem; struct semaphore sem;
unsigned char rx_buff[PEGASUS_MAX_MTU];
unsigned char tx_buff[PEGASUS_MAX_MTU];
unsigned char intr_buff[8]; unsigned char intr_buff[8];
__u8 tx_buff[PEGASUS_MTU];
__u8 eth_regs[4]; __u8 eth_regs[4];
__u8 phy; __u8 phy;
__u8 gpio_res; __u8 gpio_res;
...@@ -236,7 +237,7 @@ PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204, ...@@ -236,7 +237,7 @@ PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
LINKSYS_GPIO_RESET | HAS_HOME_PNA ) LINKSYS_GPIO_RESET | HAS_HOME_PNA )
PEGASUS_DEV( "Linksys USB Ethernet Adapter", VENDOR_LINKSYS, 0x2206, PEGASUS_DEV( "Linksys USB Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
LINKSYS_GPIO_RESET ) LINKSYS_GPIO_RESET )
PEGASUS_DEV( "Linksys USB USB10TX", VENDOR_LINKSYS, 0x400b, PEGASUS_DEV( "Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
LINKSYS_GPIO_RESET | PEGASUS_II ) LINKSYS_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c, PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
LINKSYS_GPIO_RESET | PEGASUS_II ) LINKSYS_GPIO_RESET | PEGASUS_II )
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
/* Version Information */ /* Version Information */
#define DRIVER_VERSION "v0.5.3 (2002/04/08)" #define DRIVER_VERSION "v0.5.4 (2002/04/11)"
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_DESC "rtl8150 based usb-ethernet driver" #define DRIVER_DESC "rtl8150 based usb-ethernet driver"
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#define RTL8150_HW_CRC 0 #define RTL8150_HW_CRC 0
#define RX_REG_SET 1 #define RX_REG_SET 1
#define RTL8150_UNPLUG 2 #define RTL8150_UNPLUG 2
#define RX_URB_FAIL 3
/* Define these values to match your device */ /* Define these values to match your device */
#define VENDOR_ID_REALTEK 0x0bda #define VENDOR_ID_REALTEK 0x0bda
...@@ -296,20 +297,19 @@ static void read_bulk_callback(struct urb *urb) ...@@ -296,20 +297,19 @@ static void read_bulk_callback(struct urb *urb)
u16 rx_stat; u16 rx_stat;
dev = urb->context; dev = urb->context;
if (!dev) { if (!dev)
warn("!dev"); return;
if (test_bit(RTL8150_UNPLUG, &dev->flags))
return; return;
}
netdev = dev->netdev; netdev = dev->netdev;
if (!netif_device_present(netdev)) { if (!netif_device_present(netdev))
warn("the network device is not present");
return; return;
}
switch (urb->status) { switch (urb->status) {
case 0: case 0:
break; break;
case -ENOENT: case -ENOENT:
return; return; /* urb's in unlink state */
case -ETIMEDOUT: case -ETIMEDOUT:
warn("reset needed may be?.."); warn("reset needed may be?..");
goto goon; goto goon;
...@@ -318,6 +318,8 @@ static void read_bulk_callback(struct urb *urb) ...@@ -318,6 +318,8 @@ static void read_bulk_callback(struct urb *urb)
goto goon; goto goon;
} }
tasklet_schedule(&dev->tl);
if (!dev->rx_skb) { if (!dev->rx_skb) {
/* lost packets++ */ /* lost packets++ */
return; return;
...@@ -333,8 +335,6 @@ static void read_bulk_callback(struct urb *urb) ...@@ -333,8 +335,6 @@ static void read_bulk_callback(struct urb *urb)
dev->stats.rx_packets++; dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len; dev->stats.rx_bytes += pkt_len;
tasklet_schedule(&dev->tl);
skb = pull_skb(dev); skb = pull_skb(dev);
if (!skb) { if (!skb) {
dev->rx_skb = NULL; dev->rx_skb = NULL;
...@@ -347,8 +347,10 @@ static void read_bulk_callback(struct urb *urb) ...@@ -347,8 +347,10 @@ static void read_bulk_callback(struct urb *urb)
goon: goon:
FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
if ((res = usb_submit_urb(dev->rx_urb, GFP_ATOMIC))) if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC))
warn("%s: Rx urb submission failed %d", netdev->name, res); set_bit(RX_URB_FAIL, &dev->flags);
else
clear_bit(RX_URB_FAIL, &dev->flags);
} }
static void rx_fixup(unsigned long data) static void rx_fixup(unsigned long data)
...@@ -357,18 +359,25 @@ static void rx_fixup(unsigned long data) ...@@ -357,18 +359,25 @@ static void rx_fixup(unsigned long data)
struct sk_buff *skb; struct sk_buff *skb;
dev = (rtl8150_t *)data; dev = (rtl8150_t *)data;
fill_skb_pool(dev); fill_skb_pool(dev);
skb = pull_skb(dev); if (test_bit(RX_URB_FAIL, &dev->flags))
if (!skb) { goto try_again;
if (dev->rx_skb)
return;
if (!(skb = pull_skb(dev))) {
tasklet_schedule(&dev->tl); tasklet_schedule(&dev->tl);
return; return;
} }
if (dev->rx_skb)
return;
dev->rx_skb = skb; dev->rx_skb = skb;
FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
usb_submit_urb(dev->rx_urb, GFP_ATOMIC); try_again:
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
set_bit(RX_URB_FAIL, &dev->flags);
tasklet_schedule(&dev->tl);
} else
clear_bit(RX_URB_FAIL, &dev->flags);
} }
static void write_bulk_callback(struct urb *urb) static void write_bulk_callback(struct urb *urb)
...@@ -544,7 +553,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -544,7 +553,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
dev->tx_skb = skb; dev->tx_skb = skb;
FILL_BULK_URB(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), FILL_BULK_URB(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
skb->data, count, write_bulk_callback, dev); skb->data, count, write_bulk_callback, dev);
if ((res = usb_submit_urb(dev->tx_urb, GFP_KERNEL))) { if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
warn("failed tx_urb %d\n", res); warn("failed tx_urb %d\n", res);
dev->stats.tx_errors++; dev->stats.tx_errors++;
netif_start_queue(netdev); netif_start_queue(netdev);
...@@ -598,10 +607,10 @@ static int rtl8150_close(struct net_device *netdev) ...@@ -598,10 +607,10 @@ static int rtl8150_close(struct net_device *netdev)
return -ENODEV; return -ENODEV;
down(&dev->sem); down(&dev->sem);
netif_stop_queue(netdev);
if (!test_bit(RTL8150_UNPLUG, &dev->flags)) if (!test_bit(RTL8150_UNPLUG, &dev->flags))
disable_net_traffic(dev); disable_net_traffic(dev);
unlink_all_urbs(dev); unlink_all_urbs(dev);
netif_stop_queue(netdev);
up(&dev->sem); up(&dev->sem);
return res; return res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment