firewirereg.h revision 272214
1254721Semaste/*-
2254721Semaste * Copyright (c) 2003 Hidetoshi Shimokawa
3353358Sdim * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
4353358Sdim * All rights reserved.
5353358Sdim *
6254721Semaste * Redistribution and use in source and binary forms, with or without
7254721Semaste * modification, are permitted provided that the following conditions
8254721Semaste * are met:
9254721Semaste * 1. Redistributions of source code must retain the above copyright
10254721Semaste *    notice, this list of conditions and the following disclaimer.
11353358Sdim * 2. Redistributions in binary form must reproduce the above copyright
12288943Sdim *    notice, this list of conditions and the following disclaimer in the
13288943Sdim *    documentation and/or other materials provided with the distribution.
14254721Semaste * 3. All advertising materials mentioning features or use of this software
15254721Semaste *    must display the acknowledgement as bellow:
16309124Sdim *
17254721Semaste *    This product includes software developed by K. Kobayashi and H. Shimokawa
18309124Sdim *
19309124Sdim * 4. The name of the author may not be used to endorse or promote products
20254721Semaste *    derived from this software without specific prior written permission.
21276479Sdim *
22321369Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23321369Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24344779Sdim * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25254721Semaste * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26321369Sdim * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27321369Sdim * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28276479Sdim * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29314564Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30254721Semaste * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31327952Sdim * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32254721Semaste * POSSIBILITY OF SUCH DAMAGE.
33254721Semaste *
34254721Semaste * $FreeBSD: head/sys/dev/firewire/firewirereg.h 272214 2014-09-27 16:50:21Z kan $
35254721Semaste *
36360784Sdim */
37254721Semaste
38314564Sdimtypedef	struct thread fw_proc;
39314564Sdim#include <sys/selinfo.h>
40314564Sdim
41254721Semaste#include <sys/uio.h>
42254721Semaste#include <sys/mutex.h>
43314564Sdim#include <sys/taskqueue.h>
44314564Sdim
45254721Semaste#define	splfw splimp
46254721Semaste
47314564SdimSTAILQ_HEAD(fw_xferlist, fw_xfer);
48314564Sdim
49254721Semastestruct fw_device {
50254721Semaste	uint16_t dst;
51314564Sdim	struct fw_eui64 eui;
52314564Sdim	uint8_t speed;
53314564Sdim	uint8_t maxrec;
54314564Sdim	uint8_t nport;
55314564Sdim	uint8_t power;
56341825Sdim#define CSRROMOFF 0x400
57341825Sdim#define CSRROMSIZE 0x400
58341825Sdim	int rommax;	/* offset from 0xffff f000 0000 */
59314564Sdim	uint32_t csrrom[CSRROMSIZE / 4];
60254721Semaste	int rcnt;
61344779Sdim	struct firewire_comm *fc;
62344779Sdim	uint32_t status;
63314564Sdim#define FWDEVINIT	1
64314564Sdim#define FWDEVATTACHED	2
65314564Sdim#define FWDEVINVAL	3
66314564Sdim	STAILQ_ENTRY(fw_device) link;
67314564Sdim};
68314564Sdim
69314564Sdimstruct firewire_softc {
70353358Sdim	struct cdev *dev;
71353358Sdim	struct firewire_comm *fc;
72314564Sdim};
73276479Sdim
74314564Sdim#define FW_MAX_DMACH 0x20
75314564Sdim#define FW_MAX_DEVCH FW_MAX_DMACH
76254721Semaste#define FW_XFERTIMEOUT 1
77254721Semaste
78314564Sdimstruct firewire_dev_comm {
79314564Sdim	device_t dev;
80314564Sdim	struct firewire_comm *fc;
81344779Sdim	void (*post_busreset) (void *);
82314564Sdim	void (*post_explore) (void *);
83321369Sdim};
84353358Sdim
85314564Sdimstruct tcode_info {
86314564Sdim	u_char hdr_len;	/* IEEE1394 header length */
87314564Sdim	u_char flag;
88314564Sdim#define FWTI_REQ	(1 << 0)
89254721Semaste#define FWTI_RES	(1 << 1)
90314564Sdim#define FWTI_TLABEL	(1 << 2)
91314564Sdim#define FWTI_BLOCK_STR	(1 << 3)
92254721Semaste#define FWTI_BLOCK_ASY	(1 << 4)
93254721Semaste	u_char valid_res;
94254721Semaste};
95314564Sdim
96314564Sdimstruct firewire_comm {
97314564Sdim	device_t dev;
98327952Sdim	device_t bdev;
99254721Semaste	uint16_t busid:10,
100254721Semaste		 nodeid:6;
101314564Sdim	u_int mode;
102314564Sdim	u_int nport;
103341825Sdim	u_int speed;
104341825Sdim	u_int maxrec;
105341825Sdim	u_int irm;
106341825Sdim	u_int max_node;
107314564Sdim	u_int max_hop;
108254721Semaste#define FWPHYASYST (1 << 0)
109254721Semaste	uint32_t status;
110254721Semaste#define	FWBUSDETACH	(-2)
111314564Sdim#define	FWBUSNOTREADY	(-1)
112254721Semaste#define	FWBUSRESET	0
113314564Sdim#define	FWBUSINIT	1
114254721Semaste#define	FWBUSCYMELECT	2
115314564Sdim#define	FWBUSMGRELECT	3
116344779Sdim#define	FWBUSMGRDONE	4
117344779Sdim#define	FWBUSEXPLORE	5
118344779Sdim#define	FWBUSPHYCONF	6
119344779Sdim#define	FWBUSEXPDONE	7
120254721Semaste#define	FWBUSCOMPLETION	10
121360784Sdim	int nisodma;
122360784Sdim	struct fw_eui64 eui;
123360784Sdim	struct fw_xferq
124360784Sdim		*arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH];
125360784Sdim	struct fw_xferlist tlabels[0x40];
126360784Sdim	u_char last_tlabel[0x40];
127360784Sdim	struct mtx tlabel_lock;
128360784Sdim	STAILQ_HEAD(, fw_bind) binds;
129360784Sdim	STAILQ_HEAD(, fw_device) devices;
130360784Sdim	u_int  sid_cnt;
131360784Sdim#define CSRSIZE 0x4000
132360784Sdim	uint32_t csr_arc[CSRSIZE / 4];
133360784Sdim#define CROMSIZE 0x400
134314564Sdim	uint32_t *config_rom;
135314564Sdim	struct crom_src_buf *crom_src_buf;
136314564Sdim	struct crom_src *crom_src;
137314564Sdim	struct crom_chunk *crom_root;
138344779Sdim	struct fw_topology_map *topology_map;
139344779Sdim	struct fw_speed_map *speed_map;
140344779Sdim	struct callout busprobe_callout;
141309124Sdim	struct callout bmr_callout;
142314564Sdim	struct callout timeout_callout;
143344779Sdim	struct task task_timeout;
144309124Sdim	uint32_t (*cyctimer) (struct firewire_comm *);
145314564Sdim	void (*ibr) (struct firewire_comm *);
146254721Semaste	uint32_t (*set_bmr) (struct firewire_comm *, uint32_t);
147254721Semaste	int (*ioctl) (struct cdev *, u_long, caddr_t, int, fw_proc *);
148254721Semaste	int (*irx_enable) (struct firewire_comm *, int);
149321369Sdim	int (*irx_disable) (struct firewire_comm *, int);
150321369Sdim	int (*itx_enable) (struct firewire_comm *, int);
151314564Sdim	int (*itx_disable) (struct firewire_comm *, int);
152314564Sdim	void (*timeout) (void *);
153314564Sdim	void (*poll) (struct firewire_comm *, int, int);
154314564Sdim	void (*set_intr) (struct firewire_comm *, int);
155254721Semaste	void (*irx_post) (struct firewire_comm *, uint32_t *);
156314564Sdim	void (*itx_post) (struct firewire_comm *, uint32_t *);
157353358Sdim	struct tcode_info *tcode;
158314564Sdim	bus_dma_tag_t dmat;
159314564Sdim	struct mtx mtx;
160314564Sdim	struct mtx wait_lock;
161254721Semaste	struct taskqueue *taskqueue;
162344779Sdim	struct proc *probe_thread;
163344779Sdim};
164314564Sdim#define CSRARC(sc, offset) ((sc)->csr_arc[(offset) / 4])
165314564Sdim
166314564Sdim#define FW_GMTX(fc)		(&(fc)->mtx)
167254721Semaste#define FW_GLOCK(fc)		mtx_lock(FW_GMTX(fc))
168314564Sdim#define FW_GUNLOCK(fc)		mtx_unlock(FW_GMTX(fc))
169254721Semaste#define FW_GLOCK_ASSERT(fc)	mtx_assert(FW_GMTX(fc), MA_OWNED)
170314564Sdim
171254721Semastestruct fw_xferq {
172314564Sdim	int flag;
173314564Sdim#define FWXFERQ_CHTAGMASK 0xff
174314564Sdim#define FWXFERQ_RUNNING (1 << 8)
175314564Sdim#define FWXFERQ_STREAM (1 << 9)
176314564Sdim
177344779Sdim#define FWXFERQ_BULK (1 << 11)
178344779Sdim#define FWXFERQ_MODEMASK (7 << 10)
179254721Semaste
180314564Sdim#define FWXFERQ_EXTBUF (1 << 13)
181344779Sdim#define FWXFERQ_OPEN (1 << 14)
182344779Sdim
183327952Sdim#define FWXFERQ_HANDLER (1 << 16)
184254721Semaste#define FWXFERQ_WAKEUP (1 << 17)
185314564Sdim	void (*start) (struct firewire_comm *);
186344779Sdim	int dmach;
187344779Sdim	struct fw_xferlist q;
188314564Sdim	u_int queued;
189314564Sdim	u_int maxq;
190314564Sdim	u_int psize;
191309124Sdim	struct fwdma_alloc_multi *buf;
192314564Sdim	u_int bnchunk;
193254721Semaste	u_int bnpacket;
194314564Sdim	struct fw_bulkxfer *bulkxfer;
195314564Sdim	STAILQ_HEAD(, fw_bulkxfer) stvalid;
196314564Sdim	STAILQ_HEAD(, fw_bulkxfer) stfree;
197314564Sdim	STAILQ_HEAD(, fw_bulkxfer) stdma;
198254721Semaste	struct fw_bulkxfer *stproc;
199341825Sdim	struct selinfo rsel;
200341825Sdim	caddr_t sc;
201314564Sdim	void (*hand) (struct fw_xferq *);
202276479Sdim};
203321369Sdim
204321369Sdimstruct fw_bulkxfer {
205321369Sdim	int poffset;
206321369Sdim	struct mbuf *mbuf;
207321369Sdim	STAILQ_ENTRY(fw_bulkxfer) link;
208314564Sdim	caddr_t start;
209314564Sdim	caddr_t end;
210314564Sdim	int resp;
211314564Sdim};
212314564Sdim
213314564Sdimstruct fw_bind {
214321369Sdim	u_int64_t start;
215314564Sdim	u_int64_t end;
216314564Sdim	struct fw_xferlist xferlist;
217314564Sdim	STAILQ_ENTRY(fw_bind) fclist;
218314564Sdim	STAILQ_ENTRY(fw_bind) chlist;
219314564Sdim	void *sc;
220314564Sdim};
221314564Sdim
222314564Sdimstruct fw_xfer {
223314564Sdim	caddr_t sc;
224321369Sdim	struct firewire_comm *fc;
225314564Sdim	struct fw_xferq *q;
226314564Sdim	struct timeval tv;
227314564Sdim	int8_t resp;
228314564Sdim#define FWXF_INIT	0x00
229314564Sdim#define FWXF_INQ	0x01
230296417Sdim#define FWXF_START	0x02
231314564Sdim#define FWXF_SENT	0x04
232314564Sdim#define FWXF_SENTERR	0x08
233314564Sdim#define FWXF_BUSY	0x10
234341825Sdim#define FWXF_RCVD	0x20
235314564Sdim
236314564Sdim#define FWXF_WAKE	0x80
237314564Sdim	uint8_t flag;
238314564Sdim	int8_t tl;
239314564Sdim	void (*hand) (struct fw_xfer *);
240314564Sdim	struct {
241314564Sdim		struct fw_pkt hdr;
242344779Sdim		uint32_t *payload;
243314564Sdim		uint16_t pay_len;
244353358Sdim		uint8_t spd;
245353358Sdim	} send, recv;
246314564Sdim	struct mbuf *mbuf;
247344779Sdim	STAILQ_ENTRY(fw_xfer) link;
248314564Sdim	STAILQ_ENTRY(fw_xfer) tlabel;
249314564Sdim	struct malloc_type *malloc;
250314564Sdim};
251314564Sdim
252254721Semastestruct fw_rcv_buf {
253254721Semaste	struct firewire_comm *fc;
254314564Sdim	struct fw_xfer *xfer;
255353358Sdim	struct iovec *vec;
256353358Sdim	u_int nvec;
257314564Sdim	uint8_t spd;
258353358Sdim};
259254721Semaste
260254721Semastevoid fw_sidrcv (struct firewire_comm *, uint32_t *, u_int);
261314564Sdimvoid fw_rcv (struct fw_rcv_buf *);
262314564Sdimvoid fw_xfer_unload (struct fw_xfer *);
263314564Sdimvoid fw_xfer_free_buf (struct fw_xfer *);
264314564Sdimvoid fw_xfer_free (struct fw_xfer*);
265314564Sdimstruct fw_xfer *fw_xfer_alloc (struct malloc_type *);
266254721Semastestruct fw_xfer *fw_xfer_alloc_buf (struct malloc_type *, int, int);
267314564Sdimvoid fw_init (struct firewire_comm *);
268314564Sdimint fw_tbuf_update (struct firewire_comm *, int, int);
269314564Sdimint fw_rbuf_update (struct firewire_comm *, int, int);
270314564Sdimint fw_bindadd (struct firewire_comm *, struct fw_bind *);
271314564Sdimint fw_bindremove (struct firewire_comm *, struct fw_bind *);
272314564Sdimint fw_xferlist_add (struct fw_xferlist *, struct malloc_type *, int, int, int,
273254721Semaste    struct firewire_comm *, void *, void (*)(struct fw_xfer *));
274254721Semastevoid fw_xferlist_remove (struct fw_xferlist *);
275314564Sdimint fw_asyreq (struct firewire_comm *, int, struct fw_xfer *);
276254721Semastevoid fw_busreset (struct firewire_comm *, uint32_t);
277321369Sdimuint16_t fw_crc16 (uint32_t *, uint32_t);
278254721Semastevoid fw_xfer_timeout (void *);
279254721Semastevoid fw_xfer_done (struct fw_xfer *);
280254721Semastevoid fw_xferwake (struct fw_xfer *);
281314564Sdimint fw_xferwait (struct fw_xfer *);
282254721Semastevoid fw_asy_callback_free (struct fw_xfer *);
283254721Semastestruct fw_device *fw_noderesolve_nodeid (struct firewire_comm *, int);
284314564Sdimstruct fw_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *);
285321369Sdimstruct fw_bind *fw_bindlookup (struct firewire_comm *, uint16_t, uint32_t);
286341825Sdimvoid fw_drain_txq (struct firewire_comm *);
287341825Sdimint fwdev_makedev (struct firewire_softc *);
288314564Sdimint fwdev_destroydev (struct firewire_softc *);
289254721Semastevoid fwdev_clone (void *, struct ucred *, char *, int, struct cdev **);
290254721Semasteint fw_open_isodma(struct firewire_comm *, int);
291321369Sdim
292321369Sdimextern int firewire_debug;
293314564Sdimextern devclass_t firewire_devclass;
294314564Sdimextern int firewire_phydma_enable;
295314564Sdim
296314564Sdim#define	FWPRI		((PZERO + 8) | PCATCH)
297314564Sdim
298314564Sdim#define CALLOUT_INIT(x) callout_init(x, 1 /* mpsafe */)
299314564Sdim
300314564SdimMALLOC_DECLARE(M_FW);
301314564SdimMALLOC_DECLARE(M_FWXFER);
302314564Sdim