version 1.8, 2000/06/05 07:59:52 |
version 1.9, 2000/06/07 10:09:19 |
Line 224 asc_ioasic_setup(sc, addr, len, ispullup |
|
Line 224 asc_ioasic_setup(sc, addr, len, ispullup |
|
u_int32_t ssr, scr, *p; |
u_int32_t ssr, scr, *p; |
size_t size; |
size_t size; |
vaddr_t cp; |
vaddr_t cp; |
paddr_t ptr0, ptr1; |
|
|
|
NCR_DMA(("%s: start %d@%p,%s\n", sc->sc_dev.dv_xname, |
NCR_DMA(("%s: start %d@%p,%s\n", sc->sc_dev.dv_xname, |
*asc->sc_dmalen, *asc->sc_dmaaddr, ispullup ? "IN" : "OUT")); |
*asc->sc_dmalen, *asc->sc_dmaaddr, ispullup ? "IN" : "OUT")); |
|
|
/* upto two 4KB pages */ |
/* upto two 4KB pages */ |
size = min(*dmasize, TWOPAGE((size_t)*addr)); |
size = min(*dmasize, TWOPAGE((size_t)*addr)); |
asc->sc_dmaaddr = addr; |
asc->sc_dmaaddr = addr; |
asc->sc_dmalen = len; |
asc->sc_dmalen = len; |
asc->sc_dmasize = size; |
asc->sc_dmasize = size; |
asc->sc_flags = (ispullup) ? ASC_ISPULLUP : 0; |
asc->sc_flags = (ispullup) ? ASC_ISPULLUP : 0; |
*dmasize = size; /* return trimmed transfer size */ |
*dmasize = size; /* return trimmed transfer size */ |
|
|
/* stop DMA engine first */ |
/* stop DMA engine first */ |
ssr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR); |
ssr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR); |
Line 248 asc_ioasic_setup(sc, addr, len, ispullup |
|
Line 247 asc_ioasic_setup(sc, addr, len, ispullup |
|
NULL /* kernel address */, BUS_DMA_NOWAIT)) |
NULL /* kernel address */, BUS_DMA_NOWAIT)) |
panic("%s: cannot allocate DMA address", sc->sc_dev.dv_xname); |
panic("%s: cannot allocate DMA address", sc->sc_dev.dv_xname); |
|
|
/* take care of 8B constraint on starting address */ |
/* take care of 8B constraint on starting address */ |
cp = (vaddr_t)*addr; |
cp = (vaddr_t)*addr; |
if ((cp & 7) == 0) { |
if ((cp & 7) == 0) { |
/* comfortably aligned to 8B boundary */ |
/* comfortably aligned to 8B boundary */ |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_SCR, 0); |
scr = 0; |
} |
} |
else { |
else { |
/* truncate to the boundary */ |
/* truncate to the boundary */ |
p = (u_int32_t *)(cp & ~7); |
p = (u_int32_t *)(cp & ~7); |
/* how many 16bit quantities in subject */ |
/* how many 16bit quantities in subject */ |
scr = (cp >> 1) & 3; |
scr = (cp & 7) >> 1; |
/* trim down physical address too */ |
/* trim down physical address too */ |
asc->sc_dmamap->dm_segs[0].ds_addr &= ~7; |
asc->sc_dmamap->dm_segs[0].ds_addr &= ~7; |
if ((asc->sc_flags & ASC_ISPULLUP) == 0) { |
asc->sc_dmamap->dm_segs[0].ds_len += (cp & 6); |
|
if ((asc->sc_flags & ASC_ISPULLUP) == 0) { |
/* push down to SCSI device */ |
/* push down to SCSI device */ |
scr |= 4; |
scr |= 4; |
/* round up physical address in this case */ |
/* round up physical address in this case */ |
asc->sc_dmamap->dm_segs[0].ds_addr += 8; |
asc->sc_dmamap->dm_segs[0].ds_addr += 8; |
} |
/* don't care excess cache flush */ |
/* pack fixup data in SDR0/SDR1 pair and instruct SCR */ |
} |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
/* pack fixup data in SDR0/SDR1 pair and instruct SCR */ |
IOASIC_SCSI_SDR0, p[0]); |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
IOASIC_SCSI_SDR0, p[0]); |
IOASIC_SCSI_SDR1, p[1]); |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
IOASIC_SCSI_SDR1, p[1]); |
IOASIC_SCSI_SCR, scr); |
} |
} |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
ptr0 = asc->sc_dmamap->dm_segs[0].ds_addr; |
IOASIC_SCSI_DMAPTR, |
ptr1 = (asc->sc_dmamap->dm_nsegs > 1) |
IOASIC_DMA_ADDR(asc->sc_dmamap->dm_segs[0].ds_addr)); |
? asc->sc_dmamap->dm_segs[1].ds_addr : ~0; |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
IOASIC_SCSI_NEXTPTR, |
IOASIC_SCSI_DMAPTR, |
(asc->sc_dmamap->dm_nsegs == 1) |
IOASIC_DMA_ADDR(ptr0)); |
? ~0 : IOASIC_DMA_ADDR(asc->sc_dmamap->dm_segs[1].ds_addr)); |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, |
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_SCR, scr); |
IOASIC_SCSI_NEXTPTR, |
|
IOASIC_DMA_ADDR(ptr1)); |
|
|
|
/* synchronize dmamap contents with memory image */ |
/* synchronize dmamap contents with memory image */ |
bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap, |
bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap, |
0, size, |
0, size, |
(ispullup) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); |
(ispullup) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); |
|
|
asc->sc_flags |= ASC_MAPLOADED; |
asc->sc_flags |= ASC_MAPLOADED; |
return 0; |
return 0; |
Line 315 asc_ioasic_go(sc) |
|
Line 313 asc_ioasic_go(sc) |
|
asc->sc_flags |= ASC_DMAACTIVE; |
asc->sc_flags |= ASC_DMAACTIVE; |
} |
} |
|
|
#define SCRDEBUG(x) |
|
|
|
static int |
static int |
asc_ioasic_intr(sc) |
asc_ioasic_intr(sc) |
struct ncr53c9x_softc *sc; |
struct ncr53c9x_softc *sc; |
Line 385 asc_ioasic_intr(sc) |
|
Line 381 asc_ioasic_intr(sc) |
|
|
|
scr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_SCR); |
scr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_SCR); |
if ((asc->sc_flags & ASC_ISPULLUP) && scr != 0) { |
if ((asc->sc_flags & ASC_ISPULLUP) && scr != 0) { |
u_int32_t ptr; |
u_int32_t sdr[2], ptr; |
u_int16_t *p; |
|
union { |
sdr[0] = bus_space_read_4(asc->sc_bst, asc->sc_bsh, |
u_int32_t sdr[2]; |
|
u_int16_t half[4]; |
|
} scratch; |
|
scratch.sdr[0] = bus_space_read_4(asc->sc_bst, asc->sc_bsh, |
|
IOASIC_SCSI_SDR0); |
IOASIC_SCSI_SDR0); |
scratch.sdr[1] = bus_space_read_4(asc->sc_bst, asc->sc_bsh, |
sdr[1] = bus_space_read_4(asc->sc_bst, asc->sc_bsh, |
IOASIC_SCSI_SDR1); |
IOASIC_SCSI_SDR1); |
ptr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, |
ptr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, |
IOASIC_SCSI_DMAPTR); |
IOASIC_SCSI_DMAPTR); |
ptr = (ptr >> 3) & 0x1ffffffc; |
ptr = (ptr >> 3) & 0x1ffffffc; |
SCRDEBUG(("SCSI_SCR -> %x, DMAPTR: %p\n", scr, (void *)ptr)); |
|
p = (u_int16_t *)MIPS_PHYS_TO_KSEG0(ptr); |
|
/* |
/* |
* scr |
* scr: 1 -> short[0] |
* 1 -> half[0] |
* 2 -> short[0] + short[1] |
* 2 -> half[0] + half[1] |
* 3 -> short[0] + short[1] + short[2] |
* 3 -> half[0] + half[1] + half[2] |
|
*/ |
*/ |
scr &= IOASIC_SCR_WORD; |
scr &= IOASIC_SCR_WORD; |
p[0] = scratch.half[0]; |
memcpy((void *)MIPS_PHYS_TO_KSEG0(ptr), sdr, scr << 1); |
if (scr > 1) |
|
p[1] = scratch.half[1]; |
|
if (scr > 2) |
|
p[2] = scratch.half[2]; |
|
} |
} |
|
|
bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap); |
bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap); |