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

Merge bk://linux-mtd.bkbits.net/sbc8260-2.6

into evo.osdl.org:/home/torvalds/v2.6/linux
parents 03a449ea 056d7d3a
......@@ -287,6 +287,7 @@ struct net_device *__init mc32_probe(int unit)
}
}
free_netdev(dev);
return ERR_PTR(-ENODEV);
}
......
......@@ -242,7 +242,7 @@ static void cleanup_card(struct net_device *dev)
{
#ifdef CONFIG_MCA
struct net_local *lp = netdev_priv(dev);
if (lp->mca_slot)
if (lp->mca_slot >= 0)
mca_mark_as_unused(lp->mca_slot);
#endif
free_irq(dev->irq, NULL);
......@@ -444,11 +444,11 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
break;
}
if (i == 8) {
goto err_out;
goto err_mca;
}
} else {
if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
goto err_out;
goto err_mca;
irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
}
}
......@@ -546,11 +546,16 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
if (ret) {
printk (" AT1700 at %#3x is unusable due to a conflict on"
"IRQ %d.\n", ioaddr, irq);
goto err_out;
goto err_mca;
}
return 0;
err_mca:
#ifdef CONFIG_MCA
if (slot >= 0)
mca_mark_as_unused(slot);
#endif
err_out:
#ifndef CONFIG_X86_PC9800
release_region(ioaddr, AT1700_IO_EXTENT);
......
......@@ -52,7 +52,7 @@
char e1000_driver_name[] = "e1000";
char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
char e1000_driver_version[] = "5.2.52-k2";
char e1000_driver_version[] = "5.2.52-k4";
char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
......@@ -2143,6 +2143,7 @@ e1000_clean(struct net_device *netdev, int *budget)
if(work_done < work_to_do || !netif_running(netdev)) {
netif_rx_complete(netdev);
e1000_irq_enable(adapter);
return 0;
}
return (work_done >= work_to_do);
......
......@@ -66,12 +66,15 @@
LK1.1.14 (Kryzsztof Halasa):
* fix spurious bad initializations
* pound phy a la SMSC's app note on the subject
AC1.1.14ac
* fix power up/down for ethtool that broke in 1.11
*/
#define DRV_NAME "epic100"
#define DRV_VERSION "1.11+LK1.1.14"
#define DRV_RELDATE "Aug 4, 2002"
#define DRV_VERSION "1.11+LK1.1.14+AC1.1.14"
#define DRV_RELDATE "June 2, 2004"
/* The user-configurable values.
These may be modified when a driver module is loaded.*/
......@@ -1424,6 +1427,27 @@ static void netdev_set_msglevel(struct net_device *dev, u32 value)
debug = value;
}
static int ethtool_begin(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
/* power-up, if interface is down */
if (! netif_running(dev)) {
outl(0x0200, ioaddr + GENCTL);
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
}
return 0;
}
static void ethtool_complete(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
/* power-down, if interface is down */
if (! netif_running(dev)) {
outl(0x0008, ioaddr + GENCTL);
outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL);
}
}
static struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
.get_settings = netdev_get_settings,
......@@ -1434,6 +1458,8 @@ static struct ethtool_ops netdev_ethtool_ops = {
.set_msglevel = netdev_set_msglevel,
.get_sg = ethtool_op_get_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
.begin = ethtool_begin,
.complete = ethtool_complete
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
......
......@@ -133,6 +133,10 @@ int tulip_poll(struct net_device *dev, int *budget)
tp->rx_ring[entry].status);
do {
if (inl(dev->base_addr + CSR5) == 0xffffffff) {
printk(KERN_DEBUG " In tulip_poll(), hardware disappeared.\n");
break;
}
/* Acknowledge current RX interrupt sources. */
outl((RxIntr | RxNoBuf), dev->base_addr + CSR5);
......
......@@ -351,6 +351,8 @@ struct ethtool_ops {
int (*phys_id)(struct net_device *, u32);
int (*get_stats_count)(struct net_device *);
void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
int (*begin)(struct net_device *);
void (*complete)(struct net_device *);
};
/* CMDs currently supported */
......
......@@ -29,15 +29,15 @@ void rwsemtrace(struct rw_semaphore *sem, const char *str)
/*
* handle the lock being released whilst there are processes blocked on it that can now run
* - if we come here, then:
* - the 'active part' of the count (&0x0000ffff) reached zero but has been re-incremented
* - if we come here from up_xxxx(), then:
* - the 'active part' of the count (&0x0000ffff) had reached zero (but may have changed)
* - the 'waiting part' of the count (&0xffff0000) is negative (and will still be so)
* - there must be someone on the queue
* - the spinlock must be held by the caller
* - woken process blocks are discarded from the list after having task zeroed
* - writers are only woken if wakewrite is non-zero
* - writers are only woken if downgrading is false
*/
static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int wakewrite)
static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
{
struct rwsem_waiter *waiter;
struct task_struct *tsk;
......@@ -46,10 +46,12 @@ static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int
rwsemtrace(sem,"Entering __rwsem_do_wake");
if (!wakewrite)
if (downgrading)
goto dont_wake_writers;
/* only wake someone up if we can transition the active part of the count from 0 -> 1 */
/* if we came through an up_xxxx() call, we only only wake someone up
* if we can transition the active part of the count from 0 -> 1
*/
try_again:
oldcount = rwsem_atomic_update(RWSEM_ACTIVE_BIAS,sem) - RWSEM_ACTIVE_BIAS;
if (oldcount & RWSEM_ACTIVE_MASK)
......@@ -78,9 +80,10 @@ static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int
if (waiter->flags & RWSEM_WAITING_FOR_WRITE)
goto out;
/* grant an infinite number of read locks to the readers at the front of the queue
* - note we increment the 'active part' of the count by the number of readers (less one
* for the activity decrement we've already done) before waking any processes up
/* grant an infinite number of read locks to the readers at the front
* of the queue
* - note we increment the 'active part' of the count by the number of
* readers before waking any processes up
*/
readers_only:
woken = 0;
......@@ -95,8 +98,10 @@ static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int
} while (waiter->flags & RWSEM_WAITING_FOR_READ);
loop = woken;
woken *= RWSEM_ACTIVE_BIAS-RWSEM_WAITING_BIAS;
woken -= RWSEM_ACTIVE_BIAS;
woken *= RWSEM_ACTIVE_BIAS - RWSEM_WAITING_BIAS;
if (!downgrading)
woken -= RWSEM_ACTIVE_BIAS; /* we'd already done one increment
* earlier */
rwsem_atomic_add(woken,sem);
next = sem->wait_list.next;
......@@ -150,7 +155,7 @@ static inline struct rw_semaphore *rwsem_down_failed_common(struct rw_semaphore
* - it might even be this process, since the waker takes a more active part
*/
if (!(count & RWSEM_ACTIVE_MASK))
sem = __rwsem_do_wake(sem,1);
sem = __rwsem_do_wake(sem, 0);
spin_unlock(&sem->wait_lock);
......@@ -201,7 +206,7 @@ struct rw_semaphore fastcall __sched *rwsem_down_write_failed(struct rw_semaphor
/*
* handle waking up a waiter on the semaphore
* - up_read has decremented the active part of the count if we come here
* - up_read/up_write has decremented the active part of the count if we come here
*/
struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem)
{
......@@ -211,7 +216,7 @@ struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem)
/* do nothing if list empty */
if (!list_empty(&sem->wait_list))
sem = __rwsem_do_wake(sem,1);
sem = __rwsem_do_wake(sem, 0);
spin_unlock(&sem->wait_lock);
......@@ -233,7 +238,7 @@ struct rw_semaphore fastcall *rwsem_downgrade_wake(struct rw_semaphore *sem)
/* do nothing if list empty */
if (!list_empty(&sem->wait_list))
sem = __rwsem_do_wake(sem,0);
sem = __rwsem_do_wake(sem, 1);
spin_unlock(&sem->wait_lock);
......
......@@ -652,6 +652,7 @@ int dev_ethtool(struct ifreq *ifr)
struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
void __user *useraddr = ifr->ifr_data;
u32 ethcmd;
int rc;
/*
* XXX: This can be pushed down into the ethtool_* handlers that
......@@ -669,70 +670,109 @@ int dev_ethtool(struct ifreq *ifr)
if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
return -EFAULT;
if(dev->ethtool_ops->begin)
if ((rc = dev->ethtool_ops->begin(dev)) < 0)
return rc;
switch (ethcmd) {
case ETHTOOL_GSET:
return ethtool_get_settings(dev, useraddr);
rc = ethtool_get_settings(dev, useraddr);
break;
case ETHTOOL_SSET:
return ethtool_set_settings(dev, useraddr);
rc = ethtool_set_settings(dev, useraddr);
break;
case ETHTOOL_GDRVINFO:
return ethtool_get_drvinfo(dev, useraddr);
rc = ethtool_get_drvinfo(dev, useraddr);
break;
case ETHTOOL_GREGS:
return ethtool_get_regs(dev, useraddr);
rc = ethtool_get_regs(dev, useraddr);
break;
case ETHTOOL_GWOL:
return ethtool_get_wol(dev, useraddr);
rc = ethtool_get_wol(dev, useraddr);
break;
case ETHTOOL_SWOL:
return ethtool_set_wol(dev, useraddr);
rc = ethtool_set_wol(dev, useraddr);
break;
case ETHTOOL_GMSGLVL:
return ethtool_get_msglevel(dev, useraddr);
rc = ethtool_get_msglevel(dev, useraddr);
break;
case ETHTOOL_SMSGLVL:
return ethtool_set_msglevel(dev, useraddr);
rc = ethtool_set_msglevel(dev, useraddr);
break;
case ETHTOOL_NWAY_RST:
return ethtool_nway_reset(dev);
rc = ethtool_nway_reset(dev);
break;
case ETHTOOL_GLINK:
return ethtool_get_link(dev, useraddr);
rc = ethtool_get_link(dev, useraddr);
break;
case ETHTOOL_GEEPROM:
return ethtool_get_eeprom(dev, useraddr);
rc = ethtool_get_eeprom(dev, useraddr);
break;
case ETHTOOL_SEEPROM:
return ethtool_set_eeprom(dev, useraddr);
rc = ethtool_set_eeprom(dev, useraddr);
break;
case ETHTOOL_GCOALESCE:
return ethtool_get_coalesce(dev, useraddr);
rc = ethtool_get_coalesce(dev, useraddr);
break;
case ETHTOOL_SCOALESCE:
return ethtool_set_coalesce(dev, useraddr);
rc = ethtool_set_coalesce(dev, useraddr);
break;
case ETHTOOL_GRINGPARAM:
return ethtool_get_ringparam(dev, useraddr);
rc = ethtool_get_ringparam(dev, useraddr);
break;
case ETHTOOL_SRINGPARAM:
return ethtool_set_ringparam(dev, useraddr);
rc = ethtool_set_ringparam(dev, useraddr);
break;
case ETHTOOL_GPAUSEPARAM:
return ethtool_get_pauseparam(dev, useraddr);
rc = ethtool_get_pauseparam(dev, useraddr);
break;
case ETHTOOL_SPAUSEPARAM:
return ethtool_set_pauseparam(dev, useraddr);
rc = ethtool_set_pauseparam(dev, useraddr);
break;
case ETHTOOL_GRXCSUM:
return ethtool_get_rx_csum(dev, useraddr);
rc = ethtool_get_rx_csum(dev, useraddr);
break;
case ETHTOOL_SRXCSUM:
return ethtool_set_rx_csum(dev, useraddr);
rc = ethtool_set_rx_csum(dev, useraddr);
break;
case ETHTOOL_GTXCSUM:
return ethtool_get_tx_csum(dev, useraddr);
rc = ethtool_get_tx_csum(dev, useraddr);
break;
case ETHTOOL_STXCSUM:
return ethtool_set_tx_csum(dev, useraddr);
rc = ethtool_set_tx_csum(dev, useraddr);
break;
case ETHTOOL_GSG:
return ethtool_get_sg(dev, useraddr);
rc = ethtool_get_sg(dev, useraddr);
break;
case ETHTOOL_SSG:
return ethtool_set_sg(dev, useraddr);
rc = ethtool_set_sg(dev, useraddr);
break;
case ETHTOOL_GTSO:
return ethtool_get_tso(dev, useraddr);
rc = ethtool_get_tso(dev, useraddr);
break;
case ETHTOOL_STSO:
return ethtool_set_tso(dev, useraddr);
rc = ethtool_set_tso(dev, useraddr);
break;
case ETHTOOL_TEST:
return ethtool_self_test(dev, useraddr);
rc = ethtool_self_test(dev, useraddr);
break;
case ETHTOOL_GSTRINGS:
return ethtool_get_strings(dev, useraddr);
rc = ethtool_get_strings(dev, useraddr);
break;
case ETHTOOL_PHYS_ID:
return ethtool_phys_id(dev, useraddr);
rc = ethtool_phys_id(dev, useraddr);
break;
case ETHTOOL_GSTATS:
return ethtool_get_stats(dev, useraddr);
rc = ethtool_get_stats(dev, useraddr);
break;
default:
return -EOPNOTSUPP;
rc = -EOPNOTSUPP;
}
if(dev->ethtool_ops->complete)
dev->ethtool_ops->complete(dev);
return rc;
ioctl:
if (dev->do_ioctl)
......
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