version 1.7, 2002/10/02 03:31:59 |
version 1.7.8.3, 2004/09/18 14:30:38 |
|
|
* the hardware information |
* the hardware information |
*/ |
*/ |
|
|
|
#include <sys/cdefs.h> |
|
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/conf.h> |
#include <sys/conf.h> |
|
|
#include <acorn32/podulebus/simidereg.h> |
#include <acorn32/podulebus/simidereg.h> |
|
|
#include <dev/ata/atavar.h> |
#include <dev/ata/atavar.h> |
|
#include <dev/ic/wdcreg.h> |
#include <dev/ic/wdcvar.h> |
#include <dev/ic/wdcvar.h> |
#include <dev/podulebus/podules.h> |
#include <dev/podulebus/podules.h> |
|
|
|
|
|
|
struct simide_softc { |
struct simide_softc { |
struct wdc_softc sc_wdcdev; /* common wdc definitions */ |
struct wdc_softc sc_wdcdev; /* common wdc definitions */ |
struct channel_softc *wdc_chanarray[2]; /* channels definition */ |
struct ata_channel *sc_chanarray[2]; /* channels definition */ |
podule_t *sc_podule; /* Our podule info */ |
podule_t *sc_podule; /* Our podule info */ |
int sc_podule_number; /* Our podule number */ |
int sc_podule_number; /* Our podule number */ |
int sc_ctl_reg; /* Global ctl reg */ |
int sc_ctl_reg; /* Global ctl reg */ |
Line 84 struct simide_softc { |
|
Line 88 struct simide_softc { |
|
bus_space_handle_t sc_ctlioh; /* control handle */ |
bus_space_handle_t sc_ctlioh; /* control handle */ |
struct bus_space sc_tag; /* custom tag */ |
struct bus_space sc_tag; /* custom tag */ |
struct simide_channel { |
struct simide_channel { |
struct channel_softc wdc_channel; /* generic part */ |
struct ata_channel sc_channel; /* generic part */ |
|
struct ata_queue sc_chqueue; /* channel queue */ |
irqhandler_t sc_ih; /* interrupt handler */ |
irqhandler_t sc_ih; /* interrupt handler */ |
int sc_irqmask; /* IRQ mask for this channel */ |
int sc_irqmask; /* IRQ mask for this channel */ |
} simide_channels[2]; |
} simide_channels[2]; |
|
struct wdc_regs sc_wdc_regs[2]; |
}; |
}; |
|
|
int simide_probe __P((struct device *, struct cfdata *, void *)); |
int simide_probe __P((struct device *, struct cfdata *, void *)); |
Line 157 simide_attach(parent, self, aux) |
|
Line 163 simide_attach(parent, self, aux) |
|
struct podule_attach_args *pa = (void *)aux; |
struct podule_attach_args *pa = (void *)aux; |
int status; |
int status; |
u_int iobase; |
u_int iobase; |
int channel; |
int channel, i; |
struct simide_channel *scp; |
struct simide_channel *scp; |
struct channel_softc *cp; |
struct ata_channel *cp; |
|
struct wdc_regs *wdr; |
irqhandler_t *ihp; |
irqhandler_t *ihp; |
|
|
/* Note the podule number and validate */ |
/* Note the podule number and validate */ |
Line 170 simide_attach(parent, self, aux) |
|
Line 177 simide_attach(parent, self, aux) |
|
sc->sc_podule = pa->pa_podule; |
sc->sc_podule = pa->pa_podule; |
podules[sc->sc_podule_number].attached = 1; |
podules[sc->sc_podule_number].attached = 1; |
|
|
|
sc->sc_wdcdev.regs = sc->sc_wdc_regs; |
|
|
/* |
/* |
* Ok we need our own bus tag as the register spacing |
* Ok we need our own bus tag as the register spacing |
* is not the default. |
* is not the default. |
Line 239 simide_attach(parent, self, aux) |
|
Line 248 simide_attach(parent, self, aux) |
|
CONTROL_REGISTER_OFFSET, sc->sc_ctl_reg); |
CONTROL_REGISTER_OFFSET, sc->sc_ctl_reg); |
|
|
/* Fill in wdc and channel infos */ |
/* Fill in wdc and channel infos */ |
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16; |
sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16; |
sc->sc_wdcdev.PIO_cap = 0; |
sc->sc_wdcdev.sc_atac.atac_pio_cap = 0; |
sc->sc_wdcdev.channels = sc->wdc_chanarray; |
sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanarray; |
sc->sc_wdcdev.nchannels = 2; |
sc->sc_wdcdev.sc_atac.atac_nchannels = 2; |
for (channel = 0 ; channel < 2; channel++) { |
for (channel = 0 ; channel < 2; channel++) { |
scp = &sc->simide_channels[channel]; |
scp = &sc->simide_channels[channel]; |
sc->wdc_chanarray[channel] = &scp->wdc_channel; |
sc->sc_chanarray[channel] = &scp->sc_channel; |
cp = &scp->wdc_channel; |
cp = &scp->sc_channel; |
|
wdr = &sc->sc_wdc_regs[channel]; |
cp->channel = channel; |
|
cp->wdc = &sc->sc_wdcdev; |
cp->ch_channel = channel; |
cp->ch_queue = malloc(sizeof(struct channel_queue), |
cp->ch_atac = &sc->sc_wdcdev.sc_atac; |
M_DEVBUF, M_NOWAIT); |
cp->ch_queue = &scp->sc_chqueue; |
if (cp->ch_queue == NULL) { |
wdr->cmd_iot = wdr->ctl_iot = &sc->sc_tag; |
printf("%s %s channel: can't allocate memory for " |
|
"command queue", self->dv_xname, |
|
(channel == 0) ? "primary" : "secondary"); |
|
continue; |
|
} |
|
cp->cmd_iot = cp->ctl_iot = &sc->sc_tag; |
|
iobase = pa->pa_podule->mod_base; |
iobase = pa->pa_podule->mod_base; |
if (bus_space_map(cp->cmd_iot, iobase + |
if (bus_space_map(wdr->cmd_iot, iobase + |
simide_info[channel].drive_registers, |
simide_info[channel].drive_registers, |
DRIVE_REGISTERS_SPACE, 0, &cp->cmd_ioh)) |
DRIVE_REGISTERS_SPACE, 0, &wdr->cmd_baseioh)) |
continue; |
continue; |
if (bus_space_map(cp->ctl_iot, iobase + |
for (i = 0; i < DRIVE_REGISTERS_SPACE; i++) { |
simide_info[channel].aux_register, 4, 0, &cp->ctl_ioh)) { |
if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, |
bus_space_unmap(cp->cmd_iot, cp->cmd_ioh, |
i, i == 0 ? 4 : 1, &wdr->cmd_iohs[i]) != 0) { |
|
bus_space_unmap(wdr->cmd_iot, wdr->cmd_baseioh, |
|
DRIVE_REGISTERS_SPACE); |
|
continue; |
|
} |
|
} |
|
wdc_init_shadow_regs(cp); |
|
if (bus_space_map(wdr->ctl_iot, iobase + |
|
simide_info[channel].aux_register, 4, 0, &wdr->ctl_ioh)) { |
|
bus_space_unmap(wdr->cmd_iot, wdr->cmd_baseioh, |
DRIVE_REGISTERS_SPACE); |
DRIVE_REGISTERS_SPACE); |
continue; |
continue; |
} |
} |
Line 275 simide_attach(parent, self, aux) |
|
Line 287 simide_attach(parent, self, aux) |
|
sc->sc_ctl_reg &= ~scp->sc_irqmask; |
sc->sc_ctl_reg &= ~scp->sc_irqmask; |
bus_space_write_1(sc->sc_ctliot, sc->sc_ctlioh, |
bus_space_write_1(sc->sc_ctliot, sc->sc_ctlioh, |
CONTROL_REGISTER_OFFSET, sc->sc_ctl_reg); |
CONTROL_REGISTER_OFFSET, sc->sc_ctl_reg); |
wdcattach(cp); |
|
ihp = &scp->sc_ih; |
ihp = &scp->sc_ih; |
ihp->ih_func = simide_intr; |
ihp->ih_func = simide_intr; |
ihp->ih_arg = scp; |
ihp->ih_arg = scp; |
Line 290 simide_attach(parent, self, aux) |
|
Line 301 simide_attach(parent, self, aux) |
|
sc->sc_ctl_reg |= scp->sc_irqmask; |
sc->sc_ctl_reg |= scp->sc_irqmask; |
bus_space_write_1(sc->sc_ctliot, sc->sc_ctlioh, |
bus_space_write_1(sc->sc_ctliot, sc->sc_ctlioh, |
CONTROL_REGISTER_OFFSET, sc->sc_ctl_reg); |
CONTROL_REGISTER_OFFSET, sc->sc_ctl_reg); |
|
wdcattach(cp); |
} |
} |
|
|
} |
} |
|
|
/* |
/* |
Line 329 simide_intr(arg) |
|
Line 340 simide_intr(arg) |
|
|
|
/* XXX - not bus space yet - should really be handled by podulebus */ |
/* XXX - not bus space yet - should really be handled by podulebus */ |
if ((*intraddr) & ihp->ih_maskbits) |
if ((*intraddr) & ihp->ih_maskbits) |
wdcintr(&scp->wdc_channel); |
wdcintr(&scp->sc_channel); |
|
|
return(0); |
return(0); |
} |
} |