Rework handling of Commodore Gayle chip. Avoid ugly struct casts, introduce

proper bus_space accesses and some abstraction layer. All drivers that utilised
Gayle also had to be refactored.

I tried not to break anything more, but this clearly needs more testing...
This commit is contained in:
rkujawa 2014-01-03 00:33:06 +00:00
parent 7a951eee59
commit d8300310a1
11 changed files with 334 additions and 112 deletions

View File

@ -0,0 +1,38 @@
/* $NetBSD: amiga_bus_simple_0x1000.c,v 1.1 2014/01/03 00:33:06 rkujawa Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ignatios Souvatzis.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: amiga_bus_simple_0x1000.c,v 1.1 2014/01/03 00:33:06 rkujawa Exp $");
#define AMIGA_SIMPLE_BUS_STRIDE 0x1000 /* 1 byte per 0x1000 bytes */
#define AMIGA_SIMPLE_BUS_WORD_METHODS
#include "simple_busfuncs.c"

View File

@ -1,30 +1,193 @@
/* $NetBSD: gayle.c,v 1.6 2005/12/11 12:16:26 christos Exp $ */
/* $NetBSD: gayle.c,v 1.7 2014/01/03 00:33:06 rkujawa Exp $ */
/* public domain */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gayle.c,v 1.6 2005/12/11 12:16:26 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: gayle.c,v 1.7 2014/01/03 00:33:06 rkujawa Exp $");
/*
* Gayle management routines
* Gayle management - provide functions for use in the drivers that utilise
* the chip.
*
* Any module that uses gayle should call gayle_init() before using anything
* related to gayle. gayle_init() can be called multiple times.
* These overly complicated routines try to deal with a few variants of
* Gayle chip that exists.
*/
#include <sys/bus.h>
#include <sys/systm.h>
#include <machine/cpu.h>
#include <amiga/amiga/gayle.h>
#include <amiga/dev/zbusvar.h>
struct gayle_struct *gayle_base_virtual_address = 0;
/* #define GAYLE_DEBUG 1 */
#define GAYLE_PHYS_ADDRESS 0xda8000
struct gayle_tag {
struct bus_space_tag gayle_io_bst;
bus_space_tag_t gayle_io_t;
bus_space_handle_t gayle_io_h;
struct bus_space_tag gayle_isr_bst;
bus_space_tag_t gayle_isr_t;
bus_space_handle_t gayle_isr_h;
};
typedef struct gayle_tag *gayle_tag_t;
/*
* Having these as static variables is ugly, but they don't fit into
* driver's softc, as the chip might be utilised by many different drivers.
* And since we can only have one Gayle per system it should be okay.
*/
static struct gayle_tag gayle;
static gayle_tag_t gayle_t = NULL;
/*
* Any module that uses gayle should call gayle_init() before using anything
* related to gayle. gayle_init() can be called multiple times.
*/
void
gayle_init(void) {
bus_addr_t gayle_vbase;
if (gayle_base_virtual_address != 0)
if (gayle_t != NULL)
return;
gayle_base_virtual_address =
(struct gayle_struct *) __UNVOLATILE(ztwomap(GAYLE_PHYS_ADDRESS));
#ifdef GAYLE_DEBUG
aprint_normal("gayle: doing init\n");
#endif /* GAYLE_DEBUG */
gayle_t = &gayle;
gayle_vbase = (bus_addr_t) __UNVOLATILE(ztwomap(GAYLE_REGS_BASE));
gayle_t->gayle_io_bst.base = gayle_vbase;
gayle_t->gayle_io_bst.absm = &amiga_bus_stride_0x1000;
gayle_t->gayle_io_t = &(gayle_t->gayle_io_bst);
bus_space_map(gayle_t->gayle_io_t, 0, 0x4, 0, &gayle_t->gayle_io_h);
/*
* The A4000 variant of Gayle has interrupt status register at offset
* +0x1000 from IDE registers.
* XXX: in fact, on A4000 we should initialise only this part...
*/
if (is_a4000()) {
gayle_t->gayle_isr_bst.base = (bus_addr_t) __UNVOLATILE(ztwomap(
GAYLE_IDE_BASE_A4000+GAYLE_IDE_INTREQ_A4000));
gayle_t->gayle_io_bst.absm = &amiga_bus_stride_1;
gayle_t->gayle_isr_t = &(gayle_t->gayle_isr_bst);
} else {
bus_space_subregion(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_INTREQ, 0x1, &(gayle_t->gayle_isr_h));
gayle_t->gayle_isr_bst = gayle_t->gayle_io_bst;
gayle_t->gayle_isr_t = gayle_t->gayle_io_t;
}
}
uint8_t
gayle_intr_status(void)
{
uint8_t rv;
rv = bus_space_read_1(gayle_t->gayle_isr_t, gayle_t->gayle_isr_h, 0);
#ifdef GAYLE_DEBUG
aprint_normal("gayle: intr status %x\n", rv);
#endif /* GAYLE_DEBUG */
return rv;
}
uint8_t
gayle_intr_enable_read(void)
{
uint8_t rv;
rv = bus_space_read_1(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_INTENA);
#ifdef GAYLE_DEBUG
aprint_normal("gayle: intr enable register read %x\n", rv);
#endif /* GAYLE_DEBUG */
return rv;
}
void
gayle_intr_enable_write(uint8_t val)
{
#ifdef GAYLE_DEBUG
aprint_normal("gayle: intr enable register write %x\n", val);
#endif /* GAYLE_DEBUG */
bus_space_write_1(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_INTENA, val);
}
void
gayle_intr_enable_set(uint8_t bits)
{
uint8_t val;
val = gayle_intr_enable_read();
gayle_intr_enable_write(val | bits);
}
void
gayle_intr_ack(uint8_t val)
{
#ifdef GAYLE_DEBUG
aprint_normal("gayle: intr ack write %x\n", val);
#endif /* GAYLE_DEBUG */
bus_space_write_1(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_INTREQ, val);
}
uint8_t
gayle_pcmcia_status_read(void)
{
uint8_t rv;
rv = bus_space_read_1(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_PCC_STATUS);
#ifdef GAYLE_DEBUG
aprint_normal("gayle: pcmcia status read %x\n", rv);
#endif /* GAYLE_DEBUG */
return rv;
}
void
gayle_pcmcia_status_write(uint8_t val)
{
#ifdef GAYLE_DEBUG
aprint_normal("gayle: pcmcia status write %x\n", val);
#endif /* GAYLE_DEBUG */
bus_space_write_1(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_PCC_STATUS, val);
}
void
gayle_pcmcia_config_write(uint8_t val)
{
#ifdef GAYLE_DEBUG
aprint_normal("gayle: pcmcia config write %x\n", val);
#endif /* GAYLE_DEBUG */
bus_space_write_1(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_PCC_CONFIG, val);
}
uint8_t
gayle_pcmcia_config_read(void)
{
uint8_t rv;
rv = bus_space_read_1(gayle_t->gayle_io_t, gayle_t->gayle_io_h,
GAYLE_PCC_CONFIG);
#ifdef GAYLE_DEBUG
aprint_normal("gayle: pcmcia config read %x\n", rv);
#endif /* GAYLE_DEBUG */
return rv;
}

