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:
parent
98caa2e4e9
commit
0d13f401f4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101400
@ -68,6 +68,11 @@
|
|||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/callout.h>
|
#include <sys/callout.h>
|
||||||
#include <sys/syslog.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/if.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
@ -126,25 +131,37 @@ u_int32_t next_sbni_unit;
|
|||||||
static __inline u_char
|
static __inline u_char
|
||||||
sbni_inb(struct sbni_softc *sc, enum sbni_reg reg)
|
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
|
static __inline void
|
||||||
sbni_outb(struct sbni_softc *sc, enum sbni_reg reg, u_char value)
|
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
|
static __inline void
|
||||||
sbni_insb(struct sbni_softc *sc, u_char *to, u_int len)
|
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
|
static __inline void
|
||||||
sbni_outsb(struct sbni_softc *sc, u_char *from, u_int len)
|
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)
|
* generate Ethernet address (0x00ff01xxxxxx)
|
||||||
*/
|
*/
|
||||||
*(u_int16_t*)sc->arpcom.ac_enaddr = htons(0x00ff);
|
*(u_int16_t *) sc->arpcom.ac_enaddr = htons(0x00ff);
|
||||||
if (flags.mac_addr)
|
if (flags.mac_addr) {
|
||||||
*(u_int32_t*)(sc->arpcom.ac_enaddr+2) =
|
*(u_int32_t *) (sc->arpcom.ac_enaddr + 2) =
|
||||||
htonl(flags.mac_addr | 0x01000000);
|
htonl(flags.mac_addr | 0x01000000);
|
||||||
else {
|
} else {
|
||||||
/* reading timer value */
|
*(u_char *) (sc->arpcom.ac_enaddr + 2) = 0x01;
|
||||||
outb(0x43, 0);
|
read_random(sc->arpcom.ac_enaddr + 3, 3);
|
||||||
insb(0x40, sc->arpcom.ac_enaddr + 3, 4);
|
|
||||||
*(u_char*)(sc->arpcom.ac_enaddr + 2) = 0x01;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SBNI_DUAL_COMPOUND
|
#ifdef SBNI_DUAL_COMPOUND
|
||||||
|
|
||||||
#ifndef offsetof
|
|
||||||
#define offsetof(type, member) ((u_int32_t)(&((type *)0)->member))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct sbni_softc *
|
struct sbni_softc *
|
||||||
connect_to_master(struct sbni_softc *sc)
|
connect_to_master(struct sbni_softc *sc)
|
||||||
{
|
{
|
||||||
struct sbni_softc *p;
|
struct sbni_softc *p, *p_prev;
|
||||||
|
|
||||||
p = (struct sbni_softc *)(((char *)&sbni_headlist)
|
for (p = sbni_headlist, p_prev = NULL; p; p_prev = p, p = p->link) {
|
||||||
- offsetof(struct sbni_softc, 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) {
|
||||||
for (; p->link; p = p->link) {
|
p->slave_sc = sc;
|
||||||
if (p->link->irq == sc->irq
|
if (p_prev)
|
||||||
&& (p->link->base_addr == sc->base_addr + 4
|
p_prev->link = p->link;
|
||||||
|| p->link->base_addr == sc->base_addr - 4)) {
|
else
|
||||||
|
sbni_headlist = p->link;
|
||||||
struct sbni_softc *t = p->link;
|
return p;
|
||||||
t->slave_sc = sc;
|
|
||||||
p->link = p->link->link;
|
|
||||||
return (t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1045,7 +1052,6 @@ sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
|||||||
struct sbni_softc *sc;
|
struct sbni_softc *sc;
|
||||||
struct ifreq *ifr;
|
struct ifreq *ifr;
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
struct proc *p;
|
|
||||||
struct sbni_in_stats *in_stats;
|
struct sbni_in_stats *in_stats;
|
||||||
struct sbni_flags flags;
|
struct sbni_flags flags;
|
||||||
int error, s;
|
int error, s;
|
||||||
@ -1053,7 +1059,6 @@ sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
|||||||
sc = ifp->if_softc;
|
sc = ifp->if_softc;
|
||||||
ifr = (struct ifreq *)data;
|
ifr = (struct ifreq *)data;
|
||||||
td = curthread;
|
td = curthread;
|
||||||
p = td->td_proc;
|
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
s = splimp();
|
s = splimp();
|
||||||
|
@ -93,7 +93,6 @@ sbni_probe_isa(device_t dev)
|
|||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
sc->base_addr = rman_get_start(sc->io_res);
|
|
||||||
if (sbni_probe(sc) != 0) {
|
if (sbni_probe(sc) != 0) {
|
||||||
bus_release_resource(dev, SYS_RES_IOPORT,
|
bus_release_resource(dev, SYS_RES_IOPORT,
|
||||||
sc->io_rid, sc->io_res);
|
sc->io_rid, sc->io_res);
|
||||||
@ -115,7 +114,7 @@ sbni_attach_isa(device_t dev)
|
|||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
|
|
||||||
printf("sbni%d: <Granch SBNI12/ISA adapter> port 0x%x",
|
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(
|
sc->irq_res = bus_alloc_resource(
|
||||||
dev, SYS_RES_IRQ, &sc->irq_rid, 0ul, ~0ul, 1, RF_ACTIVE);
|
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);
|
printf("sbni%d: bus_setup_intr\n", next_sbni_unit);
|
||||||
bus_release_resource(
|
bus_release_resource(
|
||||||
dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res);
|
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);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,10 +87,9 @@ sbni_pci_probe(device_t dev)
|
|||||||
if (pci_get_subdevice(dev) == 2) {
|
if (pci_get_subdevice(dev) == 2) {
|
||||||
ports <<= 1;
|
ports <<= 1;
|
||||||
sc->slave_sc = malloc(sizeof(struct sbni_softc),
|
sc->slave_sc = malloc(sizeof(struct sbni_softc),
|
||||||
M_DEVBUF, M_NOWAIT);
|
M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||||
if (!sc->slave_sc)
|
if (!sc->slave_sc)
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
bzero(sc->slave_sc, sizeof(struct sbni_softc));
|
|
||||||
device_set_desc(dev, "Granch SBNI12/PCI Dual adapter");
|
device_set_desc(dev, "Granch SBNI12/PCI Dual adapter");
|
||||||
} else
|
} else
|
||||||
device_set_desc(dev, "Granch SBNI12/PCI adapter");
|
device_set_desc(dev, "Granch SBNI12/PCI adapter");
|
||||||
@ -105,9 +104,10 @@ sbni_pci_probe(device_t dev)
|
|||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
sc->base_addr = rman_get_start(sc->io_res);
|
if (sc->slave_sc) {
|
||||||
if (sc->slave_sc)
|
sc->slave_sc->io_res = sc->io_res;
|
||||||
sc->slave_sc->base_addr = sc->base_addr + 4;
|
sc->slave_sc->io_off = 4;
|
||||||
|
}
|
||||||
if (sbni_probe(sc) != 0) {
|
if (sbni_probe(sc) != 0) {
|
||||||
bus_release_resource(dev, SYS_RES_IOPORT,
|
bus_release_resource(dev, SYS_RES_IOPORT,
|
||||||
sc->io_rid, sc->io_res);
|
sc->io_rid, sc->io_res);
|
||||||
@ -130,7 +130,8 @@ sbni_pci_attach(device_t dev)
|
|||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
|
|
||||||
printf("sbni%d: <Granch SBNI12/PCI%sadapter> port 0x%x",
|
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,
|
sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
|
||||||
0ul, ~0ul, 1, RF_SHAREABLE);
|
0ul, ~0ul, 1, RF_SHAREABLE);
|
||||||
|
|
||||||
@ -157,6 +158,10 @@ sbni_pci_attach(device_t dev)
|
|||||||
|
|
||||||
attach_failed:
|
attach_failed:
|
||||||
bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res);
|
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)
|
if (sc->slave_sc)
|
||||||
free(sc->slave_sc, M_DEVBUF);
|
free(sc->slave_sc, M_DEVBUF);
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -69,11 +69,11 @@ struct sbni_flags {
|
|||||||
struct sbni_softc {
|
struct sbni_softc {
|
||||||
struct arpcom arpcom; /* ethernet common */
|
struct arpcom arpcom; /* ethernet common */
|
||||||
|
|
||||||
int base_addr;
|
|
||||||
int irq;
|
|
||||||
int io_rid;
|
int io_rid;
|
||||||
int irq_rid;
|
|
||||||
struct resource *io_res;
|
struct resource *io_res;
|
||||||
|
int io_off;
|
||||||
|
|
||||||
|
int irq_rid;
|
||||||
struct resource *irq_res;
|
struct resource *irq_res;
|
||||||
void *irq_handle;
|
void *irq_handle;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user