summaryrefslogtreecommitdiff
path: root/sys/dev/ic/oosiopvar.h
blob: 85837139e5b07ecef173c77bb6b3fe8e18411c50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* $OpenBSD: oosiopvar.h,v 1.4 2010/04/20 20:21:56 miod Exp $ */
/* $NetBSD: oosiopvar.h,v 1.2 2003/05/03 18:11:23 wiz Exp $ */

/*
 * Copyright (c) 2001 Shuichiro URATA.  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.
 */

#include <uvm/uvm_extern.h>

#define	OOSIOP_NTGT	8		/* Max targets */
#define	OOSIOP_NCB	32		/* Initial command buffers */
#define	OOSIOP_NSG	(MIN(atop(MAXPHYS) + 1, 32)) /* Max S/G operation */
#define	OOSIOP_MAX_XFER	ptoa(OOSIOP_NSG - 1)

struct oosiop_xfer {
	/* script for scatter/gather DMA (move*nsg+jump) */
	u_int32_t datain_scr[(OOSIOP_NSG + 1) * 2];
	u_int32_t dataout_scr[(OOSIOP_NSG + 1) * 2];

	u_int8_t msgin[8];
	u_int8_t msgout[8];
	u_int8_t status;
	u_int8_t pad[7];
} __packed;

#define	SCSI_OOSIOP_NOSTATUS	0xff	/* device didn't report status */

#define	OOSIOP_XFEROFF(x)	offsetof(struct oosiop_xfer, x)
#define	OOSIOP_DINSCROFF	OOSIOP_XFEROFF(datain_scr[0])
#define	OOSIOP_DOUTSCROFF	OOSIOP_XFEROFF(dataout_scr[0])
#define	OOSIOP_MSGINOFF		OOSIOP_XFEROFF(msgin[0])
#define	OOSIOP_MSGOUTOFF	OOSIOP_XFEROFF(msgout[0])

#define	OOSIOP_XFERSCR_SYNC(sc, cb, ops)				\
	bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DINSCROFF,	\
	    OOSIOP_MSGINOFF - OOSIOP_DINSCROFF, (ops))
#define	OOSIOP_DINSCR_SYNC(sc, cb, ops)					\
	bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DINSCROFF,	\
	    OOSIOP_DOUTSCROFF - OOSIOP_DINSCROFF, (ops))
#define	OOSIOP_DOUTSCR_SYNC(sc, cb, ops)				\
	bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_DOUTSCROFF,\
	    OOSIOP_MSGINOFF - OOSIOP_DOUTSCROFF, (ops))
#define	OOSIOP_XFERMSG_SYNC(sc, cb, ops)				\
	bus_dmamap_sync((sc)->sc_dmat, (cb)->xferdma, OOSIOP_MSGINOFF,	\
	    sizeof(struct oosiop_xfer) - OOSIOP_MSGINOFF, (ops))

#define	OOSIOP_SCRIPT_SYNC(sc, ops)					\
	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_scrdma,			\
	    0, sizeof(oosiop_script), (ops))

struct oosiop_cb {
	TAILQ_ENTRY(oosiop_cb) chain;

	struct scsi_xfer *xs;		/* SCSI xfer ctrl block from above */
	int flags;
	int id;				/* target scsi id */
	int lun;			/* target lun */

	bus_dmamap_t cmddma;		/* DMA map for command out */
	bus_dmamap_t datadma;		/* DMA map for data I/O */
	bus_dmamap_t xferdma;		/* DMA map for xfer block */

	int curdp;			/* current data pointer */
	int savedp;			/* saved data pointer */
	int msgoutlen;

	int xsflags;			/* copy of xs->flags */
	int datalen;			/* copy of xs->datalen */
	int cmdlen;			/* copy of xs->cmdlen */

	struct oosiop_xfer *xfer;	/* DMA xfer block */
};

/* oosiop_cb flags */
#define	CBF_SELTOUT	0x01	/* Selection timeout */
#define	CBF_TIMEOUT	0x02	/* Command timeout */
#define	CBF_AUTOSENSE	0x04	/* Request sense due to SCSI_CHECK */

struct oosiop_target {
	struct oosiop_cb *nexus;
	int flags;
	u_int8_t scf;		/* synchronous clock divisor */
	u_int8_t sxfer;		/* synchronous period and offset */
};

/* target flags */
#define	TGTF_SYNCNEG	0x01	/* Trigger synchronous negotiation */
#define	TGTF_WAITSDTR	0x02	/* Waiting SDTR from target */

struct oosiop_softc {
	struct device sc_dev;

	bus_space_tag_t	sc_bst;		/* bus space tag */
	bus_space_handle_t sc_bsh;	/* bus space handle */

	bus_dma_tag_t sc_dmat;		/* bus DMA tag */
	bus_dmamap_t sc_scrdma;		/* script DMA map */

	bus_addr_t sc_scrbase;		/* script DMA base address */
	u_int32_t *sc_scr;		/* ptr to script memory */

	int sc_chip;			/* 700 or 700-66 */
#define	OOSIOP_700	0
#define	OOSIOP_700_66	1

	int		sc_id;		/* SCSI ID of this interface */
	int		sc_freq;	/* SCLK frequency */
	int		sc_ccf;		/* asynchronous divisor (*10) */
	u_int8_t	sc_dcntl;
	u_int8_t	sc_minperiod;

	struct oosiop_target sc_tgt[OOSIOP_NTGT];

	struct scsi_link sc_link;

	/* Lists of command blocks */
	TAILQ_HEAD(oosiop_cb_queue, oosiop_cb) sc_free_cb,
					       sc_cbq;

	struct oosiop_cb *sc_curcb;	/* current command */
	struct oosiop_cb *sc_lastcb;	/* last activated command */

	bus_addr_t sc_reselbuf;		/* msgin buffer for reselection */
	int sc_resid;			/* reselected target id */

	int sc_active;
	int sc_nextdsp;

	uint8_t	sc_scntl0;
	uint8_t sc_dmode;
	uint8_t sc_dwt;
	uint8_t sc_ctest7;
};

#define	oosiop_read_1(sc, addr)						\
    bus_space_read_1((sc)->sc_bst, (sc)->sc_bsh, (addr))
#define	oosiop_write_1(sc, addr, data)					\
    bus_space_write_1((sc)->sc_bst, (sc)->sc_bsh, (addr), (data))
/* XXX byte swapping should be handled by MD bus_space(9)? */
#define	oosiop_read_4(sc, addr)						\
    letoh32(bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (addr)))
#define	oosiop_write_4(sc, addr, data)					\
    bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (addr), htole32(data))

void oosiop_attach(struct oosiop_softc *);
int oosiop_intr(struct oosiop_softc *);