1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef _SYS_1394_ADAPTERS_HCI1394_ASYNC_H
28*7c478bd9Sstevel@tonic-gate #define	_SYS_1394_ADAPTERS_HCI1394_ASYNC_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * hci1394_async.h
32*7c478bd9Sstevel@tonic-gate  *   These routines the 1394 asynchronous dma engines.  These include incoming
33*7c478bd9Sstevel@tonic-gate  *   and outgoing reads, writes, and lock and their associated responses.
34*7c478bd9Sstevel@tonic-gate  */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
37*7c478bd9Sstevel@tonic-gate extern "C" {
38*7c478bd9Sstevel@tonic-gate #endif
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #include <sys/1394/h1394.h>
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_def.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_tlist.h>
49*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_q.h>
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate /*
53*7c478bd9Sstevel@tonic-gate  * Async descriptor and data buffer sizes. The AR descriptor buffers do not need
54*7c478bd9Sstevel@tonic-gate  * to be very big.  There will be 1 16 byte IM for every AR data buffer.  If we
55*7c478bd9Sstevel@tonic-gate  * alloc a 16KByte ARRESP data buffer on X86, we could get 4 4KByte cookies.
56*7c478bd9Sstevel@tonic-gate  * This would use up 64 bytes in the descriptor buffer. We will never need more
57*7c478bd9Sstevel@tonic-gate  * space than that.  A 256 byte descriptor should handle a 64K buffer on x86
58*7c478bd9Sstevel@tonic-gate  * if it is broken into 16 cookies.
59*7c478bd9Sstevel@tonic-gate  */
60*7c478bd9Sstevel@tonic-gate #define	ASYNC_ATREQ_DESC_SIZE		16384
61*7c478bd9Sstevel@tonic-gate #define	ASYNC_ATREQ_DATA_SIZE		16384
62*7c478bd9Sstevel@tonic-gate #define	ASYNC_ARRESP_DESC_SIZE		256
63*7c478bd9Sstevel@tonic-gate #define	ASYNC_ARRESP_DATA_SIZE		16384
64*7c478bd9Sstevel@tonic-gate #define	ASYNC_ARREQ_DESC_SIZE		256
65*7c478bd9Sstevel@tonic-gate #define	ASYNC_ARREQ_DATA_SIZE		16384
66*7c478bd9Sstevel@tonic-gate #define	ASYNC_ATRESP_DESC_SIZE		16384
67*7c478bd9Sstevel@tonic-gate #define	ASYNC_ATRESP_DATA_SIZE		16384
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /* handle passed back from init() and used for rest of functions */
71*7c478bd9Sstevel@tonic-gate typedef struct hci1394_async_s	*hci1394_async_handle_t;
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate /*
74*7c478bd9Sstevel@tonic-gate  * Async Command State. This state is used to catch a race condition between
75*7c478bd9Sstevel@tonic-gate  * the ATREQ complete interrupt handler and the ARRESP interrupt handler. The
76*7c478bd9Sstevel@tonic-gate  * ATREQ will always complete before the ARRESP arrives, but SW may not see it
77*7c478bd9Sstevel@tonic-gate  * that way. See hci1394_async_atreq_process() for more information on this.
78*7c478bd9Sstevel@tonic-gate  */
79*7c478bd9Sstevel@tonic-gate typedef enum {
80*7c478bd9Sstevel@tonic-gate 	HCI1394_CMD_STATE_IN_PROGRESS,
81*7c478bd9Sstevel@tonic-gate 	HCI1394_CMD_STATE_PENDING,
82*7c478bd9Sstevel@tonic-gate 	HCI1394_CMD_STATE_COMPLETED
83*7c478bd9Sstevel@tonic-gate } hci1394_async_cstate_t;
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate typedef struct hci1394_async_cmd_s {
87*7c478bd9Sstevel@tonic-gate 	/* Pointer to framework command allocted by services layer */
88*7c478bd9Sstevel@tonic-gate 	cmd1394_cmd_t 		*ac_cmd;
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate 	/*
91*7c478bd9Sstevel@tonic-gate 	 * Pointer to HAL/SL private area in the command. This is private info
92*7c478bd9Sstevel@tonic-gate 	 * shared between the HAL and Services Layer on a per command basis.
93*7c478bd9Sstevel@tonic-gate 	 */
94*7c478bd9Sstevel@tonic-gate 	h1394_cmd_priv_t	*ac_priv;
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	/*
97*7c478bd9Sstevel@tonic-gate 	 * Status on if we allocated a tlabel for an ATREQ. Normally we will
98*7c478bd9Sstevel@tonic-gate 	 * allocate a tlabel with every ATREQ. But, we will not allocate a
99*7c478bd9Sstevel@tonic-gate 	 * tlabel for a PHY packet. When we initialize the command, we will
100*7c478bd9Sstevel@tonic-gate 	 * assume that we are going to allocate a tlabel.  The async phy command
101*7c478bd9Sstevel@tonic-gate 	 * will "override" this setting and set ac_tlabel_alloc to b_false.
102*7c478bd9Sstevel@tonic-gate 	 */
103*7c478bd9Sstevel@tonic-gate 	boolean_t		ac_tlabel_alloc;
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate 	/* handle for tlabel logic */
106*7c478bd9Sstevel@tonic-gate 	hci1394_tlabel_info_t	ac_tlabel;
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate 	/*
109*7c478bd9Sstevel@tonic-gate 	 * This is used for ARREQs. When we get a block read or write request,
110*7c478bd9Sstevel@tonic-gate 	 * we allocate a mblk to put the data into. After the ATRESP has been
111*7c478bd9Sstevel@tonic-gate 	 * sent out and has completed, hci1394_async_response_complete() is
112*7c478bd9Sstevel@tonic-gate 	 * called to free up the ARREQ resources which were allocated. This
113*7c478bd9Sstevel@tonic-gate 	 * routine will free the mblk if we allocated it in ARREQ. If an ARREQ
114*7c478bd9Sstevel@tonic-gate 	 * block write is received and the target driver wishes to keep the
115*7c478bd9Sstevel@tonic-gate 	 * mblk w/ the data (to pass it up a stream), but releases the command,
116*7c478bd9Sstevel@tonic-gate 	 * it can set the mblk pointer in the command to null.  We will check
117*7c478bd9Sstevel@tonic-gate 	 * for mblk being == to NULL even if ac_mblk_alloc is set to true.
118*7c478bd9Sstevel@tonic-gate 	 */
119*7c478bd9Sstevel@tonic-gate 	boolean_t		ac_mblk_alloc;
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	/*
122*7c478bd9Sstevel@tonic-gate 	 * ac_status contains the 1394 RESP for an ARRESP or the ACK for ARREQ.
123*7c478bd9Sstevel@tonic-gate 	 * This status is set in either hci1394_async_arresp_read() or
124*7c478bd9Sstevel@tonic-gate 	 * hci1394_arreq_read()
125*7c478bd9Sstevel@tonic-gate 	 */
126*7c478bd9Sstevel@tonic-gate 	int			ac_status;
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	/*
129*7c478bd9Sstevel@tonic-gate 	 * Destination packet was sent to. This is used to determine if the
130*7c478bd9Sstevel@tonic-gate 	 * packet was broadcast or not in hci1394_async_arreq_read().
131*7c478bd9Sstevel@tonic-gate 	 */
132*7c478bd9Sstevel@tonic-gate 	uint_t			ac_dest;
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 	/*
135*7c478bd9Sstevel@tonic-gate 	 * Async command state. See comments above for more information. Other
136*7c478bd9Sstevel@tonic-gate 	 * than initialization, this field is only accessed in the ISR. State
137*7c478bd9Sstevel@tonic-gate 	 * is only used in ATREQ/ARRESP processing.
138*7c478bd9Sstevel@tonic-gate 	 */
139*7c478bd9Sstevel@tonic-gate 	hci1394_async_cstate_t	ac_state;
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	/*
142*7c478bd9Sstevel@tonic-gate 	 * Pointer back to the Async private state. This allows us to access
143*7c478bd9Sstevel@tonic-gate 	 * the async state structures if all we have is a pointer to the async
144*7c478bd9Sstevel@tonic-gate 	 * command.
145*7c478bd9Sstevel@tonic-gate 	 */
146*7c478bd9Sstevel@tonic-gate 	struct hci1394_async_s	*ac_async;
147*7c478bd9Sstevel@tonic-gate 
148*7c478bd9Sstevel@tonic-gate 	/*
149*7c478bd9Sstevel@tonic-gate 	 * pending list node structure.  If a command is pended, this node is
150*7c478bd9Sstevel@tonic-gate 	 * what's passed to the tlist code to add the node to the pending list.
151*7c478bd9Sstevel@tonic-gate 	 * It contains all the pointers the linked list needs so that we do not
152*7c478bd9Sstevel@tonic-gate 	 * need to allocate any space every time we add something to the list.
153*7c478bd9Sstevel@tonic-gate 	 */
154*7c478bd9Sstevel@tonic-gate 	hci1394_tlist_node_t	ac_plist_node;
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	/*
157*7c478bd9Sstevel@tonic-gate 	 * hci1394_q information about this command.  This is used for AT
158*7c478bd9Sstevel@tonic-gate 	 * commands.  It contains information passed down to the hci1394_q_at*()
159*7c478bd9Sstevel@tonic-gate 	 * routines like qc_timestamp which is used to tell the HW when an
160*7c478bd9Sstevel@tonic-gate 	 * ATRESP has timed out out.  The status of the AT command is returned
161*7c478bd9Sstevel@tonic-gate 	 * in qc_status after calling hci1394_q_at_next(). The rest of the
162*7c478bd9Sstevel@tonic-gate 	 * structure members are private members used to track the descriptor
163*7c478bd9Sstevel@tonic-gate 	 * and data buffer usage.
164*7c478bd9Sstevel@tonic-gate 	 */
165*7c478bd9Sstevel@tonic-gate 	hci1394_q_cmd_t		ac_qcmd;
166*7c478bd9Sstevel@tonic-gate } hci1394_async_cmd_t;
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("Used only by one thread", hci1394_async_cmd_s \
169*7c478bd9Sstevel@tonic-gate 	hci1394_async_cmd_s::ac_qcmd.qc_arg \
170*7c478bd9Sstevel@tonic-gate 	hci1394_async_cmd_s::ac_qcmd.qc_generation \
171*7c478bd9Sstevel@tonic-gate 	hci1394_async_cmd_s::ac_qcmd.qc_timestamp \
172*7c478bd9Sstevel@tonic-gate 	hci1394_async_cmd_s::ac_tlabel_alloc \
173*7c478bd9Sstevel@tonic-gate 	hci1394_async_cmd_s::ac_tlabel.tbi_destination \
174*7c478bd9Sstevel@tonic-gate 	hci1394_async_cmd_s::ac_tlabel.tbi_tlabel))
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate /*
177*7c478bd9Sstevel@tonic-gate  * async private state information.  It contains handles for the various modules
178*7c478bd9Sstevel@tonic-gate  * that async uses.
179*7c478bd9Sstevel@tonic-gate  */
180*7c478bd9Sstevel@tonic-gate typedef struct hci1394_async_s {
181*7c478bd9Sstevel@tonic-gate 	hci1394_tlist_handle_t	as_pending_list;
182*7c478bd9Sstevel@tonic-gate 	hci1394_ohci_handle_t	as_ohci;
183*7c478bd9Sstevel@tonic-gate 	hci1394_tlabel_handle_t	as_tlabel;
184*7c478bd9Sstevel@tonic-gate 	hci1394_csr_handle_t	as_csr;
185*7c478bd9Sstevel@tonic-gate 	hci1394_q_handle_t	as_atreq_q;
186*7c478bd9Sstevel@tonic-gate 	hci1394_q_handle_t	as_arresp_q;
187*7c478bd9Sstevel@tonic-gate 	hci1394_q_handle_t	as_arreq_q;
188*7c478bd9Sstevel@tonic-gate 	hci1394_q_handle_t	as_atresp_q;
189*7c478bd9Sstevel@tonic-gate 	hci1394_drvinfo_t	*as_drvinfo;
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 	/*
192*7c478bd9Sstevel@tonic-gate 	 * as_flushing_arreq is used in bus reset processing. It is set by
193*7c478bd9Sstevel@tonic-gate 	 * hci1394_async_arreq_flush() and tells hci1394_async_arreq_process()
194*7c478bd9Sstevel@tonic-gate 	 * not to send the ARREQ up to the Services Layer. It will be set to
195*7c478bd9Sstevel@tonic-gate 	 * FALSE by hci1394_async_arreq_read_phy() when a bus reset token with
196*7c478bd9Sstevel@tonic-gate 	 * the current bus generation is found. as_phy_reset is used to store
197*7c478bd9Sstevel@tonic-gate 	 * the last PHY packet generation seen in the ARREQ Q. The HW puts a
198*7c478bd9Sstevel@tonic-gate 	 * token in the ARREQ Q so that the SW can flush the Q up to and
199*7c478bd9Sstevel@tonic-gate 	 * including the token.
200*7c478bd9Sstevel@tonic-gate 	 */
201*7c478bd9Sstevel@tonic-gate 	boolean_t		as_flushing_arreq;
202*7c478bd9Sstevel@tonic-gate 	uint_t			as_phy_reset;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 	/*
205*7c478bd9Sstevel@tonic-gate 	 * as_atomic_lookup is used to protect the cmd from a race condition
206*7c478bd9Sstevel@tonic-gate 	 * between the ARRESP and the Pending Timeout callback. This is
207*7c478bd9Sstevel@tonic-gate 	 * explained in more detail in hci1394_async_atreq_process().
208*7c478bd9Sstevel@tonic-gate 	 */
209*7c478bd9Sstevel@tonic-gate 	kmutex_t		as_atomic_lookup;
210*7c478bd9Sstevel@tonic-gate } hci1394_async_t;
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("Used only by one thread", \
213*7c478bd9Sstevel@tonic-gate 	hci1394_async_s::as_flushing_arreq hci1394_async_s::as_phy_reset))
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate int hci1394_async_init(hci1394_drvinfo_t *drvinfo,
216*7c478bd9Sstevel@tonic-gate     hci1394_ohci_handle_t ohci_handle, hci1394_csr_handle_t csr_handle,
217*7c478bd9Sstevel@tonic-gate     hci1394_async_handle_t *async_handle);
218*7c478bd9Sstevel@tonic-gate void hci1394_async_fini(hci1394_async_handle_t *async_handle);
219*7c478bd9Sstevel@tonic-gate void hci1394_async_suspend(hci1394_async_handle_t async_handle);
220*7c478bd9Sstevel@tonic-gate int hci1394_async_resume(hci1394_async_handle_t async_handle);
221*7c478bd9Sstevel@tonic-gate uint_t hci1394_async_cmd_overhead();
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate void hci1394_async_flush(hci1394_async_handle_t async_handle);
224*7c478bd9Sstevel@tonic-gate void hci1394_async_atreq_reset(hci1394_async_handle_t async_handle);
225*7c478bd9Sstevel@tonic-gate void hci1394_async_atresp_reset(hci1394_async_handle_t async_handle);
226*7c478bd9Sstevel@tonic-gate void hci1394_async_pending_timeout_update(hci1394_async_handle_t async_handle,
227*7c478bd9Sstevel@tonic-gate     hrtime_t timeout);
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate int hci1394_async_atreq_process(hci1394_async_handle_t async_handle,
230*7c478bd9Sstevel@tonic-gate     boolean_t flush_q, boolean_t *request_available);
231*7c478bd9Sstevel@tonic-gate int hci1394_async_arresp_process(hci1394_async_handle_t async_handle,
232*7c478bd9Sstevel@tonic-gate     boolean_t *response_available);
233*7c478bd9Sstevel@tonic-gate int hci1394_async_arreq_process(hci1394_async_handle_t async_handle,
234*7c478bd9Sstevel@tonic-gate     boolean_t *request_available);
235*7c478bd9Sstevel@tonic-gate int hci1394_async_atresp_process(hci1394_async_handle_t async_handle,
236*7c478bd9Sstevel@tonic-gate     boolean_t flush_q, boolean_t *response_available);
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate int hci1394_async_phy(hci1394_async_handle_t async_handle,
239*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result);
240*7c478bd9Sstevel@tonic-gate int hci1394_async_write(hci1394_async_handle_t async_handle,
241*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result);
242*7c478bd9Sstevel@tonic-gate int hci1394_async_read(hci1394_async_handle_t async_handle,
243*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result);
244*7c478bd9Sstevel@tonic-gate int hci1394_async_lock(hci1394_async_handle_t async_handle,
245*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result);
246*7c478bd9Sstevel@tonic-gate int hci1394_async_write_response(hci1394_async_handle_t async_handle,
247*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result);
248*7c478bd9Sstevel@tonic-gate int hci1394_async_read_response(hci1394_async_handle_t async_handle,
249*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result);
250*7c478bd9Sstevel@tonic-gate int hci1394_async_lock_response(hci1394_async_handle_t async_handle,
251*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result);
252*7c478bd9Sstevel@tonic-gate void hci1394_async_response_complete(hci1394_async_handle_t async_handle,
253*7c478bd9Sstevel@tonic-gate     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv);
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
257*7c478bd9Sstevel@tonic-gate }
258*7c478bd9Sstevel@tonic-gate #endif
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate #endif	/* _SYS_1394_ADAPTERS_HCI1394_ASYNC_H */
261