View File

@ -1,58 +1,73 @@
/* $NetBSD: gayle.h,v 1.2 2002/01/26 13:24:54 aymeric Exp $ */
/* $NetBSD: gayle.h,v 1.3 2014/01/03 00:33:06 rkujawa Exp $ */
#ifndef AMIGA_GAYLE_H_
#define AMIGA_GAYLE_H_
#include <sys/types.h>
struct gayle_struct {
volatile u_int8_t pcc_status;
#define GAYLE_IDE_BASE 0xDA0000
#define GAYLE_IDE_BASE_A4000 0xDD2020
#define GAYLE_IDE_INTREQ_A4000 0x1000 /* with stride of 1 */
#define GAYLE_REGS_BASE 0xDA8000
#define GAYLE_PCC_STATUS 0x0
/* Depending on the mode the card is in, most of the bits have different
meanings */
#define GAYLE_CCMEM_DETECT 0x40
#define GAYLE_CCMEM_BVD1 0x20
#define GAYLE_CCMEM_BVD2 0x10
#define GAYLE_CCMEM_WP 0x08
#define GAYLE_CCMEM_BUSY 0x04
#define GAYLE_CCMEM_DETECT __BIT(6)
#define GAYLE_CCMEM_BVD1 __BIT(5)
#define GAYLE_CCMEM_BVD2 __BIT(4)
#define GAYLE_CCMEM_WP __BIT(3)
#define GAYLE_CCMEM_BUSY __BIT(2)
#define GAYLE_CCIO_STSCHG 0x20
#define GAYLE_CCIO_SPKR 0x10
#define GAYLE_CCIO_IREQ 0x04
#define GAYLE_CCIO_STSCHG __BIT(5)
#define GAYLE_CCIO_SPKR __BIT(4)
#define GAYLE_CCIO_IREQ __BIT(2)
u_int8_t __pad0[0xfff];
volatile u_int8_t intreq;
#define GAYLE_INTREQ 0x1 /* 0x1000 */
#define GAYLE_INTENA 0x2 /* 0x2000 */
u_int8_t __pad1[0xfff];
volatile u_int8_t intena;
#define GAYLE_INT_IDE 0x80
#define GAYLE_INT_DETECT 0x40
#define GAYLE_INT_BVD1 0x20
#define GAYLE_INT_STSCHG 0x20
#define GAYLE_INT_BVD2 0x10
#define GAYLE_INT_SPKR 0x10
#define GAYLE_INT_WP 0x08
#define GAYLE_INT_BUSY 0x04
#define GAYLE_INT_IREQ 0x04
#define GAYLE_INT_IDEACK0 0x02
#define GAYLE_INT_IDEACK1 0x01
#define GAYLE_INT_IDE __BIT(7)
#define GAYLE_INT_DETECT __BIT(6)
#define GAYLE_INT_BVD1 __BIT(5)
#define GAYLE_INT_STSCHG __BIT(5)
#define GAYLE_INT_BVD2 __BIT(4)
#define GAYLE_INT_SPKR __BIT(4)
#define GAYLE_INT_WP __BIT(3)
#define GAYLE_INT_BUSY __BIT(2)
#define GAYLE_INT_IREQ __BIT(2)
#define GAYLE_INT_IDEACK0 __BIT(1)
#define GAYLE_INT_IDEACK1 __BIT(0)
u_int8_t __pad2[0xfff];
volatile u_int8_t pcc_config;
};
#define GAYLE_INT_IDEACK (GAYLE_INT_IDEACK0 | GAYLE_INT_IDEACK1)
#define GAYLE_PCMCIA_START 0xa00000
#define GAYLE_PCMCIA_ATTR_START 0xa00000
#define GAYLE_PCMCIA_ATTR_END 0xa20000
#define GAYLE_PCC_CONFIG 0x3 /* 0x3000 */
#define GAYLE_PCMCIA_IO_START 0xa20000
#define GAYLE_PCMCIA_IO_END 0xa40000
#define GAYLE_PCMCIA_START 0xA00000
#define GAYLE_PCMCIA_ATTR_START 0xA00000
#define GAYLE_PCMCIA_ATTR_END 0xA20000
#define GAYLE_PCMCIA_RESET 0xa40000
#define GAYLE_PCMCIA_END 0xa42000
#define GAYLE_PCMCIA_IO_START 0xA20000
#define GAYLE_PCMCIA_IO_END 0xA40000
#define GAYLE_PCMCIA_RESET 0xA40000
#define GAYLE_PCMCIA_END 0xA42000
#define NPCMCIAPG btoc(GAYLE_PCMCIA_END - GAYLE_PCMCIA_START)
extern struct gayle_struct *gayle_base_virtual_address;
#define gayle (*gayle_base_virtual_address)
/*
* Convenience functions for expansions that have Gayle and even those that
* don't have real Gayle but have implemented some portions of it for the sake
* of compatibility.
*/
void gayle_init(void);
uint8_t gayle_intr_status(void);
uint8_t gayle_intr_enable_read(void);
void gayle_intr_enable_write(uint8_t);
void gayle_intr_enable_set(uint8_t);
void gayle_intr_ack(uint8_t);
uint8_t gayle_pcmcia_status_read(void);
void gayle_pcmcia_status_write(uint8_t);
uint8_t gayle_pcmcia_config_read(void);
void gayle_pcmcia_config_write(uint8_t);
#endif /* AMIGA_GAYLE_H_ */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.amiga,v 1.173 2013/12/26 20:38:11 rkujawa Exp $
# $NetBSD: files.amiga,v 1.174 2014/01/03 00:33:06 rkujawa Exp $
# maxpartitions must be first item in files.${ARCH}.newconf
maxpartitions 16 # NOTE THAT AMIGA IS SPECIAL!
@ -58,6 +58,9 @@ file arch/amiga/amiga/amiga_bus_simple_16.c amibus_b16
define amibus_b800
file arch/amiga/amiga/amiga_bus_simple_0x800.c amibus_b800
define amibus_b1000
file arch/amiga/amiga/amiga_bus_simple_0x1000.c amibus_b1000
define amibus_b4000
file arch/amiga/amiga/amiga_bus_simple_0x4000.c amibus_b4000
@ -588,7 +591,7 @@ device acafh: acafhbus, amibus_b4000
attach acafh at mainbus
file arch/amiga/dev/acafh.c acafh needs-count
attach wdc at acafhbus with wdc_acafh
attach wdc at acafhbus with wdc_acafh: gayle, amibus_b1000
file arch/amiga/dev/wdc_acafh.c wdc_acafh & acafh
include "arch/amiga/clockport/files.clockport"

