Make the fxp driver work on alpha, rather than panic the machine on boot

and/or when using the card.

o Convert the driver to using bus_space.  This allows alphas with
fxp's to boot, rather than panic'ing because rman_get_virtual()
doesn't really return a virtual address on alphas.

o Fix an alpha unaligned access error caused by some misfeature of
gcc/egcs: if link_addr & rbd_addr in the fxp_rfa struct are 32 bit
quantities, egcs will assume they are naturally aligned. So it will do
a ldl & some shifty/masky to twiddle 16 bit values in fxp_lwcopy().
However, if they are 16-bit aligned, the ldl will actually be done on
a 16-bit aligned value & we will panic with an unaligned access
error... Changing their definition to an array of chars seems to fix
this.  I obtained this from NetBSD.

I've tested this on both i386 & alpha.
This commit is contained in:
Andrew Gallatin 1999-09-30 19:03:12 +00:00
parent 394b3be19e
commit 4fc1dda91d
6 changed files with 38 additions and 60 deletions

View File

@ -76,11 +76,6 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
#ifdef __alpha__ /* XXX */
/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
#endif /* __alpha__ */
#else /* __FreeBSD__ */
@ -104,6 +99,13 @@
#endif /* __NetBSD__ */
#ifdef __alpha__ /* XXX */
/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
#endif /* __alpha__ */
#include "opt_bdg.h"
#ifdef BRIDGE
#include <net/if_types.h>
@ -541,7 +543,9 @@ fxp_attach(device_t dev)
error = ENXIO;
goto fail;
}
sc->csr = rman_get_virtual(sc->mem); /* XXX use bus_space */
sc->sc_st = rman_get_bustag(sc->mem);
sc->sc_sh = rman_get_bushandle(sc->mem);
/*
* Allocate our interrupt.
@ -1704,20 +1708,21 @@ fxp_add_rfabuf(sc, oldm)
*/
rfa = mtod(m, struct fxp_rfa *);
m->m_data += sizeof(struct fxp_rfa);
rfa->size = MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE;
rfa->size = (u_int16_t)(MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE);
/*
* Initialize the rest of the RFA. Note that since the RFA
* is misaligned, we cannot store values directly. Instead,
* we use an optimized, inline copy.
*/
rfa->rfa_status = 0;
rfa->rfa_control = FXP_RFA_CONTROL_EL;
rfa->actual_size = 0;
v = -1;
fxp_lwcopy(&v, &rfa->link_addr);
fxp_lwcopy(&v, &rfa->rbd_addr);
fxp_lwcopy(&v, (volatile u_int32_t *) rfa->link_addr);
fxp_lwcopy(&v, (volatile u_int32_t *) rfa->rbd_addr);
/*
* If there are other buffers already on the list, attach this
@ -1728,7 +1733,7 @@ fxp_add_rfabuf(sc, oldm)
RFA_ALIGNMENT_FUDGE);
sc->rfa_tailm->m_next = m;
v = vtophys(rfa);
fxp_lwcopy(&v, &p_rfa->link_addr);
fxp_lwcopy(&v, (volatile u_int32_t *) p_rfa->link_addr);
p_rfa->rfa_control &= ~FXP_RFA_CONTROL_EL;
} else {
sc->rfa_headm = m;

View File

@ -245,8 +245,8 @@ struct fxp_cb_tx {
struct fxp_rfa {
volatile u_int16_t rfa_status;
volatile u_int16_t rfa_control;
volatile u_int32_t link_addr;
volatile u_int32_t rbd_addr;
volatile u_int8_t link_addr[4];
volatile u_int8_t rbd_addr[4];
volatile u_int16_t actual_size;
volatile u_int16_t size;
};

View File

@ -42,16 +42,15 @@ struct fxp_softc {
#if defined(__NetBSD__)
struct device sc_dev; /* generic device structures */
void *sc_ih; /* interrupt handler cookie */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
struct ethercom sc_ethercom; /* ethernet common part */
#else
struct arpcom arpcom; /* per-interface network data */
caddr_t csr; /* control/status registers */
struct resource *mem; /* resource descriptor for registers */
struct resource *irq; /* resource descriptor for interrupt */
void *ih; /* interrupt handler cookie */
#endif /* __NetBSD__ */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
struct mbuf *rfa_headm; /* first mbuf in receive frame area */
struct mbuf *rfa_tailm; /* last mbuf in receive frame area */
struct fxp_cb_tx *cbl_first; /* first active TxCB in list */
@ -71,7 +70,6 @@ struct fxp_softc {
};
/* Macros to ease CSR access. */
#if defined(__NetBSD__)
#define CSR_READ_1(sc, reg) \
bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
#define CSR_READ_2(sc, reg) \
@ -84,20 +82,6 @@ struct fxp_softc {
bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
#define CSR_WRITE_4(sc, reg, val) \
bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
#else
#define CSR_READ_1(sc, reg) \
(*((u_int8_t *)((sc)->csr + (reg))))
#define CSR_READ_2(sc, reg) \
(*((u_int16_t *)((sc)->csr + (reg))))
#define CSR_READ_4(sc, reg) \
(*((u_int32_t *)((sc)->csr + (reg))))
#define CSR_WRITE_1(sc, reg, val) \
(*((u_int8_t *)((sc)->csr + (reg)))) = (val)
#define CSR_WRITE_2(sc, reg, val) \
(*((u_int16_t *)((sc)->csr + (reg)))) = (val)
#define CSR_WRITE_4(sc, reg, val) \
(*((u_int32_t *)((sc)->csr + (reg)))) = (val)
#endif /* __NetBSD__ */
/* Deal with slight differences in software interfaces. */
#if defined(__NetBSD__)

View File

@ -76,11 +76,6 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
#ifdef __alpha__ /* XXX */
/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
#endif /* __alpha__ */
#else /* __FreeBSD__ */
@ -104,6 +99,13 @@
#endif /* __NetBSD__ */
#ifdef __alpha__ /* XXX */
/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
#endif /* __alpha__ */
#include "opt_bdg.h"
#ifdef BRIDGE
#include <net/if_types.h>
@ -541,7 +543,9 @@ fxp_attach(device_t dev)
error = ENXIO;
goto fail;
}
sc->csr = rman_get_virtual(sc->mem); /* XXX use bus_space */
sc->sc_st = rman_get_bustag(sc->mem);
sc->sc_sh = rman_get_bushandle(sc->mem);
/*
* Allocate our interrupt.
@ -1704,20 +1708,21 @@ fxp_add_rfabuf(sc, oldm)
*/
rfa = mtod(m, struct fxp_rfa *);
m->m_data += sizeof(struct fxp_rfa);
rfa->size = MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE;
rfa->size = (u_int16_t)(MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE);
/*
* Initialize the rest of the RFA. Note that since the RFA
* is misaligned, we cannot store values directly. Instead,
* we use an optimized, inline copy.
*/
rfa->rfa_status = 0;
rfa->rfa_control = FXP_RFA_CONTROL_EL;
rfa->actual_size = 0;
v = -1;
fxp_lwcopy(&v, &rfa->link_addr);
fxp_lwcopy(&v, &rfa->rbd_addr);
fxp_lwcopy(&v, (volatile u_int32_t *) rfa->link_addr);
fxp_lwcopy(&v, (volatile u_int32_t *) rfa->rbd_addr);
/*
* If there are other buffers already on the list, attach this
@ -1728,7 +1733,7 @@ fxp_add_rfabuf(sc, oldm)
RFA_ALIGNMENT_FUDGE);
sc->rfa_tailm->m_next = m;
v = vtophys(rfa);
fxp_lwcopy(&v, &p_rfa->link_addr);
fxp_lwcopy(&v, (volatile u_int32_t *) p_rfa->link_addr);
p_rfa->rfa_control &= ~FXP_RFA_CONTROL_EL;
} else {
sc->rfa_headm = m;

View File

@ -245,8 +245,8 @@ struct fxp_cb_tx {
struct fxp_rfa {
volatile u_int16_t rfa_status;
volatile u_int16_t rfa_control;
volatile u_int32_t link_addr;
volatile u_int32_t rbd_addr;
volatile u_int8_t link_addr[4];
volatile u_int8_t rbd_addr[4];
volatile u_int16_t actual_size;
volatile u_int16_t size;
};

View File

@ -42,16 +42,15 @@ struct fxp_softc {
#if defined(__NetBSD__)
struct device sc_dev; /* generic device structures */
void *sc_ih; /* interrupt handler cookie */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
struct ethercom sc_ethercom; /* ethernet common part */
#else
struct arpcom arpcom; /* per-interface network data */
caddr_t csr; /* control/status registers */
struct resource *mem; /* resource descriptor for registers */
struct resource *irq; /* resource descriptor for interrupt */
void *ih; /* interrupt handler cookie */
#endif /* __NetBSD__ */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
struct mbuf *rfa_headm; /* first mbuf in receive frame area */
struct mbuf *rfa_tailm; /* last mbuf in receive frame area */
struct fxp_cb_tx *cbl_first; /* first active TxCB in list */
@ -71,7 +70,6 @@ struct fxp_softc {
};
/* Macros to ease CSR access. */
#if defined(__NetBSD__)
#define CSR_READ_1(sc, reg) \
bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
#define CSR_READ_2(sc, reg) \
@ -84,20 +82,6 @@ struct fxp_softc {
bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
#define CSR_WRITE_4(sc, reg, val) \
bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
#else
#define CSR_READ_1(sc, reg) \
(*((u_int8_t *)((sc)->csr + (reg))))
#define CSR_READ_2(sc, reg) \
(*((u_int16_t *)((sc)->csr + (reg))))
#define CSR_READ_4(sc, reg) \
(*((u_int32_t *)((sc)->csr + (reg))))
#define CSR_WRITE_1(sc, reg, val) \
(*((u_int8_t *)((sc)->csr + (reg)))) = (val)
#define CSR_WRITE_2(sc, reg, val) \
(*((u_int16_t *)((sc)->csr + (reg)))) = (val)
#define CSR_WRITE_4(sc, reg, val) \
(*((u_int32_t *)((sc)->csr + (reg)))) = (val)
#endif /* __NetBSD__ */
/* Deal with slight differences in software interfaces. */
#if defined(__NetBSD__)