Make driver portable:

- bus_space'ify
- generate fake ethernet address using read_random() instead of reading
from timer i/o ports

Other minor fixes:
- remove "hack" in connect_to_master()
- use M_ZERO
- remove unused variable in sbni_ioctl()
- properly release irq in sbni_attach_isa() on attach errors
This commit is contained in:
fjoe 2002-08-05 18:14:16 +00:00
parent fb0fc73e34
commit 78e0d7d6d4
4 changed files with 55 additions and 44 deletions

View File

@ -68,6 +68,11 @@
#include <sys/proc.h>
#include <sys/callout.h>
#include <sys/syslog.h>
#include <sys/random.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <net/if.h>
#include <net/ethernet.h>
@ -126,25 +131,37 @@ u_int32_t next_sbni_unit;
static __inline u_char
sbni_inb(struct sbni_softc *sc, enum sbni_reg reg)
{
return (inb(sc->base_addr + reg));
return bus_space_read_1(
rman_get_bustag(sc->io_res),
rman_get_bushandle(sc->io_res),
sc->io_off + reg);
}
static __inline void
sbni_outb(struct sbni_softc *sc, enum sbni_reg reg, u_char value)
{
outb(sc->base_addr + reg, value);
bus_space_write_1(
rman_get_bustag(sc->io_res),
rman_get_bushandle(sc->io_res),
sc->io_off + reg, value);
}
static __inline void
sbni_insb(struct sbni_softc *sc, u_char *to, u_int len)
{
insb(sc->base_addr + DAT, to, len);
bus_space_read_multi_1(
rman_get_bustag(sc->io_res),
rman_get_bushandle(sc->io_res),
sc->io_off + DAT, to, len);
}
static __inline void
sbni_outsb(struct sbni_softc *sc, u_char *from, u_int len)
{
outsb(sc->base_addr + DAT, from, len);
bus_space_write_multi_1(
rman_get_bustag(sc->io_res),
rman_get_bushandle(sc->io_res),
sc->io_off + DAT, from, len);
}
@ -947,43 +964,33 @@ set_initial_values(struct sbni_softc *sc, struct sbni_flags flags)
/*
* generate Ethernet address (0x00ff01xxxxxx)
*/
*(u_int16_t*)sc->arpcom.ac_enaddr = htons(0x00ff);
if (flags.mac_addr)
*(u_int32_t*)(sc->arpcom.ac_enaddr+2) =
htonl(flags.mac_addr | 0x01000000);
else {
/* reading timer value */
outb(0x43, 0);
insb(0x40, sc->arpcom.ac_enaddr + 3, 4);
*(u_char*)(sc->arpcom.ac_enaddr + 2) = 0x01;
*(u_int16_t *) sc->arpcom.ac_enaddr = htons(0x00ff);
if (flags.mac_addr) {
*(u_int32_t *) (sc->arpcom.ac_enaddr + 2) =
htonl(flags.mac_addr | 0x01000000);
} else {
*(u_char *) (sc->arpcom.ac_enaddr + 2) = 0x01;
read_random(sc->arpcom.ac_enaddr + 3, 3);
}
}
#ifdef SBNI_DUAL_COMPOUND
#ifndef offsetof
#define offsetof(type, member) ((u_int32_t)(&((type *)0)->member))
#endif
struct sbni_softc *
connect_to_master(struct sbni_softc *sc)
{
struct sbni_softc *p;
struct sbni_softc *p, *p_prev;
p = (struct sbni_softc *)(((char *)&sbni_headlist)
- offsetof(struct sbni_softc, link));
for (; p->link; p = p->link) {
if (p->link->irq == sc->irq
&& (p->link->base_addr == sc->base_addr + 4
|| p->link->base_addr == sc->base_addr - 4)) {
struct sbni_softc *t = p->link;
t->slave_sc = sc;
p->link = p->link->link;
return (t);
for (p = sbni_headlist, p_prev = NULL; p; p_prev = p, p = p->link) {
if (rman_get_start(p->io_res) == rman_get_start(sc->io_res) + 4 ||
rman_get_start(p->io_res) == rman_get_start(sc->io_res) - 4) {
p->slave_sc = sc;
if (p_prev)
p_prev->link = p->link;
else
sbni_headlist = p->link;
return p;
}
}
@ -1045,7 +1052,6 @@ sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
struct sbni_softc *sc;
struct ifreq *ifr;
struct thread *td;
struct proc *p;
struct sbni_in_stats *in_stats;
struct sbni_flags flags;
int error, s;
@ -1053,7 +1059,6 @@ sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
sc = ifp->if_softc;
ifr = (struct ifreq *)data;
td = curthread;
p = td->td_proc;
error = 0;
s = splimp();

View File

@ -93,7 +93,6 @@ sbni_probe_isa(device_t dev)
return (ENOENT);
}
sc->base_addr = rman_get_start(sc->io_res);
if (sbni_probe(sc) != 0) {
bus_release_resource(dev, SYS_RES_IOPORT,
sc->io_rid, sc->io_res);
@ -115,7 +114,7 @@ sbni_attach_isa(device_t dev)
sc = device_get_softc(dev);
printf("sbni%d: <Granch SBNI12/ISA adapter> port 0x%x",
next_sbni_unit, sc->base_addr);
next_sbni_unit, rman_get_start(sc->io_res));
sc->irq_res = bus_alloc_resource(
dev, SYS_RES_IRQ, &sc->irq_rid, 0ul, ~0ul, 1, RF_ACTIVE);
@ -128,6 +127,8 @@ sbni_attach_isa(device_t dev)
printf("sbni%d: bus_setup_intr\n", next_sbni_unit);
bus_release_resource(
dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res);
bus_release_resource(
dev, SYS_RES_IRQ, sc->irq_rid, sc->irq_res);
return (error);
}

View File

@ -87,10 +87,9 @@ sbni_pci_probe(device_t dev)
if (pci_get_subdevice(dev) == 2) {
ports <<= 1;
sc->slave_sc = malloc(sizeof(struct sbni_softc),
M_DEVBUF, M_NOWAIT);
M_DEVBUF, M_NOWAIT | M_ZERO);
if (!sc->slave_sc)
return (ENOMEM);
bzero(sc->slave_sc, sizeof(struct sbni_softc));
device_set_desc(dev, "Granch SBNI12/PCI Dual adapter");
} else
device_set_desc(dev, "Granch SBNI12/PCI adapter");
@ -105,9 +104,10 @@ sbni_pci_probe(device_t dev)
return (ENOENT);
}
sc->base_addr = rman_get_start(sc->io_res);
if (sc->slave_sc)
sc->slave_sc->base_addr = sc->base_addr + 4;
if (sc->slave_sc) {
sc->slave_sc->io_res = sc->io_res;
sc->slave_sc->io_off = 4;
}
if (sbni_probe(sc) != 0) {
bus_release_resource(dev, SYS_RES_IOPORT,
sc->io_rid, sc->io_res);
@ -130,7 +130,8 @@ sbni_pci_attach(device_t dev)
sc = device_get_softc(dev);
printf("sbni%d: <Granch SBNI12/PCI%sadapter> port 0x%x",
next_sbni_unit, sc->slave_sc ? " Dual " : " ", sc->base_addr);
next_sbni_unit, sc->slave_sc ? " Dual " : " ",
rman_get_start(sc->io_res));
sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
0ul, ~0ul, 1, RF_SHAREABLE);
@ -157,6 +158,10 @@ sbni_pci_attach(device_t dev)
attach_failed:
bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res);
if (sc->irq_res) {
bus_release_resource(
dev, SYS_RES_IRQ, sc->irq_rid, sc->irq_res);
}
if (sc->slave_sc)
free(sc->slave_sc, M_DEVBUF);
return (error);

View File

@ -69,11 +69,11 @@ struct sbni_flags {
struct sbni_softc {
struct arpcom arpcom; /* ethernet common */
int base_addr;
int irq;
int io_rid;
int irq_rid;
struct resource *io_res;
int io_off;
int irq_rid;
struct resource *irq_res;
void *irq_handle;