View File

@ -1,4 +1,4 @@
/* $NetBSD: acafhreg.h,v 1.3 2013/12/26 20:38:11 rkujawa Exp $ */
/* $NetBSD: acafhreg.h,v 1.4 2014/01/03 00:33:06 rkujawa Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -29,9 +29,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <amiga/amiga/gayle.h>
#ifndef _AMIGA_ACAFHREG_H_
#define GAYLE_IDE_BASE 0xDA0000 /* ACA500 has Gayle-compatible IDE */
#define ACAFH_IDE_BASE GAYLE_IDE_BASE /* ACA500 has Gayle-compatible IDE */
#define ACAFH_CLOCKPORT_BASE 0xD80001
#define ACAFH_MSB_SHIFT 0xF

View File

@ -1,4 +1,4 @@
/* $NetBSD: efa.c,v 1.11 2012/07/31 15:50:31 bouyer Exp $ */
/* $NetBSD: efa.c,v 1.12 2014/01/03 00:33:06 rkujawa Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@ -172,8 +172,6 @@ efa_attach(device_t parent, device_t self, void *aux)
wdc_allocate_regs(&sc->sc_wdcdev);
sc->sc_intreg = &gayle.intreq;
for (i = 0; i < FATA1_CHANNELS; i++)
efa_attach_channel(sc, i);
@ -194,7 +192,7 @@ efa_attach(device_t parent, device_t self, void *aux)
sc->sc_isr.isr_arg = sc;
sc->sc_isr.isr_ipl = 2;
add_isr (&sc->sc_isr);
gayle.intena |= GAYLE_INT_IDE;
gayle_intr_enable_set(GAYLE_INT_IDE);
}
}
@ -283,13 +281,13 @@ efa_intr(void *arg)
{
struct efa_softc *sc = (struct efa_softc *)arg;
int r1, r2, ret;
u_char intreq;
uint8_t intreq;
intreq = *sc->sc_intreg;
intreq = gayle_intr_status();
ret = 0;
if (intreq & GAYLE_INT_IDE) {
gayle.intreq = 0x7c | (intreq & 0x03);
gayle_intr_ack(0x7C | (intreq & 0x03));
/* How to check which channel caused interrupt?
* Interrupt status register is not very useful here. */
r1 = wdcintr(&sc->sc_ports[0].chan);

View File

@ -1,4 +1,4 @@
/* $NetBSD: efareg.h,v 1.2 2011/10/29 11:16:19 rkujawa Exp $ */
/* $NetBSD: efareg.h,v 1.3 2014/01/03 00:33:06 rkujawa Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@ -31,7 +31,6 @@
#ifndef _AMIGA_EFAREG_H_
#define GAYLE_IDE_BASE 0xDA0000
#define FATA1_BASE 0xDA2000
/* Offsets. Stride of 4 is used, so multiply any offset by 4. */

View File

@ -1,9 +1,9 @@
/* $NetBSD: gayle_pcmcia.c,v 1.27 2013/09/23 08:39:28 jandberg Exp $ */
/* $NetBSD: gayle_pcmcia.c,v 1.28 2014/01/03 00:33:06 rkujawa Exp $ */
/* public domain */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gayle_pcmcia.c,v 1.27 2013/09/23 08:39:28 jandberg Exp $");
__KERNEL_RCSID(0, "$NetBSD: gayle_pcmcia.c,v 1.28 2014/01/03 00:33:06 rkujawa Exp $");
/* PCMCIA front-end driver for A1200's and A600's. */
@ -165,10 +165,10 @@ pccard_attach(device_t parent, device_t self, void *aux)
sc->devs[0].intr_arg = NULL;
sc->devs[0].flags = 0;
gayle.pcc_status = 0;
gayle.intreq = 0;
gayle.pcc_config = 0;
gayle.intena &= GAYLE_INT_IDE;
gayle_pcmcia_status_write(0);
gayle_intr_ack(0);
gayle_pcmcia_config_write(0);
gayle_intr_enable_set(GAYLE_INT_IDE);
paa.paa_busname = "pcmcia";
paa.pct = &chip_functions;
@ -201,15 +201,15 @@ pccard_attach(device_t parent, device_t self, void *aux)
panic("pccard kthread_create() failed");
}
gayle.intena |= GAYLE_INT_DETECT | GAYLE_INT_IREQ;
gayle_intr_enable_set(GAYLE_INT_DETECT | GAYLE_INT_IREQ);
/* reset the card if it's already there */
if (gayle.pcc_status & GAYLE_CCMEM_DETECT) {
if (gayle_pcmcia_status_read() & GAYLE_CCMEM_DETECT) {
volatile u_int8_t x;
*reset_card_reg = 0x0;
delay(1000);
x = *reset_card_reg;
gayle.pcc_status = GAYLE_CCMEM_WP | GAYLE_CCIO_SPKR;
gayle_pcmcia_status_write(GAYLE_CCMEM_WP | GAYLE_CCIO_SPKR);
}
pccard_attach_slot(&sc->devs[0]);
@ -220,9 +220,9 @@ pccard_intr6(void *arg)
{
struct pccard_softc *sc = arg;
if (gayle.intreq & GAYLE_INT_DETECT) {
gayle.intreq = GAYLE_INT_IDE | GAYLE_INT_STSCHG |
GAYLE_INT_SPKR | GAYLE_INT_WP | GAYLE_INT_IREQ;
if (gayle_intr_status() & GAYLE_INT_DETECT) {
gayle_intr_ack(GAYLE_INT_IDE | GAYLE_INT_STSCHG |
GAYLE_INT_SPKR | GAYLE_INT_WP | GAYLE_INT_IREQ);
sc->devs[0].flags |= SLOT_NEW_CARD_EVENT;
return 1;
}
@ -239,15 +239,15 @@ pccard_intr2(void *arg)
slot->flags &= ~SLOT_NEW_CARD_EVENT;
/* reset the registers */
gayle.intreq = GAYLE_INT_IDE | GAYLE_INT_DETECT;
gayle.pcc_status = GAYLE_CCMEM_WP | GAYLE_CCIO_SPKR;
gayle.pcc_config = 0;
gayle_intr_ack(GAYLE_INT_IDE | GAYLE_INT_DETECT);
gayle_pcmcia_status_write(GAYLE_CCMEM_WP | GAYLE_CCIO_SPKR);
gayle_pcmcia_config_write(0);
pccard_attach_slot(&sc->devs[0]);
} else {
int intreq = gayle.intreq &
int intreq = gayle_intr_status() &
(GAYLE_INT_STSCHG | GAYLE_INT_WP | GAYLE_INT_IREQ);
if (intreq) {
gayle.intreq = (intreq ^ 0x2c) | 0xc0;
gayle_intr_ack((intreq ^ 0x2c) | 0xc0);
return slot->flags & SLOT_OCCUPIED &&
slot->intr_func != NULL &&
@ -268,12 +268,12 @@ pccard_kthread(void *arg)
if (slot->flags & SLOT_NEW_CARD_EVENT) {
slot->flags &= ~SLOT_NEW_CARD_EVENT;
gayle.intreq = 0xc0;
gayle_intr_ack(0xc0);
/* reset the registers */
gayle.intreq = GAYLE_INT_IDE | GAYLE_INT_DETECT;
gayle.pcc_status = GAYLE_CCMEM_WP | GAYLE_CCIO_SPKR;
gayle.pcc_config = 0;
gayle_intr_ack(GAYLE_INT_IDE | GAYLE_INT_DETECT);
gayle_pcmcia_status_write(GAYLE_CCMEM_WP | GAYLE_CCIO_SPKR);
gayle_pcmcia_config_write(0);
pccard_attach_slot(&sc->devs[0]);
}
splx(s);
@ -287,7 +287,7 @@ pccard_attach_slot(struct pccard_slot *slot)
{
if (!(slot->flags & SLOT_OCCUPIED) &&
gayle.pcc_status & GAYLE_CCMEM_DETECT) {
gayle_pcmcia_status_read() & GAYLE_CCMEM_DETECT) {
if (pcmcia_card_attach(slot->card) == 0)
slot->flags |= SLOT_OCCUPIED;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_acafh.c,v 1.2 2013/12/22 23:02:38 rkujawa Exp $ */
/* $NetBSD: wdc_acafh.c,v 1.3 2014/01/03 00:33:06 rkujawa Exp $ */
/*-
* Copyright (c) 2000, 2003, 2013 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc_acafh.c,v 1.2 2013/12/22 23:02:38 rkujawa Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc_acafh.c,v 1.3 2014/01/03 00:33:06 rkujawa Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -81,7 +81,6 @@ struct wdc_acafh_softc {
struct wdc_acafh_slot sc_slots[WDC_ACAFH_SLOTS];
struct isr sc_isr;
volatile u_char *sc_intreg;
struct bus_space_tag cmd_iot;
@ -119,7 +118,6 @@ wdc_acafh_attach(device_t parent, device_t self, void *aux)
sc->aca_sc = device_private(parent);
gayle_init();
sc->sc_intreg = &gayle.intreq;
/* XXX: take addr from attach args? */
sc->cmd_iot.base = (u_long) ztwomap(GAYLE_IDE_BASE + 2);
@ -143,7 +141,7 @@ wdc_acafh_attach(device_t parent, device_t self, void *aux)
sc->sc_isr.isr_ipl = 2;
add_isr (&sc->sc_isr);
gayle.intena |= GAYLE_INT_IDE;
gayle_intr_enable_set(GAYLE_INT_IDE);
}
@ -205,9 +203,13 @@ wdc_acafh_map_channel(struct wdc_acafh_softc *sc, int chnum)
int
wdc_acafh_intr(void *arg)
{
struct wdc_acafh_softc *sc = (struct wdc_acafh_softc *)arg;
int ret = 0;
u_char intreq = *sc->sc_intreg;
struct wdc_acafh_softc *sc;
uint8_t intreq;
int ret;
sc = (struct wdc_acafh_softc *) arg;
intreq = gayle_intr_status();
ret = 0;
if (intreq & GAYLE_INT_IDE) {
if (acafh_cf_intr_status(sc->aca_sc, 1) == 1) {
@ -216,7 +218,7 @@ wdc_acafh_intr(void *arg)
if (acafh_cf_intr_status(sc->aca_sc, 0) == 1) {
ret = wdcintr(&sc->sc_slots[0].channel);
}
gayle.intreq = 0x7c | (intreq & 0x03);
gayle_intr_ack(0x7C | (intreq & GAYLE_INT_IDEACK));
}
return ret;

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_amiga.c,v 1.36 2012/07/31 15:50:31 bouyer Exp $ */
/* $NetBSD: wdc_amiga.c,v 1.37 2014/01/03 00:33:06 rkujawa Exp $ */
/*-
* Copyright (c) 2000, 2003 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc_amiga.c,v 1.36 2012/07/31 15:50:31 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc_amiga.c,v 1.37 2014/01/03 00:33:06 rkujawa Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -59,10 +59,8 @@ struct wdc_amiga_softc {
struct ata_queue sc_chqueue;
struct wdc_regs sc_wdc_regs;
struct isr sc_isr;
volatile u_char *sc_intreg;
struct bus_space_tag cmd_iot;
struct bus_space_tag ctl_iot;
char sc_a1200;
};
int wdc_amiga_probe(device_t, cfdata_t, void *);
@ -93,16 +91,14 @@ wdc_amiga_attach(device_t parent, device_t self, void *aux)
sc->sc_wdcdev.sc_atac.atac_dev = self;
sc->sc_wdcdev.regs = wdr = &sc->sc_wdc_regs;
gayle_init();
if (is_a4000()) {
sc->cmd_iot.base = (u_long)ztwomap(0xdd2020 + 2);
sc->sc_intreg = (volatile u_char *)ztwomap(0xdd2020 + 0x1000);
sc->sc_a1200 = 0;
sc->cmd_iot.base = (bus_addr_t) ztwomap(GAYLE_IDE_BASE_A4000 + 2);
} else {
sc->cmd_iot.base = (u_long) ztwomap(0xda0000 + 2);
gayle_init();
sc->sc_intreg = &gayle.intreq;
sc->sc_a1200 = 1;
sc->cmd_iot.base = (bus_addr_t) ztwomap(GAYLE_IDE_BASE + 2);
}
sc->cmd_iot.absm = sc->ctl_iot.absm = &amiga_bus_stride_4swap;
wdr->cmd_iot = &sc->cmd_iot;
wdr->ctl_iot = &sc->ctl_iot;
@ -146,8 +142,8 @@ wdc_amiga_attach(device_t parent, device_t self, void *aux)
sc->sc_isr.isr_ipl = 2;
add_isr (&sc->sc_isr);
if (sc->sc_a1200)
gayle.intena |= GAYLE_INT_IDE;
if (!is_a4000())
gayle_intr_enable_set(GAYLE_INT_IDE);
wdcattach(&sc->sc_channel);
}
@ -155,15 +151,20 @@ wdc_amiga_attach(device_t parent, device_t self, void *aux)
int
wdc_amiga_intr(void *arg)
{
struct wdc_amiga_softc *sc = (struct wdc_amiga_softc *)arg;
u_char intreq = *sc->sc_intreg;
int ret = 0;
struct wdc_amiga_softc *sc;
uint8_t intreq;
int ret;
sc = (struct wdc_amiga_softc *)arg;
ret = 0;
intreq = gayle_intr_status();
if (intreq & GAYLE_INT_IDE) {
if (sc->sc_a1200)
gayle.intreq = 0x7c | (intreq & 0x03);
if (!is_a4000())
gayle_intr_ack(0x7C | (intreq & GAYLE_INT_IDEACK));
ret = wdcintr(&sc->sc_channel);
}
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: bus.h,v 1.28 2013/12/22 02:21:51 rkujawa Exp $ */
/* $NetBSD: bus.h,v 1.29 2014/01/03 00:33:06 rkujawa Exp $ */
/*
* Copyright (c) 1996 Leo Weppelman. All rights reserved.
@ -279,6 +279,7 @@ extern const struct amiga_bus_space_methods amiga_bus_stride_2;
extern const struct amiga_bus_space_methods amiga_bus_stride_4;
extern const struct amiga_bus_space_methods amiga_bus_stride_4swap;
extern const struct amiga_bus_space_methods amiga_bus_stride_16;
extern const struct amiga_bus_space_methods amiga_bus_stride_0x1000;
extern const struct amiga_bus_space_methods amiga_bus_stride_0x4000;
extern const struct amiga_bus_space_methods empb_bus_swap;