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_Q_H
28*7c478bd9Sstevel@tonic-gate #define	_SYS_1394_ADAPTERS_HCI1394_Q_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * hci1394_q.h
32*7c478bd9Sstevel@tonic-gate  *    This code decouples some of the OpenHCI async descriptor logic/structures
33*7c478bd9Sstevel@tonic-gate  *    from the async processing.  The goal was to combine as much of the
34*7c478bd9Sstevel@tonic-gate  *    duplicate code as possible for the different type of async transfers
35*7c478bd9Sstevel@tonic-gate  *    without going too overboard.
36*7c478bd9Sstevel@tonic-gate  *
37*7c478bd9Sstevel@tonic-gate  *    There are two parts to the Q, the descriptor buffer and the data buffer.
38*7c478bd9Sstevel@tonic-gate  *    for the most part, data to be transmitted and data which is received go
39*7c478bd9Sstevel@tonic-gate  *    in the data buffers.  The information of where to get the data and put
40*7c478bd9Sstevel@tonic-gate  *    the data reside in the descriptor buffers. There are exceptions to this.
41*7c478bd9Sstevel@tonic-gate  */
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
44*7c478bd9Sstevel@tonic-gate extern "C" {
45*7c478bd9Sstevel@tonic-gate #endif
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
49*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
50*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
51*7c478bd9Sstevel@tonic-gate #include <sys/note.h>
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_def.h>
54*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_tlist.h>
55*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_buf.h>
56*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_descriptors.h>
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate /*
60*7c478bd9Sstevel@tonic-gate  * Part of q_info passed in during q_init(). This tells us if this is an async
61*7c478bd9Sstevel@tonic-gate  * transmit or async receive Q. This makes a big difference inside of q. For
62*7c478bd9Sstevel@tonic-gate  * the transmit Q we will just setup an empty Q ready for TX calls into us. For
63*7c478bd9Sstevel@tonic-gate  * receive Q's we have to make sure we get multiple data buffers and then setup
64*7c478bd9Sstevel@tonic-gate  * the buffers so they are ready to receive data (by adding in the IM
65*7c478bd9Sstevel@tonic-gate  * descriptors).
66*7c478bd9Sstevel@tonic-gate  */
67*7c478bd9Sstevel@tonic-gate typedef enum {
68*7c478bd9Sstevel@tonic-gate 	HCI1394_ARQ,
69*7c478bd9Sstevel@tonic-gate 	HCI1394_ATQ
70*7c478bd9Sstevel@tonic-gate } hci1394_q_mode_t;
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate /*
73*7c478bd9Sstevel@tonic-gate  * Part of q_info passed in during q_init().  These are the callbacks for
74*7c478bd9Sstevel@tonic-gate  * starting and waking up the async Q's.  When the first descriptor is placed
75*7c478bd9Sstevel@tonic-gate  * on the Q, the async DMA engine is started with an address of where to find
76*7c478bd9Sstevel@tonic-gate  * the descriptor on the Q.  That descriptor will be changed to point to the
77*7c478bd9Sstevel@tonic-gate  * next descriptor when the next descriptor is added (i.e. a chained dma).
78*7c478bd9Sstevel@tonic-gate  * Whenever an additional descriptor is added, wake is called.
79*7c478bd9Sstevel@tonic-gate  */
80*7c478bd9Sstevel@tonic-gate typedef void (*hci1394_q_start_t)(void *arg, uint32_t io_addr);
81*7c478bd9Sstevel@tonic-gate typedef void (*hci1394_q_wake_t)(void *arg);
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate /*
84*7c478bd9Sstevel@tonic-gate  * Passed in during q_init().  This contains the size of the descriptor Q, the
85*7c478bd9Sstevel@tonic-gate  * size of the data Q, what kind of Q it is (AT or AR), the callbacks for start
86*7c478bd9Sstevel@tonic-gate  * and wake, and the argument to pass during start and wake.
87*7c478bd9Sstevel@tonic-gate  */
88*7c478bd9Sstevel@tonic-gate typedef struct hci1394_q_info_s {
89*7c478bd9Sstevel@tonic-gate 	uint_t			qi_desc_size;
90*7c478bd9Sstevel@tonic-gate 	uint_t			qi_data_size;
91*7c478bd9Sstevel@tonic-gate 	hci1394_q_mode_t	qi_mode;
92*7c478bd9Sstevel@tonic-gate 	hci1394_q_start_t	qi_start;
93*7c478bd9Sstevel@tonic-gate 	hci1394_q_wake_t	qi_wake;
94*7c478bd9Sstevel@tonic-gate 	void			*qi_callback_arg;
95*7c478bd9Sstevel@tonic-gate } hci1394_q_info_t;
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate /*
98*7c478bd9Sstevel@tonic-gate  * Per command tracking information for the AT Q's.  This is not used on the AR
99*7c478bd9Sstevel@tonic-gate  * side.  This structure has two parts to it, the public data and the private
100*7c478bd9Sstevel@tonic-gate  * data.  The public data is shared between async.c and q.c.  The private data
101*7c478bd9Sstevel@tonic-gate  * is for internal q.c access only.  It is only put in this structure so that
102*7c478bd9Sstevel@tonic-gate  * we do not have to dynamically alloc space for each transfer.
103*7c478bd9Sstevel@tonic-gate  */
104*7c478bd9Sstevel@tonic-gate typedef struct hci1394_q_cmd_s {
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate 	/* PUBLIC DATA STRUCTURES */
107*7c478bd9Sstevel@tonic-gate 	/*
108*7c478bd9Sstevel@tonic-gate 	 * qc_arg is an input paramter to hci1394_q_at() (along with the data
109*7c478bd9Sstevel@tonic-gate 	 * versions). It is an opaque address pointer which is used by async.c
110*7c478bd9Sstevel@tonic-gate 	 * to determine the commands address after a call to
111*7c478bd9Sstevel@tonic-gate 	 * hci1394_q_at_next().
112*7c478bd9Sstevel@tonic-gate 	 */
113*7c478bd9Sstevel@tonic-gate 	void			*qc_arg;
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	/*
116*7c478bd9Sstevel@tonic-gate 	 * qc_generation is an input parameter to hci1394_q_at() (along with the
117*7c478bd9Sstevel@tonic-gate 	 * data versions). It is the generation count for which this command is
118*7c478bd9Sstevel@tonic-gate 	 * valid. If qc_generation does not match the current bus generation,
119*7c478bd9Sstevel@tonic-gate 	 * hci1394_q_at*() will return failure.
120*7c478bd9Sstevel@tonic-gate 	 */
121*7c478bd9Sstevel@tonic-gate 	uint_t			qc_generation;
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate 	/*
124*7c478bd9Sstevel@tonic-gate 	 * qc_timestamp is used when sending an atresp to set the time when the
125*7c478bd9Sstevel@tonic-gate 	 * response is to have timed out.  It is also use on at_next to tell
126*7c478bd9Sstevel@tonic-gate 	 * when the AT command completed.
127*7c478bd9Sstevel@tonic-gate 	 */
128*7c478bd9Sstevel@tonic-gate 	uint_t			qc_timestamp;
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 	/*
131*7c478bd9Sstevel@tonic-gate 	 * qc_status is an output of hci1394_q_at_next().  It contains the
132*7c478bd9Sstevel@tonic-gate 	 * command status after completion.
133*7c478bd9Sstevel@tonic-gate 	 */
134*7c478bd9Sstevel@tonic-gate 	uint32_t		qc_status;
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	/* PRIVATE DATA STRUCTURES */
138*7c478bd9Sstevel@tonic-gate 	/*
139*7c478bd9Sstevel@tonic-gate 	 * This is the memory address of where the status of this command
140*7c478bd9Sstevel@tonic-gate 	 * resides.
141*7c478bd9Sstevel@tonic-gate 	 */
142*7c478bd9Sstevel@tonic-gate 	uint32_t		*qc_status_addr;
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate 	/*
145*7c478bd9Sstevel@tonic-gate 	 * qc_descriptor_end and qc_descriptor_buf are used to track where the
146*7c478bd9Sstevel@tonic-gate 	 * descriptor q pointers should be set to when this command has
147*7c478bd9Sstevel@tonic-gate 	 * completed (i.e. free up the space used by this command)
148*7c478bd9Sstevel@tonic-gate 	 */
149*7c478bd9Sstevel@tonic-gate 	caddr_t			qc_descriptor_end;
150*7c478bd9Sstevel@tonic-gate 	uint_t			qc_descriptor_buf;
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	/*
153*7c478bd9Sstevel@tonic-gate 	 * qc_data_end and qc_data_buf are used to track where the data q
154*7c478bd9Sstevel@tonic-gate 	 * pointers should be set to when this command has completed (i.e. free
155*7c478bd9Sstevel@tonic-gate 	 * up the space used by this command).  Not all commands use the data
156*7c478bd9Sstevel@tonic-gate 	 * q so qc_data_used give us state on if this command uses the data q.
157*7c478bd9Sstevel@tonic-gate 	 */
158*7c478bd9Sstevel@tonic-gate 	boolean_t		qc_data_used;
159*7c478bd9Sstevel@tonic-gate 	caddr_t			qc_data_end;
160*7c478bd9Sstevel@tonic-gate 	uint_t			qc_data_buf;
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	/*
163*7c478bd9Sstevel@tonic-gate 	 * This is the node for the queued list.  Since AT requests finish in
164*7c478bd9Sstevel@tonic-gate 	 * the order that they were submitted, we queue these up in a linked
165*7c478bd9Sstevel@tonic-gate 	 * list so that it is easy to figure out which command has finished.
166*7c478bd9Sstevel@tonic-gate 	 * Just look at the head of the list.
167*7c478bd9Sstevel@tonic-gate 	 */
168*7c478bd9Sstevel@tonic-gate 	hci1394_tlist_node_t	qc_node;
169*7c478bd9Sstevel@tonic-gate } hci1394_q_cmd_t;
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
172*7c478bd9Sstevel@tonic-gate 	hci1394_q_cmd_s::qc_status \
173*7c478bd9Sstevel@tonic-gate 	hci1394_q_cmd_s::qc_timestamp))
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate typedef struct hci1394_q_bufptr_s {
176*7c478bd9Sstevel@tonic-gate 	/*
177*7c478bd9Sstevel@tonic-gate 	 * kernel virtual addresses.  The q may be broken down into multiple
178*7c478bd9Sstevel@tonic-gate 	 * cookies.  The q is contiguous relative to the driver, but segmented
179*7c478bd9Sstevel@tonic-gate 	 * relative to the 1394 HW DMA engines.
180*7c478bd9Sstevel@tonic-gate 	 *
181*7c478bd9Sstevel@tonic-gate 	 * qp_top is the top the q. qp_bottom is the bottom of the q. These
182*7c478bd9Sstevel@tonic-gate 	 * never change after initial setup. qp_bottom is inclusive (i.e. for a
183*7c478bd9Sstevel@tonic-gate 	 * q size of 16 bytes where top was = to 0, qp_bottom would be = to 15).
184*7c478bd9Sstevel@tonic-gate 	 *
185*7c478bd9Sstevel@tonic-gate 	 * qp_current and qp_free are pointers within top and bottom. qp_current
186*7c478bd9Sstevel@tonic-gate 	 * refers to the next free space to write and free refers to the end of
187*7c478bd9Sstevel@tonic-gate 	 * free space (i.e. used memory within q). qp_free is inclusive (see
188*7c478bd9Sstevel@tonic-gate 	 * qp_bottom).
189*7c478bd9Sstevel@tonic-gate 	 */
190*7c478bd9Sstevel@tonic-gate 	caddr_t		qp_top;
191*7c478bd9Sstevel@tonic-gate 	caddr_t		qp_bottom;
192*7c478bd9Sstevel@tonic-gate 	caddr_t		qp_current;
193*7c478bd9Sstevel@tonic-gate 	caddr_t		qp_free;
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 	/*
196*7c478bd9Sstevel@tonic-gate 	 * qp_begin and qp_end are also kernel virtual addresses.  They are the
197*7c478bd9Sstevel@tonic-gate 	 * beginning and ending address of the current_buf (cookie) within the
198*7c478bd9Sstevel@tonic-gate 	 * q.  qp_offset is (qp_current - qp_begin). This is used to determine
199*7c478bd9Sstevel@tonic-gate 	 * the 32 bit PCI address to put into the OpenHCI descriptor. We know
200*7c478bd9Sstevel@tonic-gate 	 * the base PCI address from the cookie structure, we add offset to that
201*7c478bd9Sstevel@tonic-gate 	 * to determine the correct PCI address.
202*7c478bd9Sstevel@tonic-gate 	 */
203*7c478bd9Sstevel@tonic-gate 	caddr_t		qp_begin;
204*7c478bd9Sstevel@tonic-gate 	caddr_t		qp_end;
205*7c478bd9Sstevel@tonic-gate 	uint32_t	qp_offset;
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 	/*
208*7c478bd9Sstevel@tonic-gate 	 * As stated above, the q may be broken into multiple cookies.
209*7c478bd9Sstevel@tonic-gate 	 * qp_current_buf is the cookie qp_current is in and qp_free_buf is the
210*7c478bd9Sstevel@tonic-gate 	 * cookie qp_free is in.  NOTE: The cookie's are numbered 0, 1, 2, ...,
211*7c478bd9Sstevel@tonic-gate 	 * (i.e. if we have 4 cookies, qp_current_buf can be 0, 1, 2, or 3)
212*7c478bd9Sstevel@tonic-gate 	 */
213*7c478bd9Sstevel@tonic-gate 	uint_t		qp_current_buf;
214*7c478bd9Sstevel@tonic-gate 	uint_t		qp_free_buf;
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 	/*
217*7c478bd9Sstevel@tonic-gate 	 * qp_resv_size is only used for the AT Q's.
218*7c478bd9Sstevel@tonic-gate 	 * How much space has been reserved.  This value is set on the call to
219*7c478bd9Sstevel@tonic-gate 	 * hci1394_q_reserve() and decremented each time a data is written.  It
220*7c478bd9Sstevel@tonic-gate 	 * is used to check for overrun conditions. This extra check is in there
221*7c478bd9Sstevel@tonic-gate 	 * as an added sanity check due to the complexity of this code.
222*7c478bd9Sstevel@tonic-gate 	 */
223*7c478bd9Sstevel@tonic-gate 	uint_t		qp_resv_size;
224*7c478bd9Sstevel@tonic-gate } hci1394_q_bufptr_t;
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate typedef struct hci1394_q_buf_s {
228*7c478bd9Sstevel@tonic-gate 	/* pointers to track used/free space/cookies in the buffer */
229*7c478bd9Sstevel@tonic-gate 	hci1394_q_bufptr_t	qb_ptrs;
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate 	/*
232*7c478bd9Sstevel@tonic-gate 	 * a backup of qb_ptrs. If we fail while setting up an AT Q, we need to
233*7c478bd9Sstevel@tonic-gate 	 * cleanup by putting things back the way that they were.
234*7c478bd9Sstevel@tonic-gate 	 */
235*7c478bd9Sstevel@tonic-gate 	hci1394_q_bufptr_t	qb_backup_ptrs;
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 	/* copy of all of the cookie's structures for this buffer */
238*7c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t	qb_cookie[OHCI_MAX_COOKIE];
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 	/* Buffer handle used for calls into hci1394_buf_* routines */
241*7c478bd9Sstevel@tonic-gate 	hci1394_buf_handle_t	qb_buf_handle;
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	/* Buffer info (i.e. cookie count, kaddr, ddi handles, etc.) */
244*7c478bd9Sstevel@tonic-gate 	hci1394_buf_info_t	qb_buf;
245*7c478bd9Sstevel@tonic-gate } hci1394_q_buf_t;
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
248*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_s::qb_ptrs.qp_begin \
249*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_s::qb_ptrs.qp_bottom \
250*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_s::qb_ptrs.qp_current \
251*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_s::qb_ptrs.qp_current_buf \
252*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_s::qb_ptrs.qp_end \
253*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_s::qb_ptrs.qp_offset \
254*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_s::qb_ptrs.qp_top))
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate typedef struct hci1394_q_s {
257*7c478bd9Sstevel@tonic-gate 	/*
258*7c478bd9Sstevel@tonic-gate 	 * q_queued_list is only used in the AT descriptor Qs. AT commands
259*7c478bd9Sstevel@tonic-gate 	 * complete in the order they were issued. We Q these commands up with
260*7c478bd9Sstevel@tonic-gate 	 * each new command being added to the end of the list.  When a command
261*7c478bd9Sstevel@tonic-gate 	 * completes, we look at the top of this list to determine which command
262*7c478bd9Sstevel@tonic-gate 	 * completed.
263*7c478bd9Sstevel@tonic-gate 	 */
264*7c478bd9Sstevel@tonic-gate 	hci1394_tlist_handle_t	q_queued_list;
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 	/*
267*7c478bd9Sstevel@tonic-gate 	 * pointer to general driver information (dip, instance, etc) and to
268*7c478bd9Sstevel@tonic-gate 	 * handle for access to openHCI routines.
269*7c478bd9Sstevel@tonic-gate 	 */
270*7c478bd9Sstevel@tonic-gate 	hci1394_drvinfo_t	*q_drvinfo;
271*7c478bd9Sstevel@tonic-gate 	hci1394_ohci_handle_t 	q_ohci;
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 	/*
274*7c478bd9Sstevel@tonic-gate 	 * The OpenHCI DMA engines are basically just chained DMA engines. Each
275*7c478bd9Sstevel@tonic-gate 	 * "link" in the chain is called a descriptor in OpenHCI.  When you want
276*7c478bd9Sstevel@tonic-gate 	 * to add a new descriptor, you init the descriptor, setup its "next"
277*7c478bd9Sstevel@tonic-gate 	 * pointer to "NULL", update the previous descriptor to point to the
278*7c478bd9Sstevel@tonic-gate 	 * new descriptor, and tell the HW you added a new descriptor by setting
279*7c478bd9Sstevel@tonic-gate 	 * its wake bit. q_previous is a pointer to the previous descriptor.
280*7c478bd9Sstevel@tonic-gate 	 * When adding a new descriptor, we just de-reference q_previous to
281*7c478bd9Sstevel@tonic-gate 	 * update its "next" pointer.
282*7c478bd9Sstevel@tonic-gate 	 */
283*7c478bd9Sstevel@tonic-gate 	hci1394_desc_t		*q_previous;
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 	/*
286*7c478bd9Sstevel@tonic-gate 	 * When updating the "next" pointer in the previous descriptor block
287*7c478bd9Sstevel@tonic-gate 	 * (as described above in q_previous), one of the things you need to
288*7c478bd9Sstevel@tonic-gate 	 * tell the HW is how many 16 byte blocks the next descriptor block
289*7c478bd9Sstevel@tonic-gate 	 * uses. This is what q_block_cnt is used for.  This is only used in the
290*7c478bd9Sstevel@tonic-gate 	 * AT descriptor Q's.  Since the IM's used in the AR Q's are the only
291*7c478bd9Sstevel@tonic-gate 	 * descriptor types used in AR, the block count is always the same for
292*7c478bd9Sstevel@tonic-gate 	 * an AR descriptor Q.
293*7c478bd9Sstevel@tonic-gate 	 */
294*7c478bd9Sstevel@tonic-gate 	uint_t			q_block_cnt;
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	/*
297*7c478bd9Sstevel@tonic-gate 	 * q_head is only used in the AR descriptor Qs. It contains the location
298*7c478bd9Sstevel@tonic-gate 	 * of the first descriptor on the Q.  This is used to look at the
299*7c478bd9Sstevel@tonic-gate 	 * residual count in the AR data Q.  The residual count tells us if we
300*7c478bd9Sstevel@tonic-gate 	 * have received any new packets to process. When a descriptor's data
301*7c478bd9Sstevel@tonic-gate 	 * buffer is empty (q_space_left = 0), we move q_head to the next
302*7c478bd9Sstevel@tonic-gate 	 * descriptor in the descriptor buffer.
303*7c478bd9Sstevel@tonic-gate 	 */
304*7c478bd9Sstevel@tonic-gate 	caddr_t			q_head;
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 	/*
307*7c478bd9Sstevel@tonic-gate 	 * q_space_left is only used in the AR descriptor Qs. Each AR
308*7c478bd9Sstevel@tonic-gate 	 * descriptor has residual count embedded in the descriptor which says
309*7c478bd9Sstevel@tonic-gate 	 * how much free space is left in the descriptors associated data
310*7c478bd9Sstevel@tonic-gate 	 * buffer. q_space_left is how much SW thinks is left in the data
311*7c478bd9Sstevel@tonic-gate 	 * buffer.  When they do not match, we have a new packet(s) in the data
312*7c478bd9Sstevel@tonic-gate 	 * buffer to process.  Since the residual count is not updated by the
313*7c478bd9Sstevel@tonic-gate 	 * HW until the entire packet has been written to memory, we don't have
314*7c478bd9Sstevel@tonic-gate 	 * to worry about any partial packet RX problems.
315*7c478bd9Sstevel@tonic-gate 	 */
316*7c478bd9Sstevel@tonic-gate 	uint_t			q_space_left;
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 	/*
319*7c478bd9Sstevel@tonic-gate 	 * status of the dma controller.  This tells us if we should do a start
320*7c478bd9Sstevel@tonic-gate 	 * or a wake.  If the dma engine is not running, we should start it. If
321*7c478bd9Sstevel@tonic-gate 	 * it is running, we should wake it. When the DMA engine is started, it
322*7c478bd9Sstevel@tonic-gate 	 * expects to have a valid descriptor to process.  Since we don't have
323*7c478bd9Sstevel@tonic-gate 	 * anything to send in the beginning (AT), we have to wait until the
324*7c478bd9Sstevel@tonic-gate 	 * first AT packet comes down before we can start the DMA engine.
325*7c478bd9Sstevel@tonic-gate 	 */
326*7c478bd9Sstevel@tonic-gate 	boolean_t		q_dma_running;
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate 	/* The descriptor buffer for this Q */
329*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_t		q_desc;
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 	/* The data buffer for this Q */
332*7c478bd9Sstevel@tonic-gate 	hci1394_q_buf_t		q_data;
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 	/* copy of qinfo passed in during hci1394_q_init() */
335*7c478bd9Sstevel@tonic-gate 	hci1394_q_info_t	q_info;
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate 	kmutex_t		q_mutex;
338*7c478bd9Sstevel@tonic-gate } hci1394_q_t;
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
341*7c478bd9Sstevel@tonic-gate         hci1394_q_s::q_dma_running \
342*7c478bd9Sstevel@tonic-gate 	hci1394_q_s::q_head \
343*7c478bd9Sstevel@tonic-gate 	hci1394_q_s::q_previous \
344*7c478bd9Sstevel@tonic-gate 	hci1394_q_s::q_space_left))
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate /* handle passed back from init() and used for rest of functions */
347*7c478bd9Sstevel@tonic-gate typedef struct hci1394_q_s	*hci1394_q_handle_t;
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 
350*7c478bd9Sstevel@tonic-gate int hci1394_q_init(hci1394_drvinfo_t *drvinfo,
351*7c478bd9Sstevel@tonic-gate     hci1394_ohci_handle_t ohci_handle, hci1394_q_info_t *qinfo,
352*7c478bd9Sstevel@tonic-gate     hci1394_q_handle_t *q_handle);
353*7c478bd9Sstevel@tonic-gate void hci1394_q_fini(hci1394_q_handle_t *q_handle);
354*7c478bd9Sstevel@tonic-gate void hci1394_q_resume(hci1394_q_handle_t q_handle);
355*7c478bd9Sstevel@tonic-gate void hci1394_q_stop(hci1394_q_handle_t q_handle);
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate int hci1394_q_at(hci1394_q_handle_t q_handle, hci1394_q_cmd_t *cmd,
358*7c478bd9Sstevel@tonic-gate     hci1394_basic_pkt_t *hdr, uint_t hdrsize, int *result);
359*7c478bd9Sstevel@tonic-gate int hci1394_q_at_with_data(hci1394_q_handle_t q_handle, hci1394_q_cmd_t *cmd,
360*7c478bd9Sstevel@tonic-gate     hci1394_basic_pkt_t *hdr, uint_t hdrsize, uint8_t *data, uint_t datasize,
361*7c478bd9Sstevel@tonic-gate     int *result);
362*7c478bd9Sstevel@tonic-gate int hci1394_q_at_with_mblk(hci1394_q_handle_t q_handle, hci1394_q_cmd_t *cmd,
363*7c478bd9Sstevel@tonic-gate     hci1394_basic_pkt_t *hdr, uint_t hdrsize, h1394_mblk_t *mblk, int *result);
364*7c478bd9Sstevel@tonic-gate void hci1394_q_at_next(hci1394_q_handle_t q_handle, boolean_t flush_q,
365*7c478bd9Sstevel@tonic-gate     hci1394_q_cmd_t **cmd);
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate void hci1394_q_ar_next(hci1394_q_handle_t q_handle, uint32_t **q_addr);
368*7c478bd9Sstevel@tonic-gate void hci1394_q_ar_free(hci1394_q_handle_t q_handle, uint_t size);
369*7c478bd9Sstevel@tonic-gate uint32_t hci1394_q_ar_get32(hci1394_q_handle_t q_handle, uint32_t *addr);
370*7c478bd9Sstevel@tonic-gate void hci1394_q_ar_rep_get8(hci1394_q_handle_t q_handle, uint8_t *dest,
371*7c478bd9Sstevel@tonic-gate     uint8_t *q_addr, uint_t size);
372*7c478bd9Sstevel@tonic-gate void hci1394_q_ar_copy_to_mblk(hci1394_q_handle_t q_handle, uint8_t *addr,
373*7c478bd9Sstevel@tonic-gate     h1394_mblk_t *mblk);
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate 
376*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
377*7c478bd9Sstevel@tonic-gate }
378*7c478bd9Sstevel@tonic-gate #endif
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate #endif	/* _SYS_1394_ADAPTERS_HCI1394_Q_H */
381