freebsd-skq/sys/i386/isa/bs/bshw.h
2002-03-20 07:51:46 +00:00

354 lines
8.6 KiB
C

/* $NecBSD: bshw.h,v 1.2 1997/10/31 17:43:38 honda Exp $ */
/* $NetBSD$ */
/*
* [NetBSD for NEC PC98 series]
* Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* $FreeBSD$
*/
/*
* Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
*/
/* NEC port offsets */
#define BSHW_DEFAULT_PORT 0xcc0
#define BSHW_IOSZ 5
#define addr_port 0
#define stat_port 0
#define ctrl_port 2
#define cmd_port 4
#define BSHW_MAX_OFFSET 12
#define BSHW_SEL_TIMEOUT 0x80
#define BSHW_READ BSR_IOR
#define BSHW_WRITE 0x0
#define BSHW_SMITFIFO_OFFSET 0x1000
#define BSHW_CMD_CHECK(CCB, CAT) (bshw_cmd[(CCB)->cmd[0]] & (CAT))
/*********************************************************
* static inline declare.
*********************************************************/
static BS_INLINE void write_wd33c93(struct bs_softc *, u_int, u_int8_t);
static BS_INLINE u_int8_t read_wd33c93(struct bs_softc *, u_int);
static BS_INLINE u_int8_t bshw_get_auxstat(struct bs_softc *);
static BS_INLINE u_int8_t bshw_get_busstat(struct bs_softc *);
static BS_INLINE u_int8_t bshw_get_status_insat(struct bs_softc *);
static BS_INLINE u_int8_t bshw_read_data(struct bs_softc *);
static BS_INLINE void bshw_write_data(struct bs_softc *, u_int8_t);
static BS_INLINE void bshw_set_count(struct bs_softc *, u_int);
static BS_INLINE u_int bshw_get_count(struct bs_softc *);
static BS_INLINE void bshw_set_dst_id(struct bs_softc *, u_int, u_int);
static BS_INLINE void bshw_set_lun(struct bs_softc *, u_int);
static BS_INLINE u_int bshw_get_src_id(struct bs_softc *);
static BS_INLINE void bshw_negate_ack(struct bs_softc *);
static BS_INLINE void bshw_assert_atn(struct bs_softc *);
static BS_INLINE void bshw_assert_select(struct bs_softc *);
static BS_INLINE void bshw_start_xfer(struct bs_softc *);
static BS_INLINE void bshw_start_sxfer(struct bs_softc *);
static BS_INLINE void bshw_cmd_pass(struct bs_softc *, u_int);
static BS_INLINE void bshw_start_sat(struct bs_softc *, u_int);
static BS_INLINE void bshw_abort_cmd(struct bs_softc *);
static BS_INLINE void bshw_set_sync_reg(struct bs_softc *, u_int);
static BS_INLINE void bshw_set_poll_trans(struct bs_softc *, u_int);
static BS_INLINE void bshw_set_dma_trans(struct bs_softc *, u_int);
/*********************************************************
* global declare
*********************************************************/
void bs_dma_xfer(struct targ_info *, u_int);
void bs_dma_xfer_end(struct targ_info *);
void bshw_dmaabort(struct bs_softc *, struct targ_info *);
void bshw_adj_syncdata(struct syncdata *);
void bshw_set_synchronous(struct bs_softc *, struct targ_info *);
void bs_smit_xfer_end(struct targ_info *);
void bshw_smitabort(struct bs_softc *);
void bshw_setup_ctrl_reg(struct bs_softc *, u_int);
int bshw_chip_reset(struct bs_softc *);
void bshw_bus_reset(struct bs_softc *);
int bshw_board_probe(struct bs_softc *, u_int *, u_int *);
void bshw_lock(struct bs_softc *);
void bshw_unlock(struct bs_softc *);
void bshw_get_syncreg(struct bs_softc *);
void bshw_issue_satcmd(struct bs_softc *, struct bsccb *, int);
void bshw_print_port(struct bs_softc *);
void bs_lc_smit_xfer(struct targ_info *, u_int);
extern struct dvcfg_hwsel bshw_hwsel;
extern u_int8_t bshw_cmd[];
/*********************************************************
* hw
*********************************************************/
struct bshw {
#define BSHW_SYNC_RELOAD 0x01
#define BSHW_SMFIFO 0x02
#define BSHW_DOUBLE_DMACHAN 0x04
u_int hw_flags;
u_int sregaddr;
int ((*dma_init)(struct bs_softc *));
void ((*dma_start)(struct bs_softc *));
void ((*dma_stop)(struct bs_softc *));
};
/*********************************************************
* inline funcs.
*********************************************************/
/*
* XXX: If your board does not work well, Please try BS_NEEDS_WEIGHT.
*/
static BS_INLINE void
write_wd33c93(bsc, addr, data)
struct bs_softc *bsc;
u_int addr;
u_int8_t data;
{
BUS_IOW(addr_port, addr);
BUS_IOW(ctrl_port, data);
}
static BS_INLINE u_int8_t
read_wd33c93(bsc, addr)
struct bs_softc *bsc;
u_int addr;
{
BUS_IOW(addr_port, addr);
return BUS_IOR(ctrl_port);
}
/* status */
static BS_INLINE u_int8_t
bshw_get_auxstat(bsc)
struct bs_softc *bsc;
{
return BUS_IOR(stat_port);
}
static BS_INLINE u_int8_t
bshw_get_busstat(bsc)
struct bs_softc *bsc;
{
return read_wd33c93(bsc, wd3s_stat);
}
static BS_INLINE u_int8_t
bshw_get_status_insat(bsc)
struct bs_softc *bsc;
{
return read_wd33c93(bsc, wd3s_lun);
}
/* data */
static BS_INLINE u_int8_t
bshw_read_data(bsc)
struct bs_softc *bsc;
{
return read_wd33c93(bsc, wd3s_data);
}
static BS_INLINE void
bshw_write_data(bsc, data)
struct bs_softc *bsc;
u_int8_t data;
{
write_wd33c93(bsc, wd3s_data, data);
}
/* counter */
static BS_INLINE void
bshw_set_count(bsc, count)
struct bs_softc *bsc;
u_int count;
{
BUS_IOW(addr_port, wd3s_cnt);
BUS_IOW(ctrl_port, count >> 16);
BUS_IOW(ctrl_port, count >> 8);
BUS_IOW(ctrl_port, count);
}
static BS_INLINE u_int
bshw_get_count(bsc)
struct bs_softc *bsc;
{
u_int count;
BUS_IOW(addr_port, wd3s_cnt);
count = (((u_int) BUS_IOR(ctrl_port)) << 16);
count += (((u_int) BUS_IOR(ctrl_port)) << 8);
count += ((u_int) BUS_IOR(ctrl_port));
return count;
}
/* ID */
static BS_INLINE void
bshw_set_lun(bsc, lun)
struct bs_softc *bsc;
u_int lun;
{
write_wd33c93(bsc, wd3s_lun, lun);
}
static BS_INLINE void
bshw_set_dst_id(bsc, target, lun)
struct bs_softc *bsc;
u_int target, lun;
{
write_wd33c93(bsc, wd3s_did, target);
write_wd33c93(bsc, wd3s_lun, lun);
}
static BS_INLINE u_int
bshw_get_src_id(bsc)
struct bs_softc *bsc;
{
return (read_wd33c93(bsc, wd3s_sid) & SIDR_IDM);
}
/* phase */
static BS_INLINE void
bshw_negate_ack(bsc)
struct bs_softc *bsc;
{
write_wd33c93(bsc, wd3s_cmd, WD3S_NEGATE_ACK);
}
static BS_INLINE void
bshw_assert_atn(bsc)
struct bs_softc *bsc;
{
write_wd33c93(bsc, wd3s_cmd, WD3S_ASSERT_ATN);
}
static BS_INLINE void
bshw_assert_select(bsc)
struct bs_softc *bsc;
{
write_wd33c93(bsc, wd3s_cmd, WD3S_SELECT_ATN);
}
static BS_INLINE void
bshw_start_xfer(bsc)
struct bs_softc *bsc;
{
write_wd33c93(bsc, wd3s_cmd, WD3S_TFR_INFO);
}
static BS_INLINE void
bshw_start_sxfer(bsc)
struct bs_softc *bsc;
{
write_wd33c93(bsc, wd3s_cmd, WD3S_SBT | WD3S_TFR_INFO);
}
static BS_INLINE void
bshw_cmd_pass(bsc, ph)
struct bs_softc *bsc;
u_int ph;
{
write_wd33c93(bsc, wd3s_cph, ph);
}
static BS_INLINE void
bshw_start_sat(bsc, flag)
struct bs_softc *bsc;
u_int flag;
{
write_wd33c93(bsc, wd3s_cmd,
(flag ? WD3S_SELECT_ATN_TFR : WD3S_SELECT_NO_ATN_TFR));
}
static BS_INLINE void
bshw_abort_cmd(bsc)
struct bs_softc *bsc;
{
write_wd33c93(bsc, wd3s_cmd, WD3S_ABORT);
}
/* transfer mode */
static BS_INLINE void
bshw_set_sync_reg(bsc, val)
struct bs_softc *bsc;
u_int val;
{
write_wd33c93(bsc, wd3s_synch, val);
}
static BS_INLINE void
bshw_set_poll_trans(bsc, flags)
struct bs_softc *bsc;
u_int flags;
{
if (bsc->sc_flags & BSDMATRANSFER)
{
bsc->sc_flags &= ~BSDMATRANSFER;
bshw_setup_ctrl_reg(bsc, flags);
}
}
static BS_INLINE void
bshw_set_dma_trans(bsc, flags)
struct bs_softc *bsc;
u_int flags;
{
if ((bsc->sc_flags & BSDMATRANSFER) == 0)
{
bsc->sc_flags |= BSDMATRANSFER;
bshw_setup_ctrl_reg(bsc, flags);
}
}