Commit 2ef7e8ce authored by Linus Torvalds's avatar Linus Torvalds

v2.4.12.4 -> v2.4.12.5

  - Greg KH: usbnet fix
  - Johannes Erdfelt: uhci.c bulk queueing fixes
parent 96c4fbbe
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 13
EXTRAVERSION =-pre4
EXTRAVERSION =-pre5
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
......@@ -138,7 +138,7 @@ struct analog_port {
#ifdef __i386__
#define TSC_PRESENT (test_bit(X86_FEATURE_TSC, &boot_cpu_data.x86_capability))
#define GET_TIME(x) do { if (TSC_PRESENT) rdtscl(x); else outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } while (0)
#define GET_TIME(x) do { if (TSC_PRESENT) rdtscl(x); else { outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } } while (0)
#define DELTA(x,y) (TSC_PRESENT?((y)-(x)):((x)-(y)+((x)<(y)?1193180L/HZ:0)))
#define TIME_NAME (TSC_PRESENT?"TSC":"PIT")
#elif __x86_64__
......@@ -499,7 +499,9 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
else
printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
port->speed > 10000 ? "M" : "k", (port->loop * 1000000) / port->speed);
port->speed > 10000 ? "M" : "k",
port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
: (port->loop * 1000000) / port->speed);
}
/*
......
This diff is collapsed.
......@@ -345,6 +345,7 @@ struct urb_priv {
int status; /* Final status */
unsigned long inserttime; /* In jiffies */
unsigned long fsbrtime; /* In jiffies */
struct list_head queue_list;
struct list_head complete_list;
......
......@@ -15,7 +15,7 @@
* support as appropriate. Devices currently supported include:
*
* - AnchorChip 2720
* - Belkin F5U104 (custom)
* - Belkin, eTEK (interops with Win32 drivers)
* - "Linux Devices" (like iPaq and similar SA-1100 based PDAs)
* - NetChip 1080 (interoperates with NetChip Win32 drivers)
* - Prolific PL-2301/2302 (replaces "plusb" driver)
......@@ -73,6 +73,9 @@
* Win32 Belkin driver; other cleanups (db).
* 16-jul-2001 Bugfixes for uhci oops-on-unplug, Belkin support, various
* cleanups for problems not yet seen in the field. (db)
* 17-oct-2001 Handle "Advance USBNET" product, like Belkin/eTEK devices,
* from Ioannis Mavroukakis <i.mavroukakis@btinternet.com>;
* rx unlinks somehow weren't async; minor cleanup.
*
*-------------------------------------------------------------------------*/
......@@ -97,7 +100,7 @@
#define CONFIG_USB_AN2720
#define CONFIG_USB_BELKIN_F5U104
#define CONFIG_USB_BELKIN
#define CONFIG_USB_LINUXDEV
#define CONFIG_USB_NET1080
#define CONFIG_USB_PL2301
......@@ -119,7 +122,7 @@
#endif
// packets are always ethernet inside
// ... except they can be bigger (up to 64K with this framing)
// ... except they can be bigger (limit of 64K with NetChip framing)
#define MIN_PACKET sizeof(struct ethhdr)
#define MAX_PACKET 32768
......@@ -169,7 +172,8 @@ struct driver_info {
char *description;
int flags;
#define FLAG_FRAMING 0x0001 /* guard against device dropouts */
#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */
#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
/* reset device ... can sleep */
int (*reset)(struct usbnet *);
......@@ -251,7 +255,7 @@ struct nc_trailer {
u16 packet_id;
} __attribute__((__packed__));
// packets may use FLAG_FRAMING and optional pad
// packets may use FLAG_FRAMING_NC and optional pad
#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
+ sizeof (struct ethhdr) \
+ (mtu) \
......@@ -288,22 +292,24 @@ static const struct driver_info an2720_info = {
#ifdef CONFIG_USB_BELKIN_F5U104
#ifdef CONFIG_USB_BELKIN
/*-------------------------------------------------------------------------
*
* Belkin F5U104 ... two NetChip 2280 devices + Atmel microcontroller
*
* ... also two eTEK designs, including one sold as "Advance USBNET"
*
*-------------------------------------------------------------------------*/
static const struct driver_info belkin_info = {
description: "Belkin USB Direct Connect (F5U104)",
description: "Belkin, eTEK, or compatible",
in: 1, out: 1, // direction distinguishes these
epsize: 64,
};
#endif /* CONFIG_USB_BELKIN_F5U104 */
#endif /* CONFIG_USB_BELKIN */
......@@ -632,7 +638,7 @@ static int net1080_check_connect (struct usbnet *dev)
static const struct driver_info net1080_info = {
description: "NetChip TurboCONNECT",
flags: FLAG_FRAMING,
flags: FLAG_FRAMING_NC,
reset: net1080_reset,
check_connect: net1080_check_connect,
......@@ -729,9 +735,9 @@ static int usbnet_change_mtu (struct net_device *net, int new_mtu)
{
struct usbnet *dev = (struct usbnet *) net->priv;
if (new_mtu <= sizeof (struct ethhdr) || new_mtu > MAX_PACKET)
if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET)
return -EINVAL;
if (((dev->driver_info->flags) & FLAG_FRAMING)) {
if (((dev->driver_info->flags) & FLAG_FRAMING_NC)) {
if (FRAMED_SIZE (new_mtu) > MAX_PACKET)
return -EINVAL;
// no second zero-length packet read wanted after mtu-sized packets
......@@ -779,9 +785,11 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
unsigned long lockflags;
size_t size;
size = (dev->driver_info->flags & FLAG_FRAMING)
? FRAMED_SIZE (dev->net.mtu)
: (sizeof (struct ethhdr) + dev->net.mtu);
if (dev->driver_info->flags & FLAG_FRAMING_NC)
size = FRAMED_SIZE (dev->net.mtu);
else
size = (sizeof (struct ethhdr) + dev->net.mtu);
if ((skb = alloc_skb (size, flags)) == 0) {
dbg ("no rx skb");
tasklet_schedule (&dev->bh);
......@@ -798,9 +806,15 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
FILL_BULK_URB (urb, dev->udev,
usb_rcvbulkpipe (dev->udev, dev->driver_info->in),
skb->data, size, rx_complete, skb);
urb->transfer_flags |= USB_ASYNC_UNLINK;
#ifdef REALLY_QUEUE
urb->transfer_flags |= USB_QUEUE_BULK;
#endif
#if 0
// Idle-but-posted reads with UHCI really chew up
// PCI bandwidth unless FSBR is disabled
urb->transfer_flags |= USB_NO_FSBR;
#endif
spin_lock_irqsave (&dev->rxq.lock, lockflags);
......@@ -827,7 +841,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
{
if (dev->driver_info->flags & FLAG_FRAMING) {
if (dev->driver_info->flags & FLAG_FRAMING_NC) {
struct nc_header *header;
struct nc_trailer *trailer;
......@@ -1083,9 +1097,11 @@ static int usbnet_open (struct net_device *net)
}
netif_start_queue (net);
devdbg (dev, "open: enable queueing (rx %d, tx %d) mtu %d %sframed",
devdbg (dev, "open: enable queueing (rx %d, tx %d) mtu %d %s framing",
RX_QLEN, TX_QLEN, dev->net.mtu,
(info->flags & FLAG_FRAMING) ? "" : "un"
(info->flags & FLAG_FRAMING_NC)
? "NetChip"
: "raw"
);
// delay posting reads until we're fully open
......@@ -1194,7 +1210,7 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
if (info->flags & FLAG_FRAMING) {
if (info->flags & FLAG_FRAMING_NC) {
struct sk_buff *skb2;
skb2 = fixup_skb (skb, flags);
if (!skb2) {
......@@ -1215,7 +1231,7 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
entry->state = tx_start;
entry->length = length;
if (info->flags & FLAG_FRAMING) {
if (info->flags & FLAG_FRAMING_NC) {
header = (struct nc_header *) skb_push (skb, sizeof *header);
header->hdr_len = cpu_to_le16 (sizeof (*header));
header->packet_len = cpu_to_le16 (length);
......@@ -1223,6 +1239,8 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
*skb_put (skb, 1) = PAD_BYTE;
trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
} else if ((length % EP_SIZE (dev)) == 0) {
// not all hardware behaves with USB_ZERO_PACKET,
// so we add an extra one-byte packet
if (skb_shared (skb)) {
struct sk_buff *skb2;
skb2 = skb_unshare (skb, flags);
......@@ -1238,16 +1256,14 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
FILL_BULK_URB (urb, dev->udev,
usb_sndbulkpipe (dev->udev, info->out),
skb->data, skb->len, tx_complete, skb);
// Idle-but-posted reads with UHCI really chew up
// PCI bandwidth unless FSBR is disabled
urb->transfer_flags |= USB_ASYNC_UNLINK | USB_NO_FSBR;
urb->transfer_flags |= USB_ASYNC_UNLINK;
#ifdef REALLY_QUEUE
urb->transfer_flags |= USB_QUEUE_BULK;
#endif
// FIXME urb->timeout = ... jiffies ... ;
spin_lock_irqsave (&dev->txq.lock, flags);
if (info->flags & FLAG_FRAMING) {
if (info->flags & FLAG_FRAMING_NC) {
header->packet_id = cpu_to_le16 (dev->packet_id++);
put_unaligned (header->packet_id, &trailer->packet_id);
#if 0
......@@ -1408,10 +1424,13 @@ usbnet_probe (struct usb_device *udev, unsigned ifnum,
return 0;
}
// more sanity (unless the device is broken)
if (!(info->flags & FLAG_NO_SETINT)) {
if (usb_set_interface (udev, ifnum, altnum) < 0) {
err ("set_interface failed");
return 0;
}
}
// set up our own records
if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) {
......@@ -1484,6 +1503,18 @@ static const struct usb_device_id products [] = {
},
#endif
#ifdef CONFIG_USB_BELKIN
{
USB_DEVICE (0x050d, 0x0004), // Belkin
driver_info: (unsigned long) &belkin_info,
}, {
USB_DEVICE (0x056c, 0x8100), // eTEK
driver_info: (unsigned long) &belkin_info,
}, {
USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
driver_info: (unsigned long) &belkin_info,
},
#endif
// GeneSys GL620USB (www.genesyslogic.com.tw)
// (patch exists against an older driver version)
......@@ -1508,16 +1539,6 @@ static const struct usb_device_id products [] = {
},
#endif
#ifdef CONFIG_USB_BELKIN_F5U104
{
USB_DEVICE (0x050d, 0x0004), // Belkin
driver_info: (unsigned long) &belkin_info,
}, {
USB_DEVICE (0x056c, 0x8100), // eTEK
driver_info: (unsigned long) &belkin_info,
},
#endif
#ifdef CONFIG_USB_PL2301
{
USB_DEVICE (0x067b, 0x0000), // PL-2301
......@@ -1563,6 +1584,7 @@ static void __exit usbnet_exit (void)
}
module_exit (usbnet_exit);
EXPORT_NO_SYMBOLS;
MODULE_AUTHOR ("David Brownell <dbrownell@users.sourceforge.net>");
MODULE_DESCRIPTION ("USB Host-to-Host Link Drivers (Belkin, Linux, NetChip, Prolific, ...)");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION ("USB Host-to-Host Link Drivers (numerous vendors)");
MODULE_LICENSE ("GPL");
......@@ -1131,31 +1131,13 @@ void __brelse(struct buffer_head * buf)
}
/*
* bforget() is like brelse(), except it might discard any
* bforget() is like brelse(), except it discards any
* potentially dirty data.
*/
void __bforget(struct buffer_head * buf)
{
/* grab the lru lock here so that "b_count" is stable */
spin_lock(&lru_list_lock);
write_lock(&hash_table_lock);
if (!atomic_dec_and_test(&buf->b_count) || buffer_locked(buf))
goto in_use;
/* Mark it clean */
clear_bit(BH_Dirty, &buf->b_state);
write_unlock(&hash_table_lock);
/* After which we can remove it from all queues */
remove_inode_queue(buf);
__remove_from_lru_list(buf);
buf->b_list = BUF_CLEAN;
spin_unlock(&lru_list_lock);
return;
in_use:
write_unlock(&hash_table_lock);
spin_unlock(&lru_list_lock);
mark_buffer_clean(buf);
__brelse(buf);
}
/**
......
......@@ -394,7 +394,7 @@ struct page * __alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_
}
/* Don't let big-order allocations loop */
if (order)
if (order > 1)
return NULL;
/* Yield for kswapd, and try again */
......
......@@ -346,11 +346,7 @@ static int shrink_cache(int nr_pages, int max_scan, unsigned int gfp_mask)
page = list_entry(entry, struct page, lru);
if (unlikely(!PageInactive(page) && !PageActive(page)))
BUG();
/* Mapping-less page on LRU-list? */
if (unlikely(!page->mapping))
if (unlikely(!PageInactive(page)))
BUG();
list_del(entry);
......@@ -363,31 +359,17 @@ static int shrink_cache(int nr_pages, int max_scan, unsigned int gfp_mask)
continue;
/* Racy check to avoid trylocking when not worthwhile */
if (!is_page_cache_freeable(page))
continue;
if (unlikely(TryLockPage(page))) {
if (gfp_mask & __GFP_FS) {
page_cache_get(page);
spin_unlock(&pagemap_lru_lock);
wait_on_page(page);
page_cache_release(page);
spin_lock(&pagemap_lru_lock);
}
if (!page->buffers && page_count(page) != 1)
continue;
}
/*
* Still strictly racy - we don't own the pagecache lock,
* so somebody might look up the page while we do this.
* It's just a heuristic, though.
* The page is locked. IO in progress?
* Move it to the back of the list.
*/
if (!is_page_cache_freeable(page)) {
UnlockPage(page);
if (unlikely(TryLockPage(page)))
continue;
}
if (PageDirty(page)) {
if (PageDirty(page) && is_page_cache_freeable(page) && page->mapping) {
/*
* It is not critical here to write it only if
* the page is unmapped beause any direct writer
......@@ -461,6 +443,9 @@ static int shrink_cache(int nr_pages, int max_scan, unsigned int gfp_mask)
}
}
if (unlikely(!page->mapping))
BUG();
if (unlikely(!spin_trylock(&pagecache_lock))) {
/* we hold the page lock so the page cannot go away from under us */
spin_unlock(&pagemap_lru_lock);
......
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