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 @@
#define PEGASUS_II 0x80000000
#define HAS_HOME_PNA 0x40000000
#define PEGASUS_MTU 1500
#define PEGASUS_MAX_MTU 1536
#define PEGASUS_MTU 1536
#define EPROM_WRITE 0x01
#define EPROM_READ 0x02
......@@ -45,6 +44,7 @@
#define CTRL_URB_RUNNING 0x00000010
#define CTRL_URB_SLEEP 0x00000020
#define PEGASUS_UNPLUG 0x00000040
#define PEGASUS_RX_URB_FAIL 0x00000080
#define ETH_REGS_CHANGE 0x40000000
#define ETH_REGS_CHANGED 0x80000000
......@@ -98,13 +98,14 @@ typedef struct pegasus {
unsigned features;
int dev_index;
int intr_interval;
struct tasklet_struct rx_tl;
struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb;
struct sk_buff *rx_skb;
struct usb_ctrlrequest dr;
wait_queue_head_t ctrl_wait;
struct semaphore sem;
unsigned char rx_buff[PEGASUS_MAX_MTU];
unsigned char tx_buff[PEGASUS_MAX_MTU];
unsigned char intr_buff[8];
__u8 tx_buff[PEGASUS_MTU];
__u8 eth_regs[4];
__u8 phy;
__u8 gpio_res;
......@@ -236,7 +237,7 @@ PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
LINKSYS_GPIO_RESET | HAS_HOME_PNA )
PEGASUS_DEV( "Linksys USB Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
LINKSYS_GPIO_RESET )
PEGASUS_DEV( "Linksys USB USB10TX", VENDOR_LINKSYS, 0x400b,
PEGASUS_DEV( "Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
LINKSYS_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
LINKSYS_GPIO_RESET | PEGASUS_II )
......
......@@ -22,7 +22,7 @@
#include <asm/uaccess.h>
/* 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_DESC "rtl8150 based usb-ethernet driver"
......@@ -65,6 +65,7 @@
#define RTL8150_HW_CRC 0
#define RX_REG_SET 1
#define RTL8150_UNPLUG 2
#define RX_URB_FAIL 3
/* Define these values to match your device */
#define VENDOR_ID_REALTEK 0x0bda
......@@ -296,20 +297,19 @@ static void read_bulk_callback(struct urb *urb)
u16 rx_stat;
dev = urb->context;
if (!dev) {
warn("!dev");
if (!dev)
return;
if (test_bit(RTL8150_UNPLUG, &dev->flags))
return;
}
netdev = dev->netdev;
if (!netif_device_present(netdev)) {
warn("the network device is not present");
if (!netif_device_present(netdev))
return;
}
switch (urb->status) {
case 0:
break;
case -ENOENT:
return;
return; /* urb's in unlink state */
case -ETIMEDOUT:
warn("reset needed may be?..");
goto goon;
......@@ -318,6 +318,8 @@ static void read_bulk_callback(struct urb *urb)
goto goon;
}
tasklet_schedule(&dev->tl);
if (!dev->rx_skb) {
/* lost packets++ */
return;
......@@ -333,8 +335,6 @@ static void read_bulk_callback(struct urb *urb)
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
tasklet_schedule(&dev->tl);
skb = pull_skb(dev);
if (!skb) {
dev->rx_skb = NULL;
......@@ -347,8 +347,10 @@ static void read_bulk_callback(struct urb *urb)
goon:
FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
if ((res = usb_submit_urb(dev->rx_urb, GFP_ATOMIC)))
warn("%s: Rx urb submission failed %d", netdev->name, res);
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC))
set_bit(RX_URB_FAIL, &dev->flags);
else
clear_bit(RX_URB_FAIL, &dev->flags);
}
static void rx_fixup(unsigned long data)
......@@ -357,18 +359,25 @@ static void rx_fixup(unsigned long data)
struct sk_buff *skb;
dev = (rtl8150_t *)data;
fill_skb_pool(dev);
skb = pull_skb(dev);
if (!skb) {
if (test_bit(RX_URB_FAIL, &dev->flags))
goto try_again;
if (dev->rx_skb)
return;
if (!(skb = pull_skb(dev))) {
tasklet_schedule(&dev->tl);
return;
}
if (dev->rx_skb)
return;
dev->rx_skb = skb;
FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
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)
......@@ -544,7 +553,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
dev->tx_skb = skb;
FILL_BULK_URB(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
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);
dev->stats.tx_errors++;
netif_start_queue(netdev);
......@@ -598,10 +607,10 @@ static int rtl8150_close(struct net_device *netdev)
return -ENODEV;
down(&dev->sem);
netif_stop_queue(netdev);
if (!test_bit(RTL8150_UNPLUG, &dev->flags))
disable_net_traffic(dev);
unlink_all_urbs(dev);
netif_stop_queue(netdev);
up(&dev->sem);
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