Add couple hooks, needed primarily for NCR 53C90 MCA card driver:

* add flag to explicitly specify if the DMA should be done as 16bit or 8bit
* add flag to specify the DMA should happen via I/O port
* add new function mca_dma_set_ioport(), to set I/O port to be used for the
  DMA operation

Also clarify copyright (welcome to 2001 :), and couple other minor nits
This commit is contained in:
jdolecek 2001-12-02 17:02:33 +00:00
parent 02b1fff116
commit 492b500611
2 changed files with 61 additions and 27 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: mca_machdep.h,v 1.7 2001/11/23 22:29:16 jdolecek Exp $ */ /* $NetBSD: mca_machdep.h,v 1.8 2001/12/02 17:02:33 jdolecek Exp $ */
/* /*
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
* Copyright (c) 1999 Scott D. Telford. All rights reserved. * Copyright (c) 1999 Scott D. Telford. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -61,6 +61,7 @@ struct mcabus_attach_args;
void mca_attach_hook(struct device *, struct device *, void mca_attach_hook(struct device *, struct device *,
struct mcabus_attach_args *); struct mcabus_attach_args *);
int mca_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_dmamap_t *, int); int mca_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_dmamap_t *, int);
void mca_dma_set_ioport(int dma, u_int16_t port);
const struct evcnt *mca_intr_evcnt(mca_chipset_tag_t, mca_intr_handle_t); const struct evcnt *mca_intr_evcnt(mca_chipset_tag_t, mca_intr_handle_t);
void *mca_intr_establish(mca_chipset_tag_t, mca_intr_handle_t, void *mca_intr_establish(mca_chipset_tag_t, mca_intr_handle_t,
int, int (*)(void *), void *); int, int (*)(void *), void *);
@ -69,6 +70,14 @@ int mca_conf_read(mca_chipset_tag_t, int, int);
void mca_conf_write(mca_chipset_tag_t, int, int, int); void mca_conf_write(mca_chipset_tag_t, int, int, int);
void mca_busprobe(void); void mca_busprobe(void);
/*
* Flags for DMA. Avoid BUS_DMA_BUS1, we share dmamap routines with ISA and
* that flag is used for different purpose within _isa_dmamap_*().
*/
#define MCABUS_DMA_IOPORT BUS_DMA_BUS2 /* io-port based DMA */
#define MCABUS_DMA_16BIT BUS_DMA_BUS3 /* 16bit DMA */
#define _MCABUS_DMA_USEDMACTRL BUS_DMA_BUS4 /* internal flag */
/* /*
* These two are used to light disk busy LED on PS/2 during disk operations. * These two are used to light disk busy LED on PS/2 during disk operations.
*/ */

View File

