VERSION = 2
PATCHLEVEL = 3
-SUBLEVEL = 43
+SUBLEVEL = 44
EXTRAVERSION =
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
}
}
-void init_8259A(int auto_eoi)
+void __init init_8259A(int auto_eoi)
{
unsigned long flags;
* and IDT. We reload them nevertheless, this function acts as a
* 'CPU state barrier', nothing should get across.
*/
-void cpu_init (void)
+void __init cpu_init (void)
{
int nr = smp_processor_id();
struct tss_struct * t = &init_tss[nr];
}
}
+EXPORT_SYMBOL(keyboard_tasklet);
DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
int __init kbd_init(void)
#if defined(CONFIG_ADB)
extern void adbdev_init(void);
#endif
-#ifdef CONFIG_USB
-extern void usb_init(void);
-#endif
#ifdef CONFIG_PHONE
extern void telephony_init(void);
#endif
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
rand_initialize();
raw_init();
-#ifdef CONFIG_USB
- usb_init();
-#endif
#ifdef CONFIG_I2C
i2c_init_all();
#endif
#endif
}
+static unsigned char kbd_exists = 1;
+
static inline void handle_keyboard_event(unsigned char scancode)
{
#ifdef CONFIG_VT
+ kbd_exists = 1;
if (do_acknowledge(scancode))
handle_scancode(scancode, !(scancode & 0x80));
#endif
void pckbd_leds(unsigned char leds)
{
- if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
- send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
+ if (kbd_exists && (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))) {
+ send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
+ kbd_exists = 0;
+ }
}
/*
alloc586(dev);
init586(dev);
startrecv586(dev);
- netif_wake_queue(dev);
+ netif_start_queue(dev);
MOD_INC_USE_COUNT;
return 0; /* most done by init */
}
mc32_rx_begin(dev);
mc32_tx_begin(dev);
- netif_wake_queue(dev);
+ netif_start_queue(dev);
MOD_INC_USE_COUNT;
return 0;
static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void set_multicast_list(struct net_device *dev);
+static void net_timeout(struct net_device *dev);
static void net_rx(struct net_device *dev);
static int net_close(struct net_device *dev);
static struct net_device_stats *net_get_stats(struct net_device *dev);
If dev->base_addr == 2, allocate space for the device and return success
(detachable devices only).
*/
-#ifdef HAVE_DEVLIST
-/* Support for a alternate probe manager, which will eliminate the
- boilerplate below. */
-struct netdev_entry netcard_drv =
-{"netcard", cs89x0_probe1, NETCARD_IO_EXTENT, netcard_portlist};
-#else
-int __init
-cs89x0_probe(struct net_device *dev)
+
+int __init cs89x0_probe(struct net_device *dev)
{
int i;
int base_addr = dev ? dev->base_addr : 0;
printk("cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
return ENODEV;
}
-#endif
-static int inline
-readreg(struct net_device *dev, int portno)
+extern int inline readreg(struct net_device *dev, int portno)
{
outw(portno, dev->base_addr + ADD_PORT);
return inw(dev->base_addr + DATA_PORT);
}
-static void inline
-writereg(struct net_device *dev, int portno, int value)
+extern void inline writereg(struct net_device *dev, int portno, int value)
{
outw(portno, dev->base_addr + ADD_PORT);
outw(value, dev->base_addr + DATA_PORT);
}
-static int inline
-readword(struct net_device *dev, int portno)
+extern int inline readword(struct net_device *dev, int portno)
{
return inw(dev->base_addr + portno);
}
-static void inline
-writeword(struct net_device *dev, int portno, int value)
+extern void inline writeword(struct net_device *dev, int portno, int value)
{
outw(value, dev->base_addr + portno);
}
-static int __init
-wait_eeprom_ready(struct net_device *dev)
+static int __init wait_eeprom_ready(struct net_device *dev)
{
int timeout = jiffies;
/* check to see if the EEPROM is ready, a timeout is used -
return 0;
}
-static int __init
-get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
+static int __init get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
{
int i;
return 0;
}
-static int __init
-get_eeprom_cksum(int off, int len, int *buffer)
+static int __init get_eeprom_cksum(int off, int len, int *buffer)
{
int i, cksum;
dev->open = net_open;
dev->stop = net_close;
- dev->hard_start_xmit = net_send_packet;
- dev->get_stats = net_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->set_mac_address = &set_mac_address;
+ dev->tx_timeout = net_timeout;
+ dev->watchdog_timeo = HZ;
+ dev->hard_start_xmit = net_send_packet;
+ dev->get_stats = net_get_stats;
+ dev->set_multicast_list = set_multicast_list;
+ dev->set_mac_address = set_mac_address;
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
/* now that we've got our act together, enable everything */
writereg(dev, PP_BusCTL, ENABLE_IRQ
);
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
MOD_INC_USE_COUNT;
+ netif_start_queue(dev);
return 0;
}
-static int
-net_send_packet(struct sk_buff *skb, struct net_device *dev)
+static void net_timeout(struct net_device *dev)
{
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict ?" : "network cable problem");
- /* Try to restart the adaptor. */
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
+ /* If we get here, some higher level has decided we are broken.
+ There should really be a "kick me" function call instead. */
+ if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
+ tx_done(dev) ? "IRQ conflict ?" : "network cable problem");
+ /* Try to restart the adaptor. */
+ netif_wake_queue(dev);
+}
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
- unsigned long flags;
-
- if (net_debug > 3)printk("%s: sent %d byte packet of type %x\n", dev->name, skb->len, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
-
- /* keep the upload from being interrupted, since we
- ask the chip to start transmitting before the
- whole packet has been completely uploaded. */
- save_flags(flags);
- cli();
-
- /* initiate a transmit sequence */
- outw(lp->send_cmd, ioaddr + TX_CMD_PORT);
- outw(skb->len, ioaddr + TX_LEN_PORT);
-
- /* Test to see if the chip has allocated memory for the packet */
- if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
- /* Gasp! It hasn't. But that shouldn't happen since
- we're waiting for TxOk, so return 1 and requeue this packet. */
- restore_flags(flags);
- return 1;
- }
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+ struct net_local *lp = (struct net_local *)dev->priv;
+ short ioaddr = dev->base_addr;
+ unsigned long flags;
+
+ if (net_debug > 3)
+ printk("%s: sent %d byte packet of type %x\n", dev->name, skb->len, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
+
+ /* keep the upload from being interrupted, since we
+ ask the chip to start transmitting before the
+ whole packet has been completely uploaded. */
- /* Write the contents of the packet */
- outsw(ioaddr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
+ save_flags(flags);
+ cli();
+ netif_stop_queue(dev);
+
+ /* initiate a transmit sequence */
+ outw(lp->send_cmd, ioaddr + TX_CMD_PORT);
+ outw(skb->len, ioaddr + TX_LEN_PORT);
+ /* Test to see if the chip has allocated memory for the packet */
+ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
+ /* Gasp! It hasn't. But that shouldn't happen since
+ we're waiting for TxOk, so return 1 and requeue this packet. */
restore_flags(flags);
- dev->trans_start = jiffies;
+ return 1;
}
- dev_kfree_skb (skb);
+ /* Write the contents of the packet */
+ outsw(ioaddr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
+ restore_flags(flags);
+ dev->trans_start = jiffies;
+ dev_kfree_skb (skb);
+ netif_wake_queue(dev);
+
return 0;
}
\f
/* The typical workload of the driver:
Handle the network interface interrupts. */
+
static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
struct net_device *dev = dev_id;
struct net_local *lp;
int ioaddr, status;
- if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
- dev->interrupt = 1;
-
ioaddr = dev->base_addr;
lp = (struct net_local *)dev->priv;
break;
case ISQ_TRANSMITTER_EVENT:
lp->stats.tx_packets++;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
+ netif_wake_queue(dev); /* Inform upper layers. */
if ((status & TX_OK) == 0) lp->stats.tx_errors++;
if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
That shouldn't happen since we only ever
load one packet. Shrug. Do the right
thing anyway. */
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
+ netif_wake_queue(dev); /* Inform upper layers. */
}
if (status & TX_UNDERRUN) {
if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
avoids having to wait for the upper
layers to timeout on us, in the
event of a tx underrun */
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
+ netif_wake_queue(dev); /* Inform upper layers. */
}
break;
case ISQ_RX_MISS_EVENT:
break;
}
}
- dev->interrupt = 0;
- return;
}
/* We have a good packet(s), get it/them out of the buffers. */
static int
net_close(struct net_device *dev)
{
-
+ netif_stop_queue(dev);
+
writereg(dev, PP_RxCFG, 0);
writereg(dev, PP_TxCFG, 0);
writereg(dev, PP_BufCFG, 0);
writereg(dev, PP_BusCTL, 0);
- dev->start = 0;
-
free_irq(dev->irq, dev);
/* Update the statistics here. */
static int set_mac_address(struct net_device *dev, void *addr)
{
int i;
- if (dev->start)
+ if (test_bit(LINK_STATE_START, &dev->state))
return -EBUSY;
printk("%s: Setting MAC address to ", dev->name);
for (i = 0; i < 6; i++)
* there is a non-reboot way to recover if something goes wrong.
*
*/
-static int
-de620_open(struct net_device *dev)
+static int de620_open(struct net_device *dev)
{
if (request_irq(dev->irq, de620_interrupt, 0, "de620", dev)) {
- printk ("%s: unable to get IRQ %d\n", dev->name, dev->irq);
+ printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
return 1;
}
- MOD_INC_USE_COUNT;
- if (adapter_init(dev)) {
+ if (adapter_init(dev))
return 1;
- }
- dev->start = 1;
+
+ MOD_INC_USE_COUNT;
+ netif_start_queue(dev);
return 0;
}
* The inverse routine to de620_open().
*
*/
-static int
-de620_close(struct net_device *dev)
+
+static int de620_close(struct net_device *dev)
{
+ netif_stop_queue(dev);
/* disable recv */
de620_set_register(dev, W_TCR, RXOFF);
-
free_irq(dev->irq, dev);
-
- dev->start = 0;
MOD_DEC_USE_COUNT;
return 0;
}
}
}
+/*******************************************************
+ *
+ * Handle timeouts on transmit
+ */
+
+static void de620_timeout(struct net_device *dev)
+{
+ printk("%s: transmit timed out, %s?\n",
+ dev->name,
+ "network cable problem"
+ );
+ /* Restart the adapter. */
+ if (!adapter_init(dev)) /* maybe close it */
+ netif_wake_queue(dev);
+}
+
/*******************************************************
*
* Copy a buffer to the adapter transmit page memory.
* Start sending.
*/
-static int
-de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned long flags;
int len;
- int tickssofar;
byte *buffer = skb->data;
byte using_txbuf;
using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
- dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
-
- if (dev->tbusy) { /* Do timeouts, to avoid hangs. */
- tickssofar = jiffies - dev->trans_start;
-
- if (tickssofar < 5)
- return 1;
-
- /* else */
- printk("%s: transmit timed out (%d), %s?\n",
- dev->name,
- tickssofar,
- "network cable problem"
- );
- /* Restart the adapter. */
- if (adapter_init(dev)) /* maybe close it */
- return 1;
- }
+
+ netif_stop_queue(dev);
+
if ((len = skb->len) < RUNT)
len = RUNT;
break;
case (TXBF0 | TXBF1): /* NONE!!! */
- printk("de620: Ouch! No tx-buffer available!\n");
+ printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
restore_flags(flags);
return 1;
break;
de620_write_block(dev, buffer, len);
dev->trans_start = jiffies;
- dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
+ if(!(using_txbuf == (TXBF0 | TXBF1)))
+ netif_wake_queue(dev);
((struct net_device_stats *)(dev->priv))->tx_packets++;
-
restore_flags(flags); /* interrupts maybe back on */
-
dev_kfree_skb (skb);
-
return 0;
}
\f
* Handle the network interface interrupts.
*
*/
-static void
-de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs)
+static void de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
byte irq_status;
return;
}
- cli();
- dev->interrupt = 1;
-
/* Read the status register (_not_ the status port) */
irq_status = de620_get_register(dev, R_STS);
while (again && (++bogus_count < 100));
}
- dev->tbusy = (de620_tx_buffs(dev) == (TXBF0 | TXBF1)); /* Boolean! */
-
- dev->interrupt = 0;
- sti();
- return;
+ if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
+ netif_wake_queue(dev);
}
/**************************************
* Send it "upstairs"
*
*/
-static int
-de620_rx_intr(struct net_device *dev)
+static int de620_rx_intr(struct net_device *dev)
{
struct header_buf {
byte status;
pagelink = header_buf.Rx_NextPage;
if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
/* Ouch... Forget it! Skip all and start afresh... */
- printk("%s: Ring overrun? Restoring...\n", dev->name);
+ printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
/* You win some, you lose some. And sometimes plenty... */
adapter_init(dev);
+ netif_wake_queue(dev);
((struct net_device_stats *)(dev->priv))->rx_over_errors++;
return 0;
}
/* Is the _computed_ next page number equal to what the adapter says? */
if (pagelink != header_buf.Rx_NextPage) {
/* Naah, we'll skip this packet. Probably bogus data as well */
- printk("%s: Page link out of sync! Restoring...\n", dev->name);
+ printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
de620_send_command(dev, W_DUMMY);
de620_set_register(dev, W_NPRF, next_rx_page);
size = header_buf.Rx_ByteCount - 4;
if ((size < RUNT) || (GIANT < size)) {
- printk("%s: Illegal packet size: %d!\n", dev->name, size);
+ printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
}
else { /* Good packet? */
skb = dev_alloc_skb(size+2);
if (skb == NULL) { /* Yeah, but no place to put it... */
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
+ printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n",
dev->name, size);
((struct net_device_stats *)(dev->priv))->rx_dropped++;
}
* Reset the adapter to a known state
*
*/
-static int
-adapter_init(struct net_device *dev)
+static int adapter_init(struct net_device *dev)
{
int i;
static int was_down = 0;
/* ignore: EEDI RXGOOD COLS LNKS*/
if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
- printk("Something has happened to the DE-620! Please check it"
+ printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it"
#ifdef SHUTDOWN_WHEN_LOST
" and do a new ifconfig"
#endif
- "! (%02x)\n", i);
+ "! (%02x)\n", dev->name, i);
#ifdef SHUTDOWN_WHEN_LOST
/* Goodbye, cruel world... */
dev->flags &= ~IFF_UP;
return 1; /* failed */
}
if (was_down) {
- printk("Thanks, I feel much better now!\n");
+ printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
was_down = 0;
}
*
* Check if there is a DE-620 connected
*/
-int __init
-de620_probe(struct net_device *dev)
+int __init de620_probe(struct net_device *dev)
{
static struct net_device_stats de620_netstats;
int i;
if (de620_debug)
printk(version);
- printk("D-Link DE-620 pocket adapter");
+ printk(KERN_INFO "D-Link DE-620 pocket adapter");
/* Initially, configure basic nibble mode, so we can read the EEPROM */
NIC_Cmd = DEF_NIC_CMD;
dev->priv = &de620_netstats;
memset(dev->priv, 0, sizeof(struct net_device_stats));
- dev->get_stats = get_stats;
- dev->open = de620_open;
- dev->stop = de620_close;
- dev->hard_start_xmit = &de620_start_xmit;
- dev->set_multicast_list = &de620_set_multicast_list;
+ dev->get_stats = get_stats;
+ dev->open = de620_open;
+ dev->stop = de620_close;
+ dev->hard_start_xmit = de620_start_xmit;
+ dev->tx_timeout = de620_timeout;
+ dev->watchdog_timeo = HZ*2;
+ dev->set_multicast_list = de620_set_multicast_list;
+
/* base_addr and irq are already set, see above! */
ether_setup(dev);
*/
#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
-static unsigned short __init
-ReadAWord(struct net_device *dev, int from)
+static unsigned short __init ReadAWord(struct net_device *dev, int from)
{
unsigned short data;
int nbits;
return data;
}
-static int __init
-read_eeprom(struct net_device *dev)
+static int __init read_eeprom(struct net_device *dev)
{
unsigned short wrd;
static struct net_device de620_dev = {
nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe };
-int
-init_module(void)
+int init_module(void)
{
if (register_netdev(&de620_dev) != 0)
return -EIO;
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
unregister_netdev(&de620_dev);
release_region(de620_dev.base_addr, 3);
dmfe_init_dm910x(dev);
/* Active System Interface */
- dev->tbusy = 0; /* Can transmit packet */
- dev->start = 1; /* interface ready */
MOD_INC_USE_COUNT;
/* set and active a timer process */
db->timer.data = (unsigned long) dev;
db->timer.function = &dmfe_timer;
add_timer(&db->timer);
+
+ netif_wake_queue(dev);
return 0;
}
struct tx_desc *txptr;
DMFE_DBUG(0, "dmfe_start_xmit", 0);
-
- if ((dev->tbusy == 1) && (db->tx_packet_cnt != 0))
- return 1;
- else
- dev->tbusy = 0;
-
+
+ netif_stop_queue(dev);
+
/* Too large packet check */
if (skb->len > MAX_PACKET_SIZE) {
- printk(KERN_ERR "%s: oversized frame (%d bytes) received.\n", dev->name, (u16) skb->len);
+ printk(KERN_ERR "%s: oversized frame (%d bytes) for transmit.\n", dev->name, (u16) skb->len);
dev_kfree_skb(skb);
return 0;
}
/* No Tx resource check, it never happen nromally */
if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
- printk(KERN_WARNING "%s: No Tx resource, enter xmit() again \n", dev->name);
- dev_kfree_skb(skb);
- dev->tbusy = 1;
- return -EBUSY;
+ return 1;
}
/* transmit this packet */
outl(0x1, dev->base_addr + DCR1);
/* Tx resource check */
- if (db->tx_packet_cnt >= TX_FREE_DESC_CNT)
- dev->tbusy = 1;
+ if (db->tx_packet_cnt < TX_FREE_DESC_CNT)
+ netif_wake_queue(dev);
/* Set transmit time stamp */
dev->trans_start = jiffies; /* saved the time stamp */
DMFE_DBUG(0, "dmfe_stop", 0);
- /* disable system */
- dev->start = 0; /* interface disable */
- dev->tbusy = 1; /* can't transmit */
+ netif_stop_queue(dev);
/* Reset & stop DM910X board */
outl(DM910X_RESET, ioaddr + DCR0);
DMFE_DBUG(1, "dmfe_interrupt() without device arg", 0);
return;
}
- if (dev->interrupt) {
- DMFE_DBUG(1, "dmfe_interrupt() re-entry ", 0);
- return;
- }
/* A real interrupt coming */
- dev->interrupt = 1; /* Lock interrupt */
db = (struct dmfe_board_info *) dev->priv;
ioaddr = dev->base_addr;
if (db->cr5_data & 0x2000) {
/* A system bus error occurred */
DMFE_DBUG(1, "A system bus error occurred. CR5=", db->cr5_data);
- dev->tbusy = 1;
+ netif_stop_queue(dev);
db->wait_reset = 1; /* Need to RESET */
outl(0, ioaddr + DCR7); /* disable all interrupt */
- dev->interrupt = 0; /* unlock interrupt */
return;
}
/* Free the transmitted descriptor */
}
db->tx_remove_ptr = (struct tx_desc *) txptr;
- if (dev->tbusy && (db->tx_packet_cnt < TX_FREE_DESC_CNT)) {
- dev->tbusy = 0; /* free a resource */
- mark_bh(NET_BH); /* active bottom half */
- }
+ if (db->tx_packet_cnt < TX_FREE_DESC_CNT)
+ netif_wake_queue(dev);
+
/* Received the coming packet */
if (db->rx_avail_cnt)
dmfe_rx_packet(dev, db);
db->cr6_data |= 0x100;
update_cr6(db->cr6_data, db->ioaddr);
}
- dev->interrupt = 0; /* release interrupt lock */
/* Restore CR7 to enable interrupt mask */
db->in_reset_state = 1;
/* Disable upper layer interface */
- dev->tbusy = 1; /* transmit packet disable */
- dev->start = 0; /* interface not ready */
-
+ netif_stop_queue(dev);
+
db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */
update_cr6(db->cr6_data, dev->base_addr);
/* Re-initilize DM910X board */
dmfe_init_dm910x(dev);
- /* Restart upper layer interface */
- dev->tbusy = 0; /* Can transmit packet */
- dev->start = 1; /* interface ready */
-
/* Leave dynamic reser route */
db->in_reset_state = 0;
+
+ /* Restart upper layer interface */
+ netif_wake_queue(dev);
}
/*
/* prepare the setup frame */
db->tx_packet_cnt++;
- dev->tbusy = 1;
+ netif_stop_queue(dev);
txptr->tdes1 = 0x890000c0;
txptr->tdes0 = 0x80000000;
db->tx_insert_ptr = (struct tx_desc *) txptr->next_tx_desc;
extern int express_probe(struct net_device *dev);
static int eexp_open(struct net_device *dev);
static int eexp_close(struct net_device *dev);
+static void eexp_timeout(struct net_device *dev);
static struct net_device_stats *eexp_stats(struct net_device *dev);
static int eexp_xmit(struct sk_buff *buf, struct net_device *dev);
request_region(ioaddr+0x4000, 16, "EtherExpress shadow");
request_region(ioaddr+0x8000, 16, "EtherExpress shadow");
request_region(ioaddr+0xc000, 16, "EtherExpress shadow");
- dev->tbusy = 0;
- dev->interrupt = 0;
if (lp->width) {
printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
}
eexp_hw_init586(dev);
- dev->start = 1;
MOD_INC_USE_COUNT;
+ netif_start_queue(dev);
#if NET_DEBUG > 6
printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
#endif
int irq = dev->irq;
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
lp->started = 0;
scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
outb(0,ioaddr+SIGNAL_CA);
}
}
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
}
else
{
else
{
unsigned short txstatus = eexp_hw_lasttxstat(dev);
- if (dev->tbusy && !txstatus)
+ if (test_bit(LINK_STATE_XOFF, &dev->state) && !txstatus)
{
printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
dev->name,status,txstatus);
eexp_hw_init586(dev);
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
}
else
{
printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
dev->name, status);
eexp_hw_init586(dev);
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
}
}
}
+static void eexp_timeout(struct net_device *dev)
+{
+ struct net_local *lp = (struct net_local *)dev->priv;
+#ifdef CONFIG_SMP
+ unsigned long flags;
+#endif
+ int status;
+
+ disable_irq(dev->irq);
+
+ /*
+ * Best would be to use synchronize_irq(); spin_lock() here
+ * lets make it work first..
+ */
+
+#ifdef CONFIG_SMP
+ spin_lock_irqsave(&lp->lock, flags);
+#endif
+
+ status = scb_status(dev);
+ unstick_cu(dev);
+ printk(KERN_INFO "%s: transmit timed out, %s?", dev->name,
+ (SCB_complete(status)?"lost interrupt":
+ "board on fire"));
+ lp->stats.tx_errors++;
+ lp->last_tx = jiffies;
+ if (!SCB_complete(status)) {
+ scb_command(dev, SCB_CUabort);
+ outb(0,dev->base_addr+SIGNAL_CA);
+ }
+ netif_wake_queue(dev);
+#ifdef CONFIG_SMP
+ spin_unlock_irqrestore(&lp->lock, flags);
+#endif
+}
+
/*
* Called to transmit a packet, or to allow us to right ourselves
* if the kernel thinks we've died.
#ifdef CONFIG_SMP
spin_lock_irqsave(&lp->lock, flags);
#endif
-
- /* If dev->tbusy is set, all our tx buffers are full but the kernel
- * is calling us anyway. Check that nothing bad is happening.
- */
- if (dev->tbusy) {
- int status = scb_status(dev);
- unstick_cu(dev);
- if ((jiffies - lp->last_tx) < HZ)
- {
-#ifdef CONFIG_SMP
- spin_unlock_irqrestore(&lp->lock, flags);
-#endif
-
- return 1;
- }
- printk(KERN_INFO "%s: transmit timed out, %s?", dev->name,
- (SCB_complete(status)?"lost interrupt":
- "board on fire"));
- lp->stats.tx_errors++;
- dev->tbusy = 0;
- lp->last_tx = jiffies;
- if (!SCB_complete(status)) {
- scb_command(dev, SCB_CUabort);
- outb(0,dev->base_addr+SIGNAL_CA);
- }
- }
- if (test_and_set_bit(0,(void *)&dev->tbusy))
- {
- lp->stats.tx_dropped++;
- }
- else
{
unsigned short length = (ETH_ZLEN < buf->len) ? buf->len :
ETH_ZLEN;
outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
- dev->interrupt = 1;
-
status = scb_status(dev);
#if NET_DEBUG > 4
outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
- dev->interrupt = 0;
#if NET_DEBUG > 6
printk("%s: leaving eexp_irq()\n", dev->name);
#endif
else
lp->tx_head += TX_BUF_SIZE;
if (lp->tx_head != lp->tx_reap)
- dev->tbusy = 0;
-
+ netif_wake_queue(dev);
+
if (LOCKUP16 || lp->width) {
/* Restart the CU so that the packet can actually
be transmitted. (Zoltan Szilagyi 10-12-96) */
dev->hard_start_xmit = eexp_xmit;
dev->get_stats = eexp_stats;
dev->set_multicast_list = &eexp_set_multicast;
+ dev->tx_timeout = eexp_timeout;
+ dev->watchdog_timeo = 2*HZ;
ether_setup(dev);
return 0;
}
unsigned short tx_block = lp->tx_reap;
unsigned short status;
- if ((!dev->tbusy) && lp->tx_head==lp->tx_reap)
+ if (!test_bit(LINK_STATE_XOFF, &dev->state) && lp->tx_head==lp->tx_reap)
return 0x0000;
do
lp->tx_reap = tx_block = TX_BUF_START;
else
lp->tx_reap = tx_block += TX_BUF_SIZE;
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
}
while (lp->tx_reap != lp->tx_head);
{
printk(KERN_WARNING "%s: Failed to restart CU, resetting board...\n",dev->name);
eexp_hw_init586(dev);
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
return;
}
}
static int irport_raw_write(struct net_device *dev, __u8 *buf, int len);
static struct net_device_stats *irport_net_get_stats(struct net_device *dev);
static int irport_change_speed_complete(struct irda_task *task);
+static void irport_timeout(struct net_device *dev);
EXPORT_SYMBOL(irport_open);
EXPORT_SYMBOL(irport_close);
EXPORT_SYMBOL(irport_stop);
EXPORT_SYMBOL(irport_interrupt);
EXPORT_SYMBOL(irport_hard_xmit);
+EXPORT_SYMBOL(irport_timeout);
EXPORT_SYMBOL(irport_change_speed);
EXPORT_SYMBOL(irport_net_open);
EXPORT_SYMBOL(irport_net_close);
/* Override the network functions we need to use */
dev->init = irport_net_init;
dev->hard_start_xmit = irport_hard_xmit;
+ dev->tx_timeout = irport_timeout;
+ dev->watchdog_timeo = HZ/20;
dev->open = irport_net_open;
dev->stop = irport_net_close;
dev->get_stats = irport_net_get_stats;
NULL, (void *) self->new_speed);
self->new_speed = 0;
} else {
- self->netdev->tbusy = 0; /* Unlock */
-
/* Tell network layer that we want more frames */
- mark_bh(NET_BH);
+ netif_wake_queue(self->netdev);
}
self->stats.tx_packets++;
- /* Schedule network layer, so we can get some more frames */
- mark_bh(NET_BH);
-
/*
* Reset Rx FIFO to make sure that all reflected transmit data
* is discarded. This is needed for half duplex operation
ASSERT(self->netdev != NULL, return -1;);
/* Finished changing speed, so we are not busy any longer */
- self->netdev->tbusy = 0;
-
/* Signal network layer so it can try to send the frame */
- mark_bh(NET_BH);
+ netif_wake_queue(self->netdev);
+
return 0;
}
/*
- * Function irport_xmit (void)
+ * Function irport_timeout (struct net_device *dev)
+ *
+ * The networking layer thinks we timed out.
+ *
+ */
+
+static void irport_timeout(struct net_device *dev)
+{
+ struct irport_cb *self;
+ int iobase;
+
+ self = (struct irport_cb *) dev->priv;
+ iobase = self->io.sir_base;
+
+ WARNING("%s: transmit timed out\n", dev->name);
+ irport_start(self);
+ self->change_speed(self->priv, self->io.speed);
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+}
+
+/*
+ * Function irport_hard_start_xmit (struct sk_buff *skb, struct net_device *dev)
*
* Transmits the current frame until FIFO is full, then
* waits until the next transmitt interrupt, and continues until the
iobase = self->io.sir_base;
- /* Lock transmit buffer */
- if (irda_lock((void *) &dev->tbusy) == FALSE) {
- int tickssofar = jiffies - dev->trans_start;
- if ((tickssofar < 5) || !dev->start)
- return -EBUSY;
-
- WARNING("%s: transmit timed out\n", dev->name);
- irport_start(self);
- self->change_speed(self->priv, self->io.speed);
-
- dev->trans_start = jiffies;
- }
-
+ netif_stop_queue(dev);
+
/* Check if we need to change the speed */
if ((speed = irda_get_speed(skb)) != self->io.speed)
self->new_speed = speed;
spin_lock(&self->lock);
- dev->interrupt = 1;
-
iobase = self->io.sir_base;
iir = inb(iobase+UART_IIR) & UART_IIR_ID;
iir = inb(iobase + UART_IIR) & UART_IIR_ID;
}
- dev->interrupt = 0;
-
spin_unlock(&self->lock);
}
irport_start(self);
- /* Ready to play! */
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
/*
* Open new IrLAP layer instance, now that everything should be
self->irlap = irlap_open(dev, &self->qos);
/* FIXME: change speed of dongle */
+ /* Ready to play! */
+ netif_start_queue(dev);
+
MOD_INC_USE_COUNT;
return 0;
iobase = self->io.sir_base;
/* Stop device */
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
/* Stop and remove instance of IrLAP */
if (self->irlap)
irlap_close(self->irlap);
ASSERT(self->netdev != NULL, return -1;);
/* Finished changing speed, so we are not busy any longer */
- self->netdev->tbusy = 0;
-
/* Signal network layer so it can try to send the frame */
- mark_bh(NET_BH);
-
+ netif_wake_queue(self->netdev);
+
return 0;
}
ASSERT(self != NULL, return 0;);
/* Lock transmit buffer */
- if (irda_lock((void *) &dev->tbusy) == FALSE)
- return -EBUSY;
-
+ netif_stop_queue(dev);
+
/* Check if we need to change the speed */
if ((speed = irda_get_speed(skb)) != self->io.speed)
self->new_speed = speed;
NULL, (void *) self->new_speed);
self->new_speed = 0;
} else {
- self->netdev->tbusy = 0; /* Unlock */
-
/* Tell network layer that we want more frames */
- mark_bh(NET_BH);
+ netif_wake_queue(self->netdev);
}
}
}
IRDA_DEBUG(0, __FUNCTION__ "()\n");
/* Ready to play! */
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
+ netif_start_queue(dev);
+
/* Make sure we can receive more data */
irtty_stop_receiver(self, FALSE);
irtty_stop_receiver(self, TRUE);
/* Stop device */
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
/* Stop and remove instance of IrLAP */
if (self->irlap)
irlap_close(self->irlap);
switch_bank(iobase, BANK2);
outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);
- self->netdev->tbusy = 0;
-
/* Enable some interrupts so we can receive frames */
switch_bank(iobase, BANK0);
if (speed > 115200) {
/* Restore BSR */
outb(bank, iobase+BSR);
+ netif_wake_queue(dev);
+
}
/*
iobase = self->io.fir_base;
- /* Lock transmit buffer */
- if (irda_lock((void *) &dev->tbusy) == FALSE)
- return -EBUSY;
-
+ netif_stop_queue(dev);
+
/* Check if we need to change the speed */
if ((speed = irda_get_speed(skb)) != self->io.speed)
self->new_speed = speed;
self = (struct nsc_ircc_cb *) dev->priv;
iobase = self->io.fir_base;
- /* Lock transmit buffer */
- if (irda_lock((void *) &dev->tbusy) == FALSE)
- return -EBUSY;
-
+ netif_stop_queue(dev);
+
/* Check if we need to change the speed */
if ((speed = irda_get_speed(skb)) != self->io.speed)
self->new_speed = speed;
out:
/* Not busy transmitting anymore if window is not full */
if (self->tx_fifo.free < MAX_TX_WINDOW)
- dev->tbusy = 0;
+ netif_wake_queue(self->netdev);
/* Restore bank register */
outb(bank, iobase+BSR);
/* Make sure we have room for more frames */
if (self->tx_fifo.free < MAX_TX_WINDOW) {
/* Not busy transmitting anymore */
- self->netdev->tbusy = 0;
-
/* Tell the network layer, that we can accept more frames */
- mark_bh(NET_BH);
+ netif_wake_queue(self->netdev);
}
/* Restore bank */
if (self->tx_buff.len > 0)
self->ier = IER_TXLDL_IE;
else {
- self->netdev->tbusy = 0; /* Unlock */
- self->stats.tx_packets++;
-
- mark_bh(NET_BH);
+ self->stats.tx_packets++;
+ netif_wakeup_queue(self->netdev);
self->ier = IER_TXEMP_IE;
}
self = (struct nsc_ircc_cb *) dev->priv;
spin_lock(&self->lock);
- dev->interrupt = 1;
iobase = self->io.fir_base;
outb(self->ier, iobase+IER); /* Restore interrupts */
outb(bsr, iobase+BSR); /* Restore bank register */
- dev->interrupt = 0;
spin_unlock(&self->lock);
}
outb(bank, iobase+BSR);
/* Ready to play! */
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
+ netif_start_queue(dev);
+
/*
* Open new IrLAP layer instance, now that everything should be
* initialized properly
ASSERT(self != NULL, return 0;);
/* Stop device */
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
/* Stop and remove instance of IrLAP */
if (self->irlap)
irlap_close(self->irlap);
if ((speed = irda_get_speed(skb)) != self->io.speed)
self->new_speed = speed;
+ netif_stop_queue(dev);
+
if (self->stopped) {
dev_kfree_skb(skb);
return 0;
self->txpending++;
- /*FIXME: ask about tbusy,media_busy stuff, for the moment */
- /*tbusy means can't queue any more */
+ /*FIXME: ask about busy,media_busy stuff, for the moment */
+ /*busy means can't queue any more */
#ifndef ONETASK
- if (self->txpending == TX_SLOTS)
- {
-#else
+ if (self->txpending != TX_SLOTS)
{
-#endif
- if (irda_lock ((void *) &dev->tbusy) == FALSE)
- return -EBUSY;
+ netif_wake_queue(dev);
}
+#endif
outb_p (0x80, OBOE_RST);
outb_p (1, OBOE_REG_9);
self->new_speed = 0;
}
- self->netdev->tbusy = 0; /* Unlock */
-
/* Tell network layer that we want more frames */
- mark_bh(NET_BH);
+ netif_wake_queue(self->netdev);
}
if (irqstat & OBOE_ISR_RXDONE)
toshoboe_initptrs (self);
/* Ready to play! */
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
+ netif_start_queue(dev);
/*
* Open new IrLAP layer instance, now that everything should be
* initialized properly
self = (struct toshoboe_cb *) dev->priv;
/* Stop device */
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
/* Stop and remove instance of IrLAP */
if (self->irlap)
irlap_close(self->irlap);
toshoboe_initptrs (self);
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
- self->stopped = 0;
-
+ netif_wake_queue(self->netdev);
restore_flags (flags);
printk (KERN_WARNING "ToshOboe: waking up\n");
outb(UFR_EN_FIFO, iobase+UFR); /* First we must enable FIFO */
outb(0xa7, iobase+UFR);
- self->netdev->tbusy = 0;
-
+ netif_wake_queue(self->netdev);
+
/* Enable some interrupts so we can receive frames */
switch_bank(iobase, SET0);
if (speed > PIO_MAX_SPEED) {
(int) skb->len);
/* Lock transmit buffer */
- if (irda_lock((void *) &dev->tbusy) == FALSE)
- return -EBUSY;
-
+ netif_stop_queue(dev);
+
/* Check if we need to change the speed */
if ((speed = irda_get_speed(skb)) != self->io.speed)
self->new_speed = speed;
}
/* Unlock tx_buff and request another frame */
- self->netdev->tbusy = 0; /* Unlock */
-
/* Tell the network layer, that we want more frames */
- mark_bh(NET_BH);
-
+ netif_wake_queue(self->netdev);
+
/* Restore set */
outb(set, iobase+SSR);
}
outb(AUDR_SFEND, iobase+AUDR);
outb(set, iobase+SSR);
- self->netdev->tbusy = 0; /* Unlock */
self->stats.tx_packets++;
- /* Schedule network layer */
- mark_bh(NET_BH);
-
+ /* Feed me more packets */
+ netif_wake_queue(self->netdev);
new_icr |= ICR_ETBREI;
}
}
}
self = (struct w83977af_ir *) dev->priv;
- dev->interrupt = 1;
-
iobase = self->io.fir_base;
/* Save current bank */
outb(icr, iobase+ICR); /* Restore (new) interrupts */
outb(set, iobase+SSR); /* Restore bank register */
- self->netdev->interrupt = 0;
}
/*
outb(set, iobase+SSR);
/* Ready to play! */
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
+ netif_start_queue(dev);
+
/*
* Open new IrLAP layer instance, now that everything should be
* initialized properly
iobase = self->io.fir_base;
/* Stop device */
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
/* Stop and remove instance of IrLAP */
if (self->irlap)
irlap_close(self->irlap);
If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
printk("%s: DMAing conflict in ne_get_8390_hdr "
- "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
+ "[DMAstat:%d][irqlock:%d].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock);
return;
}
If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
printk("%s: DMAing conflict in ne_block_input "
- "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
+ "[DMAstat:%d][irqlock:%d].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
printk("%s: DMAing conflict in ne_block_output."
- "[DMAstat:%d][irqlock:%d][intr:%ld]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
+ "[DMAstat:%d][irqlock:%d]\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
"(should be %x.%02x)\n", name, version[0], version[1],
FirmwareVersion[0], FirmwareVersion[1]);
- dev->interrupt = 0;
- dev->tbusy = 0;
- dev->start = 1;
+ netif_start_queue(dev);
MOD_INC_USE_COUNT;
return 0; /* Always succeed */
}
irq);
return;
}
- if (dev->interrupt)
- printk(KERN_ERR "%s: Re-entering the interrupt handler.\n",
- dev->name);
- dev->interrupt = 1;
ioaddr[0] = dev->base_addr;
/* rmem_end holds the second I/O address - fv */
/* is it a good interrupt? */
st = inb(ioaddr[1] + 6);
if (!(st & 0x08 && st & 0x20)) {
- dev->interrupt = 0;
return;
}
lp->rx_error_count = 0;
}
- dev->interrupt = 0;
return;
}
if (sb1000_debug > 2)
printk(KERN_DEBUG "%s: Shutting down sb1000.\n", dev->name);
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
ioaddr[0] = dev->base_addr;
/* rmem_end holds the second I/O address - fv */
ioaddr[1] = dev->rmem_end;
* have to pack all state info into the device struct!
* ------------------------------------------------------------------------ */
-static char *MediaNames[Media_Count]=
- {"10Base2", "10BaseT", "10Base5", "Unknown"};
+static char *MediaNames[Media_Count] = {
+ "10Base2", "10BaseT", "10Base5", "Unknown" };
-static unsigned char poly[] =
- {1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0};
+static unsigned char poly[] = {
+ 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0
+};
/* ------------------------------------------------------------------------
* private subfunctions
#ifdef DEBUG
static void dumpmem(struct net_device *dev, u32 start, u32 len)
{
- int z;
-
- for (z = 0; z < len; z++)
- {
- if ((z & 15) == 0)
- printk("%04x:", z);
- printk(" %02x", readb(dev->mem_start + start + z));
- if ((z & 15) == 15)
- printk("\n");
- }
+ int z;
+
+ for (z = 0; z < len; z++) {
+ if ((z & 15) == 0)
+ printk("%04x:", z);
+ printk(" %02x", readb(dev->mem_start + start + z));
+ if ((z & 15) == 15)
+ printk("\n");
+ }
}
/* print exact time - ditto */
static void PrTime(void)
{
- struct timeval tv;
+ struct timeval tv;
- do_gettimeofday(&tv);
- printk("%9d:%06d: ", tv.tv_sec, tv.tv_usec);
+ do_gettimeofday(&tv);
+ printk("%9d:%06d: ", tv.tv_sec, tv.tv_usec);
}
+
#endif
/* deduce resources out of POS registers */
static void getaddrs(int slot, int junior, int *base, int *irq,
- skmca_medium *medium)
+ skmca_medium * medium)
{
- u_char pos0, pos1, pos2;
-
- if (junior)
- {
- pos0 = mca_read_stored_pos(slot, 2);
- *base = ((pos0 & 0x0e) << 13) + 0xc0000;
- *irq = ((pos0 & 0x10) >> 4) + 10;
- *medium = Media_Unknown;
- }
- else
- {
- /* reset POS 104 Bits 0+1 so the shared memory region goes to the
- configured area between 640K and 1M. Afterwards, enable the MC2.
- I really don't know what rode SK to do this... */
-
- mca_write_pos(slot, 4, mca_read_stored_pos(slot, 4) & 0xfc);
- mca_write_pos(slot, 2, mca_read_stored_pos(slot, 2) | 0x01);
-
- pos1 = mca_read_stored_pos(slot, 3);
- pos2 = mca_read_stored_pos(slot, 4);
- *base = ((pos1 & 0x07) << 14) + 0xc0000;
- switch (pos2 & 0x0c)
- {
- case 0: *irq = 3; break;
- case 4: *irq = 5; break;
- case 8: *irq = 10; break;
- case 12: *irq = 11; break;
- }
- *medium = (pos2 >> 6) & 3;
- }
+ u_char pos0, pos1, pos2;
+
+ if (junior) {
+ pos0 = mca_read_stored_pos(slot, 2);
+ *base = ((pos0 & 0x0e) << 13) + 0xc0000;
+ *irq = ((pos0 & 0x10) >> 4) + 10;
+ *medium = Media_Unknown;
+ } else {
+ /* reset POS 104 Bits 0+1 so the shared memory region goes to the
+ configured area between 640K and 1M. Afterwards, enable the MC2.
+ I really don't know what rode SK to do this... */
+
+ mca_write_pos(slot, 4,
+ mca_read_stored_pos(slot, 4) & 0xfc);
+ mca_write_pos(slot, 2,
+ mca_read_stored_pos(slot, 2) | 0x01);
+
+ pos1 = mca_read_stored_pos(slot, 3);
+ pos2 = mca_read_stored_pos(slot, 4);
+ *base = ((pos1 & 0x07) << 14) + 0xc0000;
+ switch (pos2 & 0x0c) {
+ case 0:
+ *irq = 3;
+ break;
+ case 4:
+ *irq = 5;
+ break;
+ case 8:
+ *irq = 10;
+ break;
+ case 12:
+ *irq = 11;
+ break;
+ }
+ *medium = (pos2 >> 6) & 3;
+ }
}
/* check for both cards:
static int dofind(int *junior, int firstslot)
{
- int slot;
- unsigned int id;
-
- for (slot = firstslot; slot < MCA_MAX_SLOT_NR; slot++)
- {
- id = mca_read_stored_pos(slot, 0)
- + (((unsigned int) mca_read_stored_pos(slot, 1)) << 8);
-
- *junior = 0;
- if (id == SKNET_MCA_ID)
- return slot;
- *junior = 1;
- if (id == SKNET_JUNIOR_MCA_ID)
- return slot;
- }
- return MCA_NOTFOUND;
+ int slot;
+ unsigned int id;
+
+ for (slot = firstslot; slot < MCA_MAX_SLOT_NR; slot++) {
+ id = mca_read_stored_pos(slot, 0)
+ + (((unsigned int) mca_read_stored_pos(slot, 1)) << 8);
+
+ *junior = 0;
+ if (id == SKNET_MCA_ID)
+ return slot;
+ *junior = 1;
+ if (id == SKNET_JUNIOR_MCA_ID)
+ return slot;
+ }
+ return MCA_NOTFOUND;
}
/* reset the whole board */
static void ResetBoard(struct net_device *dev)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
+ skmca_priv *priv = (skmca_priv *) dev->priv;
- writeb(CTRL_RESET_ON, priv->ctrladdr);
- udelay(10);
- writeb(CTRL_RESET_OFF, priv->ctrladdr);
+ writeb(CTRL_RESET_ON, priv->ctrladdr);
+ udelay(10);
+ writeb(CTRL_RESET_OFF, priv->ctrladdr);
}
/* set LANCE register - must be atomic */
static void SetLANCE(struct net_device *dev, u16 addr, u16 value)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
- unsigned long flags;
+ skmca_priv *priv = (skmca_priv *) dev->priv;
+ unsigned long flags;
- /* disable interrupts */
+ /* disable interrupts */
- save_flags(flags);
- cli();
+ save_flags(flags);
+ cli();
- /* wait until no transfer is pending */
-
- while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+ /* wait until no transfer is pending */
- /* transfer register address to RAP */
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
- writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
- writew(addr, priv->ioregaddr);
- writeb(IOCMD_GO, priv->cmdaddr);
- udelay(1);
- while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+ /* transfer register address to RAP */
- /* transfer data to register */
+ writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP,
+ priv->ctrladdr);
+ writew(addr, priv->ioregaddr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
- writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA, priv->ctrladdr);
- writew(value, priv->ioregaddr);
- writeb(IOCMD_GO, priv->cmdaddr);
- udelay(1);
- while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+ /* transfer data to register */
- /* reenable interrupts */
+ writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA,
+ priv->ctrladdr);
+ writew(value, priv->ioregaddr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
- restore_flags(flags);
+ /* reenable interrupts */
+
+ restore_flags(flags);
}
/* get LANCE register */
static u16 GetLANCE(struct net_device *dev, u16 addr)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
- unsigned long flags;
- unsigned int res;
+ skmca_priv *priv = (skmca_priv *) dev->priv;
+ unsigned long flags;
+ unsigned int res;
- /* disable interrupts */
+ /* disable interrupts */
- save_flags(flags);
- cli();
+ save_flags(flags);
+ cli();
- /* wait until no transfer is pending */
+ /* wait until no transfer is pending */
- while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
- /* transfer register address to RAP */
+ /* transfer register address to RAP */
- writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
- writew(addr, priv->ioregaddr);
- writeb(IOCMD_GO, priv->cmdaddr);
- udelay(1);
- while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+ writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP,
+ priv->ctrladdr);
+ writew(addr, priv->ioregaddr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
- /* transfer data from register */
+ /* transfer data from register */
- writeb(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA, priv->ctrladdr);
- writeb(IOCMD_GO, priv->cmdaddr);
- udelay(1);
- while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
- res = readw(priv->ioregaddr);
+ writeb(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA,
+ priv->ctrladdr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+ res = readw(priv->ioregaddr);
- /* reenable interrupts */
+ /* reenable interrupts */
- restore_flags(flags);
+ restore_flags(flags);
- return res;
+ return res;
}
/* build up descriptors in shared RAM */
static void InitDscrs(struct net_device *dev)
{
- u32 bufaddr;
-
- /* Set up Tx descriptors. The board has only 16K RAM so bits 16..23
- are always 0. */
-
- bufaddr = RAM_DATABASE;
- {
- LANCE_TxDescr descr;
- int z;
-
- for (z = 0; z < TXCOUNT; z++)
- {
- descr.LowAddr = bufaddr;
- descr.Flags = 0;
- descr.Len = 0xf000;
- descr.Status = 0;
- isa_memcpy_toio(dev->mem_start + RAM_TXBASE + (z * sizeof(LANCE_TxDescr)),
- &descr, sizeof(LANCE_TxDescr));
- memset_io(dev->mem_start + bufaddr, 0, RAM_BUFSIZE);
- bufaddr += RAM_BUFSIZE;
- }
- }
-
- /* do the same for the Rx descriptors */
-
- {
- LANCE_RxDescr descr;
- int z;
-
- for (z = 0; z < RXCOUNT; z++)
- {
- descr.LowAddr = bufaddr;
- descr.Flags = RXDSCR_FLAGS_OWN;
- descr.MaxLen = -RAM_BUFSIZE;
- descr.Len = 0;
- isa_memcpy_toio(dev->mem_start + RAM_RXBASE + (z * sizeof(LANCE_RxDescr)),
- &descr, sizeof(LANCE_RxDescr));
- isa_memset_io(dev->mem_start + bufaddr, 0, RAM_BUFSIZE);
- bufaddr += RAM_BUFSIZE;
- }
- }
+ u32 bufaddr;
+
+ /* Set up Tx descriptors. The board has only 16K RAM so bits 16..23
+ are always 0. */
+
+ bufaddr = RAM_DATABASE;
+ {
+ LANCE_TxDescr descr;
+ int z;
+
+ for (z = 0; z < TXCOUNT; z++) {
+ descr.LowAddr = bufaddr;
+ descr.Flags = 0;
+ descr.Len = 0xf000;
+ descr.Status = 0;
+ isa_memcpy_toio(dev->mem_start + RAM_TXBASE +
+ (z * sizeof(LANCE_TxDescr)),
+ &descr, sizeof(LANCE_TxDescr));
+ memset_io(dev->mem_start + bufaddr, 0,
+ RAM_BUFSIZE);
+ bufaddr += RAM_BUFSIZE;
+ }
+ }
+
+ /* do the same for the Rx descriptors */
+
+ {
+ LANCE_RxDescr descr;
+ int z;
+
+ for (z = 0; z < RXCOUNT; z++) {
+ descr.LowAddr = bufaddr;
+ descr.Flags = RXDSCR_FLAGS_OWN;
+ descr.MaxLen = -RAM_BUFSIZE;
+ descr.Len = 0;
+ isa_memcpy_toio(dev->mem_start + RAM_RXBASE +
+ (z * sizeof(LANCE_RxDescr)),
+ &descr, sizeof(LANCE_RxDescr));
+ isa_memset_io(dev->mem_start + bufaddr, 0,
+ RAM_BUFSIZE);
+ bufaddr += RAM_BUFSIZE;
+ }
+ }
}
/* calculate the hash bit position for a given multicast address
static void UpdateCRC(unsigned char *CRC, int bit)
{
- int j;
+ int j;
- /* shift CRC one bit */
+ /* shift CRC one bit */
- memmove(CRC + 1, CRC, 32 * sizeof(unsigned char));
- CRC[0] = 0;
+ memmove(CRC + 1, CRC, 32 * sizeof(unsigned char));
+ CRC[0] = 0;
- /* if bit XOR controlbit = 1, set CRC = CRC XOR polynomial */
+ /* if bit XOR controlbit = 1, set CRC = CRC XOR polynomial */
- if (bit ^ CRC[32])
- for (j = 0; j < 32; j++)
- CRC[j] ^= poly[j];
+ if (bit ^ CRC[32])
+ for (j = 0; j < 32; j++)
+ CRC[j] ^= poly[j];
}
static unsigned int GetHash(char *address)
{
- unsigned char CRC[33];
- int i, byte, hashcode;
+ unsigned char CRC[33];
+ int i, byte, hashcode;
- /* a multicast address has bit 0 in the first byte set */
+ /* a multicast address has bit 0 in the first byte set */
- if ((address[0] & 1) == 0)
- return -1;
+ if ((address[0] & 1) == 0)
+ return -1;
- /* initialize CRC */
+ /* initialize CRC */
- memset(CRC, 1, sizeof(CRC));
+ memset(CRC, 1, sizeof(CRC));
- /* loop through address bits */
+ /* loop through address bits */
- for (byte = 0; byte < 6; byte++)
- for (i = 0; i < 8; i++)
- UpdateCRC(CRC, (address[byte] >> i) & 1);
+ for (byte = 0; byte < 6; byte++)
+ for (i = 0; i < 8; i++)
+ UpdateCRC(CRC, (address[byte] >> i) & 1);
- /* hashcode is the 6 least significant bits of the CRC */
+ /* hashcode is the 6 least significant bits of the CRC */
- hashcode = 0;
- for (i = 0; i < 6; i++)
- hashcode = (hashcode << 1) + CRC[i];
- return hashcode;
+ hashcode = 0;
+ for (i = 0; i < 6; i++)
+ hashcode = (hashcode << 1) + CRC[i];
+ return hashcode;
}
/* feed ready-built initialization block into LANCE */
static void InitLANCE(struct net_device *dev)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
-
- /* build up descriptors. */
+ skmca_priv *priv = (skmca_priv *) dev->priv;
- InitDscrs(dev);
+ /* build up descriptors. */
- /* next RX descriptor to be read is the first one. Since the LANCE
- will start from the beginning after initialization, we have to
- reset out pointers too. */
+ InitDscrs(dev);
- priv->nextrx = 0;
+ /* next RX descriptor to be read is the first one. Since the LANCE
+ will start from the beginning after initialization, we have to
+ reset out pointers too. */
- /* no TX descriptors active */
+ priv->nextrx = 0;
- priv->nexttxput = priv->nexttxdone = priv->txbusy = 0;
+ /* no TX descriptors active */
- /* set up the LANCE bus control register - constant for SKnet boards */
+ priv->nexttxput = priv->nexttxdone = priv->txbusy = 0;
- SetLANCE(dev, LANCE_CSR3, CSR3_BSWAP_OFF | CSR3_ALE_LOW | CSR3_BCON_HOLD);
+ /* set up the LANCE bus control register - constant for SKnet boards */
- /* write address of initialization block into LANCE */
+ SetLANCE(dev, LANCE_CSR3,
+ CSR3_BSWAP_OFF | CSR3_ALE_LOW | CSR3_BCON_HOLD);
- SetLANCE(dev, LANCE_CSR1, RAM_INITBASE & 0xffff);
- SetLANCE(dev, LANCE_CSR2, (RAM_INITBASE >> 16) & 0xff);
+ /* write address of initialization block into LANCE */
- /* we don't get ready until the LANCE has read the init block */
+ SetLANCE(dev, LANCE_CSR1, RAM_INITBASE & 0xffff);
+ SetLANCE(dev, LANCE_CSR2, (RAM_INITBASE >> 16) & 0xff);
- dev->tbusy = 1;
+ /* we don't get ready until the LANCE has read the init block */
- /* let LANCE read the initialization block. LANCE is ready
- when we receive the corresponding interrupt. */
+ netif_stop_queue(dev);
+
+ /* let LANCE read the initialization block. LANCE is ready
+ when we receive the corresponding interrupt. */
- SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_INIT);
+ SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_INIT);
}
/* stop the LANCE so we can reinitialize it */
static void StopLANCE(struct net_device *dev)
{
- /* can't take frames any more */
+ /* can't take frames any more */
- dev->tbusy = 1;
+ netif_stop_queue(dev);
+
+ /* disable interrupts, stop it */
- /* disable interrupts, stop it */
-
- SetLANCE(dev, LANCE_CSR0, CSR0_STOP);
+ SetLANCE(dev, LANCE_CSR0, CSR0_STOP);
}
/* initialize card and LANCE for proper operation */
static void InitBoard(struct net_device *dev)
{
- LANCE_InitBlock block;
+ LANCE_InitBlock block;
- /* Lay out the shared RAM - first we create the init block for the LANCE.
- We do not overwrite it later because we need it again when we switch
- promiscous mode on/off. */
+ /* Lay out the shared RAM - first we create the init block for the LANCE.
+ We do not overwrite it later because we need it again when we switch
+ promiscous mode on/off. */
- block.Mode = 0;
- if (dev->flags & IFF_PROMISC)
- block.Mode |= LANCE_INIT_PROM;
- memcpy(block.PAdr, dev->dev_addr, 6);
- memset(block.LAdrF, 0, sizeof(block.LAdrF));
- block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29);
- block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29);
+ block.Mode = 0;
+ if (dev->flags & IFF_PROMISC)
+ block.Mode |= LANCE_INIT_PROM;
+ memcpy(block.PAdr, dev->dev_addr, 6);
+ memset(block.LAdrF, 0, sizeof(block.LAdrF));
+ block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29);
+ block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29);
- isa_memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
+ isa_memcpy_toio(dev->mem_start + RAM_INITBASE, &block,
+ sizeof(block));
- /* initialize LANCE. Implicitly sets up other structures in RAM. */
+ /* initialize LANCE. Implicitly sets up other structures in RAM. */
- InitLANCE(dev);
+ InitLANCE(dev);
}
/* deinitialize card and LANCE */
static void DeinitBoard(struct net_device *dev)
{
- /* stop LANCE */
+ /* stop LANCE */
- StopLANCE(dev);
+ StopLANCE(dev);
- /* reset board */
+ /* reset board */
- ResetBoard(dev);
+ ResetBoard(dev);
}
/* ------------------------------------------------------------------------
static u16 irqstart_handler(struct net_device *dev, u16 oldcsr0)
{
- /* now we're ready to transmit */
-
- dev->tbusy = 0;
+ /* now we're ready to transmit */
- /* reset IDON bit, start LANCE */
+ netif_wake_queue(dev);
+
+ /* reset IDON bit, start LANCE */
- SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_IDON | CSR0_STRT);
- return GetLANCE(dev, LANCE_CSR0);
+ SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_IDON | CSR0_STRT);
+ return GetLANCE(dev, LANCE_CSR0);
}
/* receive interrupt */
static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
- LANCE_RxDescr descr;
- unsigned int descraddr;
+ skmca_priv *priv = (skmca_priv *) dev->priv;
+ LANCE_RxDescr descr;
+ unsigned int descraddr;
+
+ /* did we loose blocks due to a FIFO overrun ? */
- /* did we loose blocks due to a FIFO overrun ? */
+ if (oldcsr0 & CSR0_MISS)
+ priv->stat.rx_fifo_errors++;
- if (oldcsr0 & CSR0_MISS)
- priv->stat.rx_fifo_errors++;
+ /* run through queue until we reach a descriptor we do not own */
- /* run through queue until we reach a descriptor we do not own */
+ descraddr = RAM_RXBASE + (priv->nextrx * sizeof(LANCE_RxDescr));
+ while (1) {
+ /* read descriptor */
+ isa_memcpy_fromio(&descr, dev->mem_start + descraddr,
+ sizeof(LANCE_RxDescr));
- descraddr = RAM_RXBASE + (priv->nextrx * sizeof(LANCE_RxDescr));
- while (1)
- {
- /* read descriptor */
- isa_memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_RxDescr));
-
- /* if we reach a descriptor we do not own, we're done */
- if ((descr.Flags & RXDSCR_FLAGS_OWN) != 0)
- break;
+ /* if we reach a descriptor we do not own, we're done */
+ if ((descr.Flags & RXDSCR_FLAGS_OWN) != 0)
+ break;
#ifdef DEBUG
- PrTime(); printk("Receive packet on descr %d len %d\n", priv->nextrx, descr.Len);
+ PrTime();
+ printk("Receive packet on descr %d len %d\n", priv->nextrx,
+ descr.Len);
#endif
- /* erroneous packet ? */
- if ((descr.Flags & RXDSCR_FLAGS_ERR) != 0)
- {
- priv->stat.rx_errors++;
- if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
- priv->stat.rx_crc_errors++;
- else if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
- priv->stat.rx_frame_errors++;
- else if ((descr.Flags & RXDSCR_FLAGS_OFLO) != 0)
- priv->stat.rx_fifo_errors++;
- }
-
- /* good packet ? */
- else
- {
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(descr.Len + 2);
- if (skb == NULL)
- priv->stat.rx_dropped++;
- else
- {
- isa_memcpy_fromio(skb_put(skb, descr.Len),
- dev->mem_start + descr.LowAddr, descr.Len);
- skb->dev = dev;
- skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
- priv->stat.rx_packets++;
-#if LINUX_VERSION_CODE >= 0x020119 /* byte counters for >= 2.1.25 */
- priv->stat.rx_bytes += descr.Len;
+ /* erroneous packet ? */
+ if ((descr.Flags & RXDSCR_FLAGS_ERR) != 0) {
+ priv->stat.rx_errors++;
+ if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
+ priv->stat.rx_crc_errors++;
+ else if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
+ priv->stat.rx_frame_errors++;
+ else if ((descr.Flags & RXDSCR_FLAGS_OFLO) != 0)
+ priv->stat.rx_fifo_errors++;
+ }
+
+ /* good packet ? */
+ else {
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(descr.Len + 2);
+ if (skb == NULL)
+ priv->stat.rx_dropped++;
+ else {
+ isa_memcpy_fromio(skb_put(skb, descr.Len),
+ dev->mem_start +
+ descr.LowAddr,
+ descr.Len);
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_NONE;
+ priv->stat.rx_packets++;
+#if LINUX_VERSION_CODE >= 0x020119 /* byte counters for >= 2.1.25 */
+ priv->stat.rx_bytes += descr.Len;
#endif
- netif_rx(skb);
- }
- }
-
- /* give descriptor back to LANCE */
- descr.Len = 0;
- descr.Flags |= RXDSCR_FLAGS_OWN;
-
- /* update descriptor in shared RAM */
- isa_memcpy_toio(dev->mem_start + descraddr, &descr, sizeof(LANCE_RxDescr));
-
- /* go to next descriptor */
- priv->nextrx++; descraddr += sizeof(LANCE_RxDescr);
- if (priv->nextrx >= RXCOUNT)
- {
- priv->nextrx = 0;
- descraddr = RAM_RXBASE;
- }
- }
-
- /* reset RINT bit */
-
- SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_RINT);
- return GetLANCE(dev, LANCE_CSR0);
+ netif_rx(skb);
+ }
+ }
+
+ /* give descriptor back to LANCE */
+ descr.Len = 0;
+ descr.Flags |= RXDSCR_FLAGS_OWN;
+
+ /* update descriptor in shared RAM */
+ isa_memcpy_toio(dev->mem_start + descraddr, &descr,
+ sizeof(LANCE_RxDescr));
+
+ /* go to next descriptor */
+ priv->nextrx++;
+ descraddr += sizeof(LANCE_RxDescr);
+ if (priv->nextrx >= RXCOUNT) {
+ priv->nextrx = 0;
+ descraddr = RAM_RXBASE;
+ }
+ }
+
+ /* reset RINT bit */
+
+ SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_RINT);
+ return GetLANCE(dev, LANCE_CSR0);
}
/* transmit interrupt */
static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
- LANCE_TxDescr descr;
- unsigned int descraddr;
+ skmca_priv *priv = (skmca_priv *) dev->priv;
+ LANCE_TxDescr descr;
+ unsigned int descraddr;
- /* check descriptors at most until no busy one is left */
+ /* check descriptors at most until no busy one is left */
- descraddr = RAM_TXBASE + (priv->nexttxdone * sizeof(LANCE_TxDescr));
- while (priv->txbusy > 0)
- {
- /* read descriptor */
- isa_memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_TxDescr));
+ descraddr =
+ RAM_TXBASE + (priv->nexttxdone * sizeof(LANCE_TxDescr));
+ while (priv->txbusy > 0) {
+ /* read descriptor */
+ isa_memcpy_fromio(&descr, dev->mem_start + descraddr,
+ sizeof(LANCE_TxDescr));
- /* if the LANCE still owns this one, we've worked out all sent packets */
- if ((descr.Flags & TXDSCR_FLAGS_OWN) != 0)
- break;
+ /* if the LANCE still owns this one, we've worked out all sent packets */
+ if ((descr.Flags & TXDSCR_FLAGS_OWN) != 0)
+ break;
#ifdef DEBUG
- PrTime(); printk("Send packet done on descr %d\n", priv->nexttxdone);
+ PrTime();
+ printk("Send packet done on descr %d\n", priv->nexttxdone);
#endif
- /* update statistics */
- if ((descr.Flags & TXDSCR_FLAGS_ERR) == 0)
- {
- priv->stat.tx_packets++;
-#if LINUX_VERSION_CODE >= 0x020119 /* byte counters for >= 2.1.25 */
- priv->stat.tx_bytes++;
+ /* update statistics */
+ if ((descr.Flags & TXDSCR_FLAGS_ERR) == 0) {
+ priv->stat.tx_packets++;
+#if LINUX_VERSION_CODE >= 0x020119 /* byte counters for >= 2.1.25 */
+ priv->stat.tx_bytes++;
#endif
- }
- else
- {
- priv->stat.tx_errors++;
- if ((descr.Status & TXDSCR_STATUS_UFLO) != 0)
- {
- priv->stat.tx_fifo_errors++;
- InitLANCE(dev);
- }
- else if ((descr.Status & TXDSCR_STATUS_LCOL) != 0)
- priv->stat.tx_window_errors++;
- else if ((descr.Status & TXDSCR_STATUS_LCAR) != 0)
- priv->stat.tx_carrier_errors++;
- else if ((descr.Status & TXDSCR_STATUS_RTRY) != 0)
- priv->stat.tx_aborted_errors++;
- }
-
- /* go to next descriptor */
- priv->nexttxdone++;
- descraddr += sizeof(LANCE_TxDescr);
- if (priv->nexttxdone >= TXCOUNT)
- {
- priv->nexttxdone = 0;
- descraddr = RAM_TXBASE;
- }
- priv->txbusy--;
- }
-
- /* reset TX interrupt bit */
-
- SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_TINT);
- oldcsr0 = GetLANCE(dev, LANCE_CSR0);
-
- /* at least one descriptor is freed. Therefore we can accept
- a new one */
-
- dev->tbusy = 0;
-
- /* inform upper layers we're in business again */
-
- mark_bh(NET_BH);
-
- return oldcsr0;
+ } else {
+ priv->stat.tx_errors++;
+ if ((descr.Status & TXDSCR_STATUS_UFLO) != 0) {
+ priv->stat.tx_fifo_errors++;
+ InitLANCE(dev);
+ }
+ else
+ if ((descr.Status & TXDSCR_STATUS_LCOL) !=
+ 0) priv->stat.tx_window_errors++;
+ else if ((descr.Status & TXDSCR_STATUS_LCAR) != 0)
+ priv->stat.tx_carrier_errors++;
+ else if ((descr.Status & TXDSCR_STATUS_RTRY) != 0)
+ priv->stat.tx_aborted_errors++;
+ }
+
+ /* go to next descriptor */
+ priv->nexttxdone++;
+ descraddr += sizeof(LANCE_TxDescr);
+ if (priv->nexttxdone >= TXCOUNT) {
+ priv->nexttxdone = 0;
+ descraddr = RAM_TXBASE;
+ }
+ priv->txbusy--;
+ }
+
+ /* reset TX interrupt bit */
+
+ SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_TINT);
+ oldcsr0 = GetLANCE(dev, LANCE_CSR0);
+
+ /* at least one descriptor is freed. Therefore we can accept
+ a new one */
+
+ netif_wake_queue(dev);
+
+ return oldcsr0;
}
/* general interrupt entry */
static void irq_handler(int irq, void *device, struct pt_regs *regs)
{
- struct net_device *dev = (struct net_device*) device;
- u16 csr0val;
-
- /* read CSR0 to get interrupt cause */
-
- csr0val = GetLANCE(dev, LANCE_CSR0);
+ struct net_device *dev = (struct net_device *) device;
+ u16 csr0val;
- /* in case we're not meant... */
+ /* read CSR0 to get interrupt cause */
- if ((csr0val & CSR0_INTR) == 0)
- return;
+ csr0val = GetLANCE(dev, LANCE_CSR0);
- dev->interrupt = 1;
+ /* in case we're not meant... */
- /* loop through the interrupt bits until everything is clear */
+ if ((csr0val & CSR0_INTR) == 0)
+ return;
- do
- {
- if ((csr0val & CSR0_IDON) != 0)
- csr0val = irqstart_handler(dev, csr0val);
- if ((csr0val & CSR0_RINT) != 0)
- csr0val = irqrx_handler(dev, csr0val);
- if ((csr0val & CSR0_TINT) != 0)
- csr0val = irqtx_handler(dev, csr0val);
- }
- while ((csr0val & CSR0_INTR) != 0);
+ /* loop through the interrupt bits until everything is clear */
- dev->interrupt = 0;
+ do {
+ if ((csr0val & CSR0_IDON) != 0)
+ csr0val = irqstart_handler(dev, csr0val);
+ if ((csr0val & CSR0_RINT) != 0)
+ csr0val = irqrx_handler(dev, csr0val);
+ if ((csr0val & CSR0_TINT) != 0)
+ csr0val = irqtx_handler(dev, csr0val);
+ }
+ while ((csr0val & CSR0_INTR) != 0);
}
/* ------------------------------------------------------------------------
static int skmca_getinfo(char *buf, int slot, void *d)
{
- int len = 0, i;
- struct net_device *dev = (struct net_device*) d;
- skmca_priv *priv;
-
- /* can't say anything about an uninitialized device... */
-
- if (dev == NULL)
- return len;
- if (dev->priv == NULL)
- return len;
- priv = (skmca_priv*) dev->priv;
-
- /* print info */
-
- len += sprintf(buf + len, "IRQ: %d\n", priv->realirq);
- len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
- dev->mem_end - 1);
- len += sprintf(buf + len, "Transceiver: %s\n", MediaNames[priv->medium]);
- len += sprintf(buf + len, "Device: %s\n", dev->name);
- len += sprintf(buf + len, "MAC address:");
- for (i = 0; i < 6; i ++ )
- len += sprintf( buf+len, " %02x", dev->dev_addr[i] );
- buf[len++] = '\n';
- buf[len] = 0;
-
- return len;
+ int len = 0, i;
+ struct net_device *dev = (struct net_device *) d;
+ skmca_priv *priv;
+
+ /* can't say anything about an uninitialized device... */
+
+ if (dev == NULL)
+ return len;
+ if (dev->priv == NULL)
+ return len;
+ priv = (skmca_priv *) dev->priv;
+
+ /* print info */
+
+ len += sprintf(buf + len, "IRQ: %d\n", priv->realirq);
+ len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
+ dev->mem_end - 1);
+ len +=
+ sprintf(buf + len, "Transceiver: %s\n",
+ MediaNames[priv->medium]);
+ len += sprintf(buf + len, "Device: %s\n", dev->name);
+ len += sprintf(buf + len, "MAC address:");
+ for (i = 0; i < 6; i++)
+ len += sprintf(buf + len, " %02x", dev->dev_addr[i]);
+ buf[len++] = '\n';
+ buf[len] = 0;
+
+ return len;
}
/* open driver. Means also initialization and start of LANCE */
static int skmca_open(struct net_device *dev)
{
- int result;
- skmca_priv *priv = (skmca_priv*) dev->priv;
-
- /* register resources - only necessary for IRQ */
- result = request_irq(priv->realirq, irq_handler, SA_SHIRQ | SA_SAMPLE_RANDOM,
- "sk_mca", dev);
- if (result != 0)
- {
- printk("%s: failed to register irq %d\n", dev->name, dev->irq);
- return result;
- }
- dev->irq = priv->realirq;
-
- /* set up the card and LANCE */
- InitBoard(dev);
+ int result;
+ skmca_priv *priv = (skmca_priv *) dev->priv;
+
+ /* register resources - only necessary for IRQ */
+ result =
+ request_irq(priv->realirq, irq_handler,
+ SA_SHIRQ | SA_SAMPLE_RANDOM, "sk_mca", dev);
+ if (result != 0) {
+ printk("%s: failed to register irq %d\n", dev->name,
+ dev->irq);
+ return result;
+ }
+ dev->irq = priv->realirq;
+
+ /* set up the card and LANCE */
+ InitBoard(dev);
#ifdef MODULE
- MOD_INC_USE_COUNT;
+ MOD_INC_USE_COUNT;
#endif
- return 0;
+ return 0;
}
/* close driver. Shut down board and free allocated resources */
static int skmca_close(struct net_device *dev)
{
- /* turn off board */
- DeinitBoard(dev);
+ /* turn off board */
+ DeinitBoard(dev);
- /* release resources */
- if (dev->irq != 0)
- free_irq(dev->irq, dev);
- dev->irq = 0;
+ /* release resources */
+ if (dev->irq != 0)
+ free_irq(dev->irq, dev);
+ dev->irq = 0;
#ifdef MODULE
- MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT;
#endif
- return 0;
+ return 0;
}
/* transmit a block. */
static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
- LANCE_TxDescr descr;
- unsigned int address;
- int tmplen, retval = 0;
- unsigned long flags;
-
- /* if we get called with a NULL descriptor, the Ethernet layer thinks
- our card is stuck an we should reset it. We'll do this completely: */
-
- if (skb == NULL)
- {
- DeinitBoard(dev);
- InitBoard(dev);
- return 0; /* don't try to free the block here ;-) */
- }
-
- /* is there space in the Tx queue ? If no, the upper layer gave us a
- packet in spite of us not being ready and is really in trouble.
- We'll do the dropping for him: */
- if (priv->txbusy >= TXCOUNT)
- {
- priv->stat.tx_dropped++;
- retval = -EIO;
- goto tx_done;
- }
-
- /* get TX descriptor */
- address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr));
- isa_memcpy_fromio(&descr, dev->mem_start + address, sizeof(LANCE_TxDescr));
-
- /* enter packet length as 2s complement - assure minimum length */
- tmplen = skb->len;
- if (tmplen < 60)
- tmplen = 60;
- descr.Len = 65536 - tmplen;
-
- /* copy filler into RAM - in case we're filling up...
- we're filling a bit more than necessary, but that doesn't harm
- since the buffer is far larger... */
- if (tmplen > skb->len)
- {
- char *fill = "NetBSD is a nice OS too! ";
- unsigned int destoffs = 0, l = strlen(fill);
-
- while (destoffs < tmplen)
- {
- isa_memcpy_toio(dev->mem_start + descr.LowAddr + destoffs, fill, l);
- destoffs += l;
- }
- }
-
- /* do the real data copying */
- isa_memcpy_toio(dev->mem_start + descr.LowAddr, skb->data, skb->len);
-
- /* hand descriptor over to LANCE - this is the first and last chunk */
- descr.Flags = TXDSCR_FLAGS_OWN | TXDSCR_FLAGS_STP | TXDSCR_FLAGS_ENP;
+ skmca_priv *priv = (skmca_priv *) dev->priv;
+ LANCE_TxDescr descr;
+ unsigned int address;
+ int tmplen, retval = 0;
+ unsigned long flags;
+
+ netif_stop_queue(dev);
+
+ /* is there space in the Tx queue ? If no, the upper layer gave us a
+ packet in spite of us not being ready and is really in trouble.
+ We'll do the dropping for him: */
+ if (priv->txbusy >= TXCOUNT) {
+ priv->stat.tx_dropped++;
+ retval = -EIO;
+ goto tx_done;
+ }
+
+ /* get TX descriptor */
+ address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr));
+ isa_memcpy_fromio(&descr, dev->mem_start + address,
+ sizeof(LANCE_TxDescr));
+
+ /* enter packet length as 2s complement - assure minimum length */
+ tmplen = skb->len;
+ if (tmplen < 60)
+ tmplen = 60;
+ descr.Len = 65536 - tmplen;
+
+ /* copy filler into RAM - in case we're filling up...
+ we're filling a bit more than necessary, but that doesn't harm
+ since the buffer is far larger... */
+ if (tmplen > skb->len) {
+ char *fill = "NetBSD is a nice OS too! ";
+ unsigned int destoffs = 0, l = strlen(fill);
+
+ while (destoffs < tmplen) {
+ isa_memcpy_toio(dev->mem_start + descr.LowAddr +
+ destoffs, fill, l);
+ destoffs += l;
+ }
+ }
+
+ /* do the real data copying */
+ isa_memcpy_toio(dev->mem_start + descr.LowAddr, skb->data,
+ skb->len);
+
+ /* hand descriptor over to LANCE - this is the first and last chunk */
+ descr.Flags =
+ TXDSCR_FLAGS_OWN | TXDSCR_FLAGS_STP | TXDSCR_FLAGS_ENP;
#ifdef DEBUG
- PrTime(); printk("Send packet on descr %d len %d\n", priv->nexttxput, skb->len);
+ PrTime();
+ printk("Send packet on descr %d len %d\n", priv->nexttxput,
+ skb->len);
#endif
- /* one more descriptor busy */
- save_flags(flags);
- cli();
- priv->nexttxput++;
- if (priv->nexttxput >= TXCOUNT)
- priv->nexttxput = 0;
- priv->txbusy++;
- dev->tbusy = (priv->txbusy >= TXCOUNT);
+ /* one more descriptor busy */
+ save_flags(flags);
+ cli();
+ priv->nexttxput++;
+ if (priv->nexttxput >= TXCOUNT)
+ priv->nexttxput = 0;
+ priv->txbusy++;
+ if (priv->txbusy < TXCOUNT)
+ netif_wake_queue(dev);
- /* write descriptor back to RAM */
- isa_memcpy_toio(dev->mem_start + address, &descr, sizeof(LANCE_TxDescr));
+ /* write descriptor back to RAM */
+ isa_memcpy_toio(dev->mem_start + address, &descr,
+ sizeof(LANCE_TxDescr));
- /* if no descriptors were active, give the LANCE a hint to read it
- immediately */
+ /* if no descriptors were active, give the LANCE a hint to read it
+ immediately */
- if (priv->txbusy == 0)
- SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_TDMD);
+ if (priv->txbusy == 0)
+ SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_TDMD);
- restore_flags(flags);
+ restore_flags(flags);
tx_done:
-
- /* When did that change exactly ? */
-
-#if LINUX_VERSION_CODE >= 0x020200
- dev_kfree_skb(skb);
-#else
- dev_kfree_skb(skb, FREE_WRITE);
-#endif
- return retval;
+ /* When did that change exactly ? */
+ dev_kfree_skb(skb);
+ return retval;
}
/* return pointer to Ethernet statistics */
static struct enet_statistics *skmca_stats(struct net_device *dev)
{
- skmca_priv *priv = (skmca_priv*) dev->priv;
-
- return &(priv->stat);
+ skmca_priv *priv = (skmca_priv *) dev->priv;
+ return &(priv->stat);
}
/* we don't support runtime reconfiguration, since an MCA card can
static int skmca_config(struct net_device *dev, struct ifmap *map)
{
- return 0;
+ return 0;
}
/* switch receiver mode. We use the LANCE's multicast filter to prefilter
static void skmca_set_multicast_list(struct net_device *dev)
{
- LANCE_InitBlock block;
-
- /* first stop the LANCE... */
- StopLANCE(dev);
-
- /* ...then modify the initialization block... */
- isa_memcpy_fromio(&block, dev->mem_start + RAM_INITBASE, sizeof(block));
- if (dev->flags & IFF_PROMISC)
- block.Mode |= LANCE_INIT_PROM;
- else
- block.Mode &= ~LANCE_INIT_PROM;
-
- if (dev->flags & IFF_ALLMULTI) /* get all multicasts */
- {
- memset(block.LAdrF, 8, 0xff);
- }
- else /* get selected/no multicasts */
- {
- struct dev_mc_list *mptr;
- int code;
-
- memset(block.LAdrF, 8, 0x00);
- for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next)
- {
- code = GetHash(mptr->dmi_addr);
- block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7);
- }
- }
-
- isa_memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
-
- /* ...then reinit LANCE with the correct flags */
- InitLANCE(dev);
+ LANCE_InitBlock block;
+
+ /* first stop the LANCE... */
+ StopLANCE(dev);
+
+ /* ...then modify the initialization block... */
+ isa_memcpy_fromio(&block, dev->mem_start + RAM_INITBASE,
+ sizeof(block));
+ if (dev->flags & IFF_PROMISC)
+ block.Mode |= LANCE_INIT_PROM;
+ else
+ block.Mode &= ~LANCE_INIT_PROM;
+
+ if (dev->flags & IFF_ALLMULTI) { /* get all multicasts */
+ memset(block.LAdrF, 8, 0xff);
+ } else { /* get selected/no multicasts */
+
+ struct dev_mc_list *mptr;
+ int code;
+
+ memset(block.LAdrF, 8, 0x00);
+ for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next) {
+ code = GetHash(mptr->dmi_addr);
+ block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7);
+ }
+ }
+
+ isa_memcpy_toio(dev->mem_start + RAM_INITBASE, &block,
+ sizeof(block));
+
+ /* ...then reinit LANCE with the correct flags */
+ InitLANCE(dev);
}
/* ------------------------------------------------------------------------
* ------------------------------------------------------------------------ */
#ifdef MODULE
-static int startslot; /* counts through slots when probing multiple devices */
+static int startslot; /* counts through slots when probing multiple devices */
#else
-#define startslot 0 /* otherwise a dummy, since there is only eth0 in-kern*/
+#define startslot 0 /* otherwise a dummy, since there is only eth0 in-kern */
#endif
int skmca_probe(struct net_device *dev)
{
- int force_detect = 0;
- int junior, slot, i;
- int base = 0, irq = 0;
- skmca_priv *priv;
- skmca_medium medium;
+ int force_detect = 0;
+ int junior, slot, i;
+ int base = 0, irq = 0;
+ skmca_priv *priv;
+ skmca_medium medium;
- /* can't work without an MCA bus ;-) */
-
- if (MCA_bus == 0)
- return ENODEV;
-
- /* start address of 1 --> forced detection */
-
- if (dev->mem_start == 1)
- force_detect = 1;
+ /* can't work without an MCA bus ;-) */
- /* search through slots */
-
- if (dev != NULL)
- {
- base = dev->mem_start;
- irq = dev->irq;
- }
- slot = dofind(&junior, startslot);
+ if (MCA_bus == 0)
+ return ENODEV;
+
+ /* start address of 1 --> forced detection */
+
+ if (dev->mem_start == 1)
+ force_detect = 1;
+
+ /* search through slots */
+
+ if (dev != NULL) {
+ base = dev->mem_start;
+ irq = dev->irq;
+ }
+ slot = dofind(&junior, startslot);
- while (slot != -1)
- {
- /* deduce card addresses */
+ while (slot != -1) {
+ /* deduce card addresses */
- getaddrs(slot, junior, &base, &irq, &medium);
+ getaddrs(slot, junior, &base, &irq, &medium);
#if LINUX_VERSION_CODE >= 0x020200
- /* slot already in use ? */
+ /* slot already in use ? */
- if (mca_is_adapter_used(slot))
- {
- slot = dofind(&junior, slot + 1);
- continue;
- }
+ if (mca_is_adapter_used(slot)) {
+ slot = dofind(&junior, slot + 1);
+ continue;
+ }
#endif
- /* were we looking for something different ? */
-
- if ((dev->irq != 0) || (dev->mem_start != 0))
- {
- if ((dev->irq != 0) && (dev->irq != irq))
- {
- slot = dofind(&junior, slot + 1);
- continue;
- }
- if ((dev->mem_start != 0) && (dev->mem_start != base))
- {
- slot = dofind(&junior, slot + 1);
- continue;
- }
- }
-
- /* found something that matches */
-
- break;
- }
+ /* were we looking for something different ? */
- /* nothing found ? */
-
- if (slot == -1)
- return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV;
-
- /* make procfs entries */
-
- if (junior)
- mca_set_adapter_name(slot, "SKNET junior MC2 Ethernet Adapter");
- else
- mca_set_adapter_name(slot, "SKNET MC2+ Ethernet Adapter");
- mca_set_adapter_procfn(slot, (MCA_ProcFn) skmca_getinfo, dev);
+ if ((dev->irq != 0) || (dev->mem_start != 0)) {
+ if ((dev->irq != 0) && (dev->irq != irq)) {
+ slot = dofind(&junior, slot + 1);
+ continue;
+ }
+ if ((dev->mem_start != 0)
+ && (dev->mem_start != base)) {
+ slot = dofind(&junior, slot + 1);
+ continue;
+ }
+ }
+
+ /* found something that matches */
+
+ break;
+ }
+
+ /* nothing found ? */
+
+ if (slot == -1)
+ return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV;
+
+ /* make procfs entries */
+
+ if (junior)
+ mca_set_adapter_name(slot,
+ "SKNET junior MC2 Ethernet Adapter");
+ else
+ mca_set_adapter_name(slot, "SKNET MC2+ Ethernet Adapter");
+ mca_set_adapter_procfn(slot, (MCA_ProcFn) skmca_getinfo, dev);
#if LINUX_VERSION_CODE >= 0x020200
- mca_mark_as_used(slot);
+ mca_mark_as_used(slot);
#endif
-
- /* announce success */
- printk("%s: SKNet %s adapter found in slot %d\n", dev->name,
- junior ? "Junior MC2" : "MC2+", slot + 1);
-
- /* allocate structure */
- priv = dev->priv = (skmca_priv*) kmalloc(sizeof(skmca_priv), GFP_KERNEL);
- priv->slot = slot;
- priv->macbase = base + 0x3fc0;
- priv->ioregaddr = base + 0x3ff0;
- priv->ctrladdr = base + 0x3ff2;
- priv->cmdaddr = base + 0x3ff3;
- priv->realirq = irq;
- priv->medium = medium;
- memset(&(priv->stat), 0, sizeof(struct enet_statistics));
-
- /* set base + irq for this device (irq not allocated so far) */
- dev->irq = 0;
- dev->mem_start = base;
- dev->mem_end = base + 0x4000;
-
- /* set methods */
- dev->open = skmca_open;
- dev->stop = skmca_close;
- dev->set_config = skmca_config;
- dev->hard_start_xmit = skmca_tx;
- dev->do_ioctl = NULL;
- dev->get_stats = skmca_stats;
- dev->set_multicast_list = skmca_set_multicast_list;
- dev->flags |= IFF_MULTICAST;
-
- /* generic setup */
- ether_setup(dev);
- dev->interrupt = 0;
- dev->tbusy = 0;
- dev->start = 0;
-
- /* copy out MAC address */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = readb(priv->macbase + (i << 1));
-
- /* print config */
- printk("%s: IRQ %d, memory %#lx-%#lx, "
- "MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n",
- dev->name, priv->realirq, dev->mem_start, dev->mem_end - 1,
- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
- printk("%s: %s medium\n", dev->name, MediaNames[priv->medium]);
-
- /* reset board */
-
- ResetBoard(dev);
+
+ /* announce success */
+ printk("%s: SKNet %s adapter found in slot %d\n", dev->name,
+ junior ? "Junior MC2" : "MC2+", slot + 1);
+
+ /* allocate structure */
+ priv = dev->priv =
+ (skmca_priv *) kmalloc(sizeof(skmca_priv), GFP_KERNEL);
+ priv->slot = slot;
+ priv->macbase = base + 0x3fc0;
+ priv->ioregaddr = base + 0x3ff0;
+ priv->ctrladdr = base + 0x3ff2;
+ priv->cmdaddr = base + 0x3ff3;
+ priv->realirq = irq;
+ priv->medium = medium;
+ memset(&(priv->stat), 0, sizeof(struct enet_statistics));
+
+ /* set base + irq for this device (irq not allocated so far) */
+ dev->irq = 0;
+ dev->mem_start = base;
+ dev->mem_end = base + 0x4000;
+
+ /* set methods */
+ dev->open = skmca_open;
+ dev->stop = skmca_close;
+ dev->set_config = skmca_config;
+ dev->hard_start_xmit = skmca_tx;
+ dev->do_ioctl = NULL;
+ dev->get_stats = skmca_stats;
+ dev->set_multicast_list = skmca_set_multicast_list;
+ dev->flags |= IFF_MULTICAST;
+
+ /* generic setup */
+ ether_setup(dev);
+
+ /* copy out MAC address */
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = readb(priv->macbase + (i << 1));
+
+ /* print config */
+ printk("%s: IRQ %d, memory %#lx-%#lx, "
+ "MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n",
+ dev->name, priv->realirq, dev->mem_start, dev->mem_end - 1,
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+ printk("%s: %s medium\n", dev->name, MediaNames[priv->medium]);
+
+ /* reset board */
+
+ ResetBoard(dev);
#ifdef MODULE
- startslot = slot + 1;
+ startslot = slot + 1;
#endif
- return 0;
+ return 0;
}
/* ------------------------------------------------------------------------
static char NameSpace[8 * DEVMAX];
static struct net_device moddevs[DEVMAX] =
- {{NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
- {NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
- {NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
- {NameSpace + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
- {NameSpace + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}};
+ { {NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{NameSpace + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{NameSpace + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}
+};
-int irq=0;
-int io=0;
+int irq = 0;
+int io = 0;
int init_module(void)
{
- int z, res;
-
- startslot = 0;
- for (z = 0; z < DEVMAX; z++)
- {
- strcpy(moddevs[z].name, " ");
- res = register_netdev(moddevs + z);
- if (res != 0)
- return (z > 0) ? 0 : -EIO;
- }
-
- return 0;
+ int z, res;
+
+ startslot = 0;
+ for (z = 0; z < DEVMAX; z++) {
+ strcpy(moddevs[z].name, " ");
+ res = register_netdev(moddevs + z);
+ if (res != 0)
+ return (z > 0) ? 0 : -EIO;
+ }
+
+ return 0;
}
void cleanup_module(void)
{
- struct net_device *dev;
- skmca_priv *priv;
- int z;
-
- if (MOD_IN_USE)
- {
- printk("cannot unload, module in use\n");
- return;
- }
-
- for (z = 0; z < DEVMAX; z++)
- {
- dev = moddevs + z;
- if (dev->priv != NULL)
- {
- priv = (skmca_priv*) dev->priv;
- DeinitBoard(dev);
- if (dev->irq != 0)
- free_irq(dev->irq, dev);
- dev->irq = 0;
- unregister_netdev(dev);
+ struct net_device *dev;
+ skmca_priv *priv;
+ int z;
+
+ if (MOD_IN_USE) {
+ printk("cannot unload, module in use\n");
+ return;
+ }
+
+ for (z = 0; z < DEVMAX; z++) {
+ dev = moddevs + z;
+ if (dev->priv != NULL) {
+ priv = (skmca_priv *) dev->priv;
+ DeinitBoard(dev);
+ if (dev->irq != 0)
+ free_irq(dev->irq, dev);
+ dev->irq = 0;
+ unregister_netdev(dev);
#if LINUX_VERSION_CODE >= 0x020200
- mca_mark_as_unused(priv->slot);
+ mca_mark_as_unused(priv->slot);
#endif
- mca_set_adapter_procfn(priv->slot, NULL, NULL);
- kfree_s(dev->priv, sizeof(skmca_priv));
- dev->priv = NULL;
- }
- }
+ mca_set_adapter_procfn(priv->slot, NULL, NULL);
+ kfree_s(dev->priv, sizeof(skmca_priv));
+ dev->priv = NULL;
+ }
+ }
}
-#endif /* MODULE */
+#endif /* MODULE */
{
int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */
- dev->start = 0;
- dev->tbusy = 1;
+ netif_stop_queue(dev);
if (ei_debug > 1)
printk("%s: Shutting down ethercard.\n", dev->name);
{
int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */
- dev->start = 0;
- dev->tbusy = 1;
-
+ netif_stop_queue(dev);
+
if (ei_debug > 1)
printk("%s: Shutting down ethercard.\n", dev->name);
* driver (almost)
* - Other minor stuff
*
+ * v1.4 Feb 10, 2000 - Updated with more changes required after Dave's
+ * network cleanup in 2.3.43pre7 (Tigran & myself)
+ * - Minor stuff.
+ *
*******************************************************************************/
static u8 *TLanPadBuffer;
static char TLanSignature[] = "TLAN";
static int TLanVersionMajor = 1;
-static int TLanVersionMinor = 3;
+static int TLanVersionMinor = 4;
static TLanAdapterEntry TLanAdapterList[] __initdata = {
u32 io_base, index;
int found;
- printk(KERN_INFO "ThunderLAN driver v%d.%d:\n",
+ printk(KERN_INFO "ThunderLAN driver v%d.%d\n",
TLanVersionMajor,
TLanVersionMinor);
*
**************************************************************/
-int TLan_PciProbe(u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_io_base, u32 *dl_ix )
+static int __init TLan_PciProbe(u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_io_base, u32 *dl_ix )
{
static int dl_index = 0;
static struct pci_dev * pdev = NULL;
*
**************************************************************/
-int TLan_Open( struct net_device *dev )
+static int TLan_Open( struct net_device *dev )
{
TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
int err;
}
netif_start_queue(dev);
-
+
/* NOTE: It might not be necessary to read the stats before a
reset if you don't care what the values are.
*/
*
**************************************************************/
-int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
+static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
{
TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
TLanList *tail_list;
if ( ! priv->phyOnline ) {
TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n", dev->name );
- dev_kfree_skb( skb );
+ if (in_irq())
+ dev_kfree_skb_irq(skb);
+ else
+ dev_kfree_skb(skb);
return 0;
}
CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
if ( bbuf ) {
- dev_kfree_skb( skb );
+ if (in_irq())
+ dev_kfree_skb_irq(skb);
+ else
+ dev_kfree_skb(skb);
}
dev->trans_start = jiffies;
*
**************************************************************/
-void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs)
{
u32 ack;
struct net_device *dev;
*
**************************************************************/
-int TLan_Close(struct net_device *dev)
+static int TLan_Close(struct net_device *dev)
{
TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
*
**************************************************************/
-struct net_device_stats *TLan_GetStats( struct net_device *dev )
+static struct net_device_stats *TLan_GetStats( struct net_device *dev )
{
TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
int i;
*
**************************************************************/
-void TLan_SetMulticastList( struct net_device *dev )
+static void TLan_SetMulticastList( struct net_device *dev )
{
struct dev_mc_list *dmi = dev->mc_list;
u32 hash1 = 0;
head_list = priv->txList + priv->txHead;
if ( ! bbuf ) {
- dev_kfree_skb( (struct sk_buff *) head_list->buffer[9].address );
+ if (in_irq())
+ dev_kfree_skb_irq( (struct sk_buff *) head_list->buffer[9].address );
+ else
+ dev_kfree_skb( (struct sk_buff *) head_list->buffer[9].address );
+
head_list->buffer[9].address = 0;
}
priv->stats.tx_bytes += head_list->frameSize;
head_list->cStat = TLAN_CSTAT_UNUSED;
+
netif_start_queue(dev);
+
CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS );
if ( eoc ) {
TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
*val = tmp;
spin_unlock_irqrestore(&priv->lock, flags);
+
return err;
} /* TLan_MiiReadReg */
TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );
spin_unlock_irqrestore(&priv->lock, flags);
+
} /* TLan_MiiWriteReg */
goto fail;
}
TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP );
-
fail:
spin_unlock_irqrestore(&priv->lock, flags);
+
return ret;
} /* TLan_EeReadByte */
if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
if (ti->open_status==SUCCESS) {
- dev->tbusy=0;
- dev->interrupt=0;
- dev->start=1;
/* NEED to see smem size *AND* reset high 512 bytes if needed */
-
+ netif_start_queue(dev);
MOD_INC_USE_COUNT;
return 0;
struct tok_info *ti=(struct tok_info *) dev->priv;
+ netif_stop_queue(dev);
+
isa_writeb(DIR_CLOSE_ADAPTER,
ti->srb + offsetof(struct srb_close_adapter, command));
isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
DPRINTK("close adapter failed: %02X\n",
(int)isa_readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
- dev->start = 0;
#ifdef PCMCIA
ti->sram = 0 ;
#endif
spin_lock(&(ti->lock));
/* Disable interrupts till processing is finished */
- dev->interrupt=1;
isa_writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
/* Reset interrupt for ISA boards */
{
DPRINTK("PCMCIA card removed.\n");
spin_unlock(&(ti->lock));
- dev->interrupt = 0;
return;
}
{
DPRINTK("PCMCIA card removed.\n");
spin_unlock(&(ti->lock));
- dev->interrupt = 0;
return;
}
#endif
isa_writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
- dev->interrupt=0;
} else if (isa_readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
& (TCR_INT | ERR_INT | ACCESS_INT)) {
isa_writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
- dev->interrupt=0;
} else if (status
& (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {
dev_kfree_skb(ti->current_skb);
ti->current_skb=NULL;
}
- dev->tbusy=0;
+ netif_wake_queue(dev);
if (ti->readlog_pending) ibmtr_readlog(dev);
}
}
dev_kfree_skb(ti->current_skb);
ti->current_skb=NULL;
}
- dev->tbusy=0;
- if (ti->readlog_pending) ibmtr_readlog(dev);
+ netif_wake_queue(dev);
+ if (ti->readlog_pending)
+ ibmtr_readlog(dev);
}
}
break;
(int)isa_readb(ti->srb+offsetof(struct srb_read_log,
token_errors)));
}
- dev->tbusy=0;
+ netif_wake_queue(dev);
break;
default:
DPRINTK("New ring status: %02X\n", ring_status);
if (ring_status & LOG_OVERFLOW) {
- if (dev->tbusy)
+ if (test_bit(LINK_STATE_XOFF, &dev->state))
ti->readlog_pending = 1;
else
ibmtr_readlog(dev);
} /* SRB, ARB, ASB or SSB response */
- dev->interrupt=0;
isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
break;
ti->do_tok_int=FIRST_INT;
/* Reset adapter */
- dev->tbusy=1; /* nothing can be done before reset and open completed */
+ netif_stop_queue(dev);
#ifdef ENABLE_PAGING
if(ti->page_mask)
isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
ti->tr_stats.tx_bytes+=ti->current_skb->len;
- dev->tbusy=0;
dev_kfree_skb(ti->current_skb);
ti->current_skb=NULL;
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
if (ti->readlog_pending) ibmtr_readlog(dev);
}
static int tok_send_packet(struct sk_buff *skb, struct net_device *dev)
{
struct tok_info *ti;
+ unsigned long flags;
ti=(struct tok_info *) dev->priv;
- if (dev->tbusy) {
- int ticks_waited;
-
- ticks_waited=jiffies - dev->trans_start;
- if (ticks_waited<TR_BUSY_INTERVAL) return 1;
-
- DPRINTK("Arrg. Transmitter busy.\n");
- dev->trans_start+=5; /* we fake the transmission start time... */
- return 1;
- }
-
- if (test_and_set_bit(0,(void *)&dev->tbusy)!=0)
- DPRINTK("Transmitter access conflict\n");
- else {
- int flags;
-
- /* lock against other CPUs */
- spin_lock_irqsave(&(ti->lock), flags);
-
- /* Save skb; we'll need it when the adapter asks for the data */
- ti->current_skb=skb;
- isa_writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
- isa_writew(ti->exsap_station_id, ti->srb
- +offsetof(struct srb_xmit, station_id));
- isa_writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
- spin_unlock_irqrestore(&(ti->lock), flags);
-
- dev->trans_start=jiffies;
- }
-
+ netif_stop_queue(dev);
+
+ /* lock against other CPUs */
+ spin_lock_irqsave(&(ti->lock), flags);
+
+ /* Save skb; we'll need it when the adapter asks for the data */
+ ti->current_skb=skb;
+ isa_writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
+ isa_writew(ti->exsap_station_id, ti->srb
+ +offsetof(struct srb_xmit, station_id));
+ isa_writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
+ spin_unlock_irqrestore(&(ti->lock), flags);
+ dev->trans_start=jiffies;
return 0;
}
isa_writeb(DIR_READ_LOG, ti->srb);
isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- dev->tbusy=1; /* really srb busy... */
+
+ netif_stop_queue(dev);
}
/* tok_get_stats(): Basically a scaffold routine which will return
#endif
- dev->start = 1;
- dev->interrupt=0;
- dev->tbusy=0;
-
+ netif_start_queue(dev);
MOD_INC_USE_COUNT ;
return 0;
spin_lock(&olympic_priv->olympic_lock);
- if (dev->interrupt)
- printk(KERN_WARNING "%s: Re-entering interrupt \n",dev->name) ;
-
- dev->interrupt = 1 ;
-
if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK |
SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF)) {
dev_kfree_skb(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=0xdeadbeef;
olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
-
- if(dev->tbusy) {
- dev->tbusy=0;
- mark_bh(NET_BH);
- }
+ netif_wake_queue(dev);
} /* SISR_TX1_EOF */
if (sisr & SISR_RX_STATUS) {
writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
adapter_check_area = (__u8 *)(olympic_mmio+LAPWWO) ;
printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ;
- dev->interrupt = 0 ;
free_irq(dev->irq, dev) ;
} /* SISR_ADAPTER_CHECK */
printk(KERN_WARNING "%s: SISR_MASK: %x\n",dev->name, readl(olympic_mmio+SISR_MASK)) ;
} /* One if the interrupts we want */
- dev->interrupt = 0 ;
-
writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
spin_unlock(&olympic_priv->olympic_lock) ;
spin_lock_irqsave(&olympic_priv->olympic_lock, flags);
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
- return 1;
- }
-
+ netif_stop_queue(dev);
+
if(olympic_priv->free_tx_ring_entries) {
olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer=virt_to_bus(skb->data);
olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length=skb->len | (0x80000000);
writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
- dev->tbusy=0;
+ netif_wake_queue(dev);
spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
return 0;
} else {
unsigned long flags;
int i;
+ netif_stop_queue(dev);
+
writel(olympic_priv->srb,olympic_mmio+LAPA);
srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
printk("%x ",readb(srb+i));
printk("\n");
#endif
- dev->start = 0;
free_irq(dev->irq,dev);
MOD_DEC_USE_COUNT ;
struct sockaddr *saddr = addr ;
struct olympic_private *olympic_priv = (struct olympic_private *)dev->priv ;
- if (dev->start) {
+ if (test_bit(LINK_STATE_START, &dev->state)) {
printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ;
return -EIO ;
}
writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);
udelay(1);
writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
- dev->tbusy = 1 ;
- dev->interrupt = 1 ;
- dev->start = 0 ;
+ netif_stop_queue(dev);
olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ;
free_irq(dev->irq,dev);
/* H */
static int smctr_hardware_send_packet(struct net_device *dev,
struct net_local *tp);
-
/* I */
static int smctr_init_acbs(struct net_device *dev);
static int smctr_init_adapter(struct net_device *dev);
static int smctr_status_chg(struct net_device *dev);
/* T */
+static void smctr_timeout(struct net_device *dev);
static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
__u16 queue);
static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue);
struct sk_buff *skb;
int err;
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
return;
}
- dev->interrupt = 1;
-
ioaddr = dev->base_addr;
tp = (struct net_local *)dev->priv;
- dev->interrupt = 0;
-
if(tp->status == NOT_INITIALIZED)
return;
dev->open = smctr_open;
dev->stop = smctr_close;
dev->hard_start_xmit = smctr_send_packet;
+ dev->tx_timeout = smctr_timeout;
+ dev->watchdog_timeo = HZ;
dev->get_stats = smctr_get_stats;
dev->set_multicast_list = &smctr_set_multicast_list;
return (0);
}
+static void smctr_timeout(struct net_device *dev)
+{
+ /*
+ * If we get here, some higher level has decided we are broken.
+ * There should really be a "kick me" function call instead.
+ *
+ * Resetting the token ring adapter takes a long time so just
+ * fake transmission time and go on trying. Our own timeout
+ * routine is in sktr_timer_chk()
+ */
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+}
+
/*
* Gets skb from system, queues it and checks if it can be sent
*/
if(smctr_debug > 10)
printk("%s: smctr_send_packet\n", dev->name);
- if(dev->tbusy)
- {
- /*
- * If we get here, some higher level has decided we are broken.
- * There should really be a "kick me" function call instead.
- *
- * Resetting the token ring adapter takes a long time so just
- * fake transmission time and go on trying. Our own timeout
- * routine is in sktr_timer_chk()
- */
- dev->tbusy = 0;
- dev->trans_start = jiffies;
- return (1);
- }
-
- /*
- * If some higher layer thinks we've missed an tx-done interrupt we
- * are passed NULL.
- */
- if(skb == NULL)
- return (0);
-
/*
- * Block a timer-based transmit from overlapping. This could better be
- * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
+ * Block a transmit overlap
*/
- if(test_and_set_bit(0, (void*)&dev->tbusy) != 0)
- {
- printk("%s: Transmitter access conflict.\n", dev->name);
- return (1);
- }
+
+ netif_stop_queue(dev);
if(tp->QueueSkb == 0)
return (1); /* Return with tbusy set: queue full */
skb_queue_tail(&tp->SendSkbQueue, skb);
smctr_hardware_send_packet(dev, tp);
if(tp->QueueSkb > 0)
- dev->tbusy = 0;
-
+ netif_wake_queue(dev);
+
return (0);
}
tp->num_tx_fcbs_used[queue]--;
fcb->frame_status = 0;
tp->tx_fcb_end[queue] = fcb->next_ptr;
-
+ netif_wake_queue(dev);
return (0);
}
}
tms380tr_enable_interrupts(dev);
tms380tr_open_adapter(dev);
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 0;
-
+ netif_start_queue(dev);
+
/* Wait for interrupt from hardware. If interrupt does not come,
* there will be a timeout from the timer.
*/
return (-1);
}
- dev->start = 1;
-
tp->StartTime = jiffies;
/* Start function control timer */
return;
}
+static void tms380tr_timeout(struct net_device *dev)
+{
+ /*
+ * If we get here, some higher level has decided we are broken.
+ * There should really be a "kick me" function call instead.
+ *
+ * Resetting the token ring adapter takes a long time so just
+ * fake transmission time and go on trying. Our own timeout
+ * routine is in tms380tr_timer_chk()
+ */
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+}
+
/*
* Gets skb from system, queues it and checks if it can be sent
*/
{
struct net_local *tp = (struct net_local *)dev->priv;
- if(dev->tbusy)
- {
- /*
- * If we get here, some higher level has decided we are broken.
- * There should really be a "kick me" function call instead.
- *
- * Resetting the token ring adapter takes a long time so just
- * fake transmission time and go on trying. Our own timeout
- * routine is in tms380tr_timer_chk()
- */
- dev->tbusy = 0;
- dev->trans_start = jiffies;
- return (1);
- }
-
/*
- * If some higher layer thinks we've missed an tx-done interrupt we
- * are passed NULL.
+ * Block transmits from overlapping.
*/
- if(skb == NULL)
- return (0);
-
- /*
- * Block a timer-based transmit from overlapping. This could better be
- * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
- */
- if(test_and_set_bit(0, (void*)&dev->tbusy) != 0)
- {
- printk("%s: Transmitter access conflict.\n", dev->name);
- return (1);
- }
-
+
+ netif_stop_queue(dev);
+
if(tp->QueueSkb == 0)
return (1); /* Return with tbusy set: queue full */
skb_queue_tail(&tp->SendSkbQueue, skb);
tms380tr_hardware_send_packet(dev, tp);
if(tp->QueueSkb > 0)
- dev->tbusy = 0;
-
+ netif_wake_queue(dev);
return (0);
}
return;
}
- dev->interrupt = 1;
-
tp = (struct net_local *)dev->priv;
irq_type = SIFREADW(SIFSTS);
irq_type = SIFREADW(SIFSTS);
}
- dev->interrupt = 0;
-
return;
}
int tms380tr_close(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
del_timer(&tp->timer);
/* Flush the Tx and disable Rx here. */
tpl->BusyFlag = 0; /* "free" TPL */
}
- dev->tbusy = 0;
+ netif_wake_queue(dev);
if(tp->QueueSkb < MAX_TX_QUEUE)
tms380tr_hardware_send_packet(dev, tp);
-
return;
}
dev->stop = tms380tr_close;
dev->do_ioctl = NULL;
dev->hard_start_xmit = tms380tr_send_packet;
+ dev->tx_timeout = tms380tr_timeout;
+ dev->watchdog_timeo = HZ;
dev->get_stats = tms380tr_get_stats;
dev->set_multicast_list = &tms380tr_set_multicast_list;
dev->set_mac_address = tms380tr_set_mac_address;
if (!skb || !dev)
return(0);
- if (dev->tbusy)
- return(1);
-
dlp = dev->priv;
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
- printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
- else
+ netif_stop_queue(dev);
+
+ ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
+ switch (ret)
{
- ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
- switch (ret)
- {
- case DLCI_RET_OK:
- dlp->stats.tx_packets++;
- ret = 0;
- break;
-
+ case DLCI_RET_OK:
+ dlp->stats.tx_packets++;
+ ret = 0;
+ break;
case DLCI_RET_ERR:
- dlp->stats.tx_errors++;
- ret = 0;
- break;
-
+ dlp->stats.tx_errors++;
+ ret = 0;
+ break;
case DLCI_RET_DROP:
- dlp->stats.tx_dropped++;
- ret = 1;
- break;
- }
-
- /* Alan Cox recommends always returning 0, and always freeing the packet */
- /* experience suggest a slightly more conservative approach */
-
- if (!ret)
- dev_kfree_skb(skb);
-
- dev->tbusy = 0;
+ dlp->stats.tx_dropped++;
+ ret = 1;
+ break;
}
+ /* Alan Cox recommends always returning 0, and always freeing the packet */
+ /* experience suggest a slightly more conservative approach */
+ if (!ret)
+ {
+ dev_kfree_skb(skb);
+ netif_wake_queue(dev);
+ }
return(ret);
}
if (!*(short *)(dev->dev_addr))
return(-EINVAL);
- if (!dlp->slave->start)
+ if (!test_bit(LINK_STATE_START, &dlp->slave->state))
return(-ENOTCONN);
- dev->flags = 0;
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
flp = dlp->slave->priv;
err = (*flp->activate)(dlp->slave, dev);
if (err)
return(err);
+ netif_start_queue(dev);
+
return 0;
}
struct frad_local *flp;
int err;
+ netif_stop_queue(dev);
+
dlp = dev->priv;
flp = dlp->slave->priv;
err = (*flp->deactivate)(dlp->slave, dev);
- dev->start = 0;
- dev->tbusy = 1;
-
return 0;
}
if (!master)
return(-ENODEV);
- if (master->start)
+ if (test_bit(LINK_STATE_START, &master->state))
return(-EBUSY);
dlp = master->priv;
/*
* Go go go
*/
- d->tbusy=0;
+
+ netif_start_queue(d);
MOD_INC_USE_COUNT;
return 0;
}
/*
* Link layer down
*/
- d->tbusy=1;
-
+ netif_stop_queue(d);
+
switch(dma)
{
case 0:
flp->dlci[i] = abs(flp->dlci[i]);
- if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+ if (test_bit(LINK_STATE_START, &slave->state) && (flp->config.station == FRAD_STATION_NODE))
sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
return(0);
flp->dlci[i] = -abs(flp->dlci[i]);
- if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+ if (test_bit(LINK_STATE_START, &slave->state) && (flp->config.station == FRAD_STATION_NODE))
sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
return(0);
flp->dlci[i] = -*(short *)(master->dev_addr);
master->mtu = slave->mtu;
- if (slave->start) {
+ if (test_bit(LINK_STATE_START, &slave->state)) {
if (flp->config.station == FRAD_STATION_CPE)
sdla_reconfig(slave);
else
MOD_DEC_USE_COUNT;
- if (slave->start) {
+ if (test_bit(LINK_STATE_START, &slave->state)) {
if (flp->config.station == FRAD_STATION_CPE)
sdla_reconfig(slave);
else
ret = SDLA_RET_OK;
len = sizeof(struct dlci_conf);
- if (slave->start) {
+ if (test_bit(LINK_STATE_START, &slave->state)) {
if (get)
ret = sdla_cmd(slave, SDLA_READ_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0,
NULL, 0, &dlp->config, &len);
static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
{
struct frad_local *flp;
- int ret, addr, accept;
+ int ret, addr, accept, i;
short size;
unsigned long flags;
struct buf_entry *pbuf;
ret = 0;
accept = 1;
- if (dev->tbusy)
- return(1);
+ netif_stop_queue(dev);
- if (skb == NULL)
- return(0);
+ /*
+ * stupid GateD insists on setting up the multicast router thru us
+ * and we're ill equipped to handle a non Frame Relay packet at this
+ * time!
+ */
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
- printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
- else
+ accept = 1;
+ switch (dev->type)
{
- /*
- * stupid GateD insists on setting up the multicast router thru us
- * and we're ill equipped to handle a non Frame Relay packet at this
- * time!
- */
-
- accept = 1;
- switch (dev->type)
+ case ARPHRD_FRAD:
+ if (skb->dev->type != ARPHRD_DLCI)
+ {
+ printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type);
+ accept = 0;
+ }
+ break;
+ default:
+ printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type);
+ accept = 0;
+ break;
+ }
+ if (accept)
+ {
+ /* this is frame specific, but till there's a PPP module, it's the default */
+ switch (flp->type)
{
- case ARPHRD_FRAD:
- if (skb->dev->type != ARPHRD_DLCI)
+ case SDLA_S502A:
+ case SDLA_S502E:
+ ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
+ break;
+ case SDLA_S508:
+ size = sizeof(addr);
+ ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
+ if (ret == SDLA_RET_OK)
{
- printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type);
- accept = 0;
+ save_flags(flags);
+ cli();
+ SDLA_WINDOW(dev, addr);
+ pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
+ sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
+ SDLA_WINDOW(dev, addr);
+ pbuf->opp_flag = 1;
+ restore_flags(flags);
}
break;
-
- default:
- printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type);
- accept = 0;
- break;
}
-
- if (accept)
+ switch (ret)
{
- /* this is frame specific, but till there's a PPP module, it's the default */
- switch (flp->type)
- {
- case SDLA_S502A:
- case SDLA_S502E:
- ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
- break;
-
- case SDLA_S508:
- size = sizeof(addr);
- ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
- if (ret == SDLA_RET_OK)
- {
- save_flags(flags);
- cli();
- SDLA_WINDOW(dev, addr);
- pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
-
- sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
-
- SDLA_WINDOW(dev, addr);
- pbuf->opp_flag = 1;
- restore_flags(flags);
- }
- break;
- }
-
- switch (ret)
- {
- case SDLA_RET_OK:
- flp->stats.tx_packets++;
- ret = DLCI_RET_OK;
- break;
+ case SDLA_RET_OK:
+ flp->stats.tx_packets++;
+ ret = DLCI_RET_OK;
+ break;
- case SDLA_RET_CIR_OVERFLOW:
- case SDLA_RET_BUF_OVERSIZE:
- case SDLA_RET_NO_BUFS:
- flp->stats.tx_dropped++;
- ret = DLCI_RET_DROP;
- break;
+ case SDLA_RET_CIR_OVERFLOW:
+ case SDLA_RET_BUF_OVERSIZE:
+ case SDLA_RET_NO_BUFS:
+ flp->stats.tx_dropped++;
+ ret = DLCI_RET_DROP;
+ break;
- default:
- flp->stats.tx_errors++;
- ret = DLCI_RET_ERR;
- break;
- }
+ default:
+ flp->stats.tx_errors++;
+ ret = DLCI_RET_ERR;
+ break;
}
- dev->tbusy = 0;
}
+ netif_wake_queue(dev);
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ {
+ if(flp->master[i]!=NULL)
+ netif_wake_queue(flp->master[i]);
+ }
return(ret);
}
return;
}
- dev->interrupt = 1;
byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
switch (byte)
{
/* this clears the byte, informing the Z80 we're done */
byte = 0;
sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
- dev->interrupt = 0;
}
static void sdla_poll(unsigned long device)
sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
+
MOD_DEC_USE_COUNT;
return(0);
sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
}
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
+ netif_start_queue(dev);
+
MOD_INC_USE_COUNT;
return(0);
if (!get)
{
- if (dev->start)
+ if (test_bit(LINK_STATE_START, &dev->state))
return(-EBUSY);
if(copy_from_user(&data.config, conf, sizeof(struct frad_conf)))
else
{
/* no sense reading if the CPU isn't started */
- if (dev->start)
+ if (test_bit(LINK_STATE_START, &dev->state))
{
size = sizeof(data);
if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
flp = dev->priv;
- if (dev->start)
+ if (test_bit(LINK_STATE_START, &dev->state))
return(-EBUSY);
/* for now, you can't change the MTU! */
/*
* Go go go
*/
- d->tbusy=0;
+ netif_start_queue(d);
MOD_INC_USE_COUNT;
return 0;
}
/*
* Link layer down
*/
- d->tbusy=1;
-
+
+ netif_stop_queue(d);
+
switch(unit)
{
case 0:
int z8530_sync_close(struct net_device *dev, struct z8530_channel *c)
{
u8 chk;
+
c->irqs = &z8530_nop;
c->max = 0;
c->sync = 0;
c->irqs = &z8530_dma_sync;
z8530_rtsdtr(c,1);
write_zsreg(c, R3, c->regs[R3]|RxENABLE);
+
return 0;
}
z8530_rtsdtr(c,1);
printk("Rx interrupts ON\n");
write_zsreg(c, R3, c->regs[R3]|RxENABLE);
+
return 0;
}
{
unsigned long flags;
u8 chk;
+
c->irqs = &z8530_nop;
c->max = 0;
c->sync = 0;
c->tx_next_skb=NULL;
c->tx_ptr=c->tx_next_ptr;
- mark_bh(NET_BH);
+ netif_wake_queue(c->netdevice);
if(c->tx_skb==NULL)
{
/* Idle on */
struct sk_buff *skb;
spin_lock_irqsave(&z8530_buffer_lock, flags);
- c->netdevice->tbusy=0;
+ netif_wake_queue(c->netdevice);
/* Actually this can happen.*/
if(c->tx_skb==NULL)
{
int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
{
unsigned long flags;
+
+ netif_stop_queue(c->netdevice);
if(c->tx_next_skb)
{
- skb->dev->tbusy=1;
return 1;
}
spin_lock_irqsave(&z8530_buffer_lock, flags);
z8530_tx_begin(c);
spin_unlock_irqrestore(&z8530_buffer_lock, flags);
+
+ netif_wake_queue(c->netdevice);
return 0;
}
return 0;
}
+
+__initcall(usb_acm_init);
{0, 0x45, "Vbrz"},
{0, 0x46, "Vno"},
{0, 0x80, "SystemControl"},
- {0, 0x81, "System PowerDown"},
- {0, 0x82, "System Sleep"},
- {0, 0x83, "System WakeUp"},
- {0, 0x84, "System ContextMenu"},
- {0, 0x85, "System MainMenu"},
- {0, 0x86, "System AppMenu"},
- {0, 0x87, "System MenuHelp"},
- {0, 0x88, "System MenuExit"},
- {0, 0x89, "System MenuSelect"},
- {0, 0x8a, "System MenuRight"},
- {0, 0x8b, "System MenuLeft"},
- {0, 0x8c, "System MenuUp"},
- {0, 0x8d, "System MenuDown"},
+ {0, 0x81, "SystemPowerDown"},
+ {0, 0x82, "SystemSleep"},
+ {0, 0x83, "SystemWakeUp"},
+ {0, 0x84, "SystemContextMenu"},
+ {0, 0x85, "SystemMainMenu"},
+ {0, 0x86, "SystemAppMenu"},
+ {0, 0x87, "SystemMenuHelp"},
+ {0, 0x88, "SystemMenuExit"},
+ {0, 0x89, "SystemMenuSelect"},
+ {0, 0x8a, "SystemMenuRight"},
+ {0, 0x8b, "SystemMenuLeft"},
+ {0, 0x8c, "SystemMenuUp"},
+ {0, 0x8d, "SystemMenuDown"},
{0, 0x90, "D-padUp"},
{0, 0x91, "D-padDown"},
{0, 0x92, "D-padRight"},
{ 7, 0, "Keyboard" },
{ 8, 0, "LED" },
{ 9, 0, "Button" },
+ { 12, 0, "Hotkey" },
{ 13, 0, "Digitizers" },
{0, 0x01, "Digitizer"},
{0, 0x02, "Pen"},
case HID_UP_GENDESK:
+ if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */
+ switch (usage->hid & 0xf) {
+ case 0x1: usage->code = KEY_POWER; break;
+ case 0x2: usage->code = KEY_SLEEP; break;
+ case 0x3: usage->code = KEY_WAKEUP; break;
+ default: usage->code = KEY_UNKNOWN; break;
+ }
+ usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+ break;
+ }
+
usage->code = usage->hid & 0xf;
+ if (field->report_size == 1) {
+ usage->code = BTN_MISC;
+ usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+ break;
+ }
+
if (field->flags & HID_MAIN_ITEM_RELATIVE) {
usage->type = EV_REL; bit = input->relbit; max = REL_MAX;
break;
}
break;
- default:
- unknown:
+ case HID_UP_HOTKEY:
+
+ switch (usage->hid & HID_USAGE) {
+
+ case 0x0034: usage->code = KEY_PHONE; break;
+ case 0x0036: usage->code = KEY_NOTEPAD; break;
+ case 0x008a: usage->code = KEY_MAIL; break;
+ case 0x0095: usage->code = KEY_CALENDAR; break;
+ case 0x00b7: usage->code = KEY_PRINT; break;
+ case 0x00b8: usage->code = KEY_HELP; break;
+ case 0x00cd: usage->code = KEY_SOUND; break;
+ case 0x00e2: usage->code = KEY_PROG1; break;
+ case 0x00e9: usage->code = KEY_PROG2; break;
+ case 0x00ea: usage->code = KEY_PROG3; break;
+ case 0x018a: usage->code = KEY_WWW; break;
+ case 0x0223: usage->code = KEY_FULLSCREEN; break;
+ default: usage->code = KEY_UNKNOWN; break;
- if (field->flags & HID_MAIN_ITEM_RELATIVE) {
- usage->code = REL_MISC;
- usage->type = EV_REL; bit = input->relbit; max = REL_MAX;
- break;
}
+
+ usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+ break;
+
+ default:
+ unknown:
if (field->report_size == 1) {
usage->code = BTN_MISC;
break;
}
+ if (field->flags & HID_MAIN_ITEM_RELATIVE) {
+ usage->code = REL_MISC;
+ usage->type = EV_REL; bit = input->relbit; max = REL_MAX;
+ break;
+ }
+
usage->code = ABS_MISC;
usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
break;
}
}
-static void hid_process_event(struct input_dev *input, struct hid_usage *usage, __s32 value)
+static void hid_process_event(struct input_dev *input, int flags, struct hid_usage *usage, __s32 value)
{
hid_dump_input(usage, value);
}
input_event(input, usage->type, usage->code, value);
+
+ if ((flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
+ input_event(input, usage->type, usage->code, 0);
}
/*
} else {
if (value[n] == field->value[n]) continue;
}
- hid_process_event(&dev->input, &field->usage[n], value[n]);
+ hid_process_event(&dev->input, field->flags, &field->usage[n], value[n]);
} else {
if (field->value[n] >= min && field->value[n] <= max /* non-NULL value */
&& field->usage[field->value[n] - min].hid /* nonzero usage */
&& search(value, field->value[n], count))
- hid_process_event(&dev->input, &field->usage[field->value[n] - min], 0);
+ hid_process_event(&dev->input, field->flags, &field->usage[field->value[n] - min], 0);
if (value[n] >= min && value[n] <= max /* non-NULL value */
&& field->usage[value[n] - min].hid /* nonzero usage */
&& search(field->value, value[n], count))
- hid_process_event(&dev->input, &field->usage[value[n] - min], 1);
+ hid_process_event(&dev->input, field->flags, &field->usage[value[n] - min], 1);
}
}
usb_register(&hid_driver);
return 0;
}
+
+__initcall(hid_init);
#define HID_UP_KEYBOARD 0x00070000
#define HID_UP_LED 0x00080000
#define HID_UP_BUTTON 0x00090000
+#define HID_UP_HOTKEY 0x000c0000
#define HID_UP_DIGITIZER 0x000d0000
#define HID_UP_PID 0x000f0000
// be shutdown by the hub, this hack enables them again.
// Works at least with mouse driver.
if (!(portstatus & USB_PORT_STAT_ENABLE) &&
- (portstatus & USB_PORT_STAT_CONNECTION)) {
+ (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
err("already running port %i disabled by hub (EMI?), re-enabling...",
i + 1);
usb_hub_port_connect_change(dev, i);
{
}
#endif
+
+__initcall(input_init);
static int keybdev_connect(struct input_handler *handler, struct input_dev *dev)
{
struct input_handle *handle;
+ int i;
- if (!test_bit(EV_KEY, dev->evbit) || !test_bit(KEY_A, dev->keybit) || !test_bit(KEY_Z, dev->keybit))
+ if (!test_bit(EV_KEY, dev->evbit))
return -1;
+ for (i = KEY_RESERVED; i < BTN_MISC; i++)
+ if (test_bit(i, dev->keybit)) break;
+
+ if (i == BTN_MISC)
+ return -1;
+
if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
return -1;
memset(handle, 0, sizeof(struct input_handle));
return 0;
}
+
+__initcall(usb_printer_init);
* USB device drivers
*/
-int usb_acm_init(void);
int usb_audio_init(void);
int usb_cpia_init(void);
int usb_ibmcam_init(void);
int usb_ov511_init(void);
int usb_dc2xx_init(void);
int usb_scanner_init(void);
-int usb_printer_init(void);
int usb_stor_init(void);
-int usb_serial_init(void);
int dabusb_init(void);
-int hid_init(void);
-int input_init(void);
int usb_mouse_init(void);
int usb_kbd_init(void);
int graphire_init(void);
void cleanup_module(void)
{
usb_major_cleanup();
- usbdevfs_cleanup();
+ usbdevfs_cleanup();
usb_hub_cleanup();
-
}
/*
#ifdef CONFIG_USB_AUDIO
usb_audio_init();
#endif
-#ifdef CONFIG_USB_ACM
- usb_acm_init();
-#endif
-#ifdef CONFIG_USB_PRINTER
- usb_printer_init();
-#endif
-#ifdef CONFIG_USB_SERIAL
- usb_serial_init();
-#endif
#ifdef CONFIG_USB_CPIA
usb_cpia_init();
#endif
#ifdef CONFIG_USB_DABUSB
dabusb_init();
#endif
-#if defined(CONFIG_USB_HID) || defined(CONFIG_USB_MOUSE) || defined(CONFIG_USB_KBD) || defined(CONFIG_USB_GRAPHIRE)
- input_init();
-#endif
-#ifdef CONFIG_USB_HID
- hid_init();
-#endif
#ifdef CONFIG_USB_MOUSE
usb_mouse_init();
#endif
usb_deregister(&usb_serial_driver);
}
+#else
+__initcall(usb_serial_init);
#endif
*/
#define __ISA_IO_base ((char *)(PAGE_OFFSET))
-#define isa_readb(a) readb(__ISA_IO_base + (unsigned long)(a))
-#define isa_readw(a) readw(__ISA_IO_base + (unsigned long)(a))
-#define isa_readl(a) readl(__ISA_IO_base + (unsigned long)(a))
-#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (unsigned long)(a))
-#define isa_writew(w,a) writew(w,__ISA_IO_base + (unsigned long)(a))
-#define isa_writel(l,a) writel(l,__ISA_IO_base + (unsigned long)(a))
-#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (unsigned long)(a),(b),(c))
-#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (unsigned long)(b),(c))
-#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (unsigned long)(a),(b),(c))
+#define isa_readb(a) readb(__ISA_IO_base + (a))
+#define isa_readw(a) readw(__ISA_IO_base + (a))
+#define isa_readl(a) readl(__ISA_IO_base + (a))
+#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
+#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
+#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
+#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c))
+#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c))
+#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c))
/*
*/
#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d))
-#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (unsigned long)(b)),(c),(d))
+#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (b)),(c),(d))
static inline int check_signature(unsigned long io_addr,
const unsigned char *signature, int length)
#define KEY_STOPCD 166
#define KEY_RECORD 167
#define KEY_REWIND 168
+#define KEY_PHONE 169
+#define KEY_CALENDAR 170
+#define KEY_NOTEPAD 171
+#define KEY_PROG3 172
+#define KEY_PRINT 173
+#define KEY_SOUND 174
+#define KEY_FULLSCREEN 175
#define KEY_UNKNOWN 180
extern void signals_init(void);
extern void bdev_init(void);
extern int init_pcmcia_ds(void);
+extern int usb_init(void);
extern void free_initmem(void);
extern void filesystem_setup(void);
#ifdef CONFIG_ISAPNP
isapnp_init();
#endif
+#ifdef CONFIG_USB
+ usb_init(); /* Do this before doing initcalls, so that we can make
+ usbcore initialize here, and all drivers initialize later */
+#endif
/* Networking initialization needs a process context */
sock_init();
/* software interrupts */
EXPORT_SYMBOL(tasklet_hi_vec);
+EXPORT_SYMBOL(tasklet_vec);
EXPORT_SYMBOL(bh_task_vec);
EXPORT_SYMBOL(init_bh);
EXPORT_SYMBOL(remove_bh);