firewirereg.h revision 171513
1139749Simp/*-
2113584Ssimokawa * Copyright (c) 2003 Hidetoshi Shimokawa
3103285Sikob * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
4103285Sikob * All rights reserved.
5103285Sikob *
6103285Sikob * Redistribution and use in source and binary forms, with or without
7103285Sikob * modification, are permitted provided that the following conditions
8103285Sikob * are met:
9103285Sikob * 1. Redistributions of source code must retain the above copyright
10103285Sikob *    notice, this list of conditions and the following disclaimer.
11103285Sikob * 2. Redistributions in binary form must reproduce the above copyright
12103285Sikob *    notice, this list of conditions and the following disclaimer in the
13103285Sikob *    documentation and/or other materials provided with the distribution.
14103285Sikob * 3. All advertising materials mentioning features or use of this software
15103285Sikob *    must display the acknowledgement as bellow:
16103285Sikob *
17103285Sikob *    This product includes software developed by K. Kobayashi and H. Shimokawa
18103285Sikob *
19103285Sikob * 4. The name of the author may not be used to endorse or promote products
20103285Sikob *    derived from this software without specific prior written permission.
21103285Sikob *
22103285Sikob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23103285Sikob * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24103285Sikob * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25103285Sikob * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26103285Sikob * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27103285Sikob * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28103285Sikob * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29103285Sikob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30103285Sikob * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31103285Sikob * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32103285Sikob * POSSIBILITY OF SUCH DAMAGE.
33103285Sikob *
34103285Sikob * $FreeBSD: head/sys/dev/firewire/firewirereg.h 171513 2007-07-20 03:42:57Z simokawa $
35103285Sikob *
36103285Sikob */
37103285Sikob
38127468Ssimokawa#ifdef __DragonFly__
39127468Ssimokawatypedef	d_thread_t fw_proc;
40127468Ssimokawa#include <sys/select.h>
41127468Ssimokawa#elif __FreeBSD_version >= 500000
42103285Sikobtypedef	struct thread fw_proc;
43103285Sikob#include <sys/selinfo.h>
44103285Sikob#else
45103285Sikobtypedef	struct proc fw_proc;
46103285Sikob#include <sys/select.h>
47103285Sikob#endif
48103285Sikob
49113584Ssimokawa#include <sys/uio.h>
50170374Ssimokawa#include <sys/mutex.h>
51170374Ssimokawa#include <sys/taskqueue.h>
52113584Ssimokawa
53103285Sikob#define	splfw splimp
54103285Sikob
55169130SsimokawaSTAILQ_HEAD(fw_xferlist, fw_xfer);
56169130Ssimokawa
57103285Sikobstruct fw_device{
58129585Sdfr	uint16_t dst;
59103285Sikob	struct fw_eui64 eui;
60129585Sdfr	uint8_t speed;
61129585Sdfr	uint8_t maxrec;
62129585Sdfr	uint8_t nport;
63129585Sdfr	uint8_t power;
64103285Sikob#define CSRROMOFF 0x400
65103285Sikob#define CSRROMSIZE 0x400
66103285Sikob	int rommax;	/* offset from 0xffff f000 0000 */
67129585Sdfr	uint32_t csrrom[CSRROMSIZE/4];
68103285Sikob	int rcnt;
69106810Ssimokawa	struct firewire_comm *fc;
70129585Sdfr	uint32_t status;
71103285Sikob#define FWDEVINIT	1
72103285Sikob#define FWDEVATTACHED	2
73103285Sikob#define FWDEVINVAL	3
74110193Ssimokawa	STAILQ_ENTRY(fw_device) link;
75103285Sikob};
76109645Ssimokawa
77103285Sikobstruct firewire_softc {
78127468Ssimokawa#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
79130585Sphk	struct cdev *dev;
80103285Sikob#endif
81103285Sikob	struct firewire_comm *fc;
82103285Sikob};
83109645Ssimokawa
84103285Sikob#define FW_MAX_DMACH 0x20
85103285Sikob#define FW_MAX_DEVCH FW_MAX_DMACH
86103285Sikob#define FW_XFERTIMEOUT 1
87109645Ssimokawa
88103285Sikobstruct firewire_dev_comm {
89103285Sikob	device_t dev;
90103285Sikob	struct firewire_comm *fc;
91124169Ssimokawa	void (*post_busreset) (void *);
92124169Ssimokawa	void (*post_explore) (void *);
93103285Sikob};
94103285Sikob
95103285Sikobstruct tcode_info {
96103285Sikob	u_char hdr_len;	/* IEEE1394 header length */
97103285Sikob	u_char flag;
98103285Sikob#define FWTI_REQ	(1 << 0)
99103285Sikob#define FWTI_RES	(1 << 1)
100103285Sikob#define FWTI_TLABEL	(1 << 2)
101103285Sikob#define FWTI_BLOCK_STR	(1 << 3)
102103285Sikob#define FWTI_BLOCK_ASY	(1 << 4)
103170374Ssimokawa	u_char valid_res;
104103285Sikob};
105103285Sikob
106103285Sikobstruct firewire_comm{
107103285Sikob	device_t dev;
108103285Sikob	device_t bdev;
109129585Sdfr	uint16_t busid:10,
110103285Sikob		  nodeid:6;
111103285Sikob	u_int mode;
112103285Sikob	u_int nport;
113103285Sikob	u_int speed;
114103285Sikob	u_int maxrec;
115103285Sikob	u_int irm;
116103285Sikob	u_int max_node;
117103285Sikob	u_int max_hop;
118103285Sikob#define FWPHYASYST (1 << 0)
119129585Sdfr	uint32_t status;
120169806Ssimokawa#define	FWBUSDETACH	(-2)
121116978Ssimokawa#define	FWBUSNOTREADY	(-1)
122103285Sikob#define	FWBUSRESET	0
123103285Sikob#define	FWBUSINIT	1
124103285Sikob#define	FWBUSCYMELECT	2
125103285Sikob#define	FWBUSMGRELECT	3
126103285Sikob#define	FWBUSMGRDONE	4
127103285Sikob#define	FWBUSEXPLORE	5
128103285Sikob#define	FWBUSPHYCONF	6
129103285Sikob#define	FWBUSEXPDONE	7
130103285Sikob#define	FWBUSCOMPLETION	10
131103285Sikob	int nisodma;
132109814Ssimokawa	struct fw_eui64 eui;
133103285Sikob	struct fw_xferq
134103285Sikob		*arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH];
135169130Ssimokawa	struct fw_xferlist tlabels[0x40];
136171457Ssimokawa	u_char last_tlabel[0x40];
137171513Ssimokawa	struct mtx tlabel_lock;
138103285Sikob	STAILQ_HEAD(, fw_bind) binds;
139110193Ssimokawa	STAILQ_HEAD(, fw_device) devices;
140103285Sikob	u_int  sid_cnt;
141103285Sikob#define CSRSIZE 0x4000
142129585Sdfr	uint32_t csr_arc[CSRSIZE/4];
143103285Sikob#define CROMSIZE 0x400
144129585Sdfr	uint32_t *config_rom;
145116376Ssimokawa	struct crom_src_buf *crom_src_buf;
146116376Ssimokawa	struct crom_src *crom_src;
147116376Ssimokawa	struct crom_chunk *crom_root;
148103285Sikob	struct fw_topology_map *topology_map;
149103285Sikob	struct fw_speed_map *speed_map;
150108853Ssimokawa	struct callout busprobe_callout;
151110193Ssimokawa	struct callout bmr_callout;
152110193Ssimokawa	struct callout timeout_callout;
153170374Ssimokawa	struct task task_timeout;
154129585Sdfr	uint32_t (*cyctimer) (struct  firewire_comm *);
155124169Ssimokawa	void (*ibr) (struct firewire_comm *);
156129585Sdfr	uint32_t (*set_bmr) (struct firewire_comm *, uint32_t);
157130585Sphk	int (*ioctl) (struct cdev *, u_long, caddr_t, int, fw_proc *);
158124169Ssimokawa	int (*irx_enable) (struct firewire_comm *, int);
159124169Ssimokawa	int (*irx_disable) (struct firewire_comm *, int);
160124169Ssimokawa	int (*itx_enable) (struct firewire_comm *, int);
161124169Ssimokawa	int (*itx_disable) (struct firewire_comm *, int);
162124169Ssimokawa	void (*timeout) (void *);
163124169Ssimokawa	void (*poll) (struct firewire_comm *, int, int);
164124169Ssimokawa	void (*set_intr) (struct firewire_comm *, int);
165129585Sdfr	void (*irx_post) (struct firewire_comm *, uint32_t *);
166129585Sdfr	void (*itx_post) (struct firewire_comm *, uint32_t *);
167103285Sikob	struct tcode_info *tcode;
168113584Ssimokawa	bus_dma_tag_t dmat;
169170374Ssimokawa	struct mtx mtx;
170170374Ssimokawa	struct mtx wait_lock;
171170374Ssimokawa	struct taskqueue *taskqueue;
172170374Ssimokawa	struct proc *probe_thread;
173103285Sikob};
174103285Sikob#define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4])
175103285Sikob
176170374Ssimokawa#define FW_GMTX(fc)		(&(fc)->mtx)
177170374Ssimokawa#define FW_GLOCK(fc)		mtx_lock(FW_GMTX(fc))
178170374Ssimokawa#define FW_GUNLOCK(fc)		mtx_unlock(FW_GMTX(fc))
179170374Ssimokawa#define FW_GLOCK_ASSERT(fc)	mtx_assert(FW_GMTX(fc), MA_OWNED)
180170374Ssimokawa
181109645Ssimokawastruct fw_xferq {
182109645Ssimokawa	int flag;
183109645Ssimokawa#define FWXFERQ_CHTAGMASK 0xff
184109645Ssimokawa#define FWXFERQ_RUNNING (1 << 8)
185109645Ssimokawa#define FWXFERQ_STREAM (1 << 9)
186109645Ssimokawa
187109645Ssimokawa#define FWXFERQ_BULK (1 << 11)
188109645Ssimokawa#define FWXFERQ_MODEMASK (7 << 10)
189109645Ssimokawa
190109645Ssimokawa#define FWXFERQ_EXTBUF (1 << 13)
191109645Ssimokawa#define FWXFERQ_OPEN (1 << 14)
192109645Ssimokawa
193109645Ssimokawa#define FWXFERQ_HANDLER (1 << 16)
194109645Ssimokawa#define FWXFERQ_WAKEUP (1 << 17)
195124169Ssimokawa	void (*start) (struct firewire_comm*);
196118293Ssimokawa	int dmach;
197169130Ssimokawa	struct fw_xferlist q;
198109645Ssimokawa	u_int queued;
199109645Ssimokawa	u_int maxq;
200109645Ssimokawa	u_int psize;
201113584Ssimokawa	struct fwdma_alloc_multi *buf;
202109645Ssimokawa	u_int bnchunk;
203109645Ssimokawa	u_int bnpacket;
204109645Ssimokawa	struct fw_bulkxfer *bulkxfer;
205109645Ssimokawa	STAILQ_HEAD(, fw_bulkxfer) stvalid;
206109645Ssimokawa	STAILQ_HEAD(, fw_bulkxfer) stfree;
207109890Ssimokawa	STAILQ_HEAD(, fw_bulkxfer) stdma;
208109645Ssimokawa	struct fw_bulkxfer *stproc;
209109645Ssimokawa	struct selinfo rsel;
210109645Ssimokawa	caddr_t sc;
211124169Ssimokawa	void (*hand) (struct fw_xferq *);
212109645Ssimokawa};
213109645Ssimokawa
214109645Ssimokawastruct fw_bulkxfer{
215113584Ssimokawa	int poffset;
216111942Ssimokawa	struct mbuf *mbuf;
217109645Ssimokawa	STAILQ_ENTRY(fw_bulkxfer) link;
218109645Ssimokawa	caddr_t start;
219109645Ssimokawa	caddr_t end;
220111942Ssimokawa	int resp;
221109645Ssimokawa};
222109645Ssimokawa
223109645Ssimokawastruct fw_bind{
224120660Ssimokawa	u_int64_t start;
225120660Ssimokawa	u_int64_t end;
226169130Ssimokawa	struct fw_xferlist xferlist;
227109645Ssimokawa	STAILQ_ENTRY(fw_bind) fclist;
228109645Ssimokawa	STAILQ_ENTRY(fw_bind) chlist;
229169130Ssimokawa	void *sc;
230109645Ssimokawa};
231109645Ssimokawa
232103285Sikobstruct fw_xfer{
233103285Sikob	caddr_t sc;
234103285Sikob	struct firewire_comm *fc;
235103285Sikob	struct fw_xferq *q;
236110577Ssimokawa	struct timeval tv;
237113584Ssimokawa	int8_t resp;
238170374Ssimokawa#define FWXF_INIT	0x00
239170374Ssimokawa#define FWXF_INQ	0x01
240170374Ssimokawa#define FWXF_START	0x02
241170374Ssimokawa#define FWXF_SENT	0x04
242170374Ssimokawa#define FWXF_SENTERR	0x08
243170374Ssimokawa#define FWXF_BUSY	0x10
244170374Ssimokawa#define FWXF_RCVD	0x20
245170374Ssimokawa
246170374Ssimokawa#define FWXF_WAKE	0x80
247170374Ssimokawa	uint8_t flag;
248169119Ssimokawa	int8_t tl;
249167632Ssimokawa	void (*hand) (struct fw_xfer *);
250103285Sikob	struct {
251120660Ssimokawa		struct fw_pkt hdr;
252129585Sdfr		uint32_t *payload;
253129585Sdfr		uint16_t pay_len;
254129585Sdfr		uint8_t spd;
255103285Sikob	} send, recv;
256103285Sikob	struct mbuf *mbuf;
257103285Sikob	STAILQ_ENTRY(fw_xfer) link;
258169119Ssimokawa	STAILQ_ENTRY(fw_xfer) tlabel;
259110269Ssimokawa	struct malloc_type *malloc;
260103285Sikob};
261120660Ssimokawa
262120660Ssimokawastruct fw_rcv_buf {
263120660Ssimokawa	struct firewire_comm *fc;
264120660Ssimokawa	struct fw_xfer *xfer;
265120660Ssimokawa	struct iovec *vec;
266120660Ssimokawa	u_int nvec;
267129585Sdfr	uint8_t spd;
268120660Ssimokawa};
269120660Ssimokawa
270129585Sdfrvoid fw_sidrcv (struct firewire_comm *, uint32_t *, u_int);
271124169Ssimokawavoid fw_rcv (struct fw_rcv_buf *);
272124169Ssimokawavoid fw_xfer_unload ( struct fw_xfer*);
273124169Ssimokawavoid fw_xfer_free_buf ( struct fw_xfer*);
274124169Ssimokawavoid fw_xfer_free ( struct fw_xfer*);
275124169Ssimokawastruct fw_xfer *fw_xfer_alloc (struct malloc_type *);
276124169Ssimokawastruct fw_xfer *fw_xfer_alloc_buf (struct malloc_type *, int, int);
277124169Ssimokawavoid fw_init (struct firewire_comm *);
278124169Ssimokawaint fw_tbuf_update (struct firewire_comm *, int, int);
279124169Ssimokawaint fw_rbuf_update (struct firewire_comm *, int, int);
280124169Ssimokawaint fw_bindadd (struct firewire_comm *, struct fw_bind *);
281124169Ssimokawaint fw_bindremove (struct firewire_comm *, struct fw_bind *);
282169130Ssimokawaint fw_xferlist_add (struct fw_xferlist *, struct malloc_type *, int, int, int,
283169130Ssimokawa    struct firewire_comm *, void *, void (*)(struct fw_xfer *));
284169130Ssimokawavoid fw_xferlist_remove (struct fw_xferlist *);
285124169Ssimokawaint fw_asyreq (struct firewire_comm *, int, struct fw_xfer*);
286169117Ssimokawavoid fw_busreset (struct firewire_comm *, uint32_t);
287129585Sdfruint16_t fw_crc16 (uint32_t *, uint32_t);
288124169Ssimokawavoid fw_xfer_timeout (void *);
289124169Ssimokawavoid fw_xfer_done (struct fw_xfer *);
290170374Ssimokawavoid fw_xferwake (struct fw_xfer *);
291170374Ssimokawaint fw_xferwait (struct fw_xfer *);
292124169Ssimokawavoid fw_asy_callback_free (struct fw_xfer *);
293124169Ssimokawastruct fw_device *fw_noderesolve_nodeid (struct firewire_comm *, int);
294124169Ssimokawastruct fw_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *);
295129585Sdfrstruct fw_bind *fw_bindlookup (struct firewire_comm *, uint16_t, uint32_t);
296124169Ssimokawavoid fw_drain_txq (struct firewire_comm *);
297124169Ssimokawaint fwdev_makedev (struct firewire_softc *);
298124169Ssimokawaint fwdev_destroydev (struct firewire_softc *);
299148868Srwatsonvoid fwdev_clone (void *, struct ucred *, char *, int, struct cdev **);
300170374Ssimokawaint fw_open_isodma(struct firewire_comm *, int);
301103285Sikob
302103285Sikobextern int firewire_debug;
303103285Sikobextern devclass_t firewire_devclass;
304170400Ssimokawaextern int firewire_phydma_enable;
305103285Sikob
306127468Ssimokawa#ifdef __DragonFly__
307127468Ssimokawa#define		FWPRI		PCATCH
308127468Ssimokawa#else
309103285Sikob#define		FWPRI		((PZERO+8)|PCATCH)
310127468Ssimokawa#endif
311103285Sikob
312127468Ssimokawa#if defined(__DragonFly__) || __FreeBSD_version < 500000
313127468Ssimokawa#define CALLOUT_INIT(x) callout_init(x)
314127468Ssimokawa#else
315170374Ssimokawa#define CALLOUT_INIT(x) callout_init(x, 1 /* mpsafe */)
316111615Ssimokawa#endif
317111615Ssimokawa
318127468Ssimokawa#if defined(__DragonFly__) || __FreeBSD_version < 500000
319120660Ssimokawa/* compatibility shim for 4.X */
320120660Ssimokawa#define bio buf
321120660Ssimokawa#define bio_bcount b_bcount
322120660Ssimokawa#define bio_cmd b_flags
323120660Ssimokawa#define bio_count b_count
324120660Ssimokawa#define bio_data b_data
325120660Ssimokawa#define bio_dev b_dev
326120660Ssimokawa#define bio_error b_error
327120660Ssimokawa#define bio_flags b_flags
328120660Ssimokawa#define bio_offset b_offset
329120660Ssimokawa#define bio_resid b_resid
330120660Ssimokawa#define BIO_ERROR B_ERROR
331120660Ssimokawa#define BIO_READ B_READ
332120660Ssimokawa#define BIO_WRITE B_WRITE
333120660Ssimokawa#define MIN(a,b) (((a)<(b))?(a):(b))
334121780Ssimokawa#define MAX(a,b) (((a)>(b))?(a):(b))
335120660Ssimokawa#endif
336120660Ssimokawa
337110195SsimokawaMALLOC_DECLARE(M_FW);
338110269SsimokawaMALLOC_DECLARE(M_FWXFER);
339