Commit 6211a2d8 authored by Linus Torvalds's avatar Linus Torvalds

v2.4.10.6 -> v2.4.11

  - Jeff Garzik: net driver updates
  - me: symlink attach fix
  - Greg KH: USB update
  - Rui Sousa: emu10k driver update
parent 0a528ace
......@@ -7,8 +7,8 @@
kernel) is copyrighted by me and others who actually wrote it.
Also note that the only valid version of the GPL as far as the kernel
is concerned is _this_ license (ie v2), unless explicitly otherwise
stated.
is concerned is _this_ particular version of the license (ie v2, not
v2.2 or v3.x or whatever), unless explicitly otherwise stated.
Linus Torvalds
......
......@@ -7637,6 +7637,53 @@ CONFIG_NET_PCMCIA_RADIO
location). You also want to check out the PCMCIA-HOWTO, available
from http://www.linuxdoc.org/docs.html#howto .
Hermes chipset 802.11b support (Orinoco/Prism2/Symbol cards)
CONFIG_HERMES
A driver for 802.11b wireless cards based based on the "Hermes" or
Intersil HFA384x (Prism 2) MAC controller. This includes the vast
majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
- except for the Cisco/Aironet cards. Cards supported include the
Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
PRO/Wireless, and Symbol Spectrum24 High Rate amongst others.
This option includes the guts of the driver, but in order to
actually use a card you will also need to enable support for PCMCIA
Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
You will also very likely also need the Wireless Tools in order to
configure your card and that /etc/pcmcia/wireless.opts works :
http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
Apple Airport support (built-in)
CONFIG_APPLE_AIRPORT
Enable support for the Apple Airport card (which is essentially a
Lucent Orinoco card with a non-standard interface) built into some
newer Apple Macintosh machines.
Hermes 802.11b in PLX9052 based PCI adaptor support
CONFIG_PLX_HERMES
Enable support for PCMCIA cards supported by the "Hermes" (aka
orinoco_cs) driver when used in PLX9052 based PCI adaptors. These
adaptors are not a full PCMCIA controller but act as a more limited
PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
802.11b PCMCIA cards can be used in desktop machines. The Netgear
MA301 is such an adaptor.
Support for these adaptors is so far still incomplete and buggy.
You have been warned.
Hermes PCMCIA card support
CONFIG_PCMCIA_HERMES
Enable support for PCMCIA 802.11b cards using the Hermes or Intersil
HFA384x (Prism 2) chipset. To use your PC-cards, you will need
supporting software from David Hinds' pcmcia-cs package (see the
file Documentation/Changes for location). You also want to check out
the PCMCIA-HOWTO, available from
http://www.linuxdoc.org/docs.html#howto .
Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)
CONFIG_PCMCIA_HERMES
A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
......@@ -15752,24 +15799,17 @@ CONFIG_SOUND_CMPCI
Creative EMU10K1 based PCI sound cards
CONFIG_SOUND_EMU10K1
Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
such as the Creative SBLive!, SB PCI512 or Emu-APS.
For more information about the degree of support for the different
card models please check:
such as the various Creative SBLive!, SB PCI512 or Emu-APS.
http://opensource.creative.com
For more information on this driver and the degree of support for the
different card models please check <http://opensource.creative.com>.
It is now possible to load dsp microcode patches into the EMU10K1
chip. These patches are used to implement real time sound processing
effects which include for example: signal routing, bass/treble control,
AC3 passthrough, ...
Userspace tools to create new patches and load/unload them can be found
at the above link. You need to get the source snapshot and then type:
% make tools
% make install-tools
in the top directory.
effects which include for example: signal routing, bass/treble
control, AC3 passthrough, ...
Userspace tools to create new patches and load/unload them can be
found at <http://opensource.creative.com/dist.html>.
Creative EMU10K1 MIDI
CONFIG_MIDI_EMU10K1
......
......@@ -164,7 +164,7 @@ the list, please report it. That's why we do beta releases, after all...
1) Work with Donald to merge fixes and updates into his driver.
2) ethtool support
2) ETHTOOL_SSET support
3) PPC platform has stability problems. (XXX: verify this is still true)
......@@ -175,8 +175,6 @@ suggestions welcome) (WIP)
9) Better documentation. (patches welcome)
11) RTL8139C support untested.
12) 10base-T support flaky or slow (todo: verify this is still true)
......@@ -185,6 +183,14 @@ suggestions welcome) (WIP)
Change History
--------------
Version 0.9.19 - October 9, 2001
* Eliminate buffer copy for unaligned Tx's (manfred)
* Better RX error recovery (manfred)
* Wake-On-LAN and ETHTOOL_GSET support (Kalle Niemitalo)
* Fix assertion in PIO mode (various)
Version 0.9.18 - July 6, 2001
* Fix race leading to crashes on some machines.
......
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 11
EXTRAVERSION =-pre6
EXTRAVERSION =
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
......@@ -1150,6 +1150,26 @@ static void __init pci_fixup_piix4_acpi(struct pci_dev *d)
d->irq = 9;
}
/*
* Nobody seems to know what this does. Damn.
*
* But it does seem to fix some unspecified problem
* with 'movntq' copies on Athlons.
*
* VIA 8363 chipset:
* - bit 7 at offset 0x55: Debug (RW)
*/
static void __init pci_fixup_via_athlon_bug(struct pci_dev *d)
{
u8 v;
pci_read_config_byte(d, 0x55, &v);
if (v & 0x80) {
printk("Trying to stomp on Athlon bug...\n");
v &= 0x7f; /* clear bit 55.7 */
pci_write_config_byte(d, 0x55, v);
}
}
struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx },
......@@ -1169,6 +1189,7 @@ struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci_fixup_piix4_acpi },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_athlon_bug },
{ 0 }
};
......
......@@ -17,6 +17,7 @@
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <asm/system.h>
......
......@@ -75,7 +75,7 @@ obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o
ide-obj-$(CONFIG_PROC_FS) += ide-proc.o
ide-mod-objs := $(export-objs) $(ide-obj-y)
ide-mod-objs := ide.o ide-features.o $(ide-obj-y)
ide-probe-mod-objs := ide-probe.o ide-geometry.o
include $(TOPDIR)/Rules.make
......
......@@ -78,6 +78,8 @@
Andrew Morton - Clear blocked signals, avoid
buffer overrun setting current->comm.
Kalle Olavi Niemitalo - Wake-on-LAN ioctls
Submitting bug reports:
"rtl8139-diag -mmmaaavvveefN" output
......@@ -429,11 +431,34 @@ enum Config1Bits {
PWRDN = (1 << 0), /* only on 8139, 8139A */
};
/* Bits in Config3 */
enum Config3Bits {
Cfg3_FBtBEn = (1 << 0), /* 1 = Fast Back to Back */
Cfg3_FuncRegEn = (1 << 1), /* 1 = enable CardBus Function registers */
Cfg3_CLKRUN_En = (1 << 2), /* 1 = enable CLKRUN */
Cfg3_CardB_En = (1 << 3), /* 1 = enable CardBus registers */
Cfg3_LinkUp = (1 << 4), /* 1 = wake up on link up */
Cfg3_Magic = (1 << 5), /* 1 = wake up on Magic Packet (tm) */
Cfg3_PARM_En = (1 << 6), /* 0 = software can set twister parameters */
Cfg3_GNTSel = (1 << 7), /* 1 = delay 1 clock from PCI GNT signal */
};
/* Bits in Config4 */
enum Config4Bits {
LWPTN = (1 << 2), /* not on 8139, 8139A */
};
/* Bits in Config5 */
enum Config5Bits {
Cfg5_PME_STS = (1 << 0), /* 1 = PCI reset resets PME_Status */
Cfg5_LANWake = (1 << 1), /* 1 = enable LANWake signal */
Cfg5_LDPS = (1 << 2), /* 0 = save power when link is down */
Cfg5_FIFOAddrPtr = (1 << 3), /* Realtek internal SRAM testing */
Cfg5_UWF = (1 << 4), /* 1 = accept unicast wakeup frame */
Cfg5_MWF = (1 << 5), /* 1 = accept multicast wakeup frame */
Cfg5_BWF = (1 << 6), /* 1 = accept broadcast wakeup frame */
};
enum RxConfigBits {
/* Early Rx threshold, none or X/16 */
RxCfgEarlyRxNone = 0,
......@@ -1041,11 +1066,11 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
tp->duplex_lock = 1;
}
if (tp->default_port) {
printk(KERN_INFO " Forcing %dMbs %s-duplex operation.\n",
printk(KERN_INFO " Forcing %dMbps %s-duplex operation.\n",
(option & 0x20 ? 100 : 10),
(option & 0x10 ? "full" : "half"));
mdio_write(dev, tp->phys[0], 0,
((option & 0x20) ? 0x2000 : 0) | /* 100mbps? */
((option & 0x20) ? 0x2000 : 0) | /* 100Mbps? */
((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
}
......@@ -1400,9 +1425,10 @@ static void rtl8139_hw_start (struct net_device *dev)
rtl_check_media (dev);
if (tp->chipset >= CH_8139B) {
/* disable magic packet scanning, which is enabled
* when PM is enabled in Config1 */
RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
/* Disable magic packet scanning, which is enabled
* when PM is enabled in Config1. It can be reenabled
* via ETHTOOL_SWOL if desired. */
RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
}
DPRINTK("init buffer addresses\n");
......@@ -2209,15 +2235,148 @@ static int rtl8139_close (struct net_device *dev)
}
/* Get the ethtool settings. Assumes that eset points to kernel
memory, *eset has been initialized as {ETHTOOL_GSET}, and other
threads or interrupts aren't messing with the 8139. */
static void netdev_get_eset (struct net_device *dev, struct ethtool_cmd *eset)
{
struct rtl8139_private *np = dev->priv;
void *ioaddr = np->mmio_addr;
u16 advert;
eset->supported = SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full
| SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full
| SUPPORTED_Autoneg
| SUPPORTED_TP;
eset->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
advert = mdio_read (dev, np->phys[0], 4);
if (advert & 0x0020)
eset->advertising |= ADVERTISED_10baseT_Half;
if (advert & 0x0040)
eset->advertising |= ADVERTISED_10baseT_Full;
if (advert & 0x0080)
eset->advertising |= ADVERTISED_100baseT_Half;
if (advert & 0x0100)
eset->advertising |= ADVERTISED_100baseT_Full;
eset->speed = (RTL_R8 (MediaStatus) & 0x08) ? 10 : 100;
/* (KON)FIXME: np->full_duplex is set or reset by the thread,
which means this always shows half duplex if the interface
isn't up yet, even if it has already autonegotiated. */
eset->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
eset->port = PORT_TP;
/* (KON)FIXME: Is np->phys[0] correct? starfire.c uses that. */
eset->phy_address = np->phys[0];
eset->transceiver = XCVR_INTERNAL;
eset->autoneg = (mdio_read (dev, np->phys[0], 0) & 0x1000) != 0;
eset->maxtxpkt = 1;
eset->maxrxpkt = 1;
}
/* Get the ethtool Wake-on-LAN settings. Assumes that wol points to
kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and
other threads or interrupts aren't messing with the 8139. */
static void netdev_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rtl8139_private *np = dev->priv;
void *ioaddr = np->mmio_addr;
if (rtl_chip_info[np->chipset].flags & HasLWake) {
u8 cfg3 = RTL_R8 (Config3);
u8 cfg5 = RTL_R8 (Config5);
wol->supported = WAKE_PHY | WAKE_MAGIC
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST;
wol->wolopts = 0;
if (cfg3 & Cfg3_LinkUp)
wol->wolopts |= WAKE_PHY;
if (cfg3 & Cfg3_Magic)
wol->wolopts |= WAKE_MAGIC;
/* (KON)FIXME: See how netdev_set_wol() handles the
following constants. */
if (cfg5 & Cfg5_UWF)
wol->wolopts |= WAKE_UCAST;
if (cfg5 & Cfg5_MWF)
wol->wolopts |= WAKE_MCAST;
if (cfg5 & Cfg5_BWF)
wol->wolopts |= WAKE_BCAST;
}
}
/* Set the ethtool Wake-on-LAN settings. Return 0 or -errno. Assumes
that wol points to kernel memory and other threads or interrupts
aren't messing with the 8139. */
static int netdev_set_wol (struct net_device *dev,
const struct ethtool_wolinfo *wol)
{
struct rtl8139_private *np = dev->priv;
void *ioaddr = np->mmio_addr;
u32 support;
u8 cfg3, cfg5;
support = ((rtl_chip_info[np->chipset].flags & HasLWake)
? (WAKE_PHY | WAKE_MAGIC
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
: 0);
if (wol->wolopts & ~support)
return -EINVAL;
cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
if (wol->wolopts & WAKE_PHY)
cfg3 |= Cfg3_LinkUp;
if (wol->wolopts & WAKE_MAGIC)
cfg3 |= Cfg3_Magic;
RTL_W8 (Cfg9346, Cfg9346_Unlock);
RTL_W8 (Config3, cfg3);
RTL_W8 (Cfg9346, Cfg9346_Lock);
cfg5 = RTL_R8 (Config5) & ~(Cfg5_UWF | Cfg5_MWF | Cfg5_BWF);
/* (KON)FIXME: These are untested. We may have to set the
CRC0, Wakeup0 and LSBCRC0 registers too, but I have no
documentation. */
if (wol->wolopts & WAKE_UCAST)
cfg5 |= Cfg5_UWF;
if (wol->wolopts & WAKE_MCAST)
cfg5 |= Cfg5_MWF;
if (wol->wolopts & WAKE_BCAST)
cfg5 |= Cfg5_BWF;
RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
return 0;
}
static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
{
struct rtl8139_private *np = dev->priv;
u32 ethcmd;
/* dev_ioctl() in ../../net/core/dev.c has already checked
capable(CAP_NET_ADMIN), so don't bother with that here. */
if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
return -EFAULT;
switch (ethcmd) {
case ETHTOOL_GSET:
{
struct ethtool_cmd eset = { ETHTOOL_GSET };
spin_lock_irq (&np->lock);
netdev_get_eset (dev, &eset);
spin_unlock_irq (&np->lock);
if (copy_to_user (useraddr, &eset, sizeof (eset)))
return -EFAULT;
return 0;
}
/* TODO: ETHTOOL_SSET */
case ETHTOOL_GDRVINFO:
{
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
......@@ -2229,6 +2388,29 @@ static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
return 0;
}
case ETHTOOL_GWOL:
{
struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
spin_lock_irq (&np->lock);
netdev_get_wol (dev, &wol);
spin_unlock_irq (&np->lock);
if (copy_to_user (useraddr, &wol, sizeof (wol)))
return -EFAULT;
return 0;
}
case ETHTOOL_SWOL:
{
struct ethtool_wolinfo wol;
int rc;
if (copy_from_user (&wol, useraddr, sizeof (wol)))
return -EFAULT;
spin_lock_irq (&np->lock);
rc = netdev_set_wol (dev, &wol);
spin_unlock_irq (&np->lock);
return rc;
}
default:
break;
}
......@@ -2236,6 +2418,7 @@ static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
return -EOPNOTSUPP;
}
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{
struct rtl8139_private *tp = dev->priv;
......@@ -2245,8 +2428,11 @@ static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
DPRINTK ("ENTER\n");
if (cmd != SIOCETHTOOL) {
/* With SIOCETHTOOL, this would corrupt the pointer. */
data->phy_id &= 0x1f;
data->reg_num &= 0x1f;
}
switch (cmd) {
case SIOCETHTOOL:
......
......@@ -471,12 +471,12 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
#define EE_READ_CMD (6 << 6)
#define EE_ERASE_CMD (7 << 6)
static int __init read_eeprom(int ioaddr, int location)
static int __init read_eeprom(long ioaddr, int location)
{
int i;
unsigned short retval = 0;
int ee_addr = ioaddr + EEPROM_Ctrl;
int ee_daddr = ioaddr + EEPROM_Data;
long ee_addr = ioaddr + EEPROM_Ctrl;
long ee_daddr = ioaddr + EEPROM_Data;
int read_cmd = location | EE_READ_CMD;
/* Shift the read command bits out. */
......
......@@ -514,8 +514,8 @@ struct hamachi_private {
int mii_cnt; /* MII device addresses. */
u16 advertising; /* NWay media advertisement */
unsigned char phys[MII_CNT]; /* MII device addresses, only first one used. */
u_int32_t rx_int_var, tx_int_var; /* interrupt control variables */
u_int32_t option; /* Hold on to a copy of the options */
u32 rx_int_var, tx_int_var; /* interrupt control variables */
u32 option; /* Hold on to a copy of the options */
struct pci_dev *pci_dev;
};
......@@ -846,8 +846,8 @@ static int hamachi_open(struct net_device *dev)
struct hamachi_private *hmp = dev->priv;
long ioaddr = dev->base_addr;
int i;
u_int32_t rx_int_var, tx_int_var;
u_int16_t fifo_info;
u32 rx_int_var, tx_int_var;
u16 fifo_info;
i = request_irq(dev->irq, &hamachi_interrupt, SA_SHIRQ, dev->name, dev);
if (i)
......
......@@ -81,6 +81,10 @@
* stop the nic before switching into silent rx mode
for wol (required according to docu).
version 1.0.10:
* use long for ee_addr (various)
* print pointers properly (DaveM)
* include asm/irq.h (?)
TODO:
* big endian support with CFG:BEM instead of cpu_to_le32
......@@ -89,8 +93,8 @@
*/
#define DRV_NAME "natsemi"
#define DRV_VERSION "1.07+LK1.0.9"
#define DRV_RELDATE "Oct 02, 2001"
#define DRV_VERSION "1.07+LK1.0.10"
#define DRV_RELDATE "Oct 09, 2001"
/* Updated to recommendations in pci-skeleton v2.03. */
......@@ -178,6 +182,7 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
/* These identify the driver base version and may not be removed. */
......@@ -656,7 +661,7 @@ static int eeprom_read(long addr, int location)
{
int i;
int retval = 0;
int ee_addr = addr + EECtrl;
long ee_addr = addr + EECtrl;
int read_cmd = location | EE_ReadCmd;
writel(EE_Write0, ee_addr);
......@@ -940,14 +945,12 @@ static void dump_ring(struct net_device *dev)
if (debug > 2) {
int i;
printk(KERN_DEBUG " Tx ring at %8.8x:\n",
(int)np->tx_ring);
printk(KERN_DEBUG " Tx ring at %p:\n", np->tx_ring);
for (i = 0; i < TX_RING_SIZE; i++)
printk(KERN_DEBUG " #%d desc. %8.8x %8.8x %8.8x.\n",
i, np->tx_ring[i].next_desc,
np->tx_ring[i].cmd_status, np->tx_ring[i].addr);
printk(KERN_DEBUG " Rx ring %8.8x:\n",
(int)np->rx_ring);
printk(KERN_DEBUG " Rx ring %p:\n", np->rx_ring);
for (i = 0; i < RX_RING_SIZE; i++) {
printk(KERN_DEBUG " #%d desc. %8.8x %8.8x %8.8x.\n",
i, np->rx_ring[i].next_desc,
......
#define VERSION "0.12"
#define VERSION "0.13"
/* ns83820.c by Benjamin LaHaise <bcrl@redhat.com>
*
* $Revision: 1.34.2.8 $
......@@ -44,6 +44,7 @@
* - fix >> 32 bugs
* 0.12 - add statistics counters
* - add allmulti/promisc support
* 20011009 0.13 - hotplug support, other smaller pci api cleanups
*
* Driver Overview
* ===============
......@@ -374,7 +375,6 @@ struct ns83820 {
u8 *base;
struct pci_dev *pci_dev;
struct ns83820 *next_dev;
struct rx_info rx_info;
......@@ -410,8 +410,6 @@ struct ns83820 {
#define start_tx_okay(dev) \
(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > NR_TX_DESC/2)
static struct ns83820 *ns83820_chain;
/* Packet Receiver
*
......@@ -1230,7 +1228,7 @@ static void ns83820_set_multicast(struct net_device *_dev)
spin_unlock_irq(&dev->misc_lock);
}
static int ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_device_id *id)
{
struct ns83820 *dev;
long addr;
......@@ -1298,10 +1296,7 @@ static int ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id
dev->net_dev.set_multicast_list = ns83820_set_multicast;
//FIXME: dev->net_dev.tx_timeout = ns83820_tx_timeout;
lock_kernel();
dev->next_dev = ns83820_chain;
ns83820_chain = dev;
unlock_kernel();
pci_set_drvdata(pci_dev, dev);
ns83820_do_reset(dev, CR_RST);
......@@ -1423,21 +1418,45 @@ static int ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id
pci_disable_device(pci_dev);
out_free:
kfree(dev);
pci_set_drvdata(pci_dev, NULL);
out:
return err;
}
static struct pci_device_id pci_device_id[] __devinitdata = {
static void __devexit ns83820_remove_one(struct pci_dev *pci_dev)
{
struct ns83820 *dev = pci_get_drvdata(pci_dev);
if (!dev) /* paranoia */
return;
writel(0, dev->base + IMR); /* paranoia */
writel(0, dev->base + IER);
readl(dev->base + IER);
unregister_netdev(&dev->net_dev);
free_irq(dev->pci_dev->irq, dev);
iounmap(dev->base);
pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC,
dev->tx_descs, dev->tx_phy_descs);
pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC,
dev->rx_info.descs, dev->rx_info.phy_descs);
pci_disable_device(dev->pci_dev);
kfree(dev);
pci_set_drvdata(pci_dev, NULL);
}
static struct pci_device_id ns83820_pci_tbl[] __devinitdata = {
{ 0x100b, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
{ 0, },
};
static struct pci_driver driver = {
name: "ns83820",
id_table: pci_device_id,
probe: ns83820_probe,
id_table: ns83820_pci_tbl,
probe: ns83820_init_one,
remove: ns83820_remove_one,
#if 0 /* FIXME: implement */
remove: ,
suspend: ,
resume: ,
#endif
......@@ -1450,37 +1469,16 @@ static int __init ns83820_init(void)
return pci_module_init(&driver);
}
static void ns83820_exit(void)
static void __exit ns83820_exit(void)
{
struct ns83820 *dev;
for (dev = ns83820_chain; dev; ) {
struct ns83820 *next = dev->next_dev;
writel(0, dev->base + IMR); /* paranoia */
writel(0, dev->base + IER);
readl(dev->base + IER);
unregister_netdev(&dev->net_dev);
free_irq(dev->pci_dev->irq, dev);
iounmap(dev->base);
pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC,
dev->tx_descs, dev->tx_phy_descs);
pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC,
dev->rx_info.descs, dev->rx_info.phy_descs);
pci_disable_device(dev->pci_dev);
kfree(dev);
dev = next;
}
pci_unregister_driver(&driver);
ns83820_chain = NULL;
}
MODULE_AUTHOR("Benjamin LaHaise <bcrl@redhat.com>");
MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, pci_device_id);
MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl);
module_init(ns83820_init);
module_exit(ns83820_exit);
This diff is collapsed.
/* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
Copyright 1999 Silicon Integrated System Corporation
Revision: 1.08.00 Jun. 11 2001
Revision: 1.08.01 Aug. 25 2001
Modified from the driver which is originally written by Donald Becker.
......@@ -18,6 +18,7 @@
preliminary Rev. 1.0 Jan. 18, 1998
http://www.sis.com.tw/support/databook.htm
Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix
Rev 1.07.11 Apr. 2 2001 Hui-Fen Hsu updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3
Rev 1.07.10 Mar. 1 2001 Hui-Fen Hsu <hfhsu@sis.com.tw> some bug fix & 635M/B support
......@@ -65,7 +66,7 @@
#include "sis900.h"
static char version[] __devinitdata =
KERN_INFO "sis900.c: v1.08.00 6/11/2001\n";
KERN_INFO "sis900.c: v1.08.01 9/25/2001\n";
static int max_interrupt_work = 40;
static int multicast_filter_limit = 128;
......@@ -407,7 +408,11 @@ static int __devinit sis900_probe (struct pci_dev *pci_dev, const struct pci_dev
goto err_out_unregister;
}
/* probe for mii transciver */
/* 630ET : set the mii access mode as software-mode */
if (revision == SIS630ET_900_REV)
outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
/* probe for mii transceiver */
if (sis900_mii_probe(net_dev) == 0) {
ret = -ENODEV;
goto err_out_unregister;
......@@ -516,6 +521,11 @@ static int __init sis900_mii_probe (struct net_device * net_dev)
((sis_priv->mii->phy_id1&0xFFF0) == 0x8000))
status = sis900_reset_phy(net_dev, sis_priv->cur_phy);
/* workaround for ICS1893 PHY */
if ((sis_priv->mii->phy_id0 == 0x0015) &&
((sis_priv->mii->phy_id1&0xFFF0) == 0xF440))
mdio_write(net_dev, sis_priv->cur_phy, 0x0018, 0xD200);
if(status & MII_STAT_LINK){
while (poll_bit) {
current->state = TASK_INTERRUPTIBLE;
......@@ -862,7 +872,7 @@ sis900_open(struct net_device *net_dev)
/* Enable all known interrupts by setting the interrupt mask. */
outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
outl(RxENA, ioaddr + cr);
outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
outl(IE, ioaddr + ier);
sis900_check_mode(net_dev, sis_priv->mii);
......@@ -1039,7 +1049,7 @@ static void sis630_set_eq(struct net_device *net_dev, u8 revision)
struct pci_dev *dev=NULL;
if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
revision == SIS630A_900_REV) )
revision == SIS630A_900_REV || revision == SIS630ET_900_REV) )
return;
dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, dev);
......@@ -1057,7 +1067,8 @@ static void sis630_set_eq(struct net_device *net_dev, u8 revision)
min_value=(eq_value < min_value) ? eq_value : min_value;
}
/* 630E rule to determine the equalizer value */
if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV) {
if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
revision == SIS630ET_900_REV) {
if (max_value < 5)
eq_value=max_value;
else if (max_value >= 5 && max_value < 15)
......@@ -1373,7 +1384,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
net_dev->trans_start = jiffies;
/* FIXME: Should we restart the transmission thread here ?? */
outl(TxENA, ioaddr + cr);
outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
/* Enable all known interrupts by setting the interrupt mask. */
outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
......@@ -1408,7 +1419,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
sis_priv->tx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev,
skb->data, skb->len, PCI_DMA_TODEVICE);
sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
outl(TxENA, ioaddr + cr);
outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) {
/* Typical path, tell upper layer that more transmission is possible */
......@@ -1624,7 +1635,7 @@ static int sis900_rx(struct net_device *net_dev)
}
}
/* re-enable the potentially idle receive state matchine */
outl(RxENA , ioaddr + cr );
outl(RxENA | inl(ioaddr + cr), ioaddr + cr );
return 0;
}
......@@ -1722,7 +1733,7 @@ sis900_close(struct net_device *net_dev)
outl(0x0000, ioaddr + ier);
/* Stop the chip's Tx and Rx Status Machine */
outl(RxDIS | TxDIS, ioaddr + cr);
outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
del_timer(&sis_priv->timer);
......@@ -2038,7 +2049,7 @@ static void sis900_reset(struct net_device *net_dev)
outl(0, ioaddr + imr);
outl(0, ioaddr + rfcr);
outl(RxRESET | TxRESET | RESET, ioaddr + cr);
outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
/* Check that the chip has finished the reset. */
while (status && (i++ < 1000)) {
......
......@@ -41,7 +41,7 @@ enum sis900_registers {
/* Symbolic names for bits in various registers */
enum sis900_command_register_bits {
RELOAD = 0x00000400,
RELOAD = 0x00000400, ACCESSMODE = 0x00000200,/* ET */
RESET = 0x00000100, SWI = 0x00000080, RxRESET = 0x00000020,
TxRESET = 0x00000010, RxDIS = 0x00000008, RxENA = 0x00000004,
TxDIS = 0x00000002, TxENA = 0x00000001
......@@ -239,7 +239,8 @@ enum mii_stssum_register_bits {
enum sis900_revision_id {
SIS630A_900_REV = 0x80, SIS630E_900_REV = 0x81,
SIS630S_900_REV = 0x82, SIS630EA1_900_REV = 0x83,
SIS635A_900_REV = 0x90, SIS900B_900_REV = 0x03
SIS630ET_900_REV = 0x84, SIS635A_900_REV = 0x90,
SIS900B_900_REV = 0x03
};
enum sis630_revision_id {
......
......@@ -557,7 +557,7 @@ static int eeprom_read(long addr, int location)
{
int i;
int retval = 0;
int ee_addr = addr + EECtrl;
long ee_addr = addr + EECtrl;
int read_cmd = location | EE_ReadCmd;
writel(EE_ChipSelect, ee_addr);
......
......@@ -6,15 +6,21 @@ if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
tristate ' Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards' CONFIG_AIRO
fi
tristate ' Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)' CONFIG_HERMES
if [ "$CONFIG_ALL_PPC" = "y" ]; then
tristate ' Apple Airport support (built-in)' CONFIG_APPLE_AIRPORT
dep_tristate ' Apple Airport support (built-in)' CONFIG_APPLE_AIRPORT $CONFIG_HERMES
fi
if [ "$CONFIG_PCI" = "y" ]; then
dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
fi
# If Pcmcia is compiled in, offer Pcmcia cards...
if [ "$CONFIG_PCMCIA" != "n" ]; then
comment 'Wireless Pcmcia cards support'
tristate ' Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)' CONFIG_PCMCIA_HERMES
dep_tristate ' Hermes PCMCIA card support' CONFIG_PCMCIA_HERMES $CONFIG_HERMES
tristate ' Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards' CONFIG_AIRO_CS
fi
......
......@@ -14,8 +14,10 @@ obj- :=
# Things that need to export symbols
export-objs := airo.o orinoco.o hermes.o
obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o orinoco.o hermes.o
obj-$(CONFIG_APPLE_AIRPORT) += airport.o orinoco.o hermes.o
obj-$(CONFIG_HERMES) += orinoco.o hermes.o
obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o
obj-$(CONFIG_APPLE_AIRPORT) += airport.o
obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
obj-$(CONFIG_AIRO) += airo.o
obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o
......
......@@ -96,9 +96,9 @@ MODULE_LICENSE("Dual MPL/GPL");
Callable from any context.
*/
static int hermes_issue_cmd(hermes_t *hw, uint16_t cmd, uint16_t param0)
static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0)
{
uint16_t reg;
u16 reg;
/* First check that the command register is not busy */
reg = hermes_read_regn(hw, CMD);
......@@ -126,7 +126,7 @@ void hermes_struct_init(hermes_t *hw, uint io)
int hermes_reset(hermes_t *hw)
{
uint16_t status, reg;
u16 status, reg;
int err = 0;
int k;
......@@ -210,11 +210,11 @@ int hermes_reset(hermes_t *hw)
* Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
*
* Callable from any context, but locking is your problem. */
int hermes_docmd_wait(hermes_t *hw, uint16_t cmd, uint16_t parm0, hermes_response_t *resp)
int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp)
{
int err;
int k;
uint16_t reg;
u16 reg;
err = hermes_issue_cmd(hw, cmd, parm0);
if (err) {
......@@ -263,12 +263,12 @@ int hermes_docmd_wait(hermes_t *hw, uint16_t cmd, uint16_t parm0, hermes_respons
return err;
}
int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid)
int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
{
int err = 0;
hermes_response_t resp;
int k;
uint16_t reg;
u16 reg;
if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
return -EINVAL;
......@@ -312,12 +312,12 @@ int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid)
* from firmware
*
* Callable from any context */
int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset)
int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
{
int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
int k;
uint16_t reg;
u16 reg;
/* Paranoia.. */
if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
......@@ -368,7 +368,7 @@ int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset)
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
uint16_t id, uint16_t offset)
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
......@@ -394,7 +394,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
uint16_t id, uint16_t offset)
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
......@@ -421,16 +421,15 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
* practice.
*
* Callable from user or bh context. */
int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen,
uint16_t *length, void *buf)
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize,
u16 *length, void *buf)
{
int err = 0;
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
uint16_t rlength, rtype;
u16 rlength, rtype;
hermes_response_t resp;
int count;
if (buflen % 2)
if (bufsize % 2)
return -EINVAL;
err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, &resp);
......@@ -450,23 +449,21 @@ int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen,
if (rtype != rid)
printk(KERN_WARNING "hermes_read_ltv(): rid (0x%04x) does "
"not match type (0x%04x)\n", rid, rtype);
if (HERMES_RECLEN_TO_BYTES(rlength) > buflen)
if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
printk(KERN_WARNING "hermes @ 0x%x: Truncating LTV record from %d to %d bytes. "
"(rid=0x%04x, len=0x%04x)\n", hw->iobase,
HERMES_RECLEN_TO_BYTES(rlength), buflen, rid, rlength);
/* For now we always read the whole buffer, the
lengths in the records seem to be wrong, frequently */
count = buflen / 2;
HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
hermes_read_words(hw, dreg, buf, count);
/* FIXME: we should read the min of the requested length and
the actual record length */
hermes_read_words(hw, dreg, buf, bufsize / 2);
out:
return err;
}
int hermes_write_ltv(hermes_t *hw, int bap, uint16_t rid,
uint16_t length, const void *value)
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
u16 length, const void *value)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
......@@ -474,7 +471,7 @@ int hermes_write_ltv(hermes_t *hw, int bap, uint16_t rid,
int count;
DEBUG(3, "write_ltv(): bap=%d rid=0x%04x length=%d (value=0x%04x)\n",
bap, rid, length, * ((uint16_t *)value));
bap, rid, length, * ((u16 *)value));
err = hermes_bap_seek(hw, bap, rid, 0);
if (err)
......
......@@ -50,7 +50,6 @@
#define HERMES_FRAME_LEN_MAX (2304)
#define HERMES_MAX_MULTICAST (16)
#define HERMES_MAGIC (0x7d1f)
#define HERMES_SYMBOL_MAX_VER (14)
/*
* Hermes register offsets
......@@ -177,12 +176,12 @@
#define HERMES_RID_CNF_TX_KEY (0xfcb1)
#define HERMES_RID_CNF_TICKTIME (0xfce0)
#define HERMES_RID_CNF_PRISM2_WEP_ON (0xfc28)
#define HERMES_RID_CNF_PRISM2_TX_KEY (0xfc23)
#define HERMES_RID_CNF_PRISM2_KEY0 (0xfc24)
#define HERMES_RID_CNF_PRISM2_KEY1 (0xfc25)
#define HERMES_RID_CNF_PRISM2_KEY2 (0xfc26)
#define HERMES_RID_CNF_PRISM2_KEY3 (0xfc27)
#define HERMES_RID_CNF_INTERSIL_WEP_ON (0xfc28)
#define HERMES_RID_CNF_INTERSIL_TX_KEY (0xfc23)
#define HERMES_RID_CNF_INTERSIL_KEY0 (0xfc24)
#define HERMES_RID_CNF_INTERSIL_KEY1 (0xfc25)
#define HERMES_RID_CNF_INTERSIL_KEY2 (0xfc26)
#define HERMES_RID_CNF_INTERSIL_KEY3 (0xfc27)
#define HERMES_RID_CNF_SYMBOL_MANDATORY_BSSID (0xfc21)
#define HERMES_RID_CNF_SYMBOL_AUTH_TYPE (0xfc2A)
#define HERMES_RID_CNF_SYMBOL_BASIC_RATES (0xfc8A)
......@@ -212,11 +211,11 @@
typedef struct hermes_frame_desc {
/* Hermes - i.e. little-endian byte-order */
uint16_t status;
uint16_t res1, res2;
uint16_t q_info;
uint16_t res3, res4;
uint16_t tx_ctl;
u16 status;
u16 res1, res2;
u16 q_info;
u16 res3, res4;
u16 tx_ctl;
} __attribute__ ((packed)) hermes_frame_desc_t;
#define HERMES_RXSTAT_ERR (0x0003)
......@@ -239,21 +238,21 @@ typedef struct hermes_frame_desc {
typedef struct hermes {
uint iobase;
uint16_t inten; /* Which interrupts should be enabled? */
u16 inten; /* Which interrupts should be enabled? */
} hermes_t;
typedef struct hermes_response {
uint16_t status, resp0, resp1, resp2;
u16 status, resp0, resp1, resp2;
} hermes_response_t;
/* "ID" structure - used for ESSID and station nickname */
typedef struct hermes_id {
uint16_t len;
uint16_t val[16];
u16 len;
u16 val[16];
} __attribute__ ((packed)) hermes_id_t;
typedef struct hermes_multicast {
uint8_t addr[HERMES_MAX_MULTICAST][ETH_ALEN];
u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
} __attribute__ ((packed)) hermes_multicast_t;
/* Register access convenience macros */
......@@ -266,18 +265,18 @@ typedef struct hermes_multicast {
/* Function prototypes */
void hermes_struct_init(hermes_t *hw, uint io);
int hermes_reset(hermes_t *hw);
int hermes_docmd_wait(hermes_t *hw, uint16_t cmd, uint16_t parm0, hermes_response_t *resp);
int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid);
int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp);
int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset);
int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset);
int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
uint16_t id, uint16_t offset);
u16 id, u16 offset);
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
uint16_t id, uint16_t offset);
int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen,
uint16_t *length, void *buf);
int hermes_write_ltv(hermes_t *hw, int bap, uint16_t rid,
uint16_t length, const void *value);
u16 id, u16 offset);
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int buflen,
u16 *length, void *buf);
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
u16 length, const void *value);
/* Inline functions */
......@@ -286,13 +285,13 @@ static inline int hermes_present(hermes_t *hw)
return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
}
static inline void hermes_enable_interrupt(hermes_t *hw, uint16_t events)
static inline void hermes_enable_interrupt(hermes_t *hw, u16 events)
{
hw->inten |= events;
hermes_write_regn(hw, INTEN, hw->inten);
}
static inline void hermes_set_irqmask(hermes_t *hw, uint16_t events)
static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
{
hw->inten = events;
hermes_write_regn(hw, INTEN, events);
......@@ -326,9 +325,9 @@ static inline int hermes_disable_port(hermes_t *hw, int port)
#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
(hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
static inline int hermes_read_wordrec(hermes_t *hw, int bap, uint16_t rid, uint16_t *word)
static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
{
uint16_t rec;
u16 rec;
int err;
err = HERMES_READ_RECORD(hw, bap, rid, &rec);
......@@ -336,9 +335,9 @@ static inline int hermes_read_wordrec(hermes_t *hw, int bap, uint16_t rid, uint1
return err;
}
static inline int hermes_write_wordrec(hermes_t *hw, int bap, uint16_t rid, uint16_t word)
static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
{
uint16_t rec = cpu_to_le16(word);
u16 rec = cpu_to_le16(word);
return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
}
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
#define _ORINOCO_H
/* To enable debug messages */
//#define ORINOCO_DEBUG 3
/* #define ORINOCO_DEBUG 3 */
#if (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10)
#error "orinoco_cs requires Wireless extensions v10 or later."
......@@ -33,7 +33,7 @@
#define MAX_FRAME_SIZE 2304
typedef struct dldwd_key {
uint16_t len;
uint16_t len; /* always store little-endian */
char data[MAX_KEY_SIZE];
} __attribute__ ((packed)) dldwd_key_t;
......
/* orinoco_cs.c 0.08 - (formerly known as dldwd_cs.c)
/* orinoco_cs.c 0.08a - (formerly known as dldwd_cs.c)
*
* A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
* as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
......@@ -44,7 +44,7 @@
/*====================================================================*/
static char version[] __initdata = "orinoco_cs.c 0.08 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
static char version[] __initdata = "orinoco_cs.c 0.08a (David Gibson <hermes@gibson.dropbear.id.au> and others)";
MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
......@@ -200,7 +200,7 @@ dldwd_cs_cor_reset(dldwd_priv_t *priv)
CardServices(AccessConfigurationRegister, link->handle, &reg);
default_cor = reg.Value;
DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%lX\n", default_cor);
DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%X\n", default_cor);
/* Soft-Reset card */
reg.Action = CS_WRITE;
......
This diff is collapsed.
......@@ -49,7 +49,6 @@
#include "irqmgr.h"
#include "audio.h"
#include "8010.h"
#include "passthrough.h"
static void calculate_ofrag(struct woinst *);
static void calculate_ifrag(struct wiinst *);
......@@ -984,6 +983,9 @@ static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned lon
unsigned long pgoff;
int rd, wr;
DPF(4, "emu10k1_mm_nopage()\n");
DPD(4, "addr: %#lx\n", address);
if (address > vma->vm_end) {
DPF(2, "EXIT, returning NOPAGE_SIGBUS\n");
return NOPAGE_SIGBUS; /* Disallow mremap */
......@@ -1013,6 +1015,8 @@ static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned lon
}
get_page (dmapage);
DPD(4, "page: %#lx\n", dmapage);
return dmapage;
}
......@@ -1023,14 +1027,14 @@ struct vm_operations_struct emu10k1_mm_ops = {
static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
{
struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
unsigned long maxsize, size, offset, pgoffset;
unsigned long max_pages, n_pages, pgoffset;
struct woinst *woinst = NULL;
struct wiinst *wiinst = NULL;
unsigned long flags;
DPF(2, "emu10k1_audio_mmap()\n");
maxsize = 0;
max_pages = 0;
if (vma->vm_flags & VM_WRITE) {
woinst = wave_dev->woinst;
......@@ -1053,7 +1057,7 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
}
woinst->mmapped = 1;
maxsize += woinst->buffer.pages * PAGE_SIZE;
max_pages += woinst->buffer.pages;
spin_unlock_irqrestore(&woinst->lock, flags);
}
......@@ -1072,15 +1076,17 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
}
wiinst->mmapped = 1;
maxsize += wiinst->buffer.pages * PAGE_SIZE;
max_pages += wiinst->buffer.pages;
spin_unlock_irqrestore(&wiinst->lock, flags);
}
size = vma->vm_end - vma->vm_start;
n_pages = ((vma->vm_end - vma->vm_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
pgoffset = vma->vm_pgoff;
offset = pgoffset << PAGE_SHIFT;
if (offset + size > maxsize)
DPD(3, "vma_start: %#lx, vma_end: %#lx, vma_offset: %d\n", vma->vm_start, vma->vm_end, pgoffset);
DPD(3, "n_pages: %d, max_pages: %d\n", n_pages, max_pages);
if (pgoffset + n_pages > max_pages)
return -EINVAL;
vma->vm_flags |= VM_RESERVED;
......@@ -1240,9 +1246,11 @@ static int emu10k1_audio_release(struct inode *inode, struct file *file)
spin_lock_irqsave(&woinst->lock, flags);
if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE)
if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE) {
spin_lock(&card->pt.lock);
emu10k1_pt_stop(card);
spin_unlock(&card->pt.lock);
}
if (woinst->state & WAVE_STATE_OPEN) {
if (woinst->state & WAVE_STATE_STARTED) {
if (!(file->f_flags & O_NONBLOCK)) {
......@@ -1259,7 +1267,7 @@ static int emu10k1_audio_release(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&woinst->lock, flags);
/* wait for the tasklet (bottom-half) to finish */
/* remove the tasklet */
tasklet_kill(&woinst->timer.tasklet);
kfree(wave_dev->woinst);
}
......@@ -1505,9 +1513,10 @@ void emu10k1_wavein_bh(unsigned long refdata)
spin_unlock_irqrestore(&wiinst->lock, flags);
if (bytestocopy >= wiinst->buffer.fragment_size && waitqueue_active(&wiinst->wait_queue))
if (bytestocopy >= wiinst->buffer.fragment_size) {
if (waitqueue_active(&wiinst->wait_queue))
wake_up_interruptible(&wiinst->wait_queue);
else
} else
DPD(3, "Not enough transfer size, %d\n", bytestocopy);
return;
......@@ -1539,9 +1548,10 @@ void emu10k1_waveout_bh(unsigned long refdata)
} else
spin_unlock_irqrestore(&woinst->lock, flags);
if (bytestocopy >= woinst->buffer.fragment_size && waitqueue_active(&woinst->wait_queue))
if (bytestocopy >= woinst->buffer.fragment_size) {
if (waitqueue_active(&woinst->wait_queue))
wake_up_interruptible(&woinst->wait_queue);
else
} else
DPD(3, "Not enough transfer size -> %d\n", bytestocopy);
return;
......
......@@ -49,7 +49,7 @@ int emu10k1_find_control_gpr(struct patch_manager *mgr, const char *patch_name,
goto match;
}
for(i = 0; i < mgr->current_pages * PATCHES_PER_PAGE; i++) {
for (i = 0; i < mgr->current_pages * PATCHES_PER_PAGE; i++) {
patch = PATCH(mgr, i);
sprintf(s,"%s", patch->name);
......@@ -97,77 +97,81 @@ void emu10k1_set_control_gpr(struct emu10k1_card *card, int addr, s32 val, int f
//An internal function for setting OSS mixer controls.
void emu10k1_set_oss_vol(struct emu10k1_card *card, int oss_mixer,
unsigned int left, unsigned int right){
extern struct oss_scaling volume_params[SOUND_MIXER_NRDEVICES];
unsigned int left, unsigned int right)
{
extern char volume_params[SOUND_MIXER_NRDEVICES];
card->ac97.mixer_state[oss_mixer] = (right << 8) | left;
if (!card->isaps)
card->ac97.write_mixer(&card->ac97, oss_mixer, left, right);
emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left,
volume_params[oss_mixer].scale,
volume_params[oss_mixer].muting);
emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right,
volume_params[oss_mixer].scale,
volume_params[oss_mixer].muting);
volume_params[oss_mixer]);
emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right,
volume_params[oss_mixer]);
}
//FIXME: mute should unmute when pressed a second time
void emu10k1_mute_irqhandler(struct emu10k1_card *card)
{
struct patch_manager *mgr = &card->mgr;
unsigned long flags;
int oss_channel = VOLCTRL_CHANNEL;
int left, right;
static int val = 0;
if (val) {
left = val & 0xff;
right = (val >> 8) & 0xff;
val = 0;
} else {
val = card->ac97.mixer_state[oss_channel];
left = 0;
right = 0;
}
spin_lock_irqsave(&mgr->lock, flags);
emu10k1_set_oss_vol(card,VOLCTRL_CHANNEL,0,0);
spin_unlock_irqrestore(&mgr->lock, flags);
emu10k1_set_oss_vol(card, oss_channel, left, right);
}
void emu10k1_volincr_irqhandler(struct emu10k1_card *card)
{
struct patch_manager *mgr = &card->mgr;
unsigned long flags;
unsigned int oss_channel=VOLCTRL_CHANNEL, left=0,right=0;
int oss_channel = VOLCTRL_CHANNEL;
int left, right;
spin_lock_irqsave(&mgr->lock, flags);
left = card->ac97.mixer_state[oss_channel] & 0xff;
right = (card->ac97.mixer_state[oss_channel] >> 8) & 0xff;
if((left+=VOLCTRL_STEP_SIZE )>100)
left=100;
if((right+=VOLCTRL_STEP_SIZE )>100)
right=100;
emu10k1_set_oss_vol(card,oss_channel,left,right);
spin_unlock_irqrestore(&mgr->lock, flags);
if ((left += VOLCTRL_STEP_SIZE) > 100)
left = 100;
if ((right += VOLCTRL_STEP_SIZE) > 100)
right = 100;
emu10k1_set_oss_vol(card, oss_channel, left, right);
}
void emu10k1_voldecr_irqhandler(struct emu10k1_card *card)
{
struct patch_manager *mgr = &card->mgr;
unsigned long flags;
int oss_channel=VOLCTRL_CHANNEL, left=0,right=0;
int oss_channel = VOLCTRL_CHANNEL;
int left, right;
spin_lock_irqsave(&mgr->lock, flags);
left = card->ac97.mixer_state[oss_channel] & 0xff;
right = (card->ac97.mixer_state[oss_channel] >> 8) & 0xff;
if((left-=VOLCTRL_STEP_SIZE )<0)
left=0;
if((right-=VOLCTRL_STEP_SIZE )<0)
right=0;
emu10k1_set_oss_vol(card,oss_channel,left,right);
spin_unlock_irqrestore(&mgr->lock, flags);
}
if ((left -= VOLCTRL_STEP_SIZE) < 0)
left = 0;
if ((right -= VOLCTRL_STEP_SIZE) < 0)
right = 0;
emu10k1_set_oss_vol(card, oss_channel, left, right);
}
void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int scale, int muting)
void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int scale)
{
struct patch_manager *mgr = &card->mgr;
unsigned long flags;
int muting;
const s32 log2lin[5] ={ // attenuation (dB)
0x7fffffff, // 0.0
......@@ -179,10 +183,12 @@ void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int sc
if (addr < 0)
return;
muting = (scale == 0x10) ? 0x7f: scale;
vol = (100 - vol ) * scale / 100;
// Thanks to the comp.dsp newsgroup for this neat trick:
vol = vol >= muting ? 0: log2lin[vol&3]>>(vol>>2);
vol = (vol >= muting) ? 0 : (log2lin[vol & 3] >> (vol >> 2));
spin_lock_irqsave(&mgr->lock, flags);
emu10k1_set_control_gpr(card, addr, vol, 0);
......@@ -197,15 +203,16 @@ void emu10k1_dsp_irqhandler(struct emu10k1_card *card)
u32 bc;
bc = sblive_readptr(card, GPR_BASE + card->pt.intr_gpr, 0);
if (bc != 0) {
spin_lock_irqsave(&card->lock, flags);
DPD(3, "pt interrupt, bc = %d\n", bc);
spin_lock_irqsave(&card->pt.lock, flags);
card->pt.blocks_played = bc;
if (card->pt.blocks_played >= card->pt.blocks_copied) {
DPF(1, "buffer underrun in passthrough playback\n");
emu10k1_pt_stop(card);
}
wake_up_interruptible(&card->pt.wait);
spin_unlock_irqrestore(&card->lock, flags);
DPD(3, "pt interrupt, bc = %d\n", bc);
spin_unlock_irqrestore(&card->pt.lock, flags);
}
}
}
......@@ -66,7 +66,8 @@ struct dsp_patch {
u32 gpr_used[NUM_GPRS / 32]; /* bitmap of used gprs */
u32 gpr_input[NUM_GPRS / 32];
u8 traml_istart; /* starting address of the internal tram lines used */ u8 traml_isize; /* number of internal tram lines used */
u8 traml_istart; /* starting address of the internal tram lines used */
u8 traml_isize; /* number of internal tram lines used */
u8 traml_estart;
u8 traml_esize;
......@@ -97,10 +98,6 @@ enum {
#define GPR_BASE 0x100
#define OUTPUT_BASE 0x20
//We can get this info by looking at the code start
//#define PATCH_TYPE_INPUT 0x1
//#define PATCH_TYPE_OUTPUT 0x2
#define MAX_PATCHES_PAGES 32
struct patch_manager {
......@@ -139,6 +136,14 @@ struct patch_manager {
#define PCM1_IN_L 0x04
#define PCM1_IN_R 0x05
//mutilchannel playback stream appear here:
#define MULTI_FRONT_L 0x08
#define MULTI_FRONT_R 0x09
#define MULTI_REAR_L 0x0a
#define MULTI_REAR_R 0x0b
#define MULTI_CENTER 0x0c
#define MULTI_LFE 0x0d
#define AC97_IN_L 0x10
#define AC97_IN_R 0x11
......@@ -150,11 +155,18 @@ struct patch_manager {
#define AC97_FRONT_R 0x21
#define DIGITAL_OUT_L 0x22
#define DIGITAL_OUT_R 0x23
#define DIGITAL_CENTER 0x24
#define DIGITAL_LFE 0x25
#define ANALOG_REAR_L 0x28
#define ANALOG_REAR_R 0x29
#define ADC_REC_L 0x2a
#define ADC_REC_R 0x2b
#define ANALOG_CENTER 0x31
#define ANALOG_LFE 0x32
#define INPUT_PATCH_START(patch, nm, ln, i) \
do { \
patch = PATCH(mgr, patch_n); \
......
......@@ -38,8 +38,8 @@
#include <linux/ac97_codec.h>
#include <linux/pci.h>
#include "passthrough.h"
#include "efxmgr.h"
#include "passthrough.h"
#include "midi.h"
#define EMUPAGESIZE 4096 /* don't change */
......@@ -122,10 +122,10 @@ struct mixer_private_ioctl {
#define CMD_SETGPR2OSS _IOW('D', 16, struct mixer_private_ioctl)
#define CMD_SETMCH_FX _IOW('D', 17, struct mixer_private_ioctl)
#define CMD_SETPASSTHROUGH _IOW('D', 18, struct mixer_private_ioctl)
#define CMD_PRIVATE3_VERSION _IOW('D', 19, struct mixer_private_ioctl)
struct oss_scaling {
char scale, muting;
};
//up this number when breaking compatibility
#define PRIVATE3_VERSION 1
struct emu10k1_card
{
......@@ -192,12 +192,12 @@ void emu10k1_addxmgr_free(struct emu10k1_card *, int);
int emu10k1_find_control_gpr(struct patch_manager *, const char *, const char *);
void emu10k1_set_control_gpr(struct emu10k1_card *, int , s32, int );
void emu10k1_set_volume_gpr(struct emu10k1_card *, int, s32, int, int);
void emu10k1_set_volume_gpr(struct emu10k1_card *, int, s32, int);
#define VOL_6BIT 0x40,0x40
#define VOL_5BIT 0x20,0x20
#define VOL_4BIT 0x10,0x7f
#define VOL_6BIT 0x40
#define VOL_5BIT 0x20
#define VOL_4BIT 0x10
#define TIMEOUT 16384
......
This diff is collapsed.
......@@ -94,7 +94,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
DPF(2, "emu10k1_midi_open()\n");
/* Check for correct device to open */
list_for_each(entry, &emu10k1_devs) {
card = list_entry(entry, struct emu10k1_card, list);
......@@ -107,11 +106,10 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
match:
#ifdef EMU10K1_SEQUENCER
if(card->seq_mididev) /* card is opened by sequencer */
if (card->seq_mididev) /* card is opened by sequencer */
return -EBUSY;
#endif
/* Wait for device to become free */
down(&card->open_sem);
while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
......@@ -130,9 +128,8 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
down(&card->open_sem);
}
if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
return -EINVAL;
}
midi_dev->card = card;
midi_dev->mistate = MIDIIN_STATE_STOPPED;
......@@ -245,7 +242,6 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file)
unlock_kernel();
return 0;
}
......@@ -466,20 +462,18 @@ int emu10k1_seq_midi_open(int dev, int mode,
struct midi_openinfo dsCardMidiOpenInfo;
struct emu10k1_mididevice *midi_dev;
if( midi_devs[dev] == NULL
|| midi_devs[dev]->devc == NULL)
if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
return -EINVAL;
card = midi_devs[dev]->devc;
if(card->open_mode) /* card is opened native */
if (card->open_mode) /* card is opened native */
return -EBUSY;
DPF(2, "emu10k1_seq_midi_open()\n");
if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
return -EINVAL;
}
midi_dev->card = card;
midi_dev->mistate = MIDIIN_STATE_STOPPED;
......@@ -507,14 +501,13 @@ void emu10k1_seq_midi_close(int dev)
struct emu10k1_card *card;
DPF(2, "emu10k1_seq_midi_close()\n");
if( midi_devs[dev] == NULL
|| midi_devs[dev]->devc == NULL)
if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
return;
card = midi_devs[dev]->devc;
emu10k1_mpuout_close(card);
if(card->seq_mididev) {
if (card->seq_mididev) {
kfree(card->seq_mididev);
card->seq_mididev = 0;
}
......@@ -522,13 +515,11 @@ void emu10k1_seq_midi_close(int dev)
int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
{
struct emu10k1_card *card;
struct midi_hdr *midihdr;
unsigned long flags;
if( midi_devs[dev] == NULL
|| midi_devs[dev]->devc == NULL)
if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
return -EINVAL;
card = midi_devs[dev]->devc;
......@@ -583,8 +574,7 @@ int emu10k1_seq_midi_buffer_status(int dev)
struct midi_queue *queue;
struct emu10k1_card *card;
if( midi_devs[dev] == NULL
|| midi_devs[dev]->devc == NULL)
if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
return -EINVAL;
count = 0;
......@@ -592,12 +582,14 @@ int emu10k1_seq_midi_buffer_status(int dev)
card = midi_devs[dev]->devc;
queue = card->mpuout->firstmidiq;
while(queue != NULL) {
while (queue != NULL) {
count++;
if(queue == card->mpuout->lastmidiq)
if (queue == card->mpuout->lastmidiq)
break;
queue = queue->next;
}
return count;
}
......
This diff is collapsed.
......@@ -47,7 +47,6 @@
#include "irqmgr.h"
#include "audio.h"
#include "8010.h"
#include "passthrough.h"
static void pt_putsamples(struct pt_data *pt, u16 *ptr, u16 left, u16 right)
{
......@@ -209,9 +208,7 @@ void emu10k1_pt_stop(struct emu10k1_card *card)
{
struct pt_data *pt = &card->pt;
int i;
unsigned long flags;
spin_lock_irqsave(&card->pt.lock, flags);
if (pt->state != PT_STATE_INACTIVE) {
DPF(2, "digital pass-through stopped\n");
sblive_writeptr(card, GPR_BASE + pt->enable_gpr, 0, 0);
......@@ -222,7 +219,6 @@ void emu10k1_pt_stop(struct emu10k1_card *card)
pt->state = PT_STATE_INACTIVE;
kfree(pt->buf);
}
spin_unlock_irqrestore(&card->pt.lock, flags);
}
void emu10k1_pt_waveout_update(struct emu10k1_wavedevice *wave_dev)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3129,4 +3129,5 @@ module_exit (uhci_hcd_cleanup);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment