Workbit NinjaATA-32 busmastering PIO IDE controller driver (njata)
This driver supports NinjaATA-32Bi and NPATA-32 chips, which are used for CardBus ATA interface cards and CardBus CompactFlash adapters.
This commit is contained in:
parent
4f593623cc
commit
cb2fb285ec
@ -1,4 +1,4 @@
|
||||
# $NetBSD: mi,v 1.927 2006/09/07 00:50:45 ad Exp $
|
||||
# $NetBSD: mi,v 1.928 2006/09/07 14:22:08 itohy Exp $
|
||||
./etc/mtree/set.man man-sys-root
|
||||
./usr/share/info/am-utils.info man-amd-info info
|
||||
./usr/share/info/as.info man-computil-info bfd,info
|
||||
@ -1097,6 +1097,7 @@
|
||||
./usr/share/man/cat4/netintro.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/netsmb.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/networking.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/njata.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/njs.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/nfe.0 man-sys-catman .cat
|
||||
./usr/share/man/cat4/ns.0 man-obsolete obsolete
|
||||
@ -3468,6 +3469,7 @@
|
||||
./usr/share/man/man4/netsmb.4 man-sys-man .man
|
||||
./usr/share/man/man4/networking.4 man-sys-man .man
|
||||
./usr/share/man/man4/nfe.4 man-sys-man .man
|
||||
./usr/share/man/man4/njata.4 man-sys-man .man
|
||||
./usr/share/man/man4/njs.4 man-sys-man .man
|
||||
./usr/share/man/man4/ns.4 man-obsolete obsolete
|
||||
./usr/share/man/man4/nsclpcsio.4 man-sys-man .man
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.402 2006/09/02 23:39:56 wiz Exp $
|
||||
# $NetBSD: Makefile,v 1.403 2006/09/07 14:22:08 itohy Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/18/93
|
||||
|
||||
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \
|
||||
@ -26,7 +26,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \
|
||||
ksyms.4 kttcp.4 lc.4 ld.4 lkm.4 lo.4 lxtphy.4 mainbus.4 makphy.4 \
|
||||
mbe.4 mca.4 mcclock.4 md.4 mfb.4 mhzc.4 midi.4 \
|
||||
mii.4 mk48txx.4 mlx.4 mly.4 mpt.4 mpu.4 mtd.4 \
|
||||
mtio.4 multicast.4 ne.4 neo.4 netintro.4 nfe.4 njs.4 \
|
||||
mtio.4 multicast.4 ne.4 neo.4 netintro.4 nfe.4 njata.4 njs.4 \
|
||||
nsclpcsio.4 nsphy.4 nsphyter.4 ntwoc.4 \
|
||||
null.4 nsmb.4 oak.4 oosiop.4 opl.4 options.4 \
|
||||
optiide.4 osiop.4 pas.4 pcdisplay.4 pciide.4 \
|
||||
|
97
share/man/man4/njata.4
Normal file
97
share/man/man4/njata.4
Normal file
@ -0,0 +1,97 @@
|
||||
.\" $NetBSD: njata.4,v 1.1 2006/09/07 14:22:08 itohy Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by ITOH Yasufumi.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.Dd September 7, 2006
|
||||
.Dt NJATA 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm njata
|
||||
.Nd Workbit NinjaATA-32 CardBus IDE controller driver
|
||||
.Sh SYNOPSIS
|
||||
.Cd "njata* at cardbus? function ?"
|
||||
.Cd "njata* at cardbus? function ? flags 1 # with wait 1"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for the following
|
||||
Workbit Bus-Master CardBus IDE controller chips:
|
||||
.Pp
|
||||
.Bl -tag -width "NinjaATA-32Bi" -offset indent
|
||||
.It NinjaATA-32Bi
|
||||
CardBus / PCMCIA dual mode IDE controller
|
||||
.Pq Dq DuoATA .
|
||||
This controller is mainly used for portable drives's equipment.
|
||||
This driver supports the CardBus mode.
|
||||
.It NPATA-32
|
||||
CardBus IDE controller.
|
||||
This controller is widely used for CardBus CompactFlash adapter.
|
||||
.El
|
||||
.Pp
|
||||
These controllers are capable of bus-mastering
|
||||
for ATA PIO transfer.
|
||||
The
|
||||
.Nm
|
||||
driver uses the bus-mastering PIO transfer
|
||||
unless transfer buffer is unaligned,
|
||||
and significantly reduces CPU usage for PIO-only ATA devices
|
||||
compared with usual PIO transfer.
|
||||
.Sh CONFIGURATION
|
||||
The optional flags parameter is the
|
||||
.Dq wait
|
||||
value for ATA transfer.
|
||||
Some combinations of host and device may fail without flags parameter or
|
||||
.Tn flags 0 ,
|
||||
in which case try the wait value
|
||||
between
|
||||
.Tn flags 1
|
||||
and
|
||||
.Tn flags 3 .
|
||||
The smaller wait value should be faster.
|
||||
Too long wait may cause DMA error.
|
||||
.Sh SEE ALSO
|
||||
.Xr ata 4 ,
|
||||
.Xr atapi 4 ,
|
||||
.Xr cardbus 4 ,
|
||||
.Xr intro 4 ,
|
||||
.Xr wd 4 ,
|
||||
.Xr wdc 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
device driver first appeared in
|
||||
.Nx 5.0 .
|
||||
.Sh AUTHORS
|
||||
.An ITOH Yasufumi Aq itohy@NetBSD.org
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files,v 1.809 2006/09/07 12:34:41 itohy Exp $
|
||||
# $NetBSD: files,v 1.810 2006/09/07 14:22:07 itohy Exp $
|
||||
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
||||
@ -857,6 +857,10 @@ attach atabus at ata
|
||||
# The strange expression is to dump ata_* definitions to ata_dma.h.
|
||||
file dev/ic/wdc.c (ata_dma | ata_udma | ata_piobm | atabus) & atabus & wdc_common needs-flag
|
||||
|
||||
# Workbit NinjaATA-32 IDE controllers
|
||||
device njata: ata, ata_piobm, wdc_common
|
||||
file dev/ic/ninjaata32.c njata
|
||||
|
||||
# CHIPS and Technologies 82C7[12][01] Universal Peripheral Controller
|
||||
#
|
||||
device upc { [offset = -1] }
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: DEVNAMES,v 1.214 2006/09/07 12:34:42 itohy Exp $
|
||||
# $NetBSD: DEVNAMES,v 1.215 2006/09/07 14:22:07 itohy Exp $
|
||||
#
|
||||
# This file contains all used device names and defined attributes in
|
||||
# alphabetical order. New devices added to the system somewhere should first
|
||||
@ -883,6 +883,7 @@ nextkbd next68k
|
||||
nfe MI
|
||||
nhpib hp300
|
||||
ni MI
|
||||
njata MI
|
||||
njs MI
|
||||
np vax
|
||||
npx i386
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.cardbus,v 1.33 2006/06/06 21:00:41 rpaulo Exp $
|
||||
# $NetBSD: files.cardbus,v 1.34 2006/09/07 14:22:07 itohy Exp $
|
||||
#
|
||||
# files.cardbus
|
||||
#
|
||||
@ -125,3 +125,9 @@ file dev/cardbus/if_ath_cardbus.c ath_cardbus
|
||||
#
|
||||
attach njs at cardbus with njs_cardbus
|
||||
file dev/cardbus/njs_cardbus.c njs_cardbus
|
||||
|
||||
#
|
||||
# Workbit NinjaATA-32 controllers
|
||||
#
|
||||
attach njata at cardbus with njata_cardbus
|
||||
file dev/cardbus/njata_cardbus.c njata_cardbus
|
||||
|
264
sys/dev/cardbus/njata_cardbus.c
Normal file
264
sys/dev/cardbus/njata_cardbus.c
Normal file
@ -0,0 +1,264 @@
|
||||
/* $Id: njata_cardbus.c,v 1.1 2006/09/07 14:22:07 itohy Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 ITOH Yasufumi <itohy@NetBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 AUTHORS 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 AUTHORS 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(0, "$NetBSD: njata_cardbus.c,v 1.1 2006/09/07 14:22:07 itohy Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <dev/cardbus/cardbusvar.h>
|
||||
#include <dev/pci/pcidevs.h>
|
||||
|
||||
#include <dev/ata/atavar.h>
|
||||
#include <dev/ic/wdcreg.h>
|
||||
#include <dev/ic/wdcvar.h>
|
||||
|
||||
#include <dev/ic/ninjaata32reg.h>
|
||||
#include <dev/ic/ninjaata32var.h>
|
||||
|
||||
#define NJATA32_CARDBUS_BASEADDR_IO CARDBUS_BASE0_REG
|
||||
#define NJATA32_CARDBUS_BASEADDR_MEM CARDBUS_BASE1_REG
|
||||
|
||||
struct njata32_cardbus_softc {
|
||||
struct njata32_softc sc_njata32;
|
||||
|
||||
/* CardBus-specific goo */
|
||||
cardbus_devfunc_t sc_ct; /* our CardBus devfuncs */
|
||||
int sc_intrline; /* our interrupt line */
|
||||
cardbustag_t sc_tag;
|
||||
|
||||
bus_space_handle_t sc_regmaph;
|
||||
bus_size_t sc_regmap_size;
|
||||
};
|
||||
|
||||
static const struct njata32_cardbus_product *njata_cardbus_lookup
|
||||
(const struct cardbus_attach_args *);
|
||||
static int njata_cardbus_match(struct device *, struct cfdata *,
|
||||
void *);
|
||||
static void njata_cardbus_attach(struct device *, struct device *,
|
||||
void *);
|
||||
static int njata_cardbus_detach(struct device *, int);
|
||||
|
||||
CFATTACH_DECL(njata_cardbus, sizeof(struct njata32_cardbus_softc),
|
||||
njata_cardbus_match, njata_cardbus_attach, njata_cardbus_detach, NULL);
|
||||
|
||||
static const struct njata32_cardbus_product {
|
||||
cardbus_vendor_id_t p_vendor;
|
||||
cardbus_product_id_t p_product;
|
||||
uint8_t p_flags;
|
||||
#define NJATA32_FL_IOMAP_ONLY 1 /* registers are only in the I/O map */
|
||||
} njata32_cardbus_products[] = {
|
||||
{ PCI_VENDOR_IODATA, PCI_PRODUCT_IODATA_CBIDE2,
|
||||
0 },
|
||||
{ PCI_VENDOR_WORKBIT, PCI_PRODUCT_WORKBIT_NJATA32BI,
|
||||
0 },
|
||||
{ PCI_VENDOR_WORKBIT, PCI_PRODUCT_WORKBIT_NJATA32BI_KME,
|
||||
0 },
|
||||
{ PCI_VENDOR_WORKBIT, PCI_PRODUCT_WORKBIT_NPATA32_CF32A,
|
||||
NJATA32_FL_IOMAP_ONLY },
|
||||
{ PCI_VENDOR_WORKBIT, PCI_PRODUCT_WORKBIT_NPATA32_KME,
|
||||
NJATA32_FL_IOMAP_ONLY },
|
||||
|
||||
{ PCI_VENDOR_INVALID, 0,
|
||||
0 }
|
||||
};
|
||||
|
||||
static const struct njata32_cardbus_product *
|
||||
njata_cardbus_lookup(ca)
|
||||
const struct cardbus_attach_args *ca;
|
||||
{
|
||||
const struct njata32_cardbus_product *p;
|
||||
|
||||
for (p = njata32_cardbus_products;
|
||||
p->p_vendor != PCI_VENDOR_INVALID; p++) {
|
||||
if (CARDBUS_VENDOR(ca->ca_id) == p->p_vendor &&
|
||||
CARDBUS_PRODUCT(ca->ca_id) == p->p_product)
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
njata_cardbus_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *match;
|
||||
void *aux;
|
||||
{
|
||||
struct cardbus_attach_args *ca = aux;
|
||||
|
||||
if (njata_cardbus_lookup(ca))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
njata_cardbus_attach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct cardbus_attach_args *ca = aux;
|
||||
struct njata32_cardbus_softc *csc = (void *)self;
|
||||
struct njata32_softc *sc = &csc->sc_njata32;
|
||||
const struct njata32_cardbus_product *prod;
|
||||
cardbus_devfunc_t ct = ca->ca_ct;
|
||||
cardbus_chipset_tag_t cc = ct->ct_cc;
|
||||
cardbus_function_tag_t cf = ct->ct_cf;
|
||||
pcireg_t reg;
|
||||
int csr;
|
||||
uint8_t latency = 0x20;
|
||||
|
||||
if ((prod = njata_cardbus_lookup(ca)) == NULL)
|
||||
panic("njata_cardbus_attach");
|
||||
|
||||
printf(": Workbit NinjaATA-32 IDE controller\n");
|
||||
|
||||
csc->sc_ct = ct;
|
||||
csc->sc_tag = ca->ca_tag;
|
||||
csc->sc_intrline = ca->ca_intrline;
|
||||
|
||||
/*
|
||||
* Map the device.
|
||||
*/
|
||||
csr = PCI_COMMAND_MASTER_ENABLE;
|
||||
|
||||
/*
|
||||
* Map registers.
|
||||
* Try memory map first, and then try I/O.
|
||||
*/
|
||||
if ((prod->p_flags & NJATA32_FL_IOMAP_ONLY) == 0 &&
|
||||
Cardbus_mapreg_map(csc->sc_ct, NJATA32_CARDBUS_BASEADDR_MEM,
|
||||
PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
|
||||
&NJATA32_REGT(sc), &csc->sc_regmaph, NULL, &csc->sc_regmap_size)
|
||||
== 0) {
|
||||
if (bus_space_subregion(NJATA32_REGT(sc), csc->sc_regmaph,
|
||||
NJATA32_MEMOFFSET_REG, NJATA32_REGSIZE, &NJATA32_REGH(sc))
|
||||
!= 0) {
|
||||
/* failed -- undo map and try I/O */
|
||||
Cardbus_mapreg_unmap(csc->sc_ct,
|
||||
NJATA32_CARDBUS_BASEADDR_MEM, NJATA32_REGT(sc),
|
||||
csc->sc_regmaph, csc->sc_regmap_size);
|
||||
goto try_io;
|
||||
}
|
||||
#ifdef NJATA32_DEBUG
|
||||
printf("%s: memory space mapped, size %u\n",
|
||||
NJATA32NAME(sc), (unsigned)csc->sc_regmap_size);
|
||||
#endif
|
||||
csr |= PCI_COMMAND_MEM_ENABLE;
|
||||
sc->sc_flags = NJATA32_MEM_MAPPED;
|
||||
(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
|
||||
} else {
|
||||
try_io:
|
||||
if (Cardbus_mapreg_map(csc->sc_ct, NJATA32_CARDBUS_BASEADDR_IO,
|
||||
PCI_MAPREG_TYPE_IO, 0, &NJATA32_REGT(sc),
|
||||
&NJATA32_REGH(sc), NULL, &csc->sc_regmap_size) == 0) {
|
||||
#ifdef NJATA32_DEBUG
|
||||
printf("%s: io space mapped, size %u\n",
|
||||
NJATA32NAME(sc), (unsigned)csc->sc_regmap_size);
|
||||
#endif
|
||||
csr |= PCI_COMMAND_IO_ENABLE;
|
||||
sc->sc_flags = NJATA32_IO_MAPPED;
|
||||
(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
|
||||
} else {
|
||||
printf("%s: unable to map device registers\n",
|
||||
NJATA32NAME(sc));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the right access type is on the CardBus bridge. */
|
||||
(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
|
||||
|
||||
/* Enable the appropriate bits in the PCI CSR. */
|
||||
reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_COMMAND_STATUS_REG);
|
||||
reg &= ~(PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE);
|
||||
reg |= csr;
|
||||
cardbus_conf_write(cc, cf, ca->ca_tag, PCI_COMMAND_STATUS_REG, reg);
|
||||
|
||||
/*
|
||||
* Make sure the latency timer is set to some reasonable
|
||||
* value.
|
||||
*/
|
||||
reg = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG);
|
||||
if (CARDBUS_LATTIMER(reg) < latency) {
|
||||
reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
|
||||
reg |= (latency << CARDBUS_LATTIMER_SHIFT);
|
||||
cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG, reg);
|
||||
}
|
||||
|
||||
sc->sc_dmat = ca->ca_dmat;
|
||||
|
||||
/*
|
||||
* Establish the interrupt.
|
||||
*/
|
||||
sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline, IPL_BIO,
|
||||
njata32_intr, sc);
|
||||
if (sc->sc_ih == NULL) {
|
||||
printf("%s: unable to establish interrupt at %d\n",
|
||||
NJATA32NAME(sc), ca->ca_intrline);
|
||||
return;
|
||||
}
|
||||
printf("%s: interrupting at %d\n", NJATA32NAME(sc), ca->ca_intrline);
|
||||
|
||||
/* attach */
|
||||
njata32_attach(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
njata_cardbus_detach(self, flags)
|
||||
struct device *self;
|
||||
int flags;
|
||||
{
|
||||
struct njata32_cardbus_softc *csc = (void *) self;
|
||||
struct njata32_softc *sc = &csc->sc_njata32;
|
||||
int rv;
|
||||
|
||||
rv = njata32_detach(sc, flags);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (sc->sc_ih)
|
||||
cardbus_intr_disestablish(csc->sc_ct->ct_cc,
|
||||
csc->sc_ct->ct_cf, sc->sc_ih);
|
||||
|
||||
if (sc->sc_flags & NJATA32_IO_MAPPED)
|
||||
Cardbus_mapreg_unmap(csc->sc_ct, NJATA32_CARDBUS_BASEADDR_IO,
|
||||
NJATA32_REGT(sc), NJATA32_REGH(sc), csc->sc_regmap_size);
|
||||
if (sc->sc_flags & NJATA32_MEM_MAPPED)
|
||||
Cardbus_mapreg_unmap(csc->sc_ct, NJATA32_CARDBUS_BASEADDR_MEM,
|
||||
NJATA32_REGT(sc), csc->sc_regmaph, csc->sc_regmap_size);
|
||||
|
||||
return 0;
|
||||
}
|
726
sys/dev/ic/ninjaata32.c
Normal file
726
sys/dev/ic/ninjaata32.c
Normal file
@ -0,0 +1,726 @@
|
||||
/* $Id: ninjaata32.c,v 1.1 2006/09/07 14:22:07 itohy Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 ITOH Yasufumi <itohy@NetBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 AUTHORS 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 AUTHORS 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(0, "$NetBSD: ninjaata32.c,v 1.1 2006/09/07 14:22:07 itohy Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <dev/ata/atavar.h>
|
||||
#include <dev/ic/wdcreg.h>
|
||||
#include <dev/ic/wdcvar.h>
|
||||
|
||||
#include <dev/ic/ninjaata32reg.h>
|
||||
#include <dev/ic/ninjaata32var.h>
|
||||
|
||||
#ifdef NJATA32_DEBUG
|
||||
#define DPRINTF(x) printf x
|
||||
#else
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
static void njata32_init(struct njata32_softc *, int nosleep);
|
||||
static void njata32_irqack(struct ata_channel *);
|
||||
static void njata32_clearirq(struct ata_channel *, int);
|
||||
static void njata32_setup_channel(struct ata_channel *);
|
||||
static int njata32_dma_init(void *, int channel, int drive,
|
||||
void *databuf, size_t datalen, int flags);
|
||||
static void njata32_piobm_start(void *, int channel, int drive, int skip,
|
||||
int xferlen, int flags);
|
||||
static int njata32_dma_finish(void *, int channel, int drive, int force);
|
||||
static void njata32_piobm_done(void *, int channel, int drive);
|
||||
|
||||
#if 0 /* ATA DMA is currently unused */
|
||||
static const uint8_t njata32_timing_dma[NJATA32_MODE_MAX_DMA + 1] = {
|
||||
NJATA32_TIMING_DMA0, NJATA32_TIMING_DMA1, NJATA32_TIMING_DMA2
|
||||
};
|
||||
#endif
|
||||
static const uint8_t njata32_timing_pio[NJATA32_MODE_MAX_PIO + 1] = {
|
||||
NJATA32_TIMING_PIO0, NJATA32_TIMING_PIO1, NJATA32_TIMING_PIO2,
|
||||
NJATA32_TIMING_PIO3, NJATA32_TIMING_PIO4
|
||||
};
|
||||
|
||||
static void
|
||||
njata32_init(sc, nosleep)
|
||||
struct njata32_softc *sc;
|
||||
int nosleep; /* can't sleep (during cold boot and in interrupt) */
|
||||
{
|
||||
|
||||
/* disable interrupts */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_IRQ_SELECT, 0);
|
||||
|
||||
/* bus reset */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_AS,
|
||||
NJATA32_AS_WAIT0 | NJATA32_AS_BUS_RESET);
|
||||
if (nosleep)
|
||||
delay(50000);
|
||||
else
|
||||
tsleep(sc, PRIBIO, "njaini", mstohz(50));
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_AS,
|
||||
NJATA32_AS_WAIT0);
|
||||
|
||||
/* initial transfer speed */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_TIMING, NJATA32_TIMING_PIO0);
|
||||
|
||||
/* setup busmaster mode */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_IOBM,
|
||||
NJATA32_IOBM_DEFAULT);
|
||||
|
||||
/* enable interrupts */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_IRQ_SELECT, NJATA32_IRQ_XFER | NJATA32_IRQ_DEV);
|
||||
}
|
||||
|
||||
void
|
||||
njata32_attach(sc)
|
||||
struct njata32_softc *sc;
|
||||
{
|
||||
bus_addr_t dmaaddr;
|
||||
int i, devno, error;
|
||||
struct wdc_regs *wdr;
|
||||
|
||||
/*
|
||||
* allocate DMA resource
|
||||
*/
|
||||
if ((error = bus_dmamem_alloc(sc->sc_dmat,
|
||||
sizeof(struct njata32_dma_page), PAGE_SIZE, 0,
|
||||
&sc->sc_sgt_seg, 1, &sc->sc_sgt_nsegs, BUS_DMA_NOWAIT)) != 0) {
|
||||
printf("%s: unable to allocate sgt page, error = %d\n",
|
||||
NJATA32NAME(sc), error);
|
||||
return;
|
||||
}
|
||||
if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_sgt_seg,
|
||||
sc->sc_sgt_nsegs, sizeof(struct njata32_dma_page),
|
||||
(caddr_t *)&sc->sc_sgtpg,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
|
||||
printf("%s: unable to map sgt page, error = %d\n",
|
||||
NJATA32NAME(sc), error);
|
||||
goto fail1;
|
||||
}
|
||||
if ((error = bus_dmamap_create(sc->sc_dmat,
|
||||
sizeof(struct njata32_dma_page), 1,
|
||||
sizeof(struct njata32_dma_page), 0, BUS_DMA_NOWAIT,
|
||||
&sc->sc_dmamap_sgt)) != 0) {
|
||||
printf("%s: unable to create sgt DMA map, error = %d\n",
|
||||
NJATA32NAME(sc), error);
|
||||
goto fail2;
|
||||
}
|
||||
if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_sgt,
|
||||
sc->sc_sgtpg, sizeof(struct njata32_dma_page),
|
||||
NULL, BUS_DMA_NOWAIT)) != 0) {
|
||||
printf("%s: unable to load sgt DMA map, error = %d\n",
|
||||
NJATA32NAME(sc), error);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
dmaaddr = sc->sc_dmamap_sgt->dm_segs[0].ds_addr;
|
||||
|
||||
for (devno = 0; devno < NJATA32_NUM_DEV; devno++) {
|
||||
sc->sc_dev[devno].d_sgt = sc->sc_sgtpg->dp_sg[devno];
|
||||
sc->sc_dev[devno].d_sgt_dma = dmaaddr +
|
||||
offsetof(struct njata32_dma_page, dp_sg[devno]);
|
||||
|
||||
error = bus_dmamap_create(sc->sc_dmat,
|
||||
NJATA32_MAX_XFER, /* max total map size */
|
||||
NJATA32_NUM_SG, /* max number of segments */
|
||||
NJATA32_SGT_MAXSEGLEN, /* max size of a segment */
|
||||
0, /* boundary */
|
||||
BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
|
||||
&sc->sc_dev[devno].d_dmamap_xfer);
|
||||
if (error) {
|
||||
printf("%s: failed to create DMA map (error = %d)\n",
|
||||
NJATA32NAME(sc), error);
|
||||
goto fail4;
|
||||
}
|
||||
}
|
||||
|
||||
/* device properties */
|
||||
sc->sc_wdcdev.sc_atac.atac_cap =
|
||||
ATAC_CAP_DATA16 | ATAC_CAP_DATA32 | ATAC_CAP_PIOBM;
|
||||
sc->sc_wdcdev.irqack = njata32_irqack;
|
||||
sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_wdc_chanarray;
|
||||
sc->sc_wdcdev.sc_atac.atac_nchannels = NJATA32_NCHAN; /* 1 */
|
||||
sc->sc_wdcdev.sc_atac.atac_pio_cap = NJATA32_MODE_MAX_PIO;
|
||||
#if 0 /* ATA DMA is currently unused */
|
||||
sc->sc_wdcdev.sc_atac.atac_dma_cap = NJATA32_MODE_MAX_DMA;
|
||||
#endif
|
||||
sc->sc_wdcdev.sc_atac.atac_set_modes = njata32_setup_channel;
|
||||
|
||||
/* DMA control functions */
|
||||
sc->sc_wdcdev.dma_arg = sc;
|
||||
sc->sc_wdcdev.dma_init = njata32_dma_init;
|
||||
sc->sc_wdcdev.piobm_start = njata32_piobm_start;
|
||||
sc->sc_wdcdev.dma_finish = njata32_dma_finish;
|
||||
sc->sc_wdcdev.piobm_done = njata32_piobm_done;
|
||||
|
||||
sc->sc_wdcdev.cap |= WDC_CAPABILITY_NO_EXTRA_RESETS;
|
||||
|
||||
sc->sc_wdcdev.regs = wdr = &sc->sc_wdc_regs;
|
||||
|
||||
/* only one channel */
|
||||
sc->sc_wdc_chanarray[0] = &sc->sc_ch[0].ch_ata_channel;
|
||||
sc->sc_ch[0].ch_ata_channel.ch_channel = 0;
|
||||
sc->sc_ch[0].ch_ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
|
||||
sc->sc_ch[0].ch_ata_channel.ch_queue = &sc->sc_wdc_chqueue;
|
||||
sc->sc_ch[0].ch_ata_channel.ch_ndrive = 2; /* max number of drives */
|
||||
|
||||
/* map ATA registers */
|
||||
for (i = 0; i < WDC_NREG; i++) {
|
||||
if (bus_space_subregion(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_OFFSET_WDCREGS + i,
|
||||
i == wd_data ? 4 : 1, &wdr->cmd_iohs[i]) != 0) {
|
||||
aprint_error("%s: couldn't subregion cmd regs\n",
|
||||
NJATA32NAME(sc));
|
||||
goto fail4;
|
||||
}
|
||||
}
|
||||
wdc_init_shadow_regs(&sc->sc_ch[0].ch_ata_channel);
|
||||
wdr->data32iot = NJATA32_REGT(sc);
|
||||
wdr->data32ioh = wdr->cmd_iohs[wd_data];
|
||||
|
||||
/* map ATA ctl reg */
|
||||
wdr->ctl_iot = NJATA32_REGT(sc);
|
||||
if (bus_space_subregion(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_ALTSTATUS, 1, &wdr->ctl_ioh) != 0) {
|
||||
aprint_error("%s: couldn't subregion ctl regs\n",
|
||||
NJATA32NAME(sc));
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
sc->sc_flags |= NJATA32_CMDPG_MAPPED;
|
||||
|
||||
/* use flags value as busmaster wait */
|
||||
if ((sc->sc_bmwait =
|
||||
device_cfdata(&sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags &
|
||||
(NJATA32_BM_WAIT_MASK >> NJATA32_BM_WAIT_SHIFT)) > 0)
|
||||
aprint_normal("%s: busmaster wait = %d\n",
|
||||
NJATA32NAME(sc), sc->sc_bmwait);
|
||||
|
||||
njata32_init(sc, cold);
|
||||
|
||||
wdcattach(&sc->sc_ch[0].ch_ata_channel);
|
||||
|
||||
return;
|
||||
|
||||
/*
|
||||
* cleanup
|
||||
*/
|
||||
fail4: while (--devno >= 0) {
|
||||
bus_dmamap_destroy(sc->sc_dmat,
|
||||
sc->sc_dev[devno].d_dmamap_xfer);
|
||||
}
|
||||
bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_sgt);
|
||||
fail3: bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_sgt);
|
||||
fail2: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_sgtpg,
|
||||
sizeof(struct njata32_dma_page));
|
||||
fail1: bus_dmamem_free(sc->sc_dmat, &sc->sc_sgt_seg, sc->sc_sgt_nsegs);
|
||||
}
|
||||
|
||||
int
|
||||
njata32_detach(sc, flags)
|
||||
struct njata32_softc *sc;
|
||||
int flags;
|
||||
{
|
||||
int rv, devno;
|
||||
|
||||
if (sc->sc_flags & NJATA32_CMDPG_MAPPED) {
|
||||
if ((rv = wdcdetach(&sc->sc_wdcdev.sc_atac.atac_dev, flags)))
|
||||
return rv;
|
||||
|
||||
/* free DMA resource */
|
||||
for (devno = 0; devno < NJATA32_NUM_DEV; devno++) {
|
||||
bus_dmamap_destroy(sc->sc_dmat,
|
||||
sc->sc_dev[devno].d_dmamap_xfer);
|
||||
}
|
||||
bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_sgt);
|
||||
bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_sgt);
|
||||
bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_sgtpg,
|
||||
sizeof(struct njata32_dma_page));
|
||||
bus_dmamem_free(sc->sc_dmat, &sc->sc_sgt_seg, sc->sc_sgt_nsegs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
njata32_irqack(chp)
|
||||
struct ata_channel *chp;
|
||||
{
|
||||
struct njata32_softc *sc = (void *)chp->ch_atac;
|
||||
|
||||
/* disable busmaster */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_BM, (sc->sc_bmwait << NJATA32_BM_WAIT_SHIFT));
|
||||
}
|
||||
|
||||
static void
|
||||
njata32_clearirq(chp, irq)
|
||||
struct ata_channel *chp;
|
||||
int irq;
|
||||
{
|
||||
struct njata32_softc *sc = (void *)chp->ch_atac;
|
||||
|
||||
printf("%s: unhandled intr: irq %#x, bm %#x, ",
|
||||
NJATA32NAME(sc), irq,
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_BM));
|
||||
|
||||
/* disable busmaster */
|
||||
njata32_irqack(chp);
|
||||
|
||||
/* clear device interrupt */
|
||||
printf("err %#x, seccnt %#x, cyl %#x, sdh %#x, ",
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_ERROR),
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_SECCNT),
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_CYL_LO) |
|
||||
(bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_CYL_HI) << 8),
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_SDH));
|
||||
printf("status %#x\n",
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_STATUS));
|
||||
}
|
||||
|
||||
static void
|
||||
njata32_setup_channel(chp)
|
||||
struct ata_channel *chp;
|
||||
{
|
||||
struct njata32_softc *sc = (void *)chp->ch_atac;
|
||||
struct ata_drive_datas *drvp;
|
||||
int drive;
|
||||
uint8_t mode;
|
||||
|
||||
KASSERT(chp->ch_ndrive != 0);
|
||||
|
||||
sc->sc_timing_pio = 0;
|
||||
#if 0 /* ATA DMA is currently unused */
|
||||
sc->sc_timing_dma = 0;
|
||||
#endif
|
||||
|
||||
for (drive = 0; drive < chp->ch_ndrive; drive++) {
|
||||
drvp = &chp->ch_drive[drive];
|
||||
if ((drvp->drive_flags & DRIVE) == 0)
|
||||
continue; /* no drive */
|
||||
|
||||
#if 0 /* ATA DMA is currently unused */
|
||||
if ((drvp->drive_flags & DRIVE_DMA) != 0) {
|
||||
/*
|
||||
* Multiword DMA
|
||||
*/
|
||||
if ((mode = drvp->DMA_mode) > NJATA32_MODE_MAX_DMA)
|
||||
mode = NJATA32_MODE_MAX_DMA;
|
||||
if (sc->sc_timing_dma < njata32_timing_dma[mode])
|
||||
sc->sc_timing_dma = njata32_timing_dma[mode];
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* PIO
|
||||
*/
|
||||
if ((mode = drvp->PIO_mode) > NJATA32_MODE_MAX_PIO)
|
||||
mode = NJATA32_MODE_MAX_PIO;
|
||||
if (sc->sc_timing_pio < njata32_timing_pio[mode])
|
||||
sc->sc_timing_pio = njata32_timing_pio[mode];
|
||||
}
|
||||
|
||||
/* set timing for PIO */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_TIMING, sc->sc_timing_pio);
|
||||
}
|
||||
|
||||
/*
|
||||
* map DMA buffer
|
||||
*/
|
||||
int
|
||||
njata32_dma_init(v, channel, drive, databuf, datalen, flags)
|
||||
void *v;
|
||||
int channel, drive;
|
||||
void *databuf;
|
||||
size_t datalen;
|
||||
int flags;
|
||||
{
|
||||
struct njata32_softc *sc = v;
|
||||
int error;
|
||||
struct njata32_device *dev = &sc->sc_dev[drive];
|
||||
|
||||
KASSERT(channel == 0);
|
||||
KASSERT((dev->d_flags & NJATA32_DEV_DMA_MAPPED) == 0);
|
||||
KASSERT((dev->d_flags & NJATA32_DEV_DMA_STARTED) == 0);
|
||||
|
||||
KASSERT(flags & (WDC_DMA_PIOBM_ATA | WDC_DMA_PIOBM_ATAPI));
|
||||
|
||||
/* use PIO for short transfer */
|
||||
if (datalen < 64 /* needs tune */) {
|
||||
DPRINTF(("%s: njata32_dma_init: short transfer (%u)\n",
|
||||
NJATA32NAME(sc), (unsigned)datalen));
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_TIMING, sc->sc_timing_pio);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* use PIO for unaligned transfer (word alignment seems OK) */
|
||||
if (((uintptr_t)databuf & 1) || (datalen & 1)) {
|
||||
DPRINTF(("%s: njata32_dma_init: unaligned: buf %p, len %u\n",
|
||||
NJATA32NAME(sc), databuf, (unsigned)datalen));
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
DPRINTF(("%s: njata32_dma_init: %s: databuf %p, datalen %u\n",
|
||||
NJATA32NAME(sc), (flags & WDC_DMA_READ) ? "read" : "write",
|
||||
databuf, (unsigned)datalen));
|
||||
|
||||
error = bus_dmamap_load(sc->sc_dmat, dev->d_dmamap_xfer,
|
||||
databuf, datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
|
||||
((flags & WDC_DMA_READ) ? BUS_DMA_READ : BUS_DMA_WRITE));
|
||||
if (error) {
|
||||
printf("%s: load xfer failed, error %d\n",
|
||||
NJATA32NAME(sc), error);
|
||||
return error;
|
||||
}
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, dev->d_dmamap_xfer, 0,
|
||||
dev->d_dmamap_xfer->dm_mapsize,
|
||||
(flags & WDC_DMA_READ) ?
|
||||
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
|
||||
|
||||
dev->d_flags =
|
||||
((flags & WDC_DMA_READ) ? NJATA32_DEV_DMA_READ : 0) |
|
||||
((flags & WDC_DMA_PIOBM_ATAPI) ? NJATA32_DEV_DMA_ATAPI : 0) |
|
||||
NJATA32_DEV_DMA_MAPPED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* start DMA
|
||||
*
|
||||
* top: databuf + skip
|
||||
* size: xferlen
|
||||
*/
|
||||
void
|
||||
njata32_piobm_start(v, channel, drive, skip, xferlen, flags)
|
||||
void *v;
|
||||
int channel, drive;
|
||||
int skip, xferlen; /* offset/size in mapped DMA buffer */
|
||||
int flags;
|
||||
{
|
||||
struct njata32_softc *sc = v;
|
||||
struct njata32_device *dev = &sc->sc_dev[drive];
|
||||
int i, nsegs, seglen;
|
||||
uint8_t bmreg;
|
||||
|
||||
DPRINTF(("%s: njata32_piobm_start: ch%d, dv%d, skip %d, xferlen %d\n",
|
||||
NJATA32NAME(sc), channel, drive, skip, xferlen));
|
||||
|
||||
KASSERT(channel == 0);
|
||||
KASSERT(dev->d_flags & NJATA32_DEV_DMA_MAPPED);
|
||||
KASSERT((dev->d_flags & NJATA32_DEV_DMA_STARTED) == 0);
|
||||
|
||||
/*
|
||||
* create scatter/gather table
|
||||
* XXX this code may be slow
|
||||
*/
|
||||
for (i = nsegs = 0;
|
||||
i < dev->d_dmamap_xfer->dm_nsegs && xferlen > 0; i++) {
|
||||
if (dev->d_dmamap_xfer->dm_segs[i].ds_len <= skip) {
|
||||
skip -= dev->d_dmamap_xfer->dm_segs[i].ds_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
seglen = dev->d_dmamap_xfer->dm_segs[i].ds_len - skip;
|
||||
if (seglen > xferlen)
|
||||
seglen = xferlen;
|
||||
|
||||
dev->d_sgt[nsegs].sg_addr =
|
||||
htole32(dev->d_dmamap_xfer->dm_segs[i].ds_addr + skip);
|
||||
dev->d_sgt[nsegs].sg_len = htole32(seglen);
|
||||
|
||||
xferlen -= seglen;
|
||||
nsegs++;
|
||||
skip = 0;
|
||||
}
|
||||
sc->sc_piobm_nsegs = nsegs;
|
||||
/* end mark */
|
||||
dev->d_sgt[nsegs - 1].sg_len |= htole32(NJATA32_SGT_ENDMARK);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (xferlen)
|
||||
panic("%s: njata32_piobm_start: xferlen residue %d\n",
|
||||
NJATA32NAME(sc), xferlen);
|
||||
#endif
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_sgt,
|
||||
(char *)dev->d_sgt - (char *)sc->sc_sgtpg,
|
||||
sizeof(struct njata32_sgtable) * nsegs,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
|
||||
/* set timing for PIO */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_TIMING, sc->sc_timing_pio);
|
||||
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_IOBM,
|
||||
NJATA32_IOBM_DEFAULT);
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_AS,
|
||||
NJATA32_AS_WAIT0);
|
||||
|
||||
/*
|
||||
* interrupt configuration
|
||||
*/
|
||||
if ((dev->d_flags & (NJATA32_DEV_DMA_READ | NJATA32_DEV_DMA_ATAPI)) ==
|
||||
NJATA32_DEV_DMA_READ) {
|
||||
/*
|
||||
* ATA piobm read is executed while device interrupt is active,
|
||||
* so disable device interrupt here
|
||||
*/
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_IRQ_SELECT, NJATA32_IRQ_XFER);
|
||||
}
|
||||
|
||||
/* enable scatter/gather busmaster transfer */
|
||||
bmreg = NJATA32_BM_EN | NJATA32_BM_SG |
|
||||
(sc->sc_bmwait << NJATA32_BM_WAIT_SHIFT) |
|
||||
((dev->d_flags & NJATA32_DEV_DMA_READ) ? NJATA32_BM_RD : 0);
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_BM,
|
||||
bmreg);
|
||||
|
||||
/* load scatter/gather table */
|
||||
bus_space_write_4(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_DMAADDR, dev->d_sgt_dma);
|
||||
bus_space_write_4(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_DMALENGTH, sizeof(struct njata32_sgtable) * nsegs);
|
||||
|
||||
/* start transfer */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_BM,
|
||||
(bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_BM)
|
||||
& ~(NJATA32_BM_RD|NJATA32_BM_SG|NJATA32_BM_WAIT_MASK)) |
|
||||
bmreg | NJATA32_BM_GO);
|
||||
|
||||
sc->sc_devflags = dev->d_flags;
|
||||
if (flags & WDC_PIOBM_XFER_IRQ)
|
||||
sc->sc_devflags |= NJATA32_DEV_XFER_INTR;
|
||||
#ifdef DIAGNOSTIC
|
||||
dev->d_flags |= NJATA32_DEV_DMA_STARTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* end of DMA
|
||||
*/
|
||||
int
|
||||
njata32_dma_finish(v, channel, drive, force)
|
||||
void *v;
|
||||
int channel, drive;
|
||||
int force;
|
||||
{
|
||||
struct njata32_softc *sc = v;
|
||||
int bm;
|
||||
int error = 0;
|
||||
|
||||
DPRINTF(("%s: njata32_dma_finish: bm = %#x\n", NJATA32NAME(sc),
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_BM)));
|
||||
|
||||
KASSERT(channel == 0);
|
||||
KASSERT(sc->sc_dev[drive].d_flags & NJATA32_DEV_DMA_MAPPED);
|
||||
KASSERT(sc->sc_dev[drive].d_flags & NJATA32_DEV_DMA_STARTED);
|
||||
|
||||
bm = bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_BM);
|
||||
|
||||
#ifdef NJATA32_DEBUG
|
||||
printf("%s: irq %#x, bm %#x, 18 %#x, 1c %#x\n", NJATA32NAME(sc),
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_IRQ_STAT),
|
||||
bm,
|
||||
bus_space_read_4(NJATA32_REGT(sc), NJATA32_REGH(sc), 0x18),
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc), 0x1c));
|
||||
#endif
|
||||
|
||||
/* check if DMA is active */
|
||||
if (bm & NJATA32_BM_GO) {
|
||||
error = WDC_DMAST_NOIRQ;
|
||||
|
||||
switch (force) {
|
||||
case WDC_DMAEND_END:
|
||||
return error;
|
||||
|
||||
case WDC_DMAEND_ABRT:
|
||||
printf("%s: aborting DMA\n", NJATA32NAME(sc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ???
|
||||
* For unknown reason, PIOBM transfer sometimes fails in the middle,
|
||||
* in which case the bit #7 of BM register becomes 0.
|
||||
* Increasing the wait value seems to improve the situation.
|
||||
*/
|
||||
if ((bm & NJATA32_BM_DONE) == 0) {
|
||||
error |= WDC_DMAST_ERR;
|
||||
printf("%s: busmaster error", NJATA32NAME(sc));
|
||||
if (sc->sc_bmwait < 1 /* XXX */) {
|
||||
sc->sc_bmwait++;
|
||||
printf(", new busmaster wait = %d", sc->sc_bmwait);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* stop command */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_AS,
|
||||
NJATA32_AS_WAIT0);
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_BM,
|
||||
(sc->sc_bmwait << NJATA32_BM_WAIT_SHIFT));
|
||||
|
||||
/* set timing for PIO */
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_TIMING, sc->sc_timing_pio);
|
||||
|
||||
/*
|
||||
* reenable device interrupt in case it was disabled for
|
||||
* this transfer
|
||||
*/
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_IRQ_SELECT, NJATA32_IRQ_XFER | NJATA32_IRQ_DEV);
|
||||
|
||||
#if 1 /* should be? */
|
||||
if ((sc->sc_devflags & NJATA32_DEV_GOT_XFER_INTR) == 0)
|
||||
error |= WDC_DMAST_ERR;
|
||||
#endif
|
||||
sc->sc_devflags = 0;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
sc->sc_dev[drive].d_flags &= ~NJATA32_DEV_DMA_STARTED;
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* unmap DMA buffer
|
||||
*/
|
||||
void
|
||||
njata32_piobm_done(v, channel, drive)
|
||||
void *v;
|
||||
int channel, drive;
|
||||
{
|
||||
struct njata32_softc *sc = v;
|
||||
struct njata32_device *dev = &sc->sc_dev[drive];
|
||||
|
||||
DPRINTF(("%s: njata32_piobm_done: ch%d dv%d\n",
|
||||
NJATA32NAME(sc), channel, drive));
|
||||
|
||||
KASSERT(channel == 0);
|
||||
KASSERT(dev->d_flags & NJATA32_DEV_DMA_MAPPED);
|
||||
KASSERT((dev->d_flags & NJATA32_DEV_DMA_STARTED) == 0);
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_sgt,
|
||||
(char *)dev->d_sgt - (char *)sc->sc_sgtpg,
|
||||
sizeof(struct njata32_sgtable) * sc->sc_piobm_nsegs,
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
/* unload dma map */
|
||||
bus_dmamap_sync(sc->sc_dmat, dev->d_dmamap_xfer,
|
||||
0, dev->d_dmamap_xfer->dm_mapsize,
|
||||
(dev->d_flags & NJATA32_DEV_DMA_READ) ?
|
||||
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_sgt,
|
||||
(char *)dev->d_sgt - (char *)sc->sc_sgtpg,
|
||||
sizeof(struct njata32_sgtable) * NJATA32_NUM_SG,
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
bus_dmamap_unload(sc->sc_dmat, dev->d_dmamap_xfer);
|
||||
dev->d_flags &= ~NJATA32_DEV_DMA_MAPPED;
|
||||
}
|
||||
|
||||
int
|
||||
njata32_intr(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct njata32_softc *sc = arg;
|
||||
struct ata_channel *chp;
|
||||
int irq;
|
||||
|
||||
irq = bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_IRQ_STAT);
|
||||
if ((irq & (NJATA32_IRQ_XFER | NJATA32_IRQ_DEV)) == 0)
|
||||
return 0; /* not mine */
|
||||
|
||||
DPRINTF(("%s: njata32_intr: irq = %#x, altstatus = %#x\n",
|
||||
NJATA32NAME(sc), irq,
|
||||
bus_space_read_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_WD_ALTSTATUS)));
|
||||
|
||||
chp = &sc->sc_ch[0].ch_ata_channel;
|
||||
|
||||
if (irq & NJATA32_IRQ_XFER)
|
||||
sc->sc_devflags |= NJATA32_DEV_GOT_XFER_INTR;
|
||||
|
||||
if ((irq & (NJATA32_IRQ_XFER | NJATA32_IRQ_DEV)) == NJATA32_IRQ_XFER &&
|
||||
(sc->sc_devflags & NJATA32_DEV_XFER_INTR) == 0) {
|
||||
/*
|
||||
* transfer done, wait for device interrupt
|
||||
*/
|
||||
bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
|
||||
NJATA32_REG_BM, (sc->sc_bmwait << NJATA32_BM_WAIT_SHIFT));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If both transfer done interrupt and device interrupt are
|
||||
* active for ATAPI transfer, call wdcintr() twice.
|
||||
*/
|
||||
if ((sc->sc_devflags & NJATA32_DEV_DMA_ATAPI) &&
|
||||
(irq & (NJATA32_IRQ_XFER | NJATA32_IRQ_DEV)) ==
|
||||
(NJATA32_IRQ_XFER | NJATA32_IRQ_DEV) &&
|
||||
(sc->sc_devflags & NJATA32_DEV_XFER_INTR)) {
|
||||
if (wdcintr(chp) == 0) {
|
||||
njata32_clearirq(&sc->sc_ch[0].ch_ata_channel, irq);
|
||||
}
|
||||
}
|
||||
|
||||
if (wdcintr(chp) == 0) {
|
||||
njata32_clearirq(&sc->sc_ch[0].ch_ata_channel, irq);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
154
sys/dev/ic/ninjaata32reg.h
Normal file
154
sys/dev/ic/ninjaata32reg.h
Normal file
@ -0,0 +1,154 @@
|
||||
/* $Id: ninjaata32reg.h,v 1.1 2006/09/07 14:22:07 itohy Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 ITOH Yasufumi <itohy@NetBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 AUTHORS 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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#ifndef _NJATA32REG_H_
|
||||
#define _NJATA32REG_H_
|
||||
|
||||
/*
|
||||
* Workbit NinjaATA (32bit versions), IDE Controller with Busmastering PIO:
|
||||
* NinjaATA-32Bi PCMCIA/CardBus dual mode device ("DuoATA")
|
||||
* (CardBus mode only)
|
||||
* PATA-32 CardBus device
|
||||
*/
|
||||
|
||||
/*
|
||||
* CAVEAT
|
||||
* The names and the functions of the registers are probably incorrect
|
||||
* since no programming information is available in the public.
|
||||
*/
|
||||
|
||||
#define NJATA32_REGSIZE 32 /* size of register set */
|
||||
#define NJATA32_MEMOFFSET_REG 0x860 /* offset of memory mapped register */
|
||||
|
||||
#define NJATA32_REG_IRQ_STAT 0x00 /* len=1 RO */
|
||||
#define NJATA32_REG_IRQ_SELECT 0x01 /* len=1 WO */
|
||||
# define NJATA32_IRQ_XFER 0x01
|
||||
# define NJATA32_IRQ_DEV 0x04
|
||||
|
||||
#define NJATA32_REG_IOBM 0x02 /* len=1 WO */
|
||||
# define NJATA32_IOBM_01 0x01
|
||||
# define NJATA32_IOBM_02 0x02
|
||||
# define NJATA32_IOBM_MMENBL 0x08
|
||||
# define NJATA32_IOBM_BURST 0x10
|
||||
# define NJATA32_IOBM_NO_BMSTART0 0x20
|
||||
# define NJATA32_IOBM_80 0x80
|
||||
|
||||
# define NJATA32_IOBM_DEFAULT (NJATA32_IOBM_01 | NJATA32_IOBM_02 | \
|
||||
NJATA32_IOBM_BURST | NJATA32_IOBM_NO_BMSTART0 | NJATA32_IOBM_80)
|
||||
|
||||
#define NJATA32_REG_AS 0x04 /* len=1 WO */
|
||||
# define NJATA32_AS_START 0x01 /* 0: PIO BM, 1: DMA BM */
|
||||
# define NJATA32_AS_WAIT0 0x00
|
||||
# define NJATA32_AS_WAIT1 0x04
|
||||
# define NJATA32_AS_WAIT2 0x08
|
||||
# define NJATA32_AS_WAIT3 0x0c
|
||||
# define NJATA32_AS_BUS_RESET 0x80
|
||||
|
||||
#define NJATA32_REG_DMAADDR 0x08 /* len=4 R/W */
|
||||
#define NJATA32_REG_DMALENGTH 0x0c /* len=4 R/W */
|
||||
|
||||
/*
|
||||
* WDC registers
|
||||
*/
|
||||
#define NJATA32_OFFSET_WDCREGS 0x10
|
||||
|
||||
#define NJATA32_REG_WD_DATA 0x10 /* len=1/2/4 R/W */
|
||||
#define NJATA32_REG_WD_ERROR 0x11 /* len=1 RO */
|
||||
#define NJATA32_REG_WD_FEATURES 0x11 /* len=1 WO */
|
||||
#define NJATA32_REG_WD_SECCNT 0x12 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_IREASON 0x12 /* len=1 R/W (ATAPI) */
|
||||
#define NJATA32_REG_WD_SECTOR 0x13 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_LBA_LO 0x13 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_CYL_LO 0x14 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_LBA_MI 0x14 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_CYL_HI 0x15 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_LBA_HI 0x15 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_SDH 0x16 /* len=1 R/W */
|
||||
#define NJATA32_REG_WD_COMMAND 0x17 /* len=1 WO */
|
||||
#define NJATA32_REG_WD_STATUS 0x17 /* len=1 RO */
|
||||
|
||||
#if 0 /* these registers seem to show the busmaster status */
|
||||
/* ? */
|
||||
#define NJATA32_REG_18 0x18 /* len=4 RO */
|
||||
/* ? */
|
||||
#define NJATA32_REG_1c 0x1c /* len=1 RO */
|
||||
#endif
|
||||
|
||||
#define NJATA32_REG_BM 0x1d /* len=1 R/W */
|
||||
# define NJATA32_BM_EN 0x01
|
||||
# define NJATA32_BM_RD 0x02 /* 0: write, 1: read */
|
||||
# define NJATA32_BM_SG 0x04 /* 1: use scatter/gather tbl */
|
||||
# define NJATA32_BM_GO 0x08
|
||||
# define NJATA32_BM_WAIT0 0x00
|
||||
# define NJATA32_BM_WAIT1 0x10
|
||||
# define NJATA32_BM_WAIT2 0x20
|
||||
# define NJATA32_BM_WAIT3 0x30
|
||||
# define NJATA32_BM_WAIT_MASK 0x30
|
||||
# define NJATA32_BM_WAIT_SHIFT 4
|
||||
# define NJATA32_BM_DONE 0x80 /* ? */
|
||||
|
||||
#define NJATA32_REG_WD_ALTSTATUS 0x1e /* len=1 R */
|
||||
|
||||
#define NJATA32_REG_TIMING 0x1f /* len=1 W */
|
||||
/* timing values for PIO transfer */
|
||||
# define NJATA32_TIMING_PIO0 0xd6
|
||||
# define NJATA32_TIMING_PIO1 0x85
|
||||
# define NJATA32_TIMING_PIO2 0x44
|
||||
# define NJATA32_TIMING_PIO3 0x33
|
||||
# define NJATA32_TIMING_PIO4 0x13
|
||||
# define NJATA32_TIMING_PIO4_ 0x14 /* for timing tweak */
|
||||
# define NJATA32_TIMING_PIO4__ 0x24 /* for timing tweak */
|
||||
/* timing values for multiword DMA transfer */
|
||||
# define NJATA32_TIMING_DMA0 0x88
|
||||
# define NJATA32_TIMING_DMA1 0x23
|
||||
# define NJATA32_TIMING_DMA2 0x13
|
||||
/* timing values for obsolete singleword DMA transfer */
|
||||
# define NJATA32_TIMING_SMDMA0 0xff
|
||||
# define NJATA32_TIMING_SMDMA1 0x88
|
||||
# define NJATA32_TIMING_SMDMA2 0x44
|
||||
|
||||
/*
|
||||
* DMA data structure
|
||||
*/
|
||||
|
||||
/* scatter/gather transfer table entry (8 bytes) */
|
||||
struct njata32_sgtable {
|
||||
uint32_t sg_addr; /* transfer address (little endian) */
|
||||
uint32_t sg_len; /* transfer length (little endian) */
|
||||
#define NJATA32_SGT_ENDMARK 0x80000000
|
||||
#define NJATA32_SGT_MAXSEGLEN 0x10000
|
||||
};
|
||||
#define NJATA32_SGT_MAXENTRY 18
|
||||
|
||||
/*
|
||||
* device specific constants
|
||||
*/
|
||||
#define NJATA32_MODE_MAX_DMA 2
|
||||
#define NJATA32_MODE_MAX_PIO 4
|
||||
|
||||
#endif /* _NJATA32REG_H_ */
|
118
sys/dev/ic/ninjaata32var.h
Normal file
118
sys/dev/ic/ninjaata32var.h
Normal file
@ -0,0 +1,118 @@
|
||||
/* $Id: ninjaata32var.h,v 1.1 2006/09/07 14:22:08 itohy Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 ITOH Yasufumi <itohy@NetBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 AUTHORS 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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#ifndef _NJATA32VAR_H_
|
||||
#define _NJATA32VAR_H_
|
||||
|
||||
#define NJATA32NAME(sc) (sc->sc_wdcdev.sc_atac.atac_dev.dv_xname)
|
||||
|
||||
/* ??? */
|
||||
#define NJATA32_MAX_XFER (64 * 1024)
|
||||
|
||||
/*
|
||||
* DMA page
|
||||
*/
|
||||
/* # device */
|
||||
#define NJATA32_NUM_DEV 2
|
||||
/* # scatter/gather table entries */
|
||||
#define NJATA32_NUM_SG NJATA32_SGT_MAXENTRY
|
||||
|
||||
struct njata32_dma_page {
|
||||
/*
|
||||
* scatter/gather transfer table
|
||||
*/
|
||||
struct njata32_sgtable dp_sg[NJATA32_NUM_DEV][NJATA32_NUM_SG];
|
||||
};
|
||||
|
||||
#define NJATA32_NCHAN 1 /* only one channel */
|
||||
|
||||
struct njata32_softc {
|
||||
struct wdc_softc sc_wdcdev; /* common wdc definitions */
|
||||
|
||||
unsigned sc_flags;
|
||||
#define NJATA32_IO_MAPPED 0x00000001
|
||||
#define NJATA32_MEM_MAPPED 0x00000002
|
||||
#define NJATA32_CMDPG_MAPPED 0x00000004
|
||||
|
||||
unsigned sc_devflags;
|
||||
|
||||
/* interrupt handle */
|
||||
void *sc_ih;
|
||||
|
||||
struct ninjaata32_channel { /* per-channel data */
|
||||
struct ata_channel ch_ata_channel; /* generic part */
|
||||
} sc_ch[NJATA32_NCHAN];
|
||||
|
||||
struct ata_channel *sc_wdc_chanarray[NJATA32_NCHAN];
|
||||
struct ata_queue sc_wdc_chqueue;
|
||||
struct wdc_regs sc_wdc_regs;
|
||||
#define NJATA32_REGT(sc) (sc)->sc_wdc_regs.cmd_iot
|
||||
#define NJATA32_REGH(sc) (sc)->sc_wdc_regs.cmd_baseioh
|
||||
|
||||
/* for DMA */
|
||||
bus_dma_tag_t sc_dmat;
|
||||
struct njata32_dma_page *sc_sgtpg; /* scatter/gather table page */
|
||||
#if 0
|
||||
bus_addr_t sc_sgt_dma;
|
||||
#endif
|
||||
bus_dma_segment_t sc_sgt_seg;
|
||||
bus_dmamap_t sc_dmamap_sgt;
|
||||
int sc_sgt_nsegs;
|
||||
|
||||
int sc_piobm_nsegs;
|
||||
|
||||
uint8_t sc_timing_pio;
|
||||
#if 0 /* ATA DMA is currently unused */
|
||||
uint8_t sc_timing_dma;
|
||||
#endif
|
||||
|
||||
uint8_t sc_bmwait;
|
||||
|
||||
/* per-device structure */
|
||||
struct njata32_device {
|
||||
/* DMA resource */
|
||||
struct njata32_sgtable *d_sgt; /* for host */
|
||||
bus_addr_t d_sgt_dma; /* for device */
|
||||
bus_dmamap_t d_dmamap_xfer;
|
||||
unsigned d_flags;
|
||||
#define NJATA32_DEV_DMA_MAPPED 0x0001
|
||||
#define NJATA32_DEV_DMA_READ 0x0002
|
||||
#define NJATA32_DEV_DMA_ATAPI 0x0004
|
||||
#define NJATA32_DEV_XFER_INTR 0x0100 /* only for sc_devflags */
|
||||
#define NJATA32_DEV_GOT_XFER_INTR 0x0200 /* only for sc_devflags */
|
||||
#define NJATA32_DEV_DMA_STARTED 0x8000 /* for diag */
|
||||
} sc_dev[NJATA32_NUM_DEV];
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
void njata32_attach(struct njata32_softc *);
|
||||
int njata32_detach(struct njata32_softc *, int);
|
||||
int njata32_intr(void *);
|
||||
#endif
|
||||
|
||||
#endif /* _NJATA32VAR_H_ */
|
Loading…
Reference in New Issue
Block a user