W: http://www.pi.se/blox/
D: Extended support for loadable modules
D: D-Link pocket adapter drivers
-S: Myrstuguv. 83
-S: S-143 32 VARBY
+S: Grevgatan 11
+S: S-114 53 Stockholm
S: Sweden
N: Fritz Elfert
-TLAN driver for Linux, version 0.43
+TLAN driver for Linux, version 1.0
README
-Note: I (James) am not maintaining this driver anymore, as I no longer
- have the equipment to do so. So it is available to anyone who
- wishes to take it over ;) If someone needs to reach me about
- it, my new email address is james@sovereign.org.
+Well, I'm back. The TLAN driver seems pretty stable, so I'm
+declaring this cycle of development finished, and calling the
+driver 1.0. I will, of course continue to work on improving
+the driver, and work towards a 2.0 release.
+
I. Supported Devices.
do {
status = LP_S(minor);
count++;
- if (need_resched)
- schedule();
} while (LP_READY(minor, status) && (count<LP_CHAR(minor)));
/* take strobe low */
outb_p(( LP_PSELECP | LP_PINITP ), ( LP_C( minor )));
#ifdef CONFIG_RISCOM8
riscom8_init();
#endif
-#ifdef CONFIG_BAYCOM
- baycom_init();
-#endif
#ifdef CONFIG_SPECIALIX
specialix_init();
#endif
vcs_init();
return 0;
}
-
if (hz > 20 && hz < 32767)
count = 1193180 / hz;
+ if (!count)
+ kd_nosound(0);
/* ignore multiple simultaneous requests for sound */
- if (!set_bit(0, &mksound_lock)) {
+ else if (!set_bit(0, &mksound_lock)) {
/* set_bit in 2.0.x is same as test-and-set in 2.1.x */
del_timer(&sound_timer);
if (count) {
sound_timer.expires = jiffies+ticks;
add_timer(&sound_timer);
}
- } else
- kd_nosound(0);
-
+ }
mksound_lock = 0;
}
return;
/* "Knobs" that adjust features and parameters. */
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
Setting to > 1512 effectively disables this feature. */
-static const int rx_copybreak = 200;
+static const rx_copybreak = 200;
/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
-static const int mtu = 1500;
+static const mtu = 1500;
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static int max_interrupt_work = 20;
programmed-I/O for Vortex cards. Full-bus-master transfers are always
enabled by default on Boomerang cards. If VORTEX_BUS_MASTER is defined,
the feature may be turned on using 'options'. */
-#if YOU_ARE_BRAVER_THAN_ME
#define VORTEX_BUS_MASTER
-#endif
/* A few values that may be tweaked. */
/* Time in jiffies before concluding the transmitter is hung. */
versions of the FastEtherLink cards. The supported product IDs are
3c590, 3c592, 3c595, 3c597, 3c900, 3c905
-The ISA 3c515 is supported with a separate driver, 3c515.c, included with
+The ISA 3c515 is supported with a seperate driver, 3c515.c, included with
the kernel source or available from
cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html
series. The primary interface is two programmed-I/O FIFOs, with an
alternate single-contiguous-region bus-master transfer (see next).
-The 3c900 "Boomerang" series uses a full-bus-master interface with separate
+The 3c900 "Boomerang" series uses a full-bus-master interface with seperate
lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
DEC Tulip and Intel Speedo3. The first chip version retains a compatible
programmed-I/O interface that will be removed in the 'B' and subsequent
}
/*
- * Handle uncommon interrupt sources. This is a separate routine to minimize
+ * Handle uncommon interrupt sources. This is a seperate routine to minimize
* the cache impact.
*/
static void
printk(KERN_DEBUG " In boomerang_rx(), status %4.4x, rx_status "
"%4.4x.\n",
inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
- while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
+ while ((--rx_work_limit >= 0) &&
+ ((rx_status = vp->rx_ring[entry].status) & RxDComplete)) {
if (rx_status & RxDError) { /* Error, update stats. */
unsigned char rx_error = rx_status >> 16;
if (vortex_debug > 2)
void *temp;
/* Pass up the skbuff already on the Rx ring. */
skb = vp->rx_skbuff[entry];
+ if (skb == NULL) {
+ printk(KERN_WARNING "%s: in boomerang_rx -- attempt to use NULL skb caught\n", dev->name);
+ break;
+ }
vp->rx_skbuff[entry] = NULL;
#if LINUX_VERSION_CODE >= 0x10300
temp = skb_put(skb, pkt_len);
vp->stats.rx_packets++;
}
entry = (++vp->cur_rx) % RX_RING_SIZE;
- if (--rx_work_limit < 0)
- break;
}
/* Refill the Rx ring buffers. */
for (; vp->dirty_rx < vp->cur_rx; vp->dirty_rx++) {
entry = vp->dirty_rx % RX_RING_SIZE;
if (vp->rx_skbuff[entry] == NULL) {
skb = DEV_ALLOC_SKB(PKT_BUF_SZ);
- if (skb == NULL)
+ if (skb == NULL) {
+ printk(KERN_DEBUG "%s: in boomerang_rx -- could not allocate skbuff\n", dev->name);
break; /* Bad news! */
+ }
skb->dev = dev; /* Mark as being used by this device. */
#if LINUX_VERSION_CODE > 0x10300
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
outw(UpUnstall, ioaddr + EL3_CMD);
}
+
+ if (vp->dirty_rx >= RX_RING_SIZE ) {
+ vp->cur_rx -= RX_RING_SIZE;
+ vp->dirty_rx -= RX_RING_SIZE;
+ }
+
return 0;
}
TLan Device Driver change log.
+1.0 - Stopped ignoring devices that didn't has the bus master
+ flag set.
+
0.43 - Changed the id strings of the Compaq devices to their real
names.
- Added 2 other Olicom devices with a patch provided by
static int lance_open(struct device *dev);
static int lance_open_fail(struct device *dev);
-static void lance_init_ring(struct device *dev);
+static void lance_init_ring(struct device *dev, int mode);
static int lance_start_xmit(struct sk_buff *skb, struct device *dev);
static int lance_rx(struct device *dev);
static void lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
(u32) virt_to_bus(lp->rx_ring),
(u32) virt_to_bus(&lp->init_block));
- lance_init_ring(dev);
+ lance_init_ring(dev, GFP_KERNEL);
/* Re-initialize the LANCE, and start it when done. */
outw(0x0001, ioaddr+LANCE_ADDR);
outw((short) (u32) virt_to_bus(&lp->init_block), ioaddr+LANCE_DATA);
/* Initialize the LANCE Rx and Tx rings. */
static void
-lance_init_ring(struct device *dev)
+lance_init_ring(struct device *dev, int gfp)
{
struct lance_private *lp = (struct lance_private *)dev->priv;
int i;
struct sk_buff *skb;
void *rx_buff;
- skb = alloc_skb(PKT_BUF_SZ, GFP_DMA | GFP_KERNEL);
+ skb = alloc_skb(PKT_BUF_SZ, GFP_DMA | gfp);
lp->rx_skbuff[i] = skb;
if (skb) {
skb->dev = dev;
rx_buff = skb->tail;
} else
- rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | GFP_KERNEL);
+ rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
if (rx_buff == NULL)
lp->rx_ring[i].base = 0;
else
if (must_reinit ||
(chip_table[lp->chip_version].flags & LANCE_MUST_REINIT_RING)) {
lance_purge_tx_ring(dev);
- lance_init_ring(dev);
+ lance_init_ring(dev, GFP_ATOMIC);
}
outw(0x0000, dev->base_addr + LANCE_ADDR);
outw(csr0_bits, dev->base_addr + LANCE_DATA);
* by James Banks
*
* (C) 1997-1998 Caldera, Inc.
+ * (C) 1998 James Banks
*
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
static int speed = 0;
static u8 *TLanPadBuffer;
static char TLanSignature[] = "TLAN";
-static int TLanVersionMajor = 0;
-static int TLanVersionMinor = 43;
+static int TLanVersionMajor = 1;
+static int TLanVersionMinor = 0;
static TLanAdapterEntry TLanAdapterList[] = {
if ( ! ( pci_command & PCI_COMMAND_MASTER ) ) {
pcibios_write_config_word ( *pci_bus, *pci_dfn, PCI_COMMAND, pci_command | PCI_COMMAND_MASTER );
- printk( "TLAN: Attempting to activate busmastering.\n" );
- printk( "TLAN: You may need to set busmastering to on in the CMOS\n" );
- printk( "TLAN: before this card will work.\n" );
- *pci_io_base = 0;
+ printk( "TLAN: Activating PCI bus mastering for this device.\n" );
}
pci_index++;
#ifdef CONFIG_BLK_DEV_FD
if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
+#ifdef CONFIG_BLK_DEV_INITRD
extern int rd_doload;
+#endif
floppy_eject();
#ifndef CONFIG_BLK_DEV_RAM
printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
if ((vf->len != name_len + 1) || (vf->name[name_len] != '.')) {
return 0;
}
+ if (name_len == 2 && name[0] == '.' && name[1] == '.') {
+ return 0;
+ }
}
s1 = name; s2 = vf->name;
extern int bpq_init(void);
extern void sdla_setup(void);
extern int dlci_setup(void);
+extern int sm_init(void);
+extern int baycom_init(void);
int net_dev_init(void)
{
#endif
#if defined(CONFIG_SDLA)
sdla_setup();
+#endif
+#if defined(CONFIG_BAYCOM)
+ baycom_init();
+#endif
+#if defined(CONFIG_SOUNDMODEM)
+ sm_init();
#endif
/*
* SLHC if present needs attaching so other people see it
if(skb->lock==0)
net_locked--;
restore_flags(flags);
+
+ if (skb->free == 3) {
+ skb->free = 1;
+ kfree_skb(skb, FREE_WRITE);
+ }
}
void dev_kfree_skb(struct sk_buff *skb, int mode)