Add support for Farallon EtherMAC PC Card.

Move ethernet MAC address setting into pccard attachment
Fix panic from IFP2ENADDR() use prior to if_alloc
Remove OLDCARD compat support.  This should work still on oldcard, however.
sn_attach now requires that the resources be activated now, so adjust.

Approved by: re (scottl)
This commit is contained in:
Warner Losh 2005-07-06 15:59:47 +00:00
parent ce44283887
commit dc1206ea0f
4 changed files with 64 additions and 65 deletions

View File

@ -156,11 +156,10 @@ sn_attach(device_t dev)
{
struct sn_softc *sc = device_get_softc(dev);
struct ifnet *ifp;
uint16_t i, w;
uint16_t i;
uint8_t *p;
int rev;
uint16_t address;
int j;
int err;
u_char eaddr[6];
@ -170,29 +169,21 @@ sn_attach(device_t dev)
return (ENOSPC);
}
sc->dev = dev;
sn_activate(dev);
SN_LOCK_INIT(sc);
snstop(sc);
sc->pages_wanted = -1;
SMC_SELECT_BANK(sc, 3);
rev = (CSR_READ_2(sc, REVISION_REG_W) >> 4) & 0xf;
if (chip_ids[rev])
device_printf(dev, " %s ", chip_ids[rev]);
else
device_printf(dev, " unsupported chip");
SMC_SELECT_BANK(sc, 1);
i = CSR_READ_2(sc, CONFIG_REG_W);
printf(i & CR_AUI_SELECT ? "AUI" : "UTP");
if (sc->pccard_enaddr)
for (j = 0; j < 3; j++) {
w = (uint16_t)eaddr[j * 2] |
(((uint16_t)eaddr[j * 2 + 1]) << 8);
CSR_WRITE_2(sc, IAR_ADDR0_REG_W + j * 2, w);
}
if (bootverbose || 1) {
SMC_SELECT_BANK(sc, 3);
rev = (CSR_READ_2(sc, REVISION_REG_W) >> 4) & 0xf;
if (chip_ids[rev])
device_printf(dev, " %s ", chip_ids[rev]);
else
device_printf(dev, " unsupported chip");
SMC_SELECT_BANK(sc, 1);
i = CSR_READ_2(sc, CONFIG_REG_W);
printf("%s\n", i & CR_AUI_SELECT ? "AUI" : "UTP");
}
/*
* Read the station address from the chip. The MAC address is bank 1,
@ -1263,7 +1254,7 @@ sn_deactivate(device_t dev)
}
/*
* Function: sn_probe( device_t dev, int pccard )
* Function: sn_probe( device_t dev)
*
* Purpose:
* Tests to see if a given ioaddr points to an SMC9xxx chip.
@ -1278,7 +1269,7 @@ sn_deactivate(device_t dev)
*
*/
int
sn_probe(device_t dev, int pccard)
sn_probe(device_t dev)
{
struct sn_softc *sc = device_get_softc(dev);
uint16_t bank;
@ -1322,11 +1313,7 @@ sn_probe(device_t dev, int pccard)
CSR_WRITE_2(sc, BANK_SELECT_REG_W, 0x0001);
base_address_register = (CSR_READ_2(sc, BASE_ADDR_REG_W) >> 3) & 0x3e0;
/*
* This test is nonsence on PC-card architecture, so if
* pccard == 1, skip this test. (hosokawa)
*/
if (!pccard && rman_get_start(sc->port_res) != base_address_register) {
if (rman_get_start(sc->port_res) != base_address_register) {
/*
* Well, the base address register didn't match. Must not

View File

@ -45,15 +45,15 @@ __FBSDID("$FreeBSD$");
#include <dev/sn/if_snvar.h>
static int sn_isa_probe (device_t);
static int sn_isa_attach (device_t);
static int sn_isa_probe(device_t);
static int sn_isa_attach(device_t);
static int
sn_isa_probe (device_t dev)
{
if (isa_get_logicalid(dev)) /* skip PnP probes */
return (ENXIO);
if (sn_probe(dev, 0) != 0)
if (sn_probe(dev) != 0)
return (ENXIO);
return (0);
}
@ -62,9 +62,18 @@ static int
sn_isa_attach (device_t dev)
{
struct sn_softc *sc = device_get_softc(dev);
int err;
sc->pccard_enaddr = 0;
return (sn_attach(dev));
sc->dev = dev;
err = sn_activate(dev);
if (err) {
sn_deactivate(dev);
return (err);
}
err = sn_attach(dev);
if (err)
sn_deactivate(dev);
return (err);
}
static device_method_t sn_isa_methods[] = {

View File

@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pccard/pccardvar.h>
#include <dev/pccard/pccard_cis.h>
#include <dev/sn/if_snreg.h>
#include <dev/sn/if_snvar.h>
#include "card_if.h"
@ -55,6 +56,7 @@ __FBSDID("$FreeBSD$");
static const struct pccard_product sn_pccard_products[] = {
PCMCIA_CARD(DSPSI, XJACK),
PCMCIA_CARD(NEWMEDIA, BASICS),
PCMCIA_CARD(SMC, SMC91C96),
#if 0
PCMCIA_CARD(SMC, 8020BT),
#endif
@ -62,7 +64,7 @@ static const struct pccard_product sn_pccard_products[] = {
};
static int
sn_pccard_match(device_t dev)
sn_pccard_probe(device_t dev)
{
const struct pccard_product *pp;
int error;
@ -84,15 +86,6 @@ sn_pccard_match(device_t dev)
return EIO;
}
static int
sn_pccard_probe(device_t dev)
{
int err;
err = sn_probe(dev, 1);
return (err);
}
static int
sn_pccard_ascii_enaddr(const char *str, u_char *enet)
{
@ -128,43 +121,54 @@ static int
sn_pccard_attach(device_t dev)
{
struct sn_softc *sc = device_get_softc(dev);
int i;
u_char sum;
u_char ether_addr[ETHER_ADDR_LEN];
const char *cisstr;
u_char eaddr[ETHER_ADDR_LEN];
int i, err;
uint16_t w;
u_char sum;
sc->pccard_enaddr = 0;
pccard_get_ether(dev, ether_addr);
pccard_get_ether(dev, eaddr);
for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
sum |= ether_addr[i];
sum |= eaddr[i];
if (sum == 0) {
pccard_get_cis3_str(dev, &cisstr);
if (strlen(cisstr) == ETHER_ADDR_LEN * 2)
sum = sn_pccard_ascii_enaddr(cisstr, ether_addr);
if (cisstr && strlen(cisstr) == ETHER_ADDR_LEN * 2)
sum = sn_pccard_ascii_enaddr(cisstr, eaddr);
}
if (sum == 0) {
pccard_get_cis4_str(dev, &cisstr);
if (strlen(cisstr) == ETHER_ADDR_LEN * 2)
sum = sn_pccard_ascii_enaddr(cisstr, ether_addr);
if (cisstr && strlen(cisstr) == ETHER_ADDR_LEN * 2)
sum = sn_pccard_ascii_enaddr(cisstr, eaddr);
}
/* Allocate resources so we can program the ether addr */
sc->dev = dev;
err = sn_activate(dev);
if (err) {
sn_deactivate(dev);
return (err);
}
if (sum) {
sc->pccard_enaddr = 1;
bcopy(ether_addr, IFP2ENADDR(sc->ifp), ETHER_ADDR_LEN);
SMC_SELECT_BANK(sc, 1);
for (i = 0; i < 3; i++) {
w = (uint16_t)eaddr[i * 2] |
(((uint16_t)eaddr[i * 2 + 1]) << 8);
CSR_WRITE_2(sc, IAR_ADDR0_REG_W + i * 2, w);
}
}
return (sn_attach(dev));
err = sn_attach(dev);
if (err)
sn_deactivate(dev);
return (err);
}
static device_method_t sn_pccard_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pccard_compat_probe),
DEVMETHOD(device_attach, pccard_compat_attach),
DEVMETHOD(device_probe, sn_pccard_probe),
DEVMETHOD(device_attach, sn_pccard_attach),
DEVMETHOD(device_detach, sn_detach),
/* Card interface */
DEVMETHOD(card_compat_match, sn_pccard_match),
DEVMETHOD(card_compat_probe, sn_pccard_probe),
DEVMETHOD(card_compat_attach, sn_pccard_attach),
{ 0, 0 }
};

View File

@ -43,10 +43,9 @@ struct sn_softc {
int irq_rid;
struct resource *port_res;
int port_rid;
int pccard_enaddr; /* MAC address in pccard CIS tupple */
};
int sn_probe(device_t, int);
int sn_probe(device_t);
int sn_attach(device_t);
int sn_detach(device_t);
void sn_intr(void *);