summaryrefslogtreecommitdiffstats
path: root/sys/dev/ct
diff options
context:
space:
mode:
authornon <non@FreeBSD.org>2001-07-14 00:38:51 +0000
committernon <non@FreeBSD.org>2001-07-14 00:38:51 +0000
commite91272502526170cc4f62c2357a8b7d3ee9b2c27 (patch)
tree01f4c48045db66f0e363a543a36a88e13470d6c9 /sys/dev/ct
parenta67c5263965b3cce0db11089854bd6f3f56f2f8e (diff)
downloadFreeBSD-src-e91272502526170cc4f62c2357a8b7d3ee9b2c27.zip
FreeBSD-src-e91272502526170cc4f62c2357a8b7d3ee9b2c27.tar.gz
Catch up with NetBSD/pc98.
o Much cleanly separate NetBSD(XS) / FreeBSD(CAM) codes. o Improve tagged queing support (full QTAG). o Improve quirk support. o Improve parity error retry. o Impliment wide negotheation. o Cmd link support. o Add copyright of CAM part. o Change for CAM_NEW_TRAN_CODE. o Work around for buggy KME UJDCD450. o stg: add disconnet condition. o nsp: use suspend I/O. and more. I thank Honda-san. conf/options.pc98: add CT_USE_RELOCATE_OFFSET and CT_BUS_WEIGHT dev/{ct,ncv,nsp,stg}/*_{pccard,isa}.c: add splcam() before calling attach/detach functions. Tested by: bsd-nomads Obtained from: NetBSD/pc98
Diffstat (limited to 'sys/dev/ct')
-rw-r--r--sys/dev/ct/bshw_machdep.c396
-rw-r--r--sys/dev/ct/bshwvar.h32
-rw-r--r--sys/dev/ct/ct.c809
-rw-r--r--sys/dev/ct/ct_isa.c114
-rw-r--r--sys/dev/ct/ct_machdep.h149
-rw-r--r--sys/dev/ct/ctvar.h70
6 files changed, 1061 insertions, 509 deletions
diff --git a/sys/dev/ct/bshw_machdep.c b/sys/dev/ct/bshw_machdep.c
index 6b375ab..c7995ce 100644
--- a/sys/dev/ct/bshw_machdep.c
+++ b/sys/dev/ct/bshw_machdep.c
@@ -1,13 +1,13 @@
/* $FreeBSD$ */
-/* $NecBSD: bshw_machdep.c,v 1.8 1999/07/23 20:54:00 honda Exp $ */
+/* $NecBSD: bshw_machdep.c,v 1.8.12.6 2001/06/29 06:28:05 honda Exp $ */
/* $NetBSD$ */
/*
* [NetBSD for NEC PC-98 series]
- * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
* NetBSD/pc98 porting staff. All rights reserved.
*
- * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
* Naofumi HONDA. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,18 +39,19 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/disklabel.h>
+#if defined(__FreeBSD__) && __FreeBSD_version > 500001
#include <sys/bio.h>
+#endif /* __ FreeBSD__ */
#include <sys/buf.h>
#include <sys/queue.h>
#include <sys/malloc.h>
-#include <sys/device_port.h>
#include <sys/errno.h>
#include <vm/vm.h>
-#include <vm/pmap.h>
#ifdef __NetBSD__
+#include <sys/device.h>
+
#include <machine/bus.h>
#include <machine/intr.h>
@@ -66,6 +67,7 @@
#include <dev/ic/wd33c93reg.h>
#include <i386/Cbus/dev/ct/ctvar.h>
+#include <i386/Cbus/dev/ct/ct_machdep.h>
#include <i386/Cbus/dev/ct/bshwvar.h>
#endif /* __NetBSD__ */
@@ -73,7 +75,6 @@
#include <machine/bus.h>
#include <machine/clock.h>
#include <machine/md_var.h>
-#include <machine/pmap.h>
#include <machine/dvcfg.h>
#include <machine/physio_proc.h>
@@ -82,32 +83,50 @@
#include <dev/ic/wd33c93reg.h>
#include <dev/ct/ctvar.h>
+#include <dev/ct/ct_machdep.h>
#include <dev/ct/bshwvar.h>
+
+#include <vm/pmap.h>
+#endif /* __FreeBSD__ */
+
+#define BSHW_IO_CONTROL_FLAGS 0
+
+u_int bshw_io_control = BSHW_IO_CONTROL_FLAGS;
+int bshw_data_read_bytes = 4096;
+int bshw_data_write_bytes = 4096;
+
+/*********************************************************
+ * OS dep part
+ *********************************************************/
+#ifdef __NetBSD__
+#define BSHW_PAGE_SIZE NBPG
+#endif /* __NetBSD__ */
+
+#ifdef __FreeBSD__
+#define BSHW_PAGE_SIZE PAGE_SIZE
+typedef unsigned long vaddr_t;
#endif /* __FreeBSD__ */
/*********************************************************
* GENERIC MACHDEP FUNCTIONS
*********************************************************/
void
-bshw_synch_setup(ct, li)
+bshw_synch_setup(ct, ti)
struct ct_softc *ct;
- struct lun_info *li;
+ struct targ_info *ti;
{
- struct scsi_low_softc *slp = &ct->sc_sclow;
- struct targ_info *ti = slp->sl_nexus;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct ct_targ_info *cti = (void *) ti;
struct bshw_softc *bs = ct->ct_hw;
struct bshw *hw = bs->sc_hw;
- if (hw->sregaddr == 0)
+ if (hw->hw_sregaddr == 0)
return;
- ct_cr_write_1(bst, bsh, hw->sregaddr + ti->ti_id, cti->cti_syncreg);
+ ct_cr_write_1(chp, hw->hw_sregaddr + ti->ti_id, cti->cti_syncreg);
if (hw->hw_flags & BSHW_DOUBLE_DMACHAN)
{
- ct_cr_write_1(bst, bsh, hw->sregaddr + ti->ti_id + 8,
+ ct_cr_write_1(chp, hw->hw_sregaddr + ti->ti_id + 8,
cti->cti_syncreg);
}
}
@@ -117,8 +136,7 @@ bshw_bus_reset(ct)
struct ct_softc *ct;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct bshw_softc *bs = ct->ct_hw;
struct bshw *hw = bs->sc_hw;
bus_addr_t offs;
@@ -126,53 +144,52 @@ bshw_bus_reset(ct)
int i;
/* open hardware busmaster mode */
- if (hw->dma_init != NULL && ((*hw->dma_init)(ct)) != 0)
+ if (hw->hw_dma_init != NULL && ((*hw->hw_dma_init)(ct)) != 0)
{
- printf("%s change mode using external DMA (%x)\n",
- slp->sl_xname, (u_int)ct_cr_read_1(bst, bsh, 0x37));
+ printf("%s: change mode using external DMA (%x)\n",
+ slp->sl_xname, (u_int)ct_cr_read_1(chp, 0x37));
}
/* clear hardware synch registers */
- offs = hw->sregaddr;
+ offs = hw->hw_sregaddr;
if (offs != 0)
{
for (i = 0; i < 8; i ++, offs ++)
{
- ct_cr_write_1(bst, bsh, offs, 0);
+ ct_cr_write_1(chp, offs, 0);
if ((hw->hw_flags & BSHW_DOUBLE_DMACHAN) != 0)
- ct_cr_write_1(bst, bsh, offs + 8, 0);
+ ct_cr_write_1(chp, offs + 8, 0);
}
}
/* disable interrupt & assert reset */
- regv = ct_cr_read_1(bst, bsh, wd3s_mbank);
+ regv = ct_cr_read_1(chp, wd3s_mbank);
regv |= MBR_RST;
regv &= ~MBR_IEN;
- ct_cr_write_1(bst, bsh, wd3s_mbank, regv);
+ ct_cr_write_1(chp, wd3s_mbank, regv);
- delay(500000);
+ SCSI_LOW_DELAY(500000);
/* reset signal off */
regv &= ~MBR_RST;
- ct_cr_write_1(bst, bsh, wd3s_mbank, regv);
+ ct_cr_write_1(chp, wd3s_mbank, regv);
/* interrupt enable */
regv |= MBR_IEN;
- ct_cr_write_1(bst, bsh, wd3s_mbank, regv);
+ ct_cr_write_1(chp, wd3s_mbank, regv);
}
/* probe */
int
-bshw_read_settings(bst, bsh, bs)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+bshw_read_settings(chp, bs)
+ struct ct_bus_access_handle *chp;
struct bshw_softc *bs;
{
static int irq_tbl[] = { 3, 5, 6, 9, 12, 13 };
- bs->sc_hostid = (ct_cr_read_1(bst, bsh, wd3s_auxc) & AUXCR_HIDM);
- bs->sc_irq = irq_tbl[(ct_cr_read_1(bst, bsh, wd3s_auxc) >> 3) & 7];
- bs->sc_drq = bus_space_read_1(bst, bsh, cmd_port) & 3;
+ bs->sc_hostid = (ct_cr_read_1(chp, wd3s_auxc) & AUXCR_HIDM);
+ bs->sc_irq = irq_tbl[(ct_cr_read_1(chp, wd3s_auxc) >> 3) & 7];
+ bs->sc_drq = ct_cmdp_read_1(chp) & 3;
return 0;
}
@@ -194,18 +211,17 @@ bshw_read_settings(bst, bsh, bs)
#define SF_RDY 0x10
static __inline void bshw_lc_smit_start __P((struct ct_softc *, int, u_int));
-static int bshw_lc_smit_fstat __P((struct ct_softc *, int, int));
static __inline void bshw_lc_smit_stop __P((struct ct_softc *));
+static int bshw_lc_smit_fstat __P((struct ct_softc *, int, int));
static __inline void
bshw_lc_smit_stop(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
- ct_cr_write_1(bst, bsh, BSHW_LC_FCTRL, 0);
- bus_space_write_1(ct->sc_iot, ct->sc_ioh, cmd_port, CMDP_DMER);
+ ct_cr_write_1(chp, BSHW_LC_FCTRL, 0);
+ ct_cmdp_write_1(chp, CMDP_DMER);
}
static __inline void
@@ -214,18 +230,17 @@ bshw_lc_smit_start(ct, count, direction)
int count;
u_int direction;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
u_int8_t pval, val;
- val = ct_cr_read_1(bst, bsh, BSHW_LC_FSET);
- cthw_set_count(bst, bsh, count);
+ val = ct_cr_read_1(chp, BSHW_LC_FSET);
+ cthw_set_count(chp, count);
pval = FCTRL_EN;
if (direction == SCSI_LOW_WRITE)
pval |= (val & 0xe0) | FCTRL_WRITE;
- ct_cr_write_1(bst, bsh, BSHW_LC_FCTRL, pval);
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_TFR_INFO);
+ ct_cr_write_1(chp, BSHW_LC_FCTRL, pval);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO);
}
static int
@@ -233,12 +248,13 @@ bshw_lc_smit_fstat(ct, wc, read)
struct ct_softc *ct;
int wc, read;
{
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
u_int8_t stat;
while (wc -- > 0)
{
- outb(0x5f, 0);
- stat = bus_space_read_1(ct->sc_iot, ct->sc_ioh, cmd_port);
+ chp->ch_bus_weight(chp);
+ stat = ct_cmdp_read_1(chp);
if (read == SCSI_LOW_READ)
{
if ((stat & SF_RDY) != 0)
@@ -268,68 +284,85 @@ bshw_smit_xfer_stop(ct)
struct targ_info *ti;
struct sc_p *sp = &slp->sl_scp;
u_int count;
- u_char *s;
bshw_lc_smit_stop(ct);
- ti = slp->sl_nexus;
+ ti = slp->sl_Tnexus;
if (ti == NULL)
return;
if (ti->ti_phase == PH_DATA)
{
- count = cthw_get_count(ct->sc_iot, ct->sc_ioh);
- if (count < (u_int) sp->scp_datalen)
+ count = cthw_get_count(&ct->sc_ch);
+ if (count < bs->sc_sdatalen)
{
- sp->scp_data += (sp->scp_datalen - count);
- sp->scp_datalen = count;
- /* XXX:
- * strict double checks!
- * target => wd33c93c transfer counts
- * wd33c93c => memory transfer counts
- */
if (sp->scp_direction == SCSI_LOW_READ &&
- count != bs->sc_tdatalen)
- {
- s = "read count miss";
+ count != bs->sc_edatalen)
goto bad;
- }
- return;
+
+ count = bs->sc_sdatalen - count;
+ if (count > (u_int) sp->scp_datalen)
+ goto bad;
+
+ sp->scp_data += count;
+ sp->scp_datalen -= count;
}
- else if (count == (u_int) sp->scp_datalen)
+ else if (count > bs->sc_sdatalen)
{
- return;
+bad:
+ printf("%s: smit_xfer_end: cnt error\n", slp->sl_xname);
+ slp->sl_error |= PDMAERR;
}
-
- s = "strange count";
+ scsi_low_data_finish(slp);
}
else
- s = "extra smit interrupt";
-
-bad:
- printf("%s: smit_xfer_end: %s", slp->sl_xname, s);
- slp->sl_error |= PDMAERR;
+ {
+ printf("%s: smit_xfer_end: phase miss\n", slp->sl_xname);
+ slp->sl_error |= PDMAERR;
+ }
}
-void
+int
bshw_smit_xfer_start(ct)
struct ct_softc *ct;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct bshw_softc *bs = ct->ct_hw;
struct sc_p *sp = &slp->sl_scp;
- struct targ_info *ti = slp->sl_nexus;
+ struct targ_info *ti = slp->sl_Tnexus;
struct ct_targ_info *cti = (void *) ti;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
- int datalen, count, wc = LC_SMIT_TIMEOUT * 1024 * 1024;
+ u_int datalen, count, io_control;
+ int wc;
u_int8_t *data;
- data = sp->scp_data;
+ io_control = bs->sc_io_control | bshw_io_control;
+ if ((io_control & BSHW_SMIT_BLOCK) != 0)
+ return EINVAL;
+
+ if ((slp->sl_scp.scp_datalen % DEV_BSIZE) != 0)
+ return EINVAL;
+
datalen = sp->scp_datalen;
+ if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
+ {
+ if ((io_control & BSHW_READ_INTERRUPT_DRIVEN) != 0 &&
+ datalen > bshw_data_read_bytes)
+ datalen = bshw_data_read_bytes;
+ }
+ else
+ {
+ if ((io_control & BSHW_WRITE_INTERRUPT_DRIVEN) != 0 &&
+ datalen > bshw_data_write_bytes)
+ datalen = bshw_data_write_bytes;
+ }
+
+ bs->sc_sdatalen = datalen;
+ data = sp->scp_data;
+ wc = LC_SMIT_TIMEOUT * 1024 * 1024;
- ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg | CR_DMA);
- bshw_lc_smit_start(ct, sp->scp_datalen, sp->scp_direction);
+ ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA);
+ bshw_lc_smit_start(ct, datalen, sp->scp_direction);
if (sp->scp_direction == SCSI_LOW_READ)
{
@@ -339,14 +372,14 @@ bshw_smit_xfer_start(ct)
break;
count = (datalen > LC_FSZ ? LC_FSZ : datalen);
- bus_space_read_region_4(ct->sc_memt, ct->sc_memh,
+ bus_space_read_region_4(chp->ch_memt, chp->ch_memh,
LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2);
data += count;
datalen -= count;
}
while (datalen > 0);
- bs->sc_tdatalen = datalen;
+ bs->sc_edatalen = datalen;
}
else
{
@@ -365,7 +398,7 @@ bshw_smit_xfer_start(ct)
}
count = (datalen > LC_SFSZ ? LC_SFSZ : datalen);
- bus_space_write_region_4(ct->sc_memt, ct->sc_memh,
+ bus_space_write_region_4(chp->ch_memt, chp->ch_memh,
LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2);
data += count;
datalen -= count;
@@ -374,7 +407,7 @@ bshw_smit_xfer_start(ct)
break;
count = (datalen > LC_REST ? LC_REST : datalen);
- bus_space_write_region_4(ct->sc_memt, ct->sc_memh,
+ bus_space_write_region_4(chp->ch_memt, chp->ch_memh,
LC_SMIT_OFFSET + LC_SFSZ,
(u_int32_t *) data, count >> 2);
data += count;
@@ -382,26 +415,33 @@ bshw_smit_xfer_start(ct)
}
while (datalen > 0);
}
+ return 0;
}
/*********************************************************
* DMA TRANSFER (BS)
*********************************************************/
+static __inline void bshw_dma_write_1 \
+ __P((struct ct_bus_access_handle *, bus_addr_t, u_int8_t));
static void bshw_dmastart __P((struct ct_softc *));
static void bshw_dmadone __P((struct ct_softc *));
-void
+int
bshw_dma_xfer_start(ct)
struct ct_softc *ct;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
struct sc_p *sp = &slp->sl_scp;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct bshw_softc *bs = ct->ct_hw;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
vaddr_t va, endva, phys, nphys;
+ u_int io_control;
+
+ io_control = bs->sc_io_control | bshw_io_control;
+ if ((io_control & BSHW_DMA_BLOCK) != 0 && sp->scp_datalen < 256)
+ return EINVAL;
- ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg | CR_DMA);
+ ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA);
phys = vtophys((vaddr_t) sp->scp_data);
if (phys >= bs->sc_minphys)
{
@@ -421,19 +461,17 @@ bshw_dma_xfer_start(ct)
/* setup segaddr */
bs->sc_segaddr = (u_int8_t *) phys;
/* setup seglen */
- endva = (vaddr_t)round_page((vaddr_t)(sp->scp_data +
- sp->scp_datalen));
+ endva = (vaddr_t) round_page((vaddr_t) sp->scp_data + sp->scp_datalen);
for (va = (vaddr_t) sp->scp_data; ; phys = nphys)
{
- if ((va += PAGE_SIZE) >= endva)
+ if ((va += BSHW_PAGE_SIZE) >= endva)
{
bs->sc_seglen = sp->scp_datalen;
break;
}
nphys = vtophys(va);
- if (phys + PAGE_SIZE != nphys ||
- nphys >= bs->sc_minphys)
+ if (phys + BSHW_PAGE_SIZE != nphys || nphys >= bs->sc_minphys)
{
bs->sc_seglen =
(u_int8_t *) trunc_page(va) - sp->scp_data;
@@ -445,7 +483,9 @@ bshw_dma_xfer_start(ct)
}
bshw_dmastart(ct);
- cthw_set_count(bst, bsh, bs->sc_seglen);
+ cthw_set_count(chp, bs->sc_seglen);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO);
+ return 0;
}
void
@@ -460,13 +500,13 @@ bshw_dma_xfer_stop(ct)
bshw_dmadone(ct);
- ti = slp->sl_nexus;
+ ti = slp->sl_Tnexus;
if (ti == NULL)
return;
if (ti->ti_phase == PH_DATA)
{
- count = cthw_get_count(ct->sc_iot, ct->sc_ioh);
+ count = cthw_get_count(&ct->sc_ch);
if (count < (u_int) bs->sc_seglen)
{
transbytes = bs->sc_seglen - count;
@@ -474,31 +514,27 @@ bshw_dma_xfer_stop(ct)
sp->scp_direction == SCSI_LOW_READ)
bcopy(bs->sc_bufp, sp->scp_data, transbytes);
- bs->sc_bufp = NULL;
sp->scp_data += transbytes;
sp->scp_datalen -= transbytes;
- return;
}
- else if (count == (u_int) bs->sc_seglen)
+ else if (count > (u_int) bs->sc_seglen)
{
- bs->sc_bufp = NULL;
- return;
+ printf("%s: port data %x != seglen %x\n",
+ slp->sl_xname, count, bs->sc_seglen);
+ slp->sl_error |= PDMAERR;
}
- printf("%s: port data %x != seglen %x\n",
- slp->sl_xname, count, bs->sc_seglen);
+ scsi_low_data_finish(slp);
}
else
{
printf("%s: extra DMA interrupt\n", slp->sl_xname);
+ slp->sl_error |= PDMAERR;
}
- slp->sl_error |= PDMAERR;
bs->sc_bufp = NULL;
}
-static int dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
-
/* common dma settings */
#undef DMA1_SMSK
#define DMA1_SMSK (0x15)
@@ -514,56 +550,64 @@ static int dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
#define DMA37MD_READ 0x08
#define DMA37MD_SINGLE 0x40
+static bus_addr_t dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
+
+static __inline void
+bshw_dma_write_1(chp, port, val)
+ struct ct_bus_access_handle *chp;
+ bus_addr_t port;
+ u_int8_t val;
+{
+
+ CT_BUS_WEIGHT(chp);
+ outb(port, val);
+}
+
static void
bshw_dmastart(ct)
struct ct_softc *ct;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
struct bshw_softc *bs = ct->ct_hw;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
int chan = bs->sc_drq;
- int waport;
- u_int8_t *phys = bs->sc_segaddr;
+ bus_addr_t waport;
+ u_int8_t regv, *phys = bs->sc_segaddr;
u_int nbytes = bs->sc_seglen;
+ /* flush cpu cache */
+ (*bs->sc_dmasync_before) (ct);
+
/*
* Program one of DMA channels 0..3. These are
* byte mode channels.
*/
/* set dma channel mode, and reset address ff */
-#ifdef __FreeBSD__
- if (need_pre_dma_flush)
- wbinvd();
-#else
- if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
- cpu_cf_preRead(curcpu);
- else
- cpu_cf_preWrite(curcpu);
-#endif
if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
- outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_WRITE | chan);
+ regv = DMA37MD_WRITE | DMA37MD_SINGLE | chan;
else
- outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_READ | chan);
- outb(DMA1_FFC, 0);
+ regv = DMA37MD_READ | DMA37MD_SINGLE | chan;
+
+ bshw_dma_write_1(chp, DMA1_MODE, regv);
+ bshw_dma_write_1(chp, DMA1_FFC, 0);
/* send start address */
waport = DMA1_CHN(chan);
- outb(waport, (u_int) phys);
- outb(waport, ((u_int) phys) >> 8);
- outb(dmapageport[chan], ((u_int) phys) >> 16);
+ bshw_dma_write_1(chp, waport, (u_int) phys);
+ bshw_dma_write_1(chp, waport, ((u_int) phys) >> 8);
+ bshw_dma_write_1(chp, dmapageport[chan], ((u_int) phys) >> 16);
/* send count */
- outb(waport + 2, --nbytes);
- outb(waport + 2, nbytes >> 8);
+ bshw_dma_write_1(chp, waport + 2, --nbytes);
+ bshw_dma_write_1(chp, waport + 2, nbytes >> 8);
/* vendor unique hook */
- if (bs->sc_hw->dma_start)
- (*bs->sc_hw->dma_start)(ct);
+ if (bs->sc_hw->hw_dma_start)
+ (*bs->sc_hw->hw_dma_start)(ct);
- outb(DMA1_SMSK, chan);
- bus_space_write_1(bst, bsh, cmd_port, CMDP_DMES);
+ bshw_dma_write_1(chp, DMA1_SMSK, chan);
+ ct_cmdp_write_1(chp, CMDP_DMES);
}
static void
@@ -571,25 +615,17 @@ bshw_dmadone(ct)
struct ct_softc *ct;
{
struct bshw_softc *bs = ct->ct_hw;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
- outb(DMA1_SMSK, (bs->sc_drq | DMA37SM_SET));
- bus_space_write_1(bst, bsh, cmd_port, CMDP_DMER);
+ bshw_dma_write_1(chp, DMA1_SMSK, (bs->sc_drq | DMA37SM_SET));
+ ct_cmdp_write_1(chp, CMDP_DMER);
/* vendor unique hook */
- if (bs->sc_hw->dma_stop)
- (*bs->sc_hw->dma_stop)(ct);
+ if (bs->sc_hw->hw_dma_stop)
+ (*bs->sc_hw->hw_dma_stop) (ct);
-#ifdef __FreeBSD__
- if (need_post_dma_flush)
- invd();
-#else
- if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
- cpu_cf_postRead(curcpu);
- else
- cpu_cf_postWrite(curcpu);
-#endif
+ /* flush cpu cache */
+ (*bs->sc_dmasync_after) (ct);
}
/**********************************************
@@ -606,16 +642,15 @@ static int
bshw_dma_init_texa(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
u_int8_t regval;
- if ((regval = ct_cr_read_1(bst, bsh, 0x37)) & 0x08)
+ if ((regval = ct_cr_read_1(chp, 0x37)) & 0x08)
return 0;
- ct_cr_write_1(bst, bsh, 0x37, regval | 0x08);
- regval = ct_cr_read_1(bst, bsh, 0x3f);
- ct_cr_write_1(bst, bsh, 0x3f, regval | 0x08);
+ ct_cr_write_1(chp, 0x37, regval | 0x08);
+ regval = ct_cr_read_1(chp, 0x3f);
+ ct_cr_write_1(chp, 0x3f, regval | 0x08);
return 1;
}
@@ -623,26 +658,25 @@ static int
bshw_dma_init_sc98(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
- if (ct_cr_read_1(bst, bsh, 0x37) & 0x08)
+ if (ct_cr_read_1(chp, 0x37) & 0x08)
return 0;
/* If your card is SC98 with bios ver 1.01 or 1.02 under no PCI */
- ct_cr_write_1(bst, bsh, 0x37, 0x1a);
- ct_cr_write_1(bst, bsh, 0x3f, 0x1a);
+ ct_cr_write_1(chp, 0x37, 0x1a);
+ ct_cr_write_1(chp, 0x3f, 0x1a);
#if 0
/* only valid for IO */
- ct_cr_write_1(bst, bsh, 0x40, 0xf4);
- ct_cr_write_1(bst, bsh, 0x41, 0x9);
- ct_cr_write_1(bst, bsh, 0x43, 0xff);
- ct_cr_write_1(bst, bsh, 0x46, 0x4e);
-
- ct_cr_write_1(bst, bsh, 0x48, 0xf4);
- ct_cr_write_1(bst, bsh, 0x49, 0x9);
- ct_cr_write_1(bst, bsh, 0x4b, 0xff);
- ct_cr_write_1(bst, bsh, 0x4e, 0x4e);
+ ct_cr_write_1(chp, 0x40, 0xf4);
+ ct_cr_write_1(chp, 0x41, 0x9);
+ ct_cr_write_1(chp, 0x43, 0xff);
+ ct_cr_write_1(chp, 0x46, 0x4e);
+
+ ct_cr_write_1(chp, 0x48, 0xf4);
+ ct_cr_write_1(chp, 0x49, 0x9);
+ ct_cr_write_1(chp, 0x4b, 0xff);
+ ct_cr_write_1(chp, 0x4e, 0x4e);
#endif
return 1;
}
@@ -651,44 +685,40 @@ static void
bshw_dma_start_sc98(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
- ct_cr_write_1(bst, bsh, 0x73, 0x32);
- ct_cr_write_1(bst, bsh, 0x74, 0x23);
+ ct_cr_write_1(chp, 0x73, 0x32);
+ ct_cr_write_1(chp, 0x74, 0x23);
}
static void
bshw_dma_stop_sc98(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
- ct_cr_write_1(bst, bsh, 0x73, 0x43);
- ct_cr_write_1(bst, bsh, 0x74, 0x34);
+ ct_cr_write_1(chp, 0x73, 0x43);
+ ct_cr_write_1(chp, 0x74, 0x34);
}
static void
bshw_dma_start_elecom(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
- u_int8_t tmp = ct_cr_read_1(bst, bsh, 0x4c);
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+ u_int8_t tmp = ct_cr_read_1(chp, 0x4c);
- ct_cr_write_1(bst, bsh, 0x32, tmp & 0xdf);
+ ct_cr_write_1(chp, 0x32, tmp & 0xdf);
}
static void
bshw_dma_stop_elecom(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
- u_int8_t tmp = ct_cr_read_1(bst, bsh, 0x4c);
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+ u_int8_t tmp = ct_cr_read_1(chp, 0x4c);
- ct_cr_write_1(bst, bsh, 0x32, tmp | 0x20);
+ ct_cr_write_1(chp, 0x32, tmp | 0x20);
}
static struct bshw bshw_generic = {
diff --git a/sys/dev/ct/bshwvar.h b/sys/dev/ct/bshwvar.h
index 6e31b4d..17268f0 100644
--- a/sys/dev/ct/bshwvar.h
+++ b/sys/dev/ct/bshwvar.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $NecBSD: bshwvar.h,v 1.3 1999/04/15 01:36:10 kmatsuda Exp $ */
+/* $NecBSD: bshwvar.h,v 1.3.14.3 2001/06/21 04:07:37 honda Exp $ */
/* $NetBSD$ */
/*
@@ -46,12 +46,11 @@ struct bshw {
#define BSHW_SMFIFO 0x02
#define BSHW_DOUBLE_DMACHAN 0x04
u_int hw_flags;
+ u_int hw_sregaddr;
- u_int sregaddr;
-
- int ((*dma_init) __P((struct ct_softc *)));
- void ((*dma_start) __P((struct ct_softc *)));
- void ((*dma_stop) __P((struct ct_softc *)));
+ int ((*hw_dma_init) __P((struct ct_softc *)));
+ void ((*hw_dma_start) __P((struct ct_softc *)));
+ void ((*hw_dma_stop) __P((struct ct_softc *)));
};
struct bshw_softc {
@@ -63,7 +62,8 @@ struct bshw_softc {
u_int8_t *sc_segaddr;
u_int8_t *sc_bufp;
int sc_seglen;
- int sc_tdatalen; /* temp datalen */
+ u_int sc_sdatalen; /* SMIT */
+ u_int sc_edatalen; /* SMIT */
/* private bounce */
u_int8_t *sc_bounce_phys;
@@ -71,16 +71,26 @@ struct bshw_softc {
u_int sc_bounce_size;
bus_addr_t sc_minphys;
+ /* io control */
+#define BSHW_READ_INTERRUPT_DRIVEN 0x0001
+#define BSHW_WRITE_INTERRUPT_DRIVEN 0x0002
+#define BSHW_DMA_BLOCK 0x0010
+#define BSHW_SMIT_BLOCK 0x0020
+ u_int sc_io_control;
+
/* hardware */
struct bshw *sc_hw;
+ void ((*sc_dmasync_before)) __P((struct ct_softc *));
+ void ((*sc_dmasync_after)) __P((struct ct_softc *));
};
-void bshw_synch_setup __P((struct ct_softc *, struct lun_info *));
+void bshw_synch_setup __P((struct ct_softc *, struct targ_info *));
void bshw_bus_reset __P((struct ct_softc *));
-int bshw_read_settings __P((bus_space_tag_t, bus_space_handle_t, struct bshw_softc *));
-void bshw_smit_xfer_start __P((struct ct_softc *));
+int bshw_read_settings __P((struct ct_bus_access_handle *, struct bshw_softc *));
+int bshw_smit_xfer_start __P((struct ct_softc *));
void bshw_smit_xfer_stop __P((struct ct_softc *));
-void bshw_dma_xfer_start __P((struct ct_softc *));
+int bshw_dma_xfer_start __P((struct ct_softc *));
void bshw_dma_xfer_stop __P((struct ct_softc *));
+
extern struct dvcfg_hwsel bshw_hwsel;
#endif /* !_BSHWVAR_H_ */
diff --git a/sys/dev/ct/ct.c b/sys/dev/ct/ct.c
index f2fe883a..6c46493 100644
--- a/sys/dev/ct/ct.c
+++ b/sys/dev/ct/ct.c
@@ -1,16 +1,16 @@
/* $FreeBSD$ */
-/* $NecBSD: ct.c,v 1.13 1999/07/23 20:54:00 honda Exp $ */
+/* $NecBSD: ct.c,v 1.13.12.5 2001/06/26 07:31:53 honda Exp $ */
/* $NetBSD$ */
#define CT_DEBUG
-#define CT_USE_CCSEQ
+#define CT_IO_CONTROL_FLAGS (CT_USE_CCSEQ | CT_FAST_INTR)
/*
* [NetBSD for NEC PC-98 series]
- * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
* NetBSD/pc98 porting staff. All rights reserved.
*
- * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
* Naofumi HONDA. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,17 +42,17 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/disklabel.h>
+#if defined(__FreeBSD__) && __FreeBSD_version > 500001
#include <sys/bio.h>
+#endif /* __ FreeBSD__ */
#include <sys/buf.h>
#include <sys/queue.h>
#include <sys/malloc.h>
-#include <sys/device_port.h>
#include <sys/errno.h>
-#include <vm/vm.h>
-
#ifdef __NetBSD__
+#include <sys/device.h>
+
#include <machine/bus.h>
#include <machine/intr.h>
@@ -68,6 +68,7 @@
#include <dev/ic/wd33c93reg.h>
#include <i386/Cbus/dev/ct/ctvar.h>
+#include <i386/Cbus/dev/ct/ct_machdep.h>
#endif /* __NetBSD__ */
#ifdef __FreeBSD__
@@ -80,28 +81,31 @@
#include <dev/ic/wd33c93reg.h>
#include <dev/ct/ctvar.h>
+#include <dev/ct/ct_machdep.h>
#endif /* __FreeBSD__ */
+#define CT_NTARGETS 8
+#define CT_NLUNS 8
+#define CT_RESET_DEFAULT 2000
+#define CT_DELAY_MAX (2 * 1000 * 1000)
+#define CT_DELAY_INTERVAL (1)
+
/***************************************************
* DEBUG
***************************************************/
-#define CT_NTARGETS 8
-#define CT_NLUNS 8
-#define CT_RESET_DEFAULT 2000
-
-#ifndef DDB
-#define Debugger() panic("should call debugger here (ct.c)")
-#else /* ! DDB */
-#ifdef __FreeBSD__
-#define Debugger() Debugger("ct")
-#endif /* __FreeBSD__ */
-#endif
-
#ifdef CT_DEBUG
int ct_debug;
#endif /* CT_DEBUG */
/***************************************************
+ * IO control
+ ***************************************************/
+#define CT_USE_CCSEQ 0x0100
+#define CT_FAST_INTR 0x0200
+
+u_int ct_io_control = CT_IO_CONTROL_FLAGS;
+
+/***************************************************
* default data
***************************************************/
u_int8_t cthw_cmdlevel[256] = {
@@ -124,44 +128,61 @@ u_int8_t cthw_cmdlevel[256] = {
/*F*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
};
+#if 0
/* default synch data table */
/* A 10 6.6 5.0 4.0 3.3 2.8 2.5 2.0 M/s */
/* X 100 150 200 250 300 350 400 500 ns */
-static struct ct_synch_data ct_synch_data_20MHz[] = {
+static struct ct_synch_data ct_synch_data_FSCSI[] = {
{25, 0xa0}, {37, 0xb0}, {50, 0x20}, {62, 0xd0}, {75, 0x30},
{87, 0xf0}, {100, 0x40}, {125, 0x50}, {0, 0}
};
-extern unsigned int delaycount;
+static struct ct_synch_data ct_synch_data_SCSI[] = {
+ {50, 0x20}, {75, 0x30}, {100, 0x40}, {125, 0x50}, {0, 0}
+};
+#endif
+/***************************************************
+ * DEVICE STRUCTURE
+ ***************************************************/
+extern struct cfdriver ct_cd;
/*****************************************************************
* Interface functions
*****************************************************************/
-static int ct_xfer __P((struct ct_softc *, u_int8_t *, int, int));
+static int ct_xfer __P((struct ct_softc *, u_int8_t *, int, int, u_int *));
static void ct_io_xfer __P((struct ct_softc *));
-static __inline int ct_reselected __P((struct ct_softc *));
+static int ct_reselected __P((struct ct_softc *, u_int8_t));
static void ct_phase_error __P((struct ct_softc *, u_int8_t));
static int ct_start_selection __P((struct ct_softc *, struct slccb *));
static int ct_msg __P((struct ct_softc *, struct targ_info *, u_int));
static int ct_world_start __P((struct ct_softc *, int));
static __inline void cthw_phase_bypass __P((struct ct_softc *, u_int8_t));
-static int cthw_chip_reset __P((bus_space_tag_t, bus_space_handle_t, int, int));
+static int cthw_chip_reset __P((struct ct_bus_access_handle *, int *, int, int));
static void cthw_bus_reset __P((struct ct_softc *));
-static int ct_nexus __P((struct ct_softc *, struct targ_info *));
+static int ct_ccb_nexus_establish __P((struct ct_softc *));
+static int ct_lun_nexus_establish __P((struct ct_softc *));
+static int ct_target_nexus_establish __P((struct ct_softc *, int, int));
static void cthw_attention __P((struct ct_softc *));
-static int ct_targ_init __P((struct ct_softc *, struct targ_info *));
+static int ct_targ_init __P((struct ct_softc *, struct targ_info *, int));
+static int ct_unbusy __P((struct ct_softc *));
+static void ct_attention __P((struct ct_softc *));
+static struct ct_synch_data *ct_make_synch_table __P((struct ct_softc *));
+static int ct_catch_intr __P((struct ct_softc *));
struct scsi_low_funcs ct_funcs = {
SC_LOW_INIT_T ct_world_start,
SC_LOW_BUSRST_T cthw_bus_reset,
SC_LOW_TARG_INIT_T ct_targ_init,
+ SC_LOW_LUN_INIT_T NULL,
SC_LOW_SELECT_T ct_start_selection,
- SC_LOW_NEXUS_T ct_nexus,
+ SC_LOW_NEXUS_T ct_lun_nexus_establish,
+ SC_LOW_NEXUS_T ct_ccb_nexus_establish,
SC_LOW_ATTEN_T cthw_attention,
SC_LOW_MSG_T ct_msg,
+ SC_LOW_TIMEOUT_T NULL,
SC_LOW_POLL_T ctintr,
NULL, /* SC_LOW_POWER_T cthw_power, */
@@ -175,12 +196,10 @@ cthw_phase_bypass(ct, ph)
struct ct_softc *ct;
u_int8_t ph;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
- ct_cr_write_1(bst, bsh, wd3s_cph, ph);
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_SELECT_ATN_TFR);
- ct->sc_satgo = CT_SAT_GOING;
+ ct_cr_write_1(chp, wd3s_cph, ph);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_SELECT_ATN_TFR);
}
static void
@@ -196,9 +215,9 @@ cthw_bus_reset(ct)
}
static int
-cthw_chip_reset(bst, bsh, chipclk, hostid)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+cthw_chip_reset(chp, chiprevp, chipclk, hostid)
+ struct ct_bus_access_handle *chp;
+ int *chiprevp;
int chipclk, hostid;
{
#define CT_SELTIMEOUT_20MHz_REGV (0x80)
@@ -207,26 +226,29 @@ cthw_chip_reset(bst, bsh, chipclk, hostid)
int wc;
/* issue abort cmd */
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_ABORT);
- delay(1000); /* 1ms wait */
- (void) ct_stat_read_1(bst, bsh);
- (void) ct_cr_read_1(bst, bsh, wd3s_stat);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_ABORT);
+ SCSI_LOW_DELAY(1000); /* 1ms wait */
+ (void) ct_stat_read_1(chp);
+ (void) ct_cr_read_1(chp, wd3s_stat);
/* setup chip registers */
regv = 0;
seltout = CT_SELTIMEOUT_20MHz_REGV;
switch (chipclk)
{
+ case 8:
case 10:
seltout = (seltout * chipclk) / 20;
- regv = 0;
+ regv = IDR_FS_8_10;
break;
+ case 12:
case 15:
seltout = (seltout * chipclk) / 20;
regv = IDR_FS_12_15;
break;
+ case 16:
case 20:
seltout = (seltout * chipclk) / 20;
regv = IDR_FS_16_20;
@@ -236,51 +258,117 @@ cthw_chip_reset(bst, bsh, chipclk, hostid)
panic("ct: illegal chip clk rate\n");
break;
}
- regv |= IDR_EHP | hostid;
- ct_cr_write_1(bst, bsh, wd3s_oid, regv);
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_RESET);
+ regv |= IDR_EHP | hostid | IDR_RAF | IDR_EAF;
+ ct_cr_write_1(chp, wd3s_oid, regv);
+
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_RESET);
for (wc = CT_RESET_DEFAULT; wc > 0; wc --)
{
- aux = ct_stat_read_1(bst, bsh);
+ aux = ct_stat_read_1(chp);
if (aux != 0xff && (aux & STR_INT))
{
- if (ct_cr_read_1(bst, bsh, wd3s_stat) == 0)
+ regv = ct_cr_read_1(chp, wd3s_stat);
+ if (regv == BSR_RESET || regv == BSR_AFM_RESET)
break;
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_RESET);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_RESET);
}
- delay(1);
+ SCSI_LOW_DELAY(1);
}
if (wc == 0)
return ENXIO;
- ct_cr_write_1(bst, bsh, wd3s_tout, seltout);
- ct_cr_write_1(bst, bsh, wd3s_sid, SIDR_RESEL);
- ct_cr_write_1(bst, bsh, wd3s_ctrl, CR_DEFAULT);
- ct_cr_write_1(bst, bsh, wd3s_synch, 0);
+ ct_cr_write_1(chp, wd3s_tout, seltout);
+ ct_cr_write_1(chp, wd3s_sid, SIDR_RESEL);
+ ct_cr_write_1(chp, wd3s_ctrl, CR_DEFAULT);
+ ct_cr_write_1(chp, wd3s_synch, 0);
+ if (chiprevp != NULL)
+ {
+ *chiprevp = CT_WD33C93;
+ if (regv == BSR_RESET)
+ goto out;
+
+ *chiprevp = CT_WD33C93_A;
+ ct_cr_write_1(chp, wd3s_qtag, 0xaa);
+ if (ct_cr_read_1(chp, wd3s_qtag) != 0xaa)
+ {
+ ct_cr_write_1(chp, wd3s_qtag, 0x0);
+ goto out;
+ }
+ ct_cr_write_1(chp, wd3s_qtag, 0x55);
+ if (ct_cr_read_1(chp, wd3s_qtag) != 0x55)
+ {
+ ct_cr_write_1(chp, wd3s_qtag, 0x0);
+ goto out;
+ }
+ ct_cr_write_1(chp, wd3s_qtag, 0x0);
+ *chiprevp = CT_WD33C93_B;
+ }
- (void) ct_stat_read_1(bst, bsh);
- (void) ct_cr_read_1(bst, bsh, wd3s_stat);
+out:
+ (void) ct_stat_read_1(chp);
+ (void) ct_cr_read_1(chp, wd3s_stat);
return 0;
}
+static struct ct_synch_data *
+ct_make_synch_table(ct)
+ struct ct_softc *ct;
+{
+ struct ct_synch_data *sdtp, *sdp;
+ u_int base, i, period;
+
+ sdtp = sdp = &ct->sc_default_sdt[0];
+
+ if ((ct->sc_chipclk % 5) == 0)
+ base = 1000 / (5 * 2); /* 5 MHz type */
+ else
+ base = 1000 / (4 * 2); /* 4 MHz type */
+
+ if (ct->sc_chiprev >= CT_WD33C93_B)
+ {
+ /* fast scsi */
+ for (i = 2; i < 8; i ++, sdp ++)
+ {
+ period = (base * i) / 2;
+ if (period >= 200) /* 5 MHz */
+ break;
+ sdp->cs_period = period / 4;
+ sdp->cs_syncr = (i * 0x10) | 0x80;
+ }
+ }
+
+ for (i = 2; i < 8; i ++, sdp ++)
+ {
+ period = (base * i);
+ if (period > 500) /* 2 MHz */
+ break;
+ sdp->cs_period = period / 4;
+ sdp->cs_syncr = (i * 0x10);
+ }
+
+ sdp->cs_period = 0;
+ sdp->cs_syncr = 0;
+ return sdtp;
+}
+
/**************************************************
* Attach & Probe
**************************************************/
int
-ctprobesubr(bst, bsh, dvcfg, hsid, chipclk)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+ctprobesubr(chp, dvcfg, hsid, chipclk, chiprevp)
+ struct ct_bus_access_handle *chp;
u_int dvcfg, chipclk;
int hsid;
+ int *chiprevp;
{
#if 0
- if ((ct_stat_read_1(bst, bsh) & STR_BUSY) != 0)
+ if ((ct_stat_read_1(chp) & STR_BSY) != 0)
return 0;
#endif
- if (cthw_chip_reset(bst, bsh, chipclk, hsid) != 0)
+ if (cthw_chip_reset(chp, chiprevp, chipclk, hsid) != 0)
return 0;
return 1;
}
@@ -302,10 +390,11 @@ ctattachsubr(ct)
{
struct scsi_low_softc *slp = &ct->sc_sclow;
- ct->sc_wc = delaycount * 2000; /* 2 sec */
+ ct->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */
slp->sl_funcs = &ct_funcs;
- (void) scsi_low_attach(slp, 2, CT_NTARGETS, CT_NLUNS,
- sizeof(struct ct_targ_info));
+ slp->sl_flags |= HW_READ_PADDING;
+ (void) scsi_low_attach(slp, 0, CT_NTARGETS, CT_NLUNS,
+ sizeof(struct ct_targ_info), 0);
}
/**************************************************
@@ -315,44 +404,75 @@ static void
cthw_attention(ct)
struct ct_softc *ct;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
- if ((ct_stat_read_1(bst, bsh) & STR_BUSY) != 0)
- {
- ct->sc_atten = 1;
+ ct->sc_atten = 1;
+ if ((ct_stat_read_1(chp) & (STR_BSY | STR_CIP)) != 0)
return;
- }
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_ASSERT_ATN);
- delay(10);
- if ((ct_stat_read_1(bst, bsh) & STR_LCI) != 0)
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_ASSERT_ATN);
+ SCSI_LOW_DELAY(10);
+ if ((ct_stat_read_1(chp) & STR_LCI) == 0)
+ ct->sc_atten = 0;
+ ct_unbusy(ct);
+ return;
+}
+
+static void
+ct_attention(ct)
+ struct ct_softc *ct;
+{
+ struct scsi_low_softc *slp = &ct->sc_sclow;
+
+ if (slp->sl_atten == 0)
{
- ct->sc_atten = 1;
- return;
+ ct_unbusy(ct);
+ scsi_low_attention(slp);
+ }
+ else if (ct->sc_atten != 0)
+ {
+ ct_unbusy(ct);
+ cthw_attention(ct);
}
- ct->sc_atten = 0;
}
static int
-ct_targ_init(ct, ti)
+ct_targ_init(ct, ti, action)
struct ct_softc *ct;
struct targ_info *ti;
+ int action;
{
struct ct_targ_info *cti = (void *) ti;
- if (ct->sc_chiprev == CT_WD33C93_A)
+ if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE)
{
- ti->ti_maxsynch.period = 200 / 4; /* 5MHz */
- ti->ti_maxsynch.offset = 8;
- }
- else
- {
- ti->ti_maxsynch.period = 100 / 4; /* 10MHz */
- ti->ti_maxsynch.offset = 12;
+ if (ct->sc_sdp == NULL)
+ {
+ ct->sc_sdp = ct_make_synch_table(ct);
+ }
+
+ switch (ct->sc_chiprev)
+ {
+ default:
+ ti->ti_maxsynch.offset = 5;
+ break;
+
+ case CT_WD33C93_A:
+ case CT_AM33C93_A:
+ ti->ti_maxsynch.offset = 12;
+ break;
+
+ case CT_WD33C93_B:
+ case CT_WD33C93_C:
+ ti->ti_maxsynch.offset = 12;
+ break;
+ }
+
+ ti->ti_maxsynch.period = ct->sc_sdp[0].cs_period;
+ ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
+ cti->cti_syncreg = 0;
}
- cti->cti_syncreg = 0;
return 0;
}
@@ -362,14 +482,13 @@ ct_world_start(ct, fdone)
int fdone;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
- intrmask_t s;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
if (ct->sc_sdp == NULL)
- ct->sc_sdp = &ct_synch_data_20MHz[0];
+ {
+ ct->sc_sdp = ct_make_synch_table(ct);
+ }
- slp->sl_cfgflags |= CFG_MSGUNIFY;
if (slp->sl_cfgflags & CFG_NOPARITY)
ct->sc_creg = CR_DEFAULT;
else
@@ -382,11 +501,9 @@ ct_world_start(ct, fdone)
ct->sc_dma = 0;
ct->sc_atten = 0;
- s = splcam();
- cthw_chip_reset(bst, bsh, ct->sc_chipclk, slp->sl_hostid);
+ cthw_chip_reset(chp, NULL, ct->sc_chipclk, slp->sl_hostid);
scsi_low_bus_reset(slp);
- cthw_chip_reset(bst, bsh, ct->sc_chipclk, slp->sl_hostid);
- splx(s);
+ cthw_chip_reset(chp, NULL, ct->sc_chipclk, slp->sl_hostid);
SOFT_INTR_REQUIRED(slp);
return 0;
@@ -398,25 +515,29 @@ ct_start_selection(ct, cb)
struct slccb *cb;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
- struct targ_info *ti = slp->sl_nexus;
- struct lun_info *li = ti->ti_li;
- int s;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+
+ struct targ_info *ti = slp->sl_Tnexus;
+ struct lun_info *li = slp->sl_Lnexus;
+ int s, satok;
u_int8_t cmd;
+ ct->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
ct->sc_atten = 0;
- if (cthw_cmdlevel[slp->sl_scp.scp_cmd[0]] != 0)
+ satok = 0;
+
+ if (scsi_low_is_disconnect_ok(cb) != 0)
+ {
+ if (ct->sc_chiprev >= CT_WD33C93_A)
+ satok = 1;
+ else if (cthw_cmdlevel[slp->sl_scp.scp_cmd[0]] != 0)
+ satok = 1;
+ }
+
+ if (satok != 0 &&
+ scsi_low_is_msgout_continue(ti, SCSI_LOW_MSG_IDENTIFY) == 0)
{
- /*
- * This completely violates scsi protocols,
- * however some old devices do not work
- * properly with scsi attentions.
- */
- if ((li->li_flags & SCSI_LOW_DISC) != 0)
- cmd = WD3S_SELECT_ATN_TFR;
- else
- cmd = WD3S_SELECT_NO_ATN_TFR;
+ cmd = WD3S_SELECT_ATN_TFR;
ct->sc_satgo = CT_SAT_GOING;
}
else
@@ -425,24 +546,33 @@ ct_start_selection(ct, cb)
ct->sc_satgo = 0;
}
- if ((ct_stat_read_1(bst, bsh) & STR_BUSY) != 0)
+ if ((ct_stat_read_1(chp) & (STR_BSY | STR_INT | STR_CIP)) != 0)
return SCSI_LOW_START_FAIL;
- scsi_low_cmd(slp, ti);
-
if ((ct->sc_satgo & CT_SAT_GOING) != 0)
- ct_write_cmds(bst, bsh,
- slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
+ {
+ (void) scsi_low_msgout(slp, ti, SCSI_LOW_MSGOUT_INIT);
+ scsi_low_cmd(slp, ti);
+ ct_cr_write_1(chp, wd3s_oid, slp->sl_scp.scp_cmdlen);
+ ct_write_cmds(chp, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
+ }
+ else
+ {
+ /* anyway attention assert */
+ SCSI_LOW_ASSERT_ATN(slp);
+ }
+
+ ct_target_nexus_establish(ct, li->li_lun, slp->sl_scp.scp_direction);
s = splhigh();
- if ((ct_stat_read_1(bst, bsh) & STR_BUSY) == 0)
+ if ((ct_stat_read_1(chp) & (STR_BSY | STR_INT | STR_CIP)) == 0)
{
/* XXX:
* Reload a lun again here.
*/
- ct_cr_write_1(bst, bsh, wd3s_lun, li->li_lun);
- ct_cr_write_1(bst, bsh, wd3s_cmd, cmd);
- if ((ct_stat_read_1(bst, bsh) & STR_LCI) == 0)
+ ct_cr_write_1(chp, wd3s_lun, li->li_lun);
+ ct_cr_write_1(chp, wd3s_cmd, cmd);
+ if ((ct_stat_read_1(chp) & STR_LCI) == 0)
{
splx(s);
SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART);
@@ -459,12 +589,23 @@ ct_msg(ct, ti, msg)
struct targ_info *ti;
u_int msg;
{
- struct lun_info *li = ti->ti_li;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct ct_targ_info *cti = (void *) ti;
struct ct_synch_data *csp = ct->sc_sdp;
u_int offset, period;
+ int error;
+
+ if ((msg & SCSI_LOW_MSG_WIDE) != 0)
+ {
+ if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8)
+ {
+ ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
+ return EINVAL;
+ }
+ return 0;
+ }
- if (msg != SCSI_LOW_MSG_SYNCH)
+ if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
return 0;
offset = ti->ti_maxsynch.offset;
@@ -480,95 +621,117 @@ ct_msg(ct, ti, msg)
ti->ti_maxsynch.period = 0;
ti->ti_maxsynch.offset = 0;
cti->cti_syncreg = 0;
- return EINVAL;
+ error = EINVAL;
+ }
+ else
+ {
+ cti->cti_syncreg = ((offset & 0x0f) | csp->cs_syncr);
+ error = 0;
}
- cti->cti_syncreg = ((offset & 0x0f) | csp->cs_syncr);
if (ct->ct_synch_setup != 0)
- (*ct->ct_synch_setup) (ct, li);
- return 0;
+ (*ct->ct_synch_setup) (ct, ti);
+ ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
+ return error;
}
/*************************************************
* <DATA PHASE>
*************************************************/
static int
-ct_xfer(ct, data, len, direction)
+ct_xfer(ct, data, len, direction, statp)
struct ct_softc *ct;
u_int8_t *data;
int len, direction;
+ u_int *statp;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
int wc;
register u_int8_t aux;
+ *statp = 0;
if (len == 1)
{
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_SBT | WD3S_TFR_INFO);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_SBT | WD3S_TFR_INFO);
}
else
{
- cthw_set_count(bst, bsh, len);
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_TFR_INFO);
+ cthw_set_count(chp, len);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO);
}
- aux = ct_stat_read_1(bst, bsh);
+ aux = ct_stat_read_1(chp);
if ((aux & STR_LCI) != 0)
{
- cthw_set_count(bst, bsh, 0);
+ cthw_set_count(chp, 0);
return len;
}
- for (wc = ct->sc_wc ; wc > 0; wc --)
+ for (wc = 0; wc < ct->sc_tmaxcnt; wc ++)
{
/* check data ready */
if ((aux & (STR_BSY | STR_DBR)) == (STR_BSY | STR_DBR))
{
if (direction == SCSI_LOW_READ)
- *data = ct_cr_read_1(bst, bsh, wd3s_data);
+ {
+ *data = ct_cr_read_1(chp, wd3s_data);
+ if ((aux & STR_PE) != 0)
+ *statp |= SCSI_LOW_DATA_PE;
+ }
else
- ct_cr_write_1(bst, bsh, wd3s_data, *data);
+ {
+ ct_cr_write_1(chp, wd3s_data, *data);
+ }
len --;
if (len <= 0)
break;
data ++;
}
+ else
+ {
+ SCSI_LOW_DELAY(1);
+ }
/* check phase miss */
- aux = ct_stat_read_1(bst, bsh);
+ aux = ct_stat_read_1(chp);
if ((aux & STR_INT) != 0)
break;
}
return len;
}
+#define CT_PADDING_BUF_SIZE 32
+
static void
ct_io_xfer(ct)
struct ct_softc *ct;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct sc_p *sp = &slp->sl_scp;
- u_int dummy;
+ u_int stat;
int len;
+ u_int8_t pbuf[CT_PADDING_BUF_SIZE];
- /* io polling mode */
- ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg);
+ /* polling mode */
+ ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg);
if (sp->scp_datalen <= 0)
{
slp->sl_error |= PDMAERR;
- dummy = 0;
- len = ct_xfer(ct, (u_int8_t *) &dummy, 1, sp->scp_direction);
+
+ if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
+ SCSI_LOW_BZERO(pbuf, CT_PADDING_BUF_SIZE);
+ ct_xfer(ct, pbuf, CT_PADDING_BUF_SIZE,
+ sp->scp_direction, &stat);
}
else
+ {
len = ct_xfer(ct, sp->scp_data, sp->scp_datalen,
- sp->scp_direction);
-
- sp->scp_data += (sp->scp_datalen - len);
- sp->scp_datalen = len;
+ sp->scp_direction, &stat);
+ sp->scp_data += (sp->scp_datalen - len);
+ sp->scp_datalen = len;
+ }
}
/**************************************************
@@ -598,7 +761,7 @@ ct_phase_error(ct, scsi_status)
u_int8_t scsi_status;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
- struct targ_info *ti = slp->sl_nexus;
+ struct targ_info *ti = slp->sl_Tnexus;
struct ct_err *pep;
u_int msg = 0;
@@ -618,13 +781,13 @@ ct_phase_error(ct, scsi_status)
msg = pep->pe_errmsg;
if (msg != 0)
- scsi_low_assert_msg(slp, slp->sl_nexus, msg, 1);
+ scsi_low_assert_msg(slp, slp->sl_Tnexus, msg, 1);
if (pep->pe_msg != NULL)
{
printf("%s: phase error: %s",
slp->sl_xname, pep->pe_msg);
- scsi_low_print(slp, slp->sl_nexus);
+ scsi_low_print(slp, slp->sl_Tnexus);
}
if (pep->pe_done != 0)
@@ -640,90 +803,193 @@ ct_phase_error(ct, scsi_status)
/**************************************************
* ### SCSI PHASE SEQUENCER ###
**************************************************/
-static __inline int
-ct_reselected(ct)
+static int
+ct_reselected(ct, scsi_status)
struct ct_softc *ct;
+ u_int8_t scsi_status;
{
struct scsi_low_softc *slp = &ct->sc_sclow;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct targ_info *ti;
u_int sid;
+ u_int8_t regv;
ct->sc_atten = 0;
- sid = (ct_cr_read_1(bst, bsh, wd3s_sid) & SIDR_IDM);
+ ct->sc_satgo &= ~CT_SAT_GOING;
+ regv = ct_cr_read_1(chp, wd3s_sid);
+ if ((regv & SIDR_VALID) == 0)
+ return EJUSTRETURN;
+
+ sid = regv & SIDR_IDM;
if ((ti = scsi_low_reselected(slp, sid)) == NULL)
return EJUSTRETURN;
- ct_cr_write_1(bst, bsh, wd3s_did, sid);
- ct_cr_write_1(bst, bsh, wd3s_lun, 0); /* temp */
- ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg | CR_DMA);
- cthw_set_count(bst, bsh, 0);
+ ct_target_nexus_establish(ct, 0, SCSI_LOW_READ);
+ if (scsi_status != BSR_AFM_RESEL)
+ return EJUSTRETURN;
+
+ SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
+ regv = ct_cr_read_1(chp, wd3s_data);
+ if (scsi_low_msgin(slp, ti, (u_int) regv) == 0)
+ {
+ if (scsi_low_is_msgout_continue(ti, 0) != 0)
+ {
+ /* XXX: scsi_low_attetion */
+ scsi_low_attention(slp);
+ }
+ }
+
+ if (ct->sc_atten != 0)
+ {
+ ct_attention(ct);
+ }
+
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_NEGATE_ACK);
return EJUSTRETURN;
}
static int
-ct_nexus(ct, ti)
+ct_target_nexus_establish(ct, lun, dir)
struct ct_softc *ct;
- struct targ_info *ti;
+ int lun, dir;
{
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
- struct lun_info *li = ti->ti_li;
+ struct scsi_low_softc *slp = &ct->sc_sclow;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+ struct targ_info *ti = slp->sl_Tnexus;
struct ct_targ_info *cti = (void *) ti;
- if ((li->li_flags & SCSI_LOW_NOPARITY) != 0)
- ct->sc_creg = CR_DEFAULT;
+ if (dir == SCSI_LOW_WRITE)
+ ct_cr_write_1(chp, wd3s_did, ti->ti_id);
else
- ct->sc_creg = CR_DEFAULT_HP;
+ ct_cr_write_1(chp, wd3s_did, ti->ti_id | DIDR_DPD);
+ ct_cr_write_1(chp, wd3s_lun, lun);
+ ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA);
+ ct_cr_write_1(chp, wd3s_cph, 0);
+ ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
+ cthw_set_count(chp, 0);
+ return 0;
+}
+
+static int
+ct_lun_nexus_establish(ct)
+ struct ct_softc *ct;
+{
+ struct scsi_low_softc *slp = &ct->sc_sclow;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+ struct lun_info *li = slp->sl_Lnexus;
+
+ ct_cr_write_1(chp, wd3s_lun, li->li_lun);
+ return 0;
+}
+
+static int
+ct_ccb_nexus_establish(ct)
+ struct ct_softc *ct;
+{
+ struct scsi_low_softc *slp = &ct->sc_sclow;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+ struct lun_info *li = slp->sl_Lnexus;
+ struct targ_info *ti = slp->sl_Tnexus;
+ struct ct_targ_info *cti = (void *) ti;
+ struct slccb *cb = slp->sl_Qnexus;
- ct_cr_write_1(bst, bsh, wd3s_did, ti->ti_id);
- ct_cr_write_1(bst, bsh, wd3s_lun, li->li_lun);
- ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg | CR_DMA);
- ct_cr_write_1(bst, bsh, wd3s_cph, 0);
- ct_cr_write_1(bst, bsh, wd3s_synch, cti->cti_syncreg);
- cthw_set_count(bst, bsh, 0);
- ct_cr_write_1(bst, bsh, wd3s_lun, li->li_lun); /* XXX */
+ ct->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
+
+ if ((ct->sc_satgo & CT_SAT_GOING) != 0)
+ {
+ ct_cr_write_1(chp, wd3s_oid, slp->sl_scp.scp_cmdlen);
+ ct_write_cmds(chp, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
+ }
+ if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
+ ct_cr_write_1(chp, wd3s_did, ti->ti_id);
+ else
+ ct_cr_write_1(chp, wd3s_did, ti->ti_id | DIDR_DPD);
+ ct_cr_write_1(chp, wd3s_lun, li->li_lun);
+ ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
return 0;
}
+static int
+ct_unbusy(ct)
+ struct ct_softc *ct;
+{
+ struct scsi_low_softc *slp = &ct->sc_sclow;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+ int wc;
+ register u_int8_t regv;
+
+ for (wc = 0; wc < CT_DELAY_MAX / CT_DELAY_INTERVAL; wc ++)
+ {
+ regv = ct_stat_read_1(chp);
+ if ((regv & (STR_BSY | STR_CIP)) == 0)
+ return 0;
+ if (regv == (u_int8_t) -1)
+ return EIO;
+
+ SCSI_LOW_DELAY(CT_DELAY_INTERVAL);
+ }
+
+ printf("%s: unbusy timeout\n", slp->sl_xname);
+ return EBUSY;
+}
+
+static int
+ct_catch_intr(ct)
+ struct ct_softc *ct;
+{
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
+ int wc;
+ register u_int8_t regv;
+
+ for (wc = 0; wc < CT_DELAY_MAX / CT_DELAY_INTERVAL; wc ++)
+ {
+ regv = ct_stat_read_1(chp);
+ if ((regv & (STR_INT | STR_BSY | STR_CIP)) == STR_INT)
+ return 0;
+
+ SCSI_LOW_DELAY(CT_DELAY_INTERVAL);
+ }
+ return EJUSTRETURN;
+}
+
int
ctintr(arg)
void *arg;
{
struct ct_softc *ct = arg;
struct scsi_low_softc *slp = &ct->sc_sclow;
- bus_space_tag_t bst = ct->sc_iot;
- bus_space_handle_t bsh = ct->sc_ioh;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct targ_info *ti;
struct physio_proc *pp;
struct buf *bp;
- int len, satgo;
+ u_int derror, flags;
+ int len, satgo, error;
u_int8_t scsi_status, regv;
+again:
if (slp->sl_flags & HW_INACTIVE)
return 0;
/**************************************************
* Get status & bus phase
**************************************************/
- if ((ct_stat_read_1(bst, bsh) & STR_INT) == 0)
+ if ((ct_stat_read_1(chp) & STR_INT) == 0)
return 0;
- scsi_status = ct_cr_read_1(bst, bsh, wd3s_stat);
+ scsi_status = ct_cr_read_1(chp, wd3s_stat);
if (scsi_status == ((u_int8_t) -1))
return 1;
/**************************************************
* Check reselection, or nexus
**************************************************/
- if (scsi_status == BSR_RESEL)
+ if (scsi_status == BSR_RESEL || scsi_status == BSR_AFM_RESEL)
{
- if (ct_reselected(ct) == EJUSTRETURN)
+ if (ct_reselected(ct, scsi_status) == EJUSTRETURN)
return 1;
}
- if ((ti = slp->sl_nexus) == NULL)
+ if ((ti = slp->sl_Tnexus) == NULL)
return 1;
/**************************************************
@@ -735,8 +1001,10 @@ ctintr(arg)
scsi_low_print(slp, NULL);
printf("%s: scsi_status 0x%x\n\n", slp->sl_xname,
(u_int) scsi_status);
+#ifdef DDB
if (ct_debug > 1)
- Debugger();
+ SCSI_LOW_DEBUGGER("ct");
+#endif /* DDB */
}
#endif /* CT_DEBUG */
@@ -744,7 +1012,7 @@ ctintr(arg)
* Internal scsi phase
**************************************************/
satgo = ct->sc_satgo;
- ct->sc_satgo = 0;
+ ct->sc_satgo &= ~CT_SAT_GOING;
switch (ti->ti_phase)
{
@@ -756,15 +1024,14 @@ ctintr(arg)
ct_phase_error(ct, scsi_status);
return 1;
}
- scsi_low_arbit_win(slp, ti);
+ scsi_low_arbit_win(slp);
SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
- scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
return 1;
}
else
{
- scsi_low_arbit_win(slp, ti);
- SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
+ scsi_low_arbit_win(slp);
+ SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); /* XXX */
}
break;
@@ -787,11 +1054,15 @@ ctintr(arg)
(*ct->ct_dma_xfer_stop) (ct);
ct->sc_dma &= ~CT_DMA_DMASTART;
}
- else
+ else if (ct->sc_dma & CT_DMA_PIOSTART)
{
(*ct->ct_pio_xfer_stop) (ct);
ct->sc_dma &= ~CT_DMA_PIOSTART;
}
+ else
+ {
+ scsi_low_data_finish(slp);
+ }
}
break;
}
@@ -815,48 +1086,78 @@ ctintr(arg)
case BSR_DATAOUT:
SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0)
- return 1;
+ {
+ ct_attention(ct);
+ }
goto common_data_phase;
case BSR_DATAIN:
SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0)
- return 1;
-
-common_data_phase:
- if (slp->sl_scp.scp_datalen <= 0)
{
- ct_io_xfer(ct);
- return 1;
+ ct_attention(ct);
}
- slp->sl_flags |= HW_PDMASTART;
- if ((ct->sc_xmode & CT_XMODE_PIO) != 0 &&
- (slp->sl_scp.scp_datalen % DEV_BSIZE) == 0)
+common_data_phase:
+ if (slp->sl_scp.scp_datalen > 0)
{
- pp = physio_proc_enter(bp);
- ct->sc_dma |= CT_DMA_PIOSTART;
- (*ct->ct_pio_xfer_start) (ct);
- physio_proc_leave(pp);
- return 1;
+ slp->sl_flags |= HW_PDMASTART;
+ if ((ct->sc_xmode & CT_XMODE_PIO) != 0)
+ {
+ pp = physio_proc_enter(bp);
+ error = (*ct->ct_pio_xfer_start) (ct);
+ physio_proc_leave(pp);
+ if (error == 0)
+ {
+ ct->sc_dma |= CT_DMA_PIOSTART;
+ return 1;
+ }
+ }
+
+ if ((ct->sc_xmode & CT_XMODE_DMA) != 0)
+ {
+ error = (*ct->ct_dma_xfer_start) (ct);
+ if (error == 0)
+ {
+ ct->sc_dma |= CT_DMA_DMASTART;
+ return 1;
+ }
+ }
}
else
- {
- ct->sc_dma |= CT_DMA_DMASTART;
- (*ct->ct_dma_xfer_start) (ct);
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_TFR_INFO);
+ {
+ if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
+ {
+ if (!(slp->sl_flags & HW_READ_PADDING))
+ {
+ printf("%s: read padding required\n", slp->sl_xname);
+ return 1;
+ }
+ }
+ else
+ {
+ if (!(slp->sl_flags & HW_WRITE_PADDING))
+ {
+ printf("%s: write padding required\n", slp->sl_xname);
+ return 1;
+ }
+ }
+ slp->sl_flags |= HW_PDMASTART;
}
+
+ ct_io_xfer(ct);
return 1;
case BSR_CMDOUT:
SCSI_LOW_SETUP_PHASE(ti, PH_CMD);
if (scsi_low_cmd(slp, ti) != 0)
- break;
+ {
+ ct_attention(ct);
+ }
- if (ct_xfer(ct,
- slp->sl_scp.scp_cmd,
+ if (ct_xfer(ct, slp->sl_scp.scp_cmd,
slp->sl_scp.scp_cmdlen,
- SCSI_LOW_WRITE) != 0)
+ SCSI_LOW_WRITE, &derror) != 0)
{
printf("%s: scsi cmd xfer short\n",
slp->sl_xname);
@@ -865,20 +1166,28 @@ common_data_phase:
case BSR_STATIN:
SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
-#ifdef CT_USE_CCSEQ
- if (scsi_low_is_msgout_continue(ti) != 0 ||
- ct->sc_atten != 0)
+ if ((ct_io_control & CT_USE_CCSEQ) != 0)
{
- ct_xfer(ct, &ti->ti_status, 1, SCSI_LOW_READ);
+ if (scsi_low_is_msgout_continue(ti, 0) != 0 ||
+ ct->sc_atten != 0)
+ {
+ ct_xfer(ct, &regv, 1, SCSI_LOW_READ,
+ &derror);
+ scsi_low_statusin(slp, ti,
+ regv | derror);
+ }
+ else
+ {
+ ct->sc_satgo |= CT_SAT_GOING;
+ cthw_set_count(chp, 0);
+ cthw_phase_bypass(ct, 0x41);
+ }
}
else
{
- cthw_set_count(bst, bsh, 0);
- cthw_phase_bypass(ct, 0x41);
+ ct_xfer(ct, &regv, 1, SCSI_LOW_READ, &derror);
+ scsi_low_statusin(slp, ti, regv | derror);
}
-#else /* !CT_USE_CCSEQ */
- ct_xfer(ct, &ti->ti_status, 1, SCSI_LOW_READ);
-#endif /* !CT_USE_CCSEQ */
return 1;
case BSR_UNSPINFO0:
@@ -890,20 +1199,44 @@ common_data_phase:
case BSR_MSGOUT:
SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
- len = scsi_low_msgout(slp, ti);
- if (ct_xfer(ct, ti->ti_msgoutstr, len, SCSI_LOW_WRITE))
+ flags = SCSI_LOW_MSGOUT_UNIFY;
+ if (ti->ti_ophase != ti->ti_phase)
+ flags |= SCSI_LOW_MSGOUT_INIT;
+ len = scsi_low_msgout(slp, ti, flags);
+
+ if (len > 1 && slp->sl_atten == 0)
+ {
+ ct_attention(ct);
+ }
+
+ if (ct_xfer(ct, ti->ti_msgoutstr, len,
+ SCSI_LOW_WRITE, &derror) != 0)
{
printf("%s: scsi msgout xfer short\n",
slp->sl_xname);
- scsi_low_assert_msg(slp, ti,
- SCSI_LOW_MSG_ABORT, 1);
}
+ SCSI_LOW_DEASSERT_ATN(slp);
+ ct->sc_atten = 0;
return 1;
case BSR_MSGIN:/* msg in */
SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
- ct_xfer(ct, &regv, 1, SCSI_LOW_READ);
- scsi_low_msgin(slp, ti, regv);
+
+ ct_xfer(ct, &regv, 1, SCSI_LOW_READ, &derror);
+ if (scsi_low_msgin(slp, ti, regv | derror) == 0)
+ {
+ if (scsi_low_is_msgout_continue(ti, 0) != 0)
+ {
+ /* XXX: scsi_low_attetion */
+ scsi_low_attention(slp);
+ }
+ }
+
+ if ((ct_io_control & CT_FAST_INTR) != 0)
+ {
+ if (ct_catch_intr(ct) == 0)
+ goto again;
+ }
return 1;
}
}
@@ -916,6 +1249,7 @@ common_data_phase:
{
case BSR_SATSDP: /* SAT with save data pointer */
SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
+ ct->sc_satgo |= CT_SAT_GOING;
scsi_low_msgin(slp, ti, MSG_SAVESP);
cthw_phase_bypass(ct, 0x41);
return 1;
@@ -924,17 +1258,30 @@ common_data_phase:
/*
* emulate statusin => msgin
*/
- ti->ti_status = ct_cr_read_1(bst, bsh, wd3s_lun);
+ SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
+ scsi_low_statusin(slp, ti, ct_cr_read_1(chp, wd3s_lun));
+
SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
- SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
+ scsi_low_msgin(slp, ti, MSG_COMP);
+
scsi_low_disconnected(slp, ti);
return 1;
case BSR_ACKREQ: /* negate ACK */
if (ct->sc_atten != 0)
- cthw_attention(ct);
+ {
+ ct_attention(ct);
+ }
- ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_NEGATE_ACK);
+ ct_cr_write_1(chp, wd3s_cmd, WD3S_NEGATE_ACK);
+ if ((ct_io_control & CT_FAST_INTR) != 0)
+ {
+ /* XXX:
+ * Should clear a pending interrupt and
+ * sync with a next interrupt!
+ */
+ ct_catch_intr(ct);
+ }
return 1;
case BSR_DISC: /* disconnect */
@@ -945,7 +1292,7 @@ common_data_phase:
* emulate disconnect msg
*/
SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
- SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
+ scsi_low_msgin(slp, ti, MSG_DISCON);
}
scsi_low_disconnected(slp, ti);
return 1;
diff --git a/sys/dev/ct/ct_isa.c b/sys/dev/ct/ct_isa.c
index 5ca8006..ec38efe 100644
--- a/sys/dev/ct/ct_isa.c
+++ b/sys/dev/ct/ct_isa.c
@@ -75,6 +75,7 @@
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/rman.h>
+#include <machine/md_var.h>
#include <pc98/pc98/pc98.h>
#include <isa/isavar.h>
@@ -100,6 +101,9 @@ static int ct_space_map(device_t, struct bshw *,
static void ct_space_unmap(device_t, struct ct_softc *);
static struct bshw *ct_find_hw(device_t);
static void ct_dmamap(void *, bus_dma_segment_t *, int, int);
+static void ct_isa_bus_access_weight __P((struct ct_bus_access_handle *));
+static void ct_isa_dmasync_before __P((struct ct_softc *));
+static void ct_isa_dmasync_after __P((struct ct_softc *));
struct ct_isa_softc {
struct ct_softc sc_ct;
@@ -132,6 +136,7 @@ ct_isa_match(device_t dev)
{
struct bshw *hw;
struct resource *port_res, *mem_res;
+ struct ct_bus_access_handle ch;
int rv;
if (ISA_PNP_PROBE(device_get_parent(dev), dev, ct_pnp_ids) == ENXIO)
@@ -146,17 +151,20 @@ ct_isa_match(device_t dev)
if (ct_space_map(dev, hw, &port_res, &mem_res) != 0)
return ENXIO;
- rv = ctprobesubr(rman_get_bustag(port_res),
- rman_get_bushandle(port_res),
- 0, BSHW_DEFAULT_HOSTID, BSHW_DEFAULT_CHIPCLK);
+ bzero(&ch, sizeof(ch));
+ ch.ch_iot = rman_get_bustag(port_res);
+ ch.ch_ioh = rman_get_bushandle(port_res),
+ ch.ch_bus_weight = ct_isa_bus_access_weight;
+
+ rv = ctprobesubr(&ch, 0, BSHW_DEFAULT_HOSTID,
+ BSHW_DEFAULT_CHIPCLK, NULL);
if (rv != 0)
{
struct bshw_softc bshw_tab;
struct bshw_softc *bs = &bshw_tab;
memset(bs, 0, sizeof(*bs));
- bshw_read_settings(rman_get_bustag(port_res),
- rman_get_bushandle(port_res), bs);
+ bshw_read_settings(&ch, bs);
bus_set_resource(dev, SYS_RES_IRQ, 0, bs->sc_irq, 1);
bus_set_resource(dev, SYS_RES_DRQ, 0, bs->sc_drq, 1);
}
@@ -175,12 +183,14 @@ ct_isa_attach(device_t dev)
{
struct ct_isa_softc *pct = device_get_softc(dev);
struct ct_softc *ct = &pct->sc_ct;
+ struct ct_bus_access_handle *chp = &ct->sc_ch;
struct scsi_low_softc *slp = &ct->sc_sclow;
struct bshw_softc *bs = &pct->sc_bshw;
struct bshw *hw;
- int irq_rid, drq_rid;
+ int irq_rid, drq_rid, chiprev;
u_int8_t *vaddr;
bus_addr_t addr;
+ intrmask_t s;
hw = ct_find_hw(dev);
if (ct_space_map(dev, hw, &ct->port_res, &ct->mem_res) != 0) {
@@ -188,12 +198,14 @@ ct_isa_attach(device_t dev)
return ENXIO;
}
- ct->sc_iot = rman_get_bustag(ct->port_res);
- ct->sc_ioh = rman_get_bushandle(ct->port_res);
+ bzero(chp, sizeof(*chp));
+ chp->ch_iot = rman_get_bustag(ct->port_res);
+ chp->ch_ioh = rman_get_bushandle(ct->port_res);
if (ct->mem_res) {
- ct->sc_memt = rman_get_bustag(ct->mem_res);
- ct->sc_memh = rman_get_bushandle(ct->mem_res);
+ chp->ch_memt = rman_get_bustag(ct->mem_res);
+ chp->ch_memh = rman_get_bushandle(ct->mem_res);
}
+ chp->ch_bus_weight = ct_isa_bus_access_weight;
irq_rid = 0;
ct->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, 0, ~0,
@@ -206,6 +218,14 @@ ct_isa_attach(device_t dev)
return ENXIO;
}
+ if (ctprobesubr(chp, 0, BSHW_DEFAULT_HOSTID,
+ BSHW_DEFAULT_CHIPCLK, &chiprev) == 0)
+ {
+ device_printf(dev, "hardware missing\n");
+ ct_space_unmap(dev, ct);
+ return ENXIO;
+ }
+
/* setup DMA map */
if (bus_dma_tag_create(NULL, 1, 0,
BUS_SPACE_MAXADDR_24BIT, BUS_SPACE_MAXADDR,
@@ -229,11 +249,14 @@ ct_isa_attach(device_t dev)
/* setup machdep softc */
bs->sc_hw = hw;
+ bs->sc_io_control = 0;
bs->sc_bounce_phys = (u_int8_t *)addr;
bs->sc_bounce_addr = vaddr;
bs->sc_bounce_size = MAXBSIZE;
bs->sc_minphys = (1 << 24);
- bshw_read_settings(ct->sc_iot, ct->sc_ioh, bs);
+ bs->sc_dmasync_before = ct_isa_dmasync_before;
+ bs->sc_dmasync_after = ct_isa_dmasync_after;
+ bshw_read_settings(chp, bs);
/* setup ct driver softc */
ct->ct_hw = bs;
@@ -245,17 +268,54 @@ ct_isa_attach(device_t dev)
ct->ct_synch_setup = bshw_synch_setup;
ct->sc_xmode = CT_XMODE_DMA;
- if (ct->sc_memh != NULL)
+ if (chp->ch_memh != NULL)
ct->sc_xmode |= CT_XMODE_PIO;
- ct->sc_chiprev = CT_WD33C93_B;
- ct->sc_chipclk = BSHW_DEFAULT_CHIPCLK;
+
+ ct->sc_chiprev = chiprev;
+ switch (chiprev)
+ {
+ case CT_WD33C93:
+ /* s = "WD33C93"; */
+ ct->sc_chipclk = 8;
+ break;
+ case CT_WD33C93_A:
+ if (DVCFG_MAJOR(device_get_flags(dev)) > 0)
+ {
+ /* s = "AM33C93_A"; */
+ ct->sc_chipclk = 20;
+ ct->sc_chiprev = CT_AM33C93_A;
+ }
+ else
+ {
+ /* s = "WD33C93_A"; */
+ ct->sc_chipclk = 10;
+ }
+ break;
+
+ case CT_AM33C93_A:
+ /* s = "AM33C93_A"; */
+ ct->sc_chipclk = 20;
+ break;
+
+ default:
+ case CT_WD33C93_B:
+ /* s = "WD33C93_B"; */
+ ct->sc_chipclk = 20;
+ break;
+ }
+#if 0
+ printf("%s: chiprev %s chipclk %d Mhz\n",
+ slp->sl_dev.dv_xname, s, ct->sc_chipclk);
+#endif
slp->sl_dev = dev;
slp->sl_hostid = bs->sc_hostid;
slp->sl_irq = isa_get_irq(dev);
slp->sl_cfgflags = device_get_flags(dev);
+ s = splcam();
ctattachsubr(ct);
+ splx(s);
if (bus_setup_intr(dev, ct->irq_res, INTR_TYPE_CAM,
(driver_intr_t *)ctintr, ct, &ct->sc_ih)) {
@@ -320,3 +380,29 @@ ct_dmamap(void *arg, bus_dma_segment_t *seg, int nseg, int error)
*addr = seg->ds_addr;
}
+
+static void
+ct_isa_bus_access_weight(chp)
+ struct ct_bus_access_handle *chp;
+{
+
+ outb(0x5f, 0);
+}
+
+static void
+ct_isa_dmasync_before(ct)
+ struct ct_softc *ct;
+{
+
+ if (need_pre_dma_flush)
+ wbinvd();
+}
+
+static void
+ct_isa_dmasync_after(ct)
+ struct ct_softc *ct;
+{
+
+ if (need_post_dma_flush)
+ invd();
+}
diff --git a/sys/dev/ct/ct_machdep.h b/sys/dev/ct/ct_machdep.h
index 195af5b..be10331 100644
--- a/sys/dev/ct/ct_machdep.h
+++ b/sys/dev/ct/ct_machdep.h
@@ -1,12 +1,12 @@
/* $FreeBSD$ */
-/* $NecBSD: ct_machdep.h,v 1.4 1999/07/23 20:54:00 honda Exp $ */
+/* $NecBSD: ct_machdep.h,v 1.4.12.2 2001/06/20 06:13:34 honda Exp $ */
/* $NetBSD$ */
/*
* [NetBSD for NEC PC-98 series]
- * Copyright (c) 1995, 1996, 1997, 1998
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
* NetBSD/pc98 porting staff. All rights reserved.
- * Copyright (c) 1995, 1996, 1997, 1998
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
* Naofumi HONDA. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,8 @@
#ifndef _CT_MACHDEP_H_
#define _CT_MACHDEP_H_
+#include "opt_ct.h"
+
/*
* Principal rules:
* 1) do not use bus_space_write/read_X directly in ct.c.
@@ -43,101 +45,167 @@
*/
/* special weight if requried */
-#define CT_BUS_WEIGHT
+#ifdef CT_BUS_WEIGHT
+#undef CT_BUS_WEIGHT
+#define CT_BUS_WEIGHT(chp) \
+{ \
+ if ((chp)->ch_bus_weight != NULL) \
+ (chp)->ch_bus_weight((chp)); \
+}
+#else /* !CT_BUS_WEIGHT */
+#define CT_BUS_WEIGHT(chp)
+#endif /* !CT_BUS_WEIGHT */
/* port offset */
+#ifndef CT_USE_RELOCATE_OFFSET
#define addr_port 0
#define stat_port 0
#define ctrl_port 2
#define cmd_port 4
+#else /* CT_USE_RELOCATE_OFFSET */
+#define addr_port ((chp)->ch_offset[0])
+#define stat_port ((chp)->ch_offset[1])
+#define ctrl_port ((chp)->ch_offset[2])
+#define cmd_port ((chp)->ch_offset[3])
+#endif /* CT_USE_RELOCATE_OFFSET */
/*
* All port accesses primitive methods
*/
-static __inline u_int8_t ct_cr_read_1 __P((bus_space_tag_t, bus_space_handle_t, bus_addr_t));
-static __inline void ct_cr_write_1 __P((bus_space_tag_t, bus_space_handle_t, bus_addr_t, u_int8_t));
-static __inline void ct_write_cmds __P((bus_space_tag_t, bus_space_handle_t, u_int8_t *, int));
-static __inline u_int cthw_get_count __P((bus_space_tag_t, bus_space_handle_t));
-static __inline void cthw_set_count __P((bus_space_tag_t, bus_space_handle_t, u_int));
+static __inline u_int8_t ct_stat_read_1
+ __P((struct ct_bus_access_handle *));
+static __inline u_int8_t ct_cmdp_read_1
+ __P((struct ct_bus_access_handle *));
+static __inline void ct_cmdp_write_1
+ __P((struct ct_bus_access_handle *, u_int8_t));
+static __inline u_int8_t ct_cr_read_1
+ __P((struct ct_bus_access_handle *, bus_addr_t));
+static __inline void ct_cr_write_1
+ __P((struct ct_bus_access_handle *, bus_addr_t, u_int8_t));
+static __inline void ct_write_cmds
+ __P((struct ct_bus_access_handle *, u_int8_t *, int));
+static __inline u_int cthw_get_count
+ __P((struct ct_bus_access_handle *));
+static __inline void cthw_set_count
+ __P((struct ct_bus_access_handle *, u_int));
+
+static __inline u_int8_t
+ct_stat_read_1(chp)
+ struct ct_bus_access_handle *chp;
+{
+ u_int8_t regv;
-#define ct_stat_read_1(bst, bsh) bus_space_read_1((bst), (bsh), stat_port)
+ regv = bus_space_read_1(chp->ch_iot, chp->ch_ioh, stat_port);
+ CT_BUS_WEIGHT(chp)
+ return regv;
+}
static __inline void
-cthw_set_count(bst, bsh, count)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+cthw_set_count(chp, count)
+ struct ct_bus_access_handle *chp;
u_int count;
{
+ bus_space_tag_t bst = chp->ch_iot;
+ bus_space_handle_t bsh = chp->ch_ioh;
bus_space_write_1(bst, bsh, addr_port, wd3s_cnt);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
bus_space_write_1(bst, bsh, ctrl_port, count >> 16);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
bus_space_write_1(bst, bsh, ctrl_port, count >> 8);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
bus_space_write_1(bst, bsh, ctrl_port, count);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
}
static __inline u_int
-cthw_get_count(bst, bsh)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+cthw_get_count(chp)
+ struct ct_bus_access_handle *chp;
{
+ bus_space_tag_t bst = chp->ch_iot;
+ bus_space_handle_t bsh = chp->ch_ioh;
u_int count;
bus_space_write_1(bst, bsh, addr_port, wd3s_cnt);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
count = (((u_int) bus_space_read_1(bst, bsh, ctrl_port)) << 16);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
count += (((u_int) bus_space_read_1(bst, bsh, ctrl_port)) << 8);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
count += ((u_int) bus_space_read_1(bst, bsh, ctrl_port));
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
return count;
}
static __inline void
-ct_write_cmds(bst, bsh, cmd, len)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+ct_write_cmds(chp, cmd, len)
+ struct ct_bus_access_handle *chp;
u_int8_t *cmd;
int len;
{
+ bus_space_tag_t bst = chp->ch_iot;
+ bus_space_handle_t bsh = chp->ch_ioh;
int i;
bus_space_write_1(bst, bsh, addr_port, wd3s_cdb);
+ CT_BUS_WEIGHT(chp)
for (i = 0; i < len; i ++)
+ {
bus_space_write_1(bst, bsh, ctrl_port, cmd[i]);
+ CT_BUS_WEIGHT(chp)
+ }
}
static __inline u_int8_t
-ct_cr_read_1(bst, bsh, offs)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+ct_cr_read_1(chp, offs)
+ struct ct_bus_access_handle *chp;
bus_addr_t offs;
{
+ bus_space_tag_t bst = chp->ch_iot;
+ bus_space_handle_t bsh = chp->ch_ioh;
u_int8_t regv;
bus_space_write_1(bst, bsh, addr_port, offs);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
regv = bus_space_read_1(bst, bsh, ctrl_port);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
return regv;
}
static __inline void
-ct_cr_write_1(bst, bsh, offs, val)
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
+ct_cr_write_1(chp, offs, val)
+ struct ct_bus_access_handle *chp;
bus_addr_t offs;
u_int8_t val;
{
+ bus_space_tag_t bst = chp->ch_iot;
+ bus_space_handle_t bsh = chp->ch_ioh;
bus_space_write_1(bst, bsh, addr_port, offs);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
bus_space_write_1(bst, bsh, ctrl_port, val);
- CT_BUS_WEIGHT
+ CT_BUS_WEIGHT(chp)
+}
+
+static __inline u_int8_t
+ct_cmdp_read_1(chp)
+ struct ct_bus_access_handle *chp;
+{
+ u_int8_t regv;
+
+ regv = bus_space_read_1(chp->ch_iot, chp->ch_ioh, cmd_port);
+ CT_BUS_WEIGHT(chp)
+ return regv;
+}
+
+static __inline void
+ct_cmdp_write_1(chp, val)
+ struct ct_bus_access_handle *chp;
+ u_int8_t val;
+{
+
+ bus_space_write_1(chp->ch_iot, chp->ch_ioh, cmd_port, val);
+ CT_BUS_WEIGHT(chp)
}
#if defined(i386)
@@ -145,11 +213,4 @@ ct_cr_write_1(bst, bsh, offs, val)
#else /* !i386 */
#define SOFT_INTR_REQUIRED(slp)
#endif /* !i386 */
-
-#ifdef __FreeBSD__
-typedef unsigned long vaddr_t;
-
-#define delay(t) DELAY(t)
-#endif
-
#endif /* !_CT_MACHDEP_H_ */
diff --git a/sys/dev/ct/ctvar.h b/sys/dev/ct/ctvar.h
index 5ad3db1..235990a 100644
--- a/sys/dev/ct/ctvar.h
+++ b/sys/dev/ct/ctvar.h
@@ -1,12 +1,12 @@
/* $FreeBSD$ */
-/* $NecBSD: ctvar.h,v 1.4 1999/04/15 01:36:13 kmatsuda Exp $ */
+/* $NecBSD: ctvar.h,v 1.4.14.3 2001/06/20 06:13:34 honda Exp $ */
/* $NetBSD$ */
/*
* [NetBSD for NEC PC-98 series]
- * Copyright (c) 1995, 1996, 1997, 1998
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
* NetBSD/pc98 porting staff. All rights reserved.
- * Copyright (c) 1995, 1996, 1997, 1998
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
* Naofumi HONDA. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,31 +43,53 @@
/*****************************************************************
* Host adapter structure
*****************************************************************/
+struct ct_bus_access_handle {
+ bus_space_tag_t ch_iot; /* core chip ctrl port tag */
+ bus_space_tag_t ch_delayt; /* delay port tag */
+ bus_space_tag_t ch_datat; /* data port tag (pio) */
+ bus_space_tag_t ch_memt; /* data port tag (shm) */
+
+ bus_space_handle_t ch_ioh;
+ bus_space_handle_t ch_delaybah;
+ bus_space_handle_t ch_datah;
+ bus_space_handle_t ch_memh;
+
+ void (*ch_bus_weight) __P((struct ct_bus_access_handle *));
+
+#ifdef CT_USE_RELOCATE_OFFSET
+ bus_addr_t ch_offset[4];
+#endif /* CT_USE_RELOCATE_OFFSET */
+};
+
struct ct_softc {
struct scsi_low_softc sc_sclow; /* generic data */
+ struct ct_bus_access_handle sc_ch; /* bus access handle */
+
+#ifdef __NetBSD__
+ bus_dma_tag_t sc_dmat; /* data DMA tag */
+
+ void *sc_ih;
+#endif /* __NetBSD__ */
+
+#ifdef __FreeBSD__
struct resource *port_res;
struct resource *mem_res;
struct resource *irq_res;
struct resource *drq_res;
- bus_space_tag_t sc_iot; /* core chip ctrl port tag */
- bus_space_tag_t sc_datat; /* data port tag (pio) */
- bus_space_tag_t sc_memt; /* data port tag (shm) */
bus_dma_tag_t sc_dmat; /* data DMA tag */
bus_dmamap_t sc_dmamapt; /* data DMAMAP tag */
- bus_space_handle_t sc_ioh;
- bus_space_handle_t sc_datah;
- bus_space_handle_t sc_memh;
-
void *sc_ih;
- int sc_wc; /* weight counter */
+#endif /* __FreeBSD__ */
int sc_chiprev; /* chip version */
-#define CT_WD33C93_A 0x00000
-#define CT_WD33C93_B 0x10000
-#define CT_WD33C93_C 0x20000
+#define CT_WD33C93 0x00000
+#define CT_WD33C93_A 0x10000
+#define CT_AM33C93_A 0x10001
+#define CT_WD33C93_B 0x20000
+#define CT_WD33C93_C 0x30000
int sc_xmode;
#define CT_XMODE_PIO 1
@@ -80,6 +102,7 @@ struct ct_softc {
int sc_satgo; /* combination cmd start */
#define CT_SAT_GOING 1
+ int sc_tmaxcnt;
int sc_atten; /* attention */
u_int8_t sc_creg; /* control register value */
@@ -89,20 +112,22 @@ struct ct_softc {
u_int cs_syncr;
} *sc_sdp; /* synchronous data table pt */
+ struct ct_synch_data sc_default_sdt[16];
+
/*
* Machdep stuff.
*/
void *ct_hw; /* point to bshw_softc etc ... */
- void (*ct_dma_xfer_start) __P((struct ct_softc *));
- void (*ct_pio_xfer_start) __P((struct ct_softc *));
+ int (*ct_dma_xfer_start) __P((struct ct_softc *));
+ int (*ct_pio_xfer_start) __P((struct ct_softc *));
void (*ct_dma_xfer_stop) __P((struct ct_softc *));
void (*ct_pio_xfer_stop) __P((struct ct_softc *));
void (*ct_bus_reset) __P((struct ct_softc *));
- void (*ct_synch_setup) __P((struct ct_softc *, struct lun_info *));
+ void (*ct_synch_setup) __P((struct ct_softc *, struct targ_info *));
};
/*****************************************************************
- * Target information
+ * Lun information
*****************************************************************/
struct ct_targ_info {
struct targ_info cti_ti;
@@ -113,14 +138,7 @@ struct ct_targ_info {
/*****************************************************************
* PROTO
*****************************************************************/
-#ifdef __NetBSD__
-#include <i386/Cbus/dev/ct/ct_machdep.h>
-#endif
-#ifdef __FreeBSD__
-#include <dev/ct/ct_machdep.h>
-#endif
-
-int ctprobesubr __P((bus_space_tag_t, bus_space_handle_t ioh, u_int, int, u_int));
+int ctprobesubr __P((struct ct_bus_access_handle *, u_int, int, u_int, int *));
void ctattachsubr __P((struct ct_softc *));
int ctprint __P((void *, const char *));
int ctintr __P((void *));
OpenPOWER on IntegriCloud