@ -1,12 +1,13 @@
/* $NetBSD: mca_machdep.c,v 1.11 2001/11/23 22:24:36 jdolecek Exp $ */ /* $NetBSD: mca_machdep.c,v 1.12 2001/12/02 17:02:33 jdolecek Exp $ */
/*- /*-
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
* Copyright (c) 1996-1999 Scott D. Telford. * Copyright (c) 1996-1999 Scott D. Telford.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
* by Scott Telford <s.telford@ed.ac.uk>. * by Scott Telford <s.telford@ed.ac.uk> and Jaromir Dolecek
* <jdolecek@NetBSD.org>.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -42,7 +43,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mca_machdep.c,v 1.11 2001/11/23 22:24:36 jdolecek Exp $"); __KERNEL_RCSID(0, "$NetBSD: mca_machdep.c,v 1.12 2001/12/02 17:02:33 jdolecek Exp $");
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
@ -144,15 +145,6 @@ struct i386_bus_dma_tag mca_bus_dma_tag = {
/* Updated in mca_busprobe() if appropriate. */ /* Updated in mca_busprobe() if appropriate. */
int MCA_system = 0; int MCA_system = 0;
/*
* Some devices drive DMA themselves, and don't need the MCA DMA
* controller. To distinguish the two, add a flag for dmamaps
* which use the DMA controller. Avoid BUS_DMA_BUS1, we share
* dmamap routines with ISA and that flag is used for different
* purpose within _isa_dmamap_*().
*/
#define MCABUS_DMA_USEDMACTRL BUS_DMA_BUS4
/* Used to kick MCA DMA controller */ /* Used to kick MCA DMA controller */
#define DMA_CMD 0x18 /* command the controller */ #define DMA_CMD 0x18 /* command the controller */
#define DMA_EXEC 0x1A /* tell controller how to do things */ #define DMA_EXEC 0x1A /* tell controller how to do things */
@ -463,7 +455,7 @@ _mca_bus_dmamap_sync(t, map, offset, len, ops)
/* /*
* Don't do anything if not using the DMA controller. * Don't do anything if not using the DMA controller.
*/ */
if ((map->_dm_flags & MCABUS_DMA_USEDMACTRL) == 0) if ((map->_dm_flags & _MCABUS_DMA_USEDMACTRL) == 0)
return; return;
/* /*
@ -482,9 +474,17 @@ _mca_bus_dmamap_sync(t, map, offset, len, ops)
mode = DMACMD_MODE_XFER; mode = DMACMD_MODE_XFER;
mode |= (ops == BUS_DMASYNC_PREREAD) mode |= (ops == BUS_DMASYNC_PREREAD)
? DMACMD_MODE_READ : DMACMD_MODE_WRITE; ? DMACMD_MODE_READ : DMACMD_MODE_WRITE;
if (map->_dm_flags & MCABUS_DMA_IOPORT)
mode |= DMACMD_MODE_IOPORT;
/* If transfer size can be divided by two, use 16bit DMA */ /* If transfer size can be divided by two, use 16bit DMA */
if ((cnt % 2) == 0) { if (map->_dm_flags & MCABUS_DMA_16BIT) {
#ifdef DIAGNOSTIC
if ((cnt % 2) != 0) {
panic("_mca_bus_dmamap_sync: 16bit DMA and cnt %lu odd",
cnt);
}
#endif
mode |= DMACMD_MODE_16BIT; mode |= DMACMD_MODE_16BIT;
cnt /= 2; cnt /= 2;
} }
@ -495,10 +495,14 @@ _mca_bus_dmamap_sync(t, map, offset, len, ops)
*/ */
/* Disable access to dma channel. */ /* Disable access to dma channel. */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_MASK + dmach); bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_MASK | dmach);
/* Set the transfer mode. */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_SET_MODE | dmach);
bus_space_write_1(dmaiot, dmaexech, 0, mode);
/* Set the address byte pointer. */ /* Set the address byte pointer. */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_SET_ADDR + dmach); bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_SET_ADDR | dmach);
/* address bits 0..7 */ /* address bits 0..7 */
bus_space_write_1(dmaiot, dmaexech, 0, (phys >> 0) & 0xff); bus_space_write_1(dmaiot, dmaexech, 0, (phys >> 0) & 0xff);
/* address bits 8..15 */ /* address bits 8..15 */
@ -507,18 +511,14 @@ _mca_bus_dmamap_sync(t, map, offset, len, ops)
bus_space_write_1(dmaiot, dmaexech, 0, (phys >> 16) & 0xff); bus_space_write_1(dmaiot, dmaexech, 0, (phys >> 16) & 0xff);
/* Set the count byte pointer */ /* Set the count byte pointer */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_SET_CNT + dmach); bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_SET_CNT | dmach);
/* count bits 0..7 */ /* count bits 0..7 */
bus_space_write_1(dmaiot, dmaexech, 0, ((cnt - 1) >> 0) & 0xff); bus_space_write_1(dmaiot, dmaexech, 0, ((cnt - 1) >> 0) & 0xff);
/* count bits 8..15 */ /* count bits 8..15 */
bus_space_write_1(dmaiot, dmaexech, 0, ((cnt - 1) >> 8) & 0xff); bus_space_write_1(dmaiot, dmaexech, 0, ((cnt - 1) >> 8) & 0xff);
/* Set the transfer mode. */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_SET_MODE + dmach);
bus_space_write_1(dmaiot, dmaexech, 0, mode);
/* Enable access to dma channel. */ /* Enable access to dma channel. */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_RESET_MASK + dmach); bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_RESET_MASK | dmach);
} }
/* /*
@ -561,8 +561,33 @@ mca_dmamap_create(t, size, flags, dmamp, dmach)
cookie->id_flags &= 0x0f; cookie->id_flags &= 0x0f;
cookie->id_flags |= dmach << 4; cookie->id_flags |= dmach << 4;
/* Mark the dmamap as using DMA controller */ /* Mark the dmamap as using DMA controller. Some devices
(*dmamp)->_dm_flags |= MCABUS_DMA_USEDMACTRL; * drive DMA themselves, and don't need the MCA DMA controller.
* To distinguish the two, use a flag for dmamaps which use the DMA
* controller.
*/
(*dmamp)->_dm_flags |= _MCABUS_DMA_USEDMACTRL;
return (0); return (0);
} }
/*
* Set I/O port for DMA. Implemented separately from _mca_bus_dmamap_sync()
* so that it's available for one-shot setup.
*/
void
mca_dma_set_ioport(dma, port)
int dma;
u_int16_t port;
{
/* Disable access to dma channel. */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_MASK | dma);
/* Set I/O port to use for DMA */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_SET_IO);
bus_space_write_1(dmaiot, dmaexech, 0, port & 0xff);
bus_space_write_1(dmaiot, dmaexech, 0, (port & 0xff) >> 8);
/* Enable access to dma channel. */
bus_space_write_1(dmaiot, dmacmdh, 0, DMACMD_RESET_MASK | dma);
}