1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 /*
28  * hci1394_async.c
29  *    These routines manipulate the 1394 asynchronous dma engines.  This
30  *    includes incoming and outgoing reads, writes, and locks and their
31  *    associated responses.
32  */
33 
34 #include <sys/conf.h>
35 #include <sys/ddi.h>
36 #include <sys/modctl.h>
37 #include <sys/stat.h>
38 #include <sys/sunddi.h>
39 #include <sys/cmn_err.h>
40 #include <sys/kmem.h>
41 #include <sys/types.h>
42 #include <sys/note.h>
43 
44 #include <sys/1394/h1394.h>
45 #include <sys/1394/adapters/hci1394.h>
46 
47 
48 /*
49  * ASYNC_ARRESP_ACK_ERROR is or'd into the error status when we get an ACK error
50  * on an ARRESP.  Since the 1394 response code overlaps with the OpenHCI ACK/EVT
51  * errors, we use this to distinguish between the errors in process_arresp().
52  */
53 #define	ASYNC_ARRESP_ACK_ERROR		0x8000
54 
55 /* Macro's to help extract 48-bit 1394 address into a uint64_t */
56 #define	HCI1394_TO_ADDR_HI(data) (((uint64_t)((data) & 0xFFFF)) << 32)
57 #define	HCI1394_TO_ADDR_LO(data) ((uint64_t)((data) & 0xFFFFFFFF))
58 
59 /*
60  * Macro to convert a byte stream into a big endian quadlet or octlet or back
61  * the other way. 1394 arithmetic lock operations are done on big endian
62  * quadlets or octlets. compare swaps and bit masks are done on a byte streams.
63  * All data is treated as byte streams over the bus. These macros will convert
64  * the data to a big endian "integer" on x86 plaforms if the operation is an
65  * arithmetic lock operation.  It will do nothing if it is not on x86 or is not
66  * an arithmetic lock operation.
67  */
68 #ifdef _LITTLE_ENDIAN
69 #define	HCI1394_ARITH_LOCK_SWAP32(tcode, data) \
70 	(((tcode) == CMD1394_LOCK_FETCH_ADD) || \
71 	((tcode) == CMD1394_LOCK_BOUNDED_ADD) || \
72 	((tcode) == CMD1394_LOCK_WRAP_ADD)) ? \
73 	(ddi_swap32(data)) : (data)
74 #define	HCI1394_ARITH_LOCK_SWAP64(tcode, data) \
75 	(((tcode) == CMD1394_LOCK_FETCH_ADD) || \
76 	((tcode) == CMD1394_LOCK_BOUNDED_ADD) || \
77 	((tcode) == CMD1394_LOCK_WRAP_ADD)) ? \
78 	(ddi_swap64(data)) : (data)
79 #else
80 #define	HCI1394_ARITH_LOCK_SWAP32(tcode, data) (data)
81 #define	HCI1394_ARITH_LOCK_SWAP64(tcode, data) (data)
82 #endif
83 
84 
85 
86 static int hci1394_async_arresp_read(hci1394_async_handle_t async_handle,
87     hci1394_basic_pkt_t *pkt, uint_t *tcode, hci1394_async_cmd_t **hcicmd,
88     uint_t *size);
89 static int hci1394_async_arresp_size_get(uint_t tcode, hci1394_q_handle_t q,
90     uint32_t *addr, uint_t *size);
91 
92 static int hci1394_async_arreq_read(hci1394_async_handle_t async_handle,
93     hci1394_basic_pkt_t *pkt, uint_t *tcode, hci1394_async_cmd_t **hcicmd,
94     uint_t *size);
95 static int hci1394_async_arreq_read_qrd(hci1394_async_handle_t async_handle,
96     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
97 static int hci1394_async_arreq_read_qwr(hci1394_async_handle_t async_handle,
98     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
99 static int hci1394_async_arreq_read_brd(hci1394_async_handle_t async_handle,
100     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
101 static int hci1394_async_arreq_read_bwr(hci1394_async_handle_t async_handle,
102     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
103 static int hci1394_async_arreq_read_lck(hci1394_async_handle_t async_handle,
104     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
105 static int hci1394_async_arreq_read_phy(hci1394_async_handle_t async_handle,
106     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size,
107     boolean_t *bus_reset_token);
108 
109 static void hci1394_async_hcicmd_init(hci1394_async_handle_t async_handle,
110     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv,
111     hci1394_async_cmd_t **hcicmd);
112 
113 static void hci1394_async_atreq_start(void *async, uint32_t command_ptr);
114 static void hci1394_async_arresp_start(void *async, uint32_t command_ptr);
115 static void hci1394_async_arreq_start(void *async, uint32_t command_ptr);
116 static void hci1394_async_atresp_start(void *async, uint32_t command_ptr);
117 
118 static void hci1394_async_atreq_wake(void *async);
119 static void hci1394_async_arresp_wake(void *async);
120 static void hci1394_async_arreq_wake(void *async);
121 static void hci1394_async_atresp_wake(void *async);
122 
123 static void hci1394_async_atreq_flush(hci1394_async_handle_t async_handle);
124 static void hci1394_async_arresp_flush(hci1394_async_handle_t async_handle);
125 static void hci1394_async_arreq_flush(hci1394_async_handle_t async_handle);
126 static void hci1394_async_atresp_flush(hci1394_async_handle_t async_handle);
127 static void hci1394_async_pending_list_flush(hci1394_async_handle_t
128     async_handle);
129 
130 static void hci1394_async_pending_timeout(hci1394_tlist_node_t *node,
131     void *arg);
132 static uint_t hci1394_async_timeout_calc(hci1394_async_handle_t async_handle,
133     uint_t current_time);
134 
135 _NOTE(SCHEME_PROTECTS_DATA("unique", msgb))
136 
137 /*
138  * hci1394_async_init()
139  *    Initialize the async DMA engines and state. We init the tlabels; ATREQ
140  *    pending Q; and ATREQ, ARRESP, ARREQ, and ATRESP Q's. init() returns a
141  *    handle to be used in rest of the functions.
142  */
143 int
hci1394_async_init(hci1394_drvinfo_t * drvinfo,hci1394_ohci_handle_t ohci_handle,hci1394_csr_handle_t csr_handle,hci1394_async_handle_t * async_handle)144 hci1394_async_init(hci1394_drvinfo_t *drvinfo,
145     hci1394_ohci_handle_t ohci_handle, hci1394_csr_handle_t csr_handle,
146     hci1394_async_handle_t *async_handle)
147 {
148 	hci1394_tlist_timer_t timer_info;
149 	hci1394_q_info_t qinfo;
150 	hci1394_async_t *async;
151 	int status;
152 
153 
154 	ASSERT(drvinfo != NULL);
155 	ASSERT(ohci_handle != NULL);
156 	ASSERT(csr_handle != NULL);
157 	ASSERT(async_handle != NULL);
158 
159 	/* alloc the space to keep track of the list */
160 	async = kmem_alloc(sizeof (hci1394_async_t), KM_SLEEP);
161 
162 	/* copy in parms to our local state */
163 	async->as_drvinfo = drvinfo;
164 	async->as_ohci = ohci_handle;
165 	async->as_csr = csr_handle;
166 	async->as_flushing_arreq = B_FALSE;
167 	async->as_phy_reset = 0xFFFFFFFF;
168 	mutex_init(&async->as_atomic_lookup, NULL, MUTEX_DRIVER,
169 	    drvinfo->di_iblock_cookie);
170 
171 	/*
172 	 * Initialize the tlabels. Reclaim a bad tlabel after the split timeout
173 	 * has gone by. This time is in reference to the point the transaction
174 	 * has been marked as bad. Therefore the tlabel will be reclaimed at
175 	 * twice the split_timeout. (i.e. if the split timeout was set to 100mS
176 	 * and the transaction has timed out, 100mS has already gone by. We need
177 	 * to wait for 100mS more before we can reuse the tlabel. Therefore, the
178 	 * reclaim time is split_timeout and not split_timeout * 2. The split
179 	 * timeout is stored as the number of bus cycles.  We need to convert
180 	 * this to nS since the reclaim time is passed as nS.
181 	 */
182 	hci1394_tlabel_init(drvinfo, OHCI_BUS_CYCLE_TO_nS(
183 	    hci1394_csr_split_timeout_get(csr_handle)), &async->as_tlabel);
184 
185 	/*
186 	 * Initialize ATREQ pending list. A pended ATREQ will be timed out after
187 	 * "split_timeout" has gone by. split timeout is in bus cycles so we
188 	 * need to convert that to nS for the tlist timer info. We will set the
189 	 * timer resolution to 1/2 of the timeout so that we will have a worst
190 	 * case timeout of split timeout + (1/2 * split timeout).  See
191 	 * hci1394_tlist.h for more information about this.
192 	 */
193 	timer_info.tlt_timeout =
194 	    OHCI_BUS_CYCLE_TO_nS(hci1394_csr_split_timeout_get(csr_handle));
195 	timer_info.tlt_timer_resolution = timer_info.tlt_timeout / 2;
196 	timer_info.tlt_callback = hci1394_async_pending_timeout;
197 	timer_info.tlt_callback_arg = async;
198 	hci1394_tlist_init(drvinfo, &timer_info, &async->as_pending_list);
199 
200 	/* Initialize ATREQ Q */
201 	qinfo.qi_desc_size = ASYNC_ATREQ_DESC_SIZE;
202 	qinfo.qi_data_size = ASYNC_ATREQ_DATA_SIZE;
203 	qinfo.qi_mode = HCI1394_ATQ;
204 	qinfo.qi_start = hci1394_async_atreq_start;
205 	qinfo.qi_wake = hci1394_async_atreq_wake;
206 	qinfo.qi_callback_arg = async;
207 	status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
208 	    &async->as_atreq_q);
209 	if (status != DDI_SUCCESS) {
210 		mutex_destroy(&async->as_atomic_lookup);
211 		hci1394_tlist_fini(&async->as_pending_list);
212 		hci1394_tlabel_fini(&async->as_tlabel);
213 		kmem_free(async, sizeof (hci1394_async_t));
214 		*async_handle = NULL;
215 		return (DDI_FAILURE);
216 	}
217 
218 	/* Initialize ARRESP Q */
219 	qinfo.qi_desc_size = ASYNC_ARRESP_DESC_SIZE;
220 	qinfo.qi_data_size = ASYNC_ARRESP_DATA_SIZE;
221 	qinfo.qi_mode = HCI1394_ARQ;
222 	qinfo.qi_start = hci1394_async_arresp_start;
223 	qinfo.qi_wake = hci1394_async_arresp_wake;
224 	qinfo.qi_callback_arg = async;
225 	status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
226 	    &async->as_arresp_q);
227 	if (status != DDI_SUCCESS) {
228 		mutex_destroy(&async->as_atomic_lookup);
229 		hci1394_tlist_fini(&async->as_pending_list);
230 		hci1394_tlabel_fini(&async->as_tlabel);
231 		hci1394_q_fini(&async->as_atreq_q);
232 		kmem_free(async, sizeof (hci1394_async_t));
233 		*async_handle = NULL;
234 		return (DDI_FAILURE);
235 	}
236 
237 	/* Initialize ARREQ Q */
238 	qinfo.qi_desc_size = ASYNC_ARREQ_DESC_SIZE;
239 	qinfo.qi_data_size = ASYNC_ARREQ_DATA_SIZE;
240 	qinfo.qi_mode = HCI1394_ARQ;
241 	qinfo.qi_start = hci1394_async_arreq_start;
242 	qinfo.qi_wake = hci1394_async_arreq_wake;
243 	qinfo.qi_callback_arg = async;
244 	status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
245 	    &async->as_arreq_q);
246 	if (status != DDI_SUCCESS) {
247 		mutex_destroy(&async->as_atomic_lookup);
248 		hci1394_tlist_fini(&async->as_pending_list);
249 		hci1394_tlabel_fini(&async->as_tlabel);
250 		hci1394_q_fini(&async->as_atreq_q);
251 		hci1394_q_fini(&async->as_arresp_q);
252 		kmem_free(async, sizeof (hci1394_async_t));
253 		*async_handle = NULL;
254 		return (DDI_FAILURE);
255 	}
256 
257 	/* Initialize ATRESP Q */
258 	qinfo.qi_desc_size = ASYNC_ATRESP_DESC_SIZE;
259 	qinfo.qi_data_size = ASYNC_ATRESP_DATA_SIZE;
260 	qinfo.qi_mode = HCI1394_ATQ;
261 	qinfo.qi_start = hci1394_async_atresp_start;
262 	qinfo.qi_wake = hci1394_async_atresp_wake;
263 	qinfo.qi_callback_arg = async;
264 	status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
265 	    &async->as_atresp_q);
266 	if (status != DDI_SUCCESS) {
267 		mutex_destroy(&async->as_atomic_lookup);
268 		hci1394_tlist_fini(&async->as_pending_list);
269 		hci1394_tlabel_fini(&async->as_tlabel);
270 		hci1394_q_fini(&async->as_atreq_q);
271 		hci1394_q_fini(&async->as_arresp_q);
272 		hci1394_q_fini(&async->as_arreq_q);
273 		kmem_free(async, sizeof (hci1394_async_t));
274 		*async_handle = NULL;
275 		return (DDI_FAILURE);
276 	}
277 
278 	*async_handle = async;
279 
280 	return (DDI_SUCCESS);
281 }
282 
283 
284 /*
285  * hci1394_async_fini()
286  *    Free's up the space allocated in init().  Notice that a pointer to the
287  *    handle is used for the parameter.  fini() will set your handle to NULL
288  *    before returning.
289  */
290 void
hci1394_async_fini(hci1394_async_handle_t * async_handle)291 hci1394_async_fini(hci1394_async_handle_t *async_handle)
292 {
293 	hci1394_async_t *async;
294 
295 
296 	ASSERT(async_handle != NULL);
297 
298 	async = (hci1394_async_t *)*async_handle;
299 
300 	mutex_destroy(&async->as_atomic_lookup);
301 	hci1394_tlabel_fini(&async->as_tlabel);
302 	hci1394_tlist_fini(&async->as_pending_list);
303 	hci1394_q_fini(&async->as_atreq_q);
304 	hci1394_q_fini(&async->as_atresp_q);
305 	hci1394_q_fini(&async->as_arreq_q);
306 	hci1394_q_fini(&async->as_arresp_q);
307 
308 	kmem_free(async, sizeof (hci1394_async_t));
309 
310 	/* set handle to null.  This helps catch bugs. */
311 	*async_handle = NULL;
312 }
313 
314 
315 /*
316  * hci1394_async_suspend()
317  *    The system is getting ready to be suspended.  Make sure that all of
318  *    the Q's are clean and that the there are no scheduled timeouts in the
319  *    pending Q.
320  */
321 void
hci1394_async_suspend(hci1394_async_handle_t async_handle)322 hci1394_async_suspend(hci1394_async_handle_t async_handle)
323 {
324 	ASSERT(async_handle != NULL);
325 
326 	/* Flush out async DMA Q's */
327 	hci1394_async_flush(async_handle);
328 
329 	/* Cancel any scheduled pending timeouts */
330 	hci1394_tlist_timeout_cancel(async_handle->as_pending_list);
331 }
332 
333 
334 /*
335  * hci1394_async_resume()
336  *    Re-setup the DMA Q's during a resume after a successful suspend. The
337  *    tlabels will be re-initialized during the bus reset and the pending Q will
338  *    be flushed during the suspend.
339  */
340 int
hci1394_async_resume(hci1394_async_handle_t async_handle)341 hci1394_async_resume(hci1394_async_handle_t async_handle)
342 {
343 	ASSERT(async_handle != NULL);
344 
345 	hci1394_q_resume(async_handle->as_atreq_q);
346 	hci1394_q_resume(async_handle->as_atresp_q);
347 	hci1394_q_resume(async_handle->as_arreq_q);
348 	hci1394_q_resume(async_handle->as_arresp_q);
349 
350 	return (DDI_SUCCESS);
351 }
352 
353 
354 /*
355  * hci1394_async_cmd_overhead()
356  *    Return the size of the HAL private area to attach to every alloced 1394
357  *    framework command.  This allows us to track command state without having
358  *    to alloc memory every time a command comes down the pipe.
359  */
360 uint_t
hci1394_async_cmd_overhead()361 hci1394_async_cmd_overhead()
362 {
363 	return (sizeof (hci1394_async_cmd_t));
364 }
365 
366 
367 /*
368  * hci1394_async_flush()
369  *    Flush out the Async Q's and the ATREQ pending list.  This is called every
370  *    bus reset so that we're sync'd up with the HW and when shutting down or
371  *    suspending to make sure we cleanup after all commands.
372  */
373 void
hci1394_async_flush(hci1394_async_handle_t async_handle)374 hci1394_async_flush(hci1394_async_handle_t async_handle)
375 {
376 	ASSERT(async_handle != NULL);
377 
378 	hci1394_async_atreq_flush(async_handle);
379 	hci1394_async_arresp_flush(async_handle);
380 	hci1394_async_pending_list_flush(async_handle);
381 	hci1394_async_arreq_flush(async_handle);
382 	hci1394_async_atresp_flush(async_handle);
383 	hci1394_tlabel_reset(async_handle->as_tlabel);
384 }
385 
386 
387 /*
388  * hci1394_async_pending_timeout_update()
389  *    Update the timeout for the pending list. This updates both the pending
390  *    list timeout and time we wait to reclaim  bad tlabels.  timeout is the
391  *    time in nS so we do not have to do any conversions. This routine will be
392  *    called when the CSR split timeout registers are updated.
393  */
394 void
hci1394_async_pending_timeout_update(hci1394_async_handle_t async_handle,hrtime_t timeout)395 hci1394_async_pending_timeout_update(hci1394_async_handle_t async_handle,
396     hrtime_t timeout)
397 {
398 	ASSERT(async_handle != NULL);
399 	hci1394_tlist_timeout_update(async_handle->as_pending_list, timeout);
400 	hci1394_tlabel_set_reclaim_time(async_handle->as_tlabel, timeout);
401 }
402 
403 
404 /*
405  * hci1394_async_atreq_process()
406  *    Process an atreq, if one has completed. This is called during interrupt
407  *    processing and will process a completed atreq. It returns status if an
408  *    atreq was processed so that the ISR knows that it needs to be called
409  *    again to see if another ATREQ has completed. flush_q set to B_TRUE tells
410  *    this routine to process all commands regardless of their completion
411  *    status.  This is used during bus reset processing to remove all commands
412  *    from the Q.
413  *
414  *    There are a few race conditions that we have to watch for in atreq/arresp.
415  *    They all have to do with pended responses so they are not applicable in
416  *    the ARREQ/ATRESP engine (since ATRESP's can't be pended).
417  *
418  *    Since the race conditions only exist for pended responses, we will only
419  *    talk about that sequence here. We're also going to simplify the discussion
420  *    so what the code does, so it won't exactly match what we say (e.g. we
421  *    don't always setup a timeout for every single command, etc.)
422  *
423  *    After Q'ing up an ATREQ, we will process the result of that command in
424  *    one of a couple different paths. A normal condition would be that we Q up
425  *    a command, we get an ATREQ complete interrupt and look at the ATREQ
426  *    result. In the case it has been pended, we setup a timeout to wait for the
427  *    response. If we receive the response before the timeout, the command is
428  *    done and we send the response up the chain, if we do not, the command is
429  *    done and we send a timeout notification up the chain.
430  *
431  *    The first race condition is when we get the timeout at the same time as
432  *    the response. At first glance a mutex around the command state would
433  *    solve this problem. But on a multi-processor machine, we may have the
434  *    ARRESP interrupt handler(ISR) running on one processor and the timeout on
435  *    another. This means that the command state could change between two
436  *    reads while in the ISR. This means we need to have a little more complex
437  *    logic around changing the command state and have to be careful how and
438  *    when we do this.
439  *
440  *    The second race condition is that we could see the ARRESP before we
441  *    process the ATREQ. We could be processing a few ARRESP from previous
442  *    ATREQ's when the ATREQ completes and then the ARRESP comes in.  Since we
443  *    already are in the interrupt handler, the ATREQ complete will not preempt
444  *    us.
445  *
446  *    We will never see a race condition between the ATREQ interrupt for a
447  *    command and the pending timeout since the command is not being timed until
448  *    this routine is run for that command.
449  */
450 int
hci1394_async_atreq_process(hci1394_async_handle_t async_handle,boolean_t flush_q,boolean_t * request_available)451 hci1394_async_atreq_process(hci1394_async_handle_t async_handle,
452     boolean_t flush_q, boolean_t *request_available)
453 {
454 	hci1394_async_cmd_t *hcicmd;
455 	hci1394_q_cmd_t *qcmd;
456 	int cmd_status;
457 
458 
459 	ASSERT(async_handle != NULL);
460 	ASSERT(request_available != NULL);
461 
462 	/*
463 	 * Get the next ATREQ that has completed (if one has). Space is free'd
464 	 * up in atreq_q and atreq_data_q as part of this function call.
465 	 */
466 	hci1394_q_at_next(async_handle->as_atreq_q, flush_q, &qcmd);
467 
468 	/*
469 	 * See if there were anymore requests on ATREQ Q. A NULL means there
470 	 * were no completed commands left on the Q
471 	 */
472 	if (qcmd == NULL) {
473 		*request_available = B_FALSE;
474 		return (DDI_SUCCESS);
475 	}
476 
477 	/* There is a completed ATREQ, setup the HAL command pointer */
478 	*request_available = B_TRUE;
479 	hcicmd = (hci1394_async_cmd_t *)qcmd->qc_arg;
480 
481 	/* save away the command completed timestamp for the services layer */
482 	hcicmd->ac_priv->ack_tstamp = qcmd->qc_timestamp;
483 
484 	/*
485 	 * Make sure this command has not already been processed. This command
486 	 * may have already received a response.  If the ACK was not an ACK
487 	 * pending, we have a HW error (i.e. The target HW sent a response to a
488 	 * non-pended request). There is a race condition where the software
489 	 * will see and complete a response before processing it's ACK Pending.
490 	 * This can only happen for ACK pendings. We have seen this race
491 	 * condition and response to a non-pended request during real-world
492 	 * testing :-)
493 	 */
494 	if (hcicmd->ac_state != HCI1394_CMD_STATE_IN_PROGRESS) {
495 		/*
496 		 * we already processed the ARRESP in arresp_process(), it
497 		 * better have been ACK pended. Otherwise the target device
498 		 * performed an illegal action.
499 		 */
500 		if (qcmd->qc_status == OHCI_ACK_PENDING) {
501 			/*
502 			 * Tell source that their command has completed. We're
503 			 * done with this command.
504 			 * NOTE: We use ac_status which was set in
505 			 * process_arresp()
506 			 */
507 			h1394_cmd_is_complete(
508 			    async_handle->as_drvinfo->di_sl_private,
509 			    hcicmd->ac_cmd, H1394_AT_REQ,
510 			    hcicmd->ac_status);
511 			return (DDI_SUCCESS);
512 		/*
513 		 * This is a HW error.  Process the ACK like we never saw the
514 		 * response. We will do this below.
515 		 */
516 		}
517 	}
518 
519 	/*
520 	 * if we got an ack pending, add it to the pending list and leave. We
521 	 * will either get an ARRESP or the pending list will timeout the
522 	 * response.
523 	 */
524 	if (qcmd->qc_status == OHCI_ACK_PENDING) {
525 		hcicmd->ac_state = HCI1394_CMD_STATE_PENDING;
526 		/* Add this command to the pending list */
527 		hcicmd->ac_plist_node.tln_addr = hcicmd;
528 		hci1394_tlist_add(async_handle->as_pending_list,
529 		    &hcicmd->ac_plist_node);
530 		return (DDI_SUCCESS);
531 	}
532 
533 	/*
534 	 * setup our return command status based on the ACK from the HW. See the
535 	 * OpenHCI 1.0 spec (table 3.2 on pg. 18) for more information about
536 	 * these ACK/EVT's.
537 	 */
538 	switch (qcmd->qc_status) {
539 	case OHCI_ACK_COMPLETE:
540 		cmd_status = H1394_CMD_SUCCESS;
541 		break;
542 
543 	/*
544 	 * we can get a nostatus during a bus reset (i.e. we shutdown the AT
545 	 * engine before it flushed all the commands)
546 	 */
547 	case OHCI_EVT_FLUSHED:
548 	case OHCI_EVT_NO_STATUS:
549 		cmd_status = H1394_CMD_EBUSRESET;
550 		break;
551 
552 	case OHCI_EVT_MISSING_ACK:
553 	case OHCI_EVT_TIMEOUT:
554 		cmd_status = H1394_CMD_ETIMEOUT;
555 		break;
556 
557 	case OHCI_ACK_BUSY_X:
558 	case OHCI_ACK_BUSY_A:
559 	case OHCI_ACK_BUSY_B:
560 		cmd_status = H1394_CMD_EDEVICE_BUSY;
561 		break;
562 
563 	case OHCI_ACK_TARDY:
564 		cmd_status = H1394_CMD_EDEVICE_POWERUP;
565 		break;
566 
567 	case OHCI_ACK_DATA_ERROR:
568 		cmd_status = H1394_CMD_EDATA_ERROR;
569 		break;
570 
571 	case OHCI_ACK_TYPE_ERROR:
572 		cmd_status = H1394_CMD_ETYPE_ERROR;
573 		break;
574 
575 	case OHCI_ACK_CONFLICT_ERROR:
576 		cmd_status = H1394_CMD_ERSRC_CONFLICT;
577 		break;
578 
579 	case OHCI_ACK_ADDRESS_ERROR:
580 		cmd_status = H1394_CMD_EADDR_ERROR;
581 		break;
582 
583 	case OHCI_EVT_UNDERRUN:
584 	case OHCI_EVT_DATA_READ:
585 	case OHCI_EVT_TCODE_ERR:
586 	case OHCI_EVT_DESCRIPTOR_READ:
587 	case OHCI_EVT_UNKNOWN:
588 	default:
589 		cmd_status = H1394_CMD_EUNKNOWN_ERROR;
590 		break;
591 	}
592 
593 	/*
594 	 * Free the tlabel that was used for this transfer. We will not try and
595 	 * free the tlabel in the case that we already received a response or if
596 	 * we did not allocate one (PHY packet). If we already received a
597 	 * response, the tlabel would have been free'd in
598 	 * hci1394_async_arresp_process().
599 	 */
600 	if ((hcicmd->ac_state == HCI1394_CMD_STATE_IN_PROGRESS) &&
601 	    (hcicmd->ac_tlabel_alloc == B_TRUE)) {
602 		hci1394_tlabel_free(async_handle->as_tlabel,
603 		    &hcicmd->ac_tlabel);
604 	}
605 
606 	/*
607 	 * if we got anything other than and ACK pending, we are done w/ this
608 	 * transaction.
609 	 */
610 	hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
611 
612 	/* tell the services layer that the command has completed */
613 	h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
614 	    hcicmd->ac_cmd, H1394_AT_REQ, cmd_status);
615 
616 	return (DDI_SUCCESS);
617 }
618 
619 
620 /*
621  * hci1394_async_arresp_process()
622  *    Process an arresp, if one has completed. This is called during interrupt
623  *    processing and will process a completed arresp. It returns status if an
624  *    arresp was processed so that the ISR knows that it needs to be called
625  *    again to see if another ARRESP has completed.
626  */
627 int
hci1394_async_arresp_process(hci1394_async_handle_t async_handle,boolean_t * response_available)628 hci1394_async_arresp_process(hci1394_async_handle_t async_handle,
629     boolean_t *response_available)
630 {
631 	hci1394_async_cmd_t *hcicmd;
632 	uint32_t *addr;
633 	int cmd_status;
634 	uint_t tcode;
635 	uint_t size;
636 	int status;
637 
638 
639 	ASSERT(async_handle != NULL);
640 	ASSERT(response_available != NULL);
641 
642 	/*
643 	 * See if there were any responses on ARRESP Q. A NULL means there
644 	 * were no responses on the Q. This call does NOT free up space. We
645 	 * need to do that later after we figure out how much space the
646 	 * response takes up.
647 	 */
648 	hci1394_q_ar_next(async_handle->as_arresp_q, &addr);
649 	if (addr == NULL) {
650 		*response_available = B_FALSE;
651 		return (DDI_SUCCESS);
652 	}
653 
654 	/*
655 	 * We got a response. Lock out pending timeout callback from marking
656 	 * tlabel bad.
657 	 */
658 	*response_available = B_TRUE;
659 	mutex_enter(&async_handle->as_atomic_lookup);
660 
661 	/*
662 	 * Read in the response into the 1394 framework command. We could get a
663 	 * NULL for a command if we got a response with an error (i.e. tlabel
664 	 * that didn't match a request) This would be a successful read but with
665 	 * a NULL hcicmd returned. If we ever get a DDI_FAILURE, we will
666 	 * shutdown.
667 	 */
668 	status = hci1394_async_arresp_read(async_handle,
669 	    (hci1394_basic_pkt_t *)addr, &tcode, &hcicmd, &size);
670 	if (status != DDI_SUCCESS) {
671 		mutex_exit(&async_handle->as_atomic_lookup);
672 		h1394_error_detected(async_handle->as_drvinfo->di_sl_private,
673 		    H1394_SELF_INITIATED_SHUTDOWN, NULL);
674 		cmn_err(CE_WARN, "hci1394(%d): driver shutdown: "
675 		    "unrecoverable error interrupt detected",
676 		    async_handle->as_drvinfo->di_instance);
677 		hci1394_shutdown(async_handle->as_drvinfo->di_dip);
678 		return (DDI_FAILURE);
679 	}
680 
681 	/* Free up the arresp Q space, we are done with the data */
682 	hci1394_q_ar_free(async_handle->as_arresp_q, size);
683 
684 	/*
685 	 * if we did not get a valid command response (i.e. we got a bad tlabel
686 	 * or something like that) we don't have anything else to do.  We will
687 	 * say that we processed a response and will return successfully. We
688 	 * still may have other responses on the Q.
689 	 */
690 	if (hcicmd == NULL) {
691 		mutex_exit(&async_handle->as_atomic_lookup);
692 		return (DDI_SUCCESS);
693 	}
694 
695 	/*
696 	 * Make sure this is in the pending list. There is a small chance that
697 	 * we will see the response before we see the ACK PENDING. If it is the
698 	 * expected case, it is in the pending list.  We will remove it since
699 	 * we are done with the command.
700 	 *
701 	 * NOTE: there is a race condition here with the pending timeout.  Look
702 	 * at the comments before hci1394_async_atreq_process() for more info.
703 	 */
704 	if (hcicmd->ac_state == HCI1394_CMD_STATE_PENDING) {
705 		/* remove this transfer from our the pending list */
706 		status = hci1394_tlist_delete(async_handle->as_pending_list,
707 		    &hcicmd->ac_plist_node);
708 		if (status != DDI_SUCCESS) {
709 			mutex_exit(&async_handle->as_atomic_lookup);
710 			return (DDI_SUCCESS);
711 		}
712 	}
713 
714 	/* allow pending timeout callback to mark tlabel as bad */
715 	mutex_exit(&async_handle->as_atomic_lookup);
716 
717 	/*
718 	 * We got a valid response that we were able to read in. Free the tlabel
719 	 * that was used for this transfer.
720 	 */
721 	hci1394_tlabel_free(async_handle->as_tlabel, &hcicmd->ac_tlabel);
722 
723 	/*
724 	 * Setup our return command status based on the RESP or ACK or SW error.
725 	 * See the IEEE1394-1995 spec (6.2.4.10 on pg. 159) for more information
726 	 * on response codes. See the OpenHCI 1.0 spec (table 3.2 on pg. 18) for
727 	 * more information about ACK/EVT's. ac_status could have an IEEE1394
728 	 * response in it, a 1394 EVT/ACK, or a special cmd1394 error for a
729 	 * device error caught in SW (e.g. for a block read request that got a
730 	 * quadlet read response). We use a special mask to separate the
731 	 * ACK/EVT's from the responses (ASYNC_ARRESP_ACK_ERROR).
732 	 */
733 	switch (hcicmd->ac_status) {
734 	case IEEE1394_RESP_COMPLETE:
735 		cmd_status = H1394_CMD_SUCCESS;
736 		break;
737 	case IEEE1394_RESP_DATA_ERROR:
738 		cmd_status = H1394_CMD_EDATA_ERROR;
739 		break;
740 	case IEEE1394_RESP_TYPE_ERROR:
741 		cmd_status = H1394_CMD_ETYPE_ERROR;
742 		break;
743 	case IEEE1394_RESP_CONFLICT_ERROR:
744 		cmd_status = H1394_CMD_ERSRC_CONFLICT;
745 		break;
746 	case IEEE1394_RESP_ADDRESS_ERROR:
747 		cmd_status = H1394_CMD_EADDR_ERROR;
748 		break;
749 	case H1394_CMD_EDEVICE_ERROR:
750 		cmd_status = H1394_CMD_EDEVICE_ERROR;
751 		break;
752 	case OHCI_ACK_DATA_ERROR | ASYNC_ARRESP_ACK_ERROR:
753 		cmd_status = H1394_CMD_EDATA_ERROR;
754 		break;
755 	case OHCI_ACK_TYPE_ERROR | ASYNC_ARRESP_ACK_ERROR:
756 		cmd_status = H1394_CMD_ETYPE_ERROR;
757 		break;
758 	case OHCI_EVT_UNDERRUN | ASYNC_ARRESP_ACK_ERROR:
759 	case OHCI_EVT_DATA_READ | ASYNC_ARRESP_ACK_ERROR:
760 	case OHCI_EVT_TCODE_ERR | ASYNC_ARRESP_ACK_ERROR:
761 		cmd_status = H1394_CMD_EUNKNOWN_ERROR;
762 		break;
763 	default:
764 		cmd_status = H1394_CMD_EUNKNOWN_ERROR;
765 		break;
766 	}
767 
768 	/*
769 	 * if we have already processed the atreq and put it on the pending Q
770 	 * (normal case), tell the services layer it completed.
771 	 */
772 	if (hcicmd->ac_state == HCI1394_CMD_STATE_PENDING) {
773 		/* Set state indicating that we are done with this cmd */
774 		hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
775 
776 		/* tell the services lyaer the command has completed */
777 		h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
778 		    hcicmd->ac_cmd, H1394_AT_REQ, cmd_status);
779 
780 	/*
781 	 * We have not seen the atreq status yet.  We will call
782 	 * h1394_command_is_complete() in atreq_process() in case we did not get
783 	 * an ack pending (target HW error -> this is based on real world
784 	 * experience :-))
785 	 */
786 	} else {
787 		/* Set state indicating that we are done with this cmd */
788 		hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
789 
790 		/* save away the status for atreq_process() */
791 		hcicmd->ac_status = cmd_status;
792 	}
793 
794 	return (DDI_SUCCESS);
795 }
796 
797 
798 /*
799  * hci1394_async_arreq_process()
800  *    Process an arreq, if one has arrived. This is called during interrupt
801  *    processing and will process an arreq that has arrived. It returns status
802  *    if an arreq was processed so that the ISR knows that it needs to be
803  *    called again to see if another ARREQ has arrived.
804  */
805 int
hci1394_async_arreq_process(hci1394_async_handle_t async_handle,boolean_t * request_available)806 hci1394_async_arreq_process(hci1394_async_handle_t async_handle,
807     boolean_t *request_available)
808 {
809 	hci1394_async_cmd_t *hcicmd;
810 	uint32_t *addr;
811 	uint_t tcode;
812 	uint_t size;
813 	int status;
814 
815 
816 	ASSERT(async_handle != NULL);
817 	ASSERT(request_available != NULL);
818 
819 	/*
820 	 * See if there were any requests on ARREQ Q. A NULL means there
821 	 * were no requests on the Q. This call does NOT free up space. We
822 	 * need to do that later after we figure out how much space the
823 	 * request takes up.
824 	 */
825 	hci1394_q_ar_next(async_handle->as_arreq_q, &addr);
826 	if (addr == NULL) {
827 		*request_available = B_FALSE;
828 		return (DDI_SUCCESS);
829 	}
830 
831 	/*
832 	 * We got a request. Read the request into a 1394 framework command.
833 	 * We could get a NULL for a command if we got a request with an error
834 	 * (i.e. ARREQ ACK was not ack pending or ack complete). This would be a
835 	 * successful read but with a NULL hcicmd returned. If we ever get a
836 	 * DDI_FAILURE, we will shutdown.
837 	 */
838 	*request_available = B_TRUE;
839 	status = hci1394_async_arreq_read(async_handle,
840 	    (hci1394_basic_pkt_t *)addr, &tcode, &hcicmd, &size);
841 	if (status != DDI_SUCCESS) {
842 		h1394_error_detected(async_handle->as_drvinfo->di_sl_private,
843 		    H1394_SELF_INITIATED_SHUTDOWN, NULL);
844 		cmn_err(CE_WARN, "hci1394(%d): driver shutdown: "
845 		    "unrecoverable error interrupt detected",
846 		    async_handle->as_drvinfo->di_instance);
847 		hci1394_shutdown(async_handle->as_drvinfo->di_dip);
848 		return (DDI_FAILURE);
849 	}
850 
851 	/* Free up the arreq Q space, we are done with the data */
852 	hci1394_q_ar_free(async_handle->as_arreq_q, size);
853 
854 	/*
855 	 * if we did not get a valid request (i.e. The ARREQ had a bad ACK
856 	 * or something like that) we don't have anything else to do.  We will
857 	 * say that we processed a request and will return successfully. We
858 	 * still may have other requests on the Q.
859 	 */
860 	if (hcicmd == NULL) {
861 		return (DDI_SUCCESS);
862 	}
863 
864 	/*
865 	 * If as_flushing_arreq is set, we do not want to send any requests up
866 	 * to the Services Layer. We are flushing the ARREQ until we see a bus
867 	 * reset token that matches the current bus generation. Free up the
868 	 * alloc'd command and return success.
869 	 */
870 	if (async_handle->as_flushing_arreq == B_TRUE) {
871 		hci1394_async_response_complete(async_handle, hcicmd->ac_cmd,
872 		    hcicmd->ac_priv);
873 		return (DDI_SUCCESS);
874 	}
875 
876 	/*
877 	 * We got a valid request that we were able to read in. Call into the
878 	 * services layer based on the type of request.
879 	 */
880 	switch (tcode) {
881 	case IEEE1394_TCODE_READ_QUADLET:
882 	case IEEE1394_TCODE_READ_BLOCK:
883 		h1394_read_request(async_handle->as_drvinfo->di_sl_private,
884 		    hcicmd->ac_cmd);
885 		break;
886 	case IEEE1394_TCODE_WRITE_QUADLET:
887 	case IEEE1394_TCODE_WRITE_BLOCK:
888 		h1394_write_request(async_handle->as_drvinfo->di_sl_private,
889 		    hcicmd->ac_cmd);
890 		break;
891 	case IEEE1394_TCODE_LOCK:
892 		h1394_lock_request(async_handle->as_drvinfo->di_sl_private,
893 		    hcicmd->ac_cmd);
894 		break;
895 	case IEEE1394_TCODE_PHY:
896 		/*
897 		 * OpenHCI only handles 1 PHY quadlet at a time. If a selfid
898 		 * packet was received with multiple quadlets, we will treat
899 		 * each quadlet as a separate call.  We do not notify the
900 		 * services layer through the normal command interface, we will
901 		 * treat it like a command internally and then free up the
902 		 * command ourselves when we are done with it.
903 		 */
904 		h1394_phy_packet(async_handle->as_drvinfo->di_sl_private,
905 		    &hcicmd->ac_cmd->cmd_u.q.quadlet_data, 1,
906 		    hcicmd->ac_priv->recv_tstamp);
907 		/* free alloc'd command */
908 		hci1394_async_response_complete(async_handle, hcicmd->ac_cmd,
909 		    hcicmd->ac_priv);
910 		break;
911 	default:
912 		/* free alloc'd command */
913 		hci1394_async_response_complete(async_handle, hcicmd->ac_cmd,
914 		    hcicmd->ac_priv);
915 		break;
916 	}
917 
918 	return (DDI_SUCCESS);
919 }
920 
921 
922 /*
923  * hci1394_async_atresp_process()
924  *    Process an atresp, if one has completed. This is called during interrupt
925  *    processing and will process a completed atresp. It returns status if an
926  *    atresp was processed so that the ISR knows that it needs to be called
927  *    again to see if another ATRESP has completed. flush_q set to B_TRUE tells
928  *    this routine to process all commands regardless of their completion
929  *    status.  This is used during bus reset processing to remove all commands
930  *    from the Q.
931  */
932 int
hci1394_async_atresp_process(hci1394_async_handle_t async_handle,boolean_t flush_q,boolean_t * response_available)933 hci1394_async_atresp_process(hci1394_async_handle_t async_handle,
934     boolean_t flush_q, boolean_t *response_available)
935 {
936 	hci1394_async_cmd_t *hcicmd;
937 	hci1394_q_cmd_t *qcmd;
938 	int cmd_status;
939 
940 
941 	ASSERT(async_handle != NULL);
942 	ASSERT(response_available != NULL);
943 
944 	/*
945 	 * Get the next ATRESP that has completed (if one has). Space is free'd
946 	 * up in atresp_q and atresp_data_q as part of this function call.
947 	 */
948 	hci1394_q_at_next(async_handle->as_atresp_q, flush_q, &qcmd);
949 
950 	/*
951 	 * See if there were anymore requests on ATRESP Q. A NULL means there
952 	 * were no completed commands left on the Q.
953 	 */
954 	if (qcmd == NULL) {
955 		*response_available = B_FALSE;
956 		return (DDI_SUCCESS);
957 	}
958 
959 	/* There is a completed ATRESP, setup the HAL command pointer */
960 	*response_available = B_TRUE;
961 	hcicmd = (hci1394_async_cmd_t *)qcmd->qc_arg;
962 
963 	/* save away the command completed timestamp for the services layer */
964 	hcicmd->ac_priv->ack_tstamp = qcmd->qc_timestamp;
965 
966 	/*
967 	 * setup our return command status based on the ACK from the HW. See the
968 	 * OpenHCI 1.0 spec (table 3.2 on pg. 18) for more information about
969 	 * these ACK/EVT's.
970 	 */
971 	switch (qcmd->qc_status) {
972 	case OHCI_ACK_COMPLETE:
973 		cmd_status = H1394_CMD_SUCCESS;
974 		break;
975 
976 	/*
977 	 * we can get a nostatus during a bus reset (i.e. we shutdown the AT
978 	 * engine before it flushed all the commands)
979 	 */
980 	case OHCI_EVT_FLUSHED:
981 	case OHCI_EVT_NO_STATUS:
982 		cmd_status = H1394_CMD_EBUSRESET;
983 		break;
984 
985 	case OHCI_EVT_MISSING_ACK:
986 	case OHCI_EVT_TIMEOUT:
987 		cmd_status = H1394_CMD_ETIMEOUT;
988 		break;
989 
990 	case OHCI_ACK_BUSY_X:
991 	case OHCI_ACK_BUSY_A:
992 	case OHCI_ACK_BUSY_B:
993 		cmd_status = H1394_CMD_EDEVICE_BUSY;
994 		break;
995 
996 	case OHCI_ACK_TARDY:
997 		cmd_status = H1394_CMD_EDEVICE_POWERUP;
998 		break;
999 
1000 	case OHCI_ACK_DATA_ERROR:
1001 		cmd_status = H1394_CMD_EDATA_ERROR;
1002 		break;
1003 
1004 	case OHCI_ACK_TYPE_ERROR:
1005 		cmd_status = H1394_CMD_ETYPE_ERROR;
1006 		break;
1007 
1008 	case OHCI_ACK_CONFLICT_ERROR:
1009 		cmd_status = H1394_CMD_ERSRC_CONFLICT;
1010 		break;
1011 
1012 	case OHCI_ACK_ADDRESS_ERROR:
1013 		cmd_status = H1394_CMD_EADDR_ERROR;
1014 		break;
1015 
1016 	case OHCI_EVT_UNKNOWN:
1017 		cmd_status = H1394_CMD_EUNKNOWN_ERROR;
1018 		break;
1019 
1020 	case OHCI_EVT_UNDERRUN:
1021 	case OHCI_EVT_DATA_READ:
1022 	case OHCI_EVT_TCODE_ERR:
1023 	case OHCI_EVT_DESCRIPTOR_READ:
1024 	default:
1025 		cmd_status = H1394_CMD_EUNKNOWN_ERROR;
1026 		break;
1027 	}
1028 
1029 	/* tell the services layer that the command has completed */
1030 	h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
1031 	    hcicmd->ac_cmd, H1394_AT_RESP, cmd_status);
1032 
1033 	return (DDI_SUCCESS);
1034 }
1035 
1036 
1037 /*
1038  * hci1394_async_arresp_read()
1039  *    Read ARRESP in from memory into 1394 Framework command. We read the tcode
1040  *    which tells us which kind of arresp the packet is, get the size of the
1041  *    response, read in the sender, tlabel, and response code, and then
1042  *    lookup the command based on the sender and tlabel. Once we get the command
1043  *    (corresponding to the ATREQ), we will copy the rest of the response into
1044  *    that command.
1045  *
1046  *    The only time this routine should return DDI_FAILURE is if it was unable
1047  *    to maintain a good state in the ARRESP Q (i.e. an unknown response was
1048  *    received and we can not cleanup after it.)  If we detect a recoverable
1049  *    error, and it doesn't make sense to pass the response up to the Services
1050  *    Layer, we should return DDI_SUCCESS with hcicmd = NULL.
1051  */
1052 static int
hci1394_async_arresp_read(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,uint_t * tcode,hci1394_async_cmd_t ** hcicmd,uint_t * size)1053 hci1394_async_arresp_read(hci1394_async_handle_t async_handle,
1054     hci1394_basic_pkt_t *pkt,  uint_t *tcode, hci1394_async_cmd_t **hcicmd,
1055     uint_t *size)
1056 {
1057 	hci1394_tlabel_info_t ac_tlabel;
1058 	h1394_cmd_priv_t *cmd_priv;
1059 	cmd1394_cmd_t *cmd;
1060 	uint32_t *status_addr;
1061 	uint_t data_length;
1062 	uint32_t quadlet;
1063 	void *command;
1064 	uint_t rcode;
1065 	uint_t ack;
1066 	int status;
1067 
1068 
1069 	ASSERT(async_handle != NULL);
1070 	ASSERT(pkt != NULL);
1071 	ASSERT(tcode != NULL);
1072 	ASSERT(hcicmd != NULL);
1073 	ASSERT(size != NULL);
1074 
1075 	/* read in the arresp tcode */
1076 	quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, &pkt->q1);
1077 	*tcode = HCI1394_DESC_TCODE_GET(quadlet);
1078 
1079 	/* Get the size of the arresp */
1080 	status = hci1394_async_arresp_size_get(*tcode,
1081 	    async_handle->as_arresp_q, &pkt->q1, size);
1082 	if (status != DDI_SUCCESS) {
1083 		return (DDI_FAILURE);
1084 	}
1085 
1086 	/* Read in the tlabel, destination, and rcode (response code) */
1087 	quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, &pkt->q1);
1088 	ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1089 	quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, &pkt->q2);
1090 	ac_tlabel.tbi_destination = HCI1394_DESC_DESTID_GET(quadlet);
1091 	rcode = HCI1394_DESC_RCODE_GET(quadlet);
1092 
1093 	/* Lookup the ATREQ framework command this response goes with */
1094 	hci1394_tlabel_lookup(async_handle->as_tlabel, &ac_tlabel, &command);
1095 
1096 	/*
1097 	 * If there is not a cooresponding ATREQ command, this is an error. We
1098 	 * will ignore this response but still return success so we cleanup
1099 	 * after it and go on with other arresp's. This could happend if a
1100 	 * response was sent after the command has timed out or if the target
1101 	 * device is misbehaving. (we have seen both cases)
1102 	 */
1103 	*hcicmd = (hci1394_async_cmd_t *)command;
1104 	if ((*hcicmd) == NULL) {
1105 		return (DDI_SUCCESS);
1106 	}
1107 
1108 	/*
1109 	 * copy the response code into the hal private command space. Setup
1110 	 * shortcuts to the 1394 framework command (cmd) and the HAL/SL private
1111 	 * area (cmd_priv). A command is made up of 4 parts. There is the public
1112 	 * part which is accessable to the target driver, there is the Services
1113 	 * Layer private part which is only accessible to the services layer,
1114 	 * there is the SL/HAL private area which is where the SL and HAL share
1115 	 * information about a particular command, and there is the HAL private
1116 	 * area where we keep track of our command specific state information.
1117 	 */
1118 	(*hcicmd)->ac_status = rcode;
1119 	cmd = (*hcicmd)->ac_cmd;
1120 	cmd_priv = (*hcicmd)->ac_priv;
1121 
1122 	/*
1123 	 * Calculate the address where the status of the ARRESP and timestamp is
1124 	 * kept at.  It is the last quadlet in the response. Save away the
1125 	 * timestamp.
1126 	 */
1127 	status_addr = (uint32_t *)((uintptr_t)pkt + (uintptr_t)*size -
1128 	    (uintptr_t)IEEE1394_QUADLET);
1129 	quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, status_addr);
1130 	cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1131 
1132 	/*
1133 	 * if we did not get an ACK_COMPLETE, we will use the ack error instead
1134 	 * of the response in the packet for our status. We use special mask to
1135 	 * separate the reponses from the ACKs (ASYNC_ARRESP_ACK_ERROR). We will
1136 	 * return success with hcicmd set to the command so that this error gets
1137 	 * sent up to the Services Layer.
1138 	 */
1139 	ack = HCI1394_DESC_EVT_GET(quadlet);
1140 	if (ack != OHCI_ACK_COMPLETE) {
1141 		/* use the ack error instead of rcode for the command status */
1142 		(*hcicmd)->ac_status = ack | ASYNC_ARRESP_ACK_ERROR;
1143 		return (DDI_SUCCESS);
1144 	}
1145 
1146 	/*
1147 	 * If we get to this point we have gotten a valid ACK on the response
1148 	 * and have matched up the response with an ATREQ. Now we check the
1149 	 * response code. If it is not resp_complete, we do not have anything
1150 	 * left to look at in the response. Return successfully.
1151 	 */
1152 	if (rcode != IEEE1394_RESP_COMPLETE) {
1153 		return (DDI_SUCCESS);
1154 	}
1155 
1156 	/*
1157 	 * Read the rest of the response (based on which kind of response it is)
1158 	 * into the 1394 framework command. In all of the different responses,
1159 	 * we check to make sure the response matches the original request. We
1160 	 * originally did not have this check but found a device or two which
1161 	 * did not behave very well and would cause us to corrupt our commands.
1162 	 * Now we check :-) We will return success when we get this error since
1163 	 * we can recover from it.
1164 	 */
1165 	switch (*tcode) {
1166 	case IEEE1394_TCODE_WRITE_RESP:
1167 		/*
1168 		 * make sure the ATREQ was a quadlet/block write. The same
1169 		 * response is sent back for those two type of ATREQs.
1170 		 */
1171 		if ((cmd->cmd_type != CMD1394_ASYNCH_WR_QUAD) &&
1172 		    (cmd->cmd_type != CMD1394_ASYNCH_WR_BLOCK)) {
1173 			(*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1174 			return (DDI_SUCCESS);
1175 		}
1176 		break;
1177 
1178 	case IEEE1394_TCODE_READ_QUADLET_RESP:
1179 		/* make sure the ATREQ was a quadlet read */
1180 		if (cmd->cmd_type != CMD1394_ASYNCH_RD_QUAD) {
1181 			(*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1182 			return (DDI_SUCCESS);
1183 		}
1184 
1185 		/*
1186 		 * read the quadlet read response in.  Data is treated as a byte
1187 		 * stream.
1188 		 */
1189 		hci1394_q_ar_rep_get8(async_handle->as_arresp_q,
1190 		    (uint8_t *)&cmd->cmd_u.q.quadlet_data,
1191 		    (uint8_t *)&pkt->q4, IEEE1394_QUADLET);
1192 		break;
1193 
1194 	case IEEE1394_TCODE_READ_BLOCK_RESP:
1195 		/* make sure the ATREQ was a block read */
1196 		if (cmd->cmd_type != CMD1394_ASYNCH_RD_BLOCK) {
1197 			(*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1198 			return (DDI_SUCCESS);
1199 		}
1200 
1201 		/*
1202 		 * read in the data length.  Make sure the data length is the
1203 		 * same size as the read block request size that went out.
1204 		 */
1205 		quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q,
1206 		    &pkt->q4);
1207 		data_length = HCI1394_DESC_DATALEN_GET(quadlet);
1208 		if (data_length != cmd_priv->mblk.length) {
1209 			(*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1210 			return (DDI_SUCCESS);
1211 		}
1212 
1213 		/* Copy the read block data into the command mblk */
1214 		hci1394_q_ar_copy_to_mblk(async_handle->as_arresp_q,
1215 		    (uint8_t *)&pkt->q5, &cmd_priv->mblk);
1216 		break;
1217 
1218 	case IEEE1394_TCODE_LOCK_RESP:
1219 		/* read in the data length */
1220 		quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q,
1221 		    &pkt->q4);
1222 		data_length = HCI1394_DESC_DATALEN_GET(quadlet);
1223 
1224 		if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
1225 			/*
1226 			 * read in the data length.  Make sure the data length
1227 			 * is the valid for a lock32 response (1 quadlet)
1228 			 */
1229 			if (data_length != IEEE1394_QUADLET) {
1230 				(*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1231 				return (DDI_SUCCESS);
1232 			}
1233 
1234 			/*
1235 			 * read the lock32 response in. Data is treated as a
1236 			 * byte stream unless it is an arithmetic lock
1237 			 * operation. In that case we treat data like a 32-bit
1238 			 * word.
1239 			 */
1240 			hci1394_q_ar_rep_get8(async_handle->as_arresp_q,
1241 			    (uint8_t *)&cmd->cmd_u.l32.old_value,
1242 			    (uint8_t *)&pkt->q5, IEEE1394_QUADLET);
1243 			cmd->cmd_u.l32.old_value = HCI1394_ARITH_LOCK_SWAP32(
1244 			    cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.old_value);
1245 
1246 		} else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
1247 			/*
1248 			 * read in the data length.  Make sure the data length
1249 			 * is the valid for a lock64 response (1 octlet)
1250 			 */
1251 			if (data_length != IEEE1394_OCTLET) {
1252 				(*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1253 				return (DDI_SUCCESS);
1254 			}
1255 
1256 			/*
1257 			 * read the lock64 response in. Data is treated as a
1258 			 * byte stream unless it is an arithmetic lock
1259 			 * operation. In that case we treat data like a 64-bit
1260 			 * word.
1261 			 */
1262 			hci1394_q_ar_rep_get8(async_handle->as_arresp_q,
1263 			    (uint8_t *)&cmd->cmd_u.l64.old_value,
1264 			    (uint8_t *)&pkt->q5, IEEE1394_OCTLET);
1265 			cmd->cmd_u.l64.old_value = HCI1394_ARITH_LOCK_SWAP64(
1266 			    cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.old_value);
1267 
1268 		/*
1269 		 * we sent out a request that was NOT a lock request and got
1270 		 * back a lock response.
1271 		 */
1272 		} else {
1273 			(*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1274 			return (DDI_SUCCESS);
1275 		}
1276 		break;
1277 
1278 	default:
1279 		/* we got a tcode that we don't know about. Return error */
1280 		return (DDI_FAILURE);
1281 	}
1282 
1283 	return (DDI_SUCCESS);
1284 }
1285 
1286 
1287 /*
1288  * hci1394_async_arreq_read()
1289  *    Read ARREQ in from memory into a 1394 Framework command. Allocate a 1394
1290  *    framework command, read in the ARREQ, and before passing it up to the
1291  *    services layer, see if it was a valid broadcast request.
1292  *
1293  *    The only time this routine should return DDI_FAILURE is if it was unable
1294  *    to maintain a good state in the ARREQ Q (i.e. an unknown request was
1295  *    received and we can not cleanup after it.)  If we detect a recoverable
1296  *    error we should return DDI_SUCCESS with hcicmd = NULL.
1297  */
1298 static int
hci1394_async_arreq_read(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,uint_t * tcode,hci1394_async_cmd_t ** hcicmd,uint_t * size)1299 hci1394_async_arreq_read(hci1394_async_handle_t async_handle,
1300     hci1394_basic_pkt_t *pkt, uint_t *tcode, hci1394_async_cmd_t **hcicmd,
1301     uint_t *size)
1302 {
1303 	h1394_cmd_priv_t *cmd_priv;
1304 	boolean_t is_reset_token;
1305 	cmd1394_cmd_t *cmd;
1306 	uint32_t quadlet;
1307 	int status;
1308 
1309 
1310 	ASSERT(async_handle != NULL);
1311 	ASSERT(pkt != NULL);
1312 	ASSERT(tcode != NULL);
1313 	ASSERT(hcicmd != NULL);
1314 	ASSERT(size != NULL);
1315 
1316 	/* read in the arresp tcode */
1317 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1318 	*tcode = HCI1394_DESC_TCODE_GET(quadlet);
1319 
1320 	/*
1321 	 * Allocated 1394 framework command.  The Services layer takes care of
1322 	 * cacheing commands. This is called during interrupt processing so we
1323 	 * do not want to sleep.
1324 	 */
1325 	status = h1394_alloc_cmd(async_handle->as_drvinfo->di_sl_private,
1326 	    H1394_ALLOC_CMD_NOSLEEP, &cmd, &cmd_priv);
1327 	if (status != DDI_SUCCESS) {
1328 		return (DDI_FAILURE);
1329 	}
1330 
1331 	/* Initialize the HAL private command info */
1332 	hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, hcicmd);
1333 
1334 	/*
1335 	 * There are two generations in the command structure, one in the public
1336 	 * space and one in the HAL/SL private shared space. We need to fill in
1337 	 * both.  We only use the private one internally.
1338 	 */
1339 	cmd_priv->bus_generation = async_handle->as_drvinfo->di_gencnt;
1340 	cmd->bus_generation = async_handle->as_drvinfo->di_gencnt;
1341 
1342 	/*
1343 	 * Read the request (based on which kind of request it is) into the 1394
1344 	 * framework command.
1345 	 */
1346 	switch (*tcode) {
1347 	case IEEE1394_TCODE_READ_QUADLET:
1348 		/*
1349 		 * We got a ARREQ quadlet read request. Read in the packet.
1350 		 * If there is a problem with the packet (i.e. we don't get
1351 		 * DDI_SUCCESS), we will free up the command and return NULL in
1352 		 * hcicmd to indicate that we did not get a valid ARREQ to
1353 		 * process.
1354 		 */
1355 		status = hci1394_async_arreq_read_qrd(async_handle, pkt,
1356 		    *hcicmd, size);
1357 		if (status != DDI_SUCCESS) {
1358 			hci1394_async_response_complete(async_handle, cmd,
1359 			    cmd_priv);
1360 			*hcicmd = NULL;
1361 			return (DDI_SUCCESS);
1362 		}
1363 		break;
1364 
1365 	case IEEE1394_TCODE_WRITE_QUADLET:
1366 		/*
1367 		 * We got a ARREQ quadlet write request. Read in the packet.
1368 		 * If there is a problem with the packet (i.e. we don't get
1369 		 * DDI_SUCCESS), we will free up the command and return NULL in
1370 		 * hcicmd to indicate that we did not get a valid ARREQ to
1371 		 * process.
1372 		 */
1373 		status = hci1394_async_arreq_read_qwr(async_handle, pkt,
1374 		    *hcicmd, size);
1375 		if (status != DDI_SUCCESS) {
1376 			hci1394_async_response_complete(async_handle, cmd,
1377 			    cmd_priv);
1378 			*hcicmd = NULL;
1379 			return (DDI_SUCCESS);
1380 		}
1381 		break;
1382 
1383 	case IEEE1394_TCODE_READ_BLOCK:
1384 		/*
1385 		 * We got a ARREQ block read request. Read in the packet.
1386 		 * If there is a problem with the packet (i.e. we don't get
1387 		 * DDI_SUCCESS), we will free up the command and return NULL in
1388 		 * hcicmd to indicate that we did not get a valid ARREQ to
1389 		 * process.
1390 		 */
1391 		status = hci1394_async_arreq_read_brd(async_handle, pkt,
1392 		    *hcicmd, size);
1393 		if (status != DDI_SUCCESS) {
1394 			hci1394_async_response_complete(async_handle, cmd,
1395 			    cmd_priv);
1396 			*hcicmd = NULL;
1397 			return (DDI_SUCCESS);
1398 		}
1399 		break;
1400 
1401 	case IEEE1394_TCODE_WRITE_BLOCK:
1402 		/*
1403 		 * We got a ARREQ block write request. Read in the packet.
1404 		 * If there is a problem with the packet (i.e. we don't get
1405 		 * DDI_SUCCESS), we will free up the command and return NULL in
1406 		 * hcicmd to indicate that we did not get a valid ARREQ to
1407 		 * process.
1408 		 */
1409 		status = hci1394_async_arreq_read_bwr(async_handle, pkt,
1410 		    *hcicmd, size);
1411 		if (status != DDI_SUCCESS) {
1412 			hci1394_async_response_complete(async_handle, cmd,
1413 			    cmd_priv);
1414 			*hcicmd = NULL;
1415 			return (DDI_SUCCESS);
1416 		}
1417 		break;
1418 
1419 	case IEEE1394_TCODE_LOCK:
1420 		/*
1421 		 * We got a ARREQ lock request. Read in the packet.
1422 		 * If there is a problem with the packet (i.e. we don't get
1423 		 * DDI_SUCCESS), we will free up the command and return NULL in
1424 		 * hcicmd to indicate that we did not get a valid ARREQ to
1425 		 * process.
1426 		 */
1427 		status = hci1394_async_arreq_read_lck(async_handle, pkt,
1428 		    *hcicmd, size);
1429 		if (status != DDI_SUCCESS) {
1430 			hci1394_async_response_complete(async_handle, cmd,
1431 			    cmd_priv);
1432 			*hcicmd = NULL;
1433 			return (DDI_SUCCESS);
1434 		}
1435 		break;
1436 
1437 	case IEEE1394_TCODE_PHY:
1438 		/*
1439 		 * We got a PHY packet in the ARREQ buffer. Read in the packet.
1440 		 * If there is a problem with the packet (i.e. we don't get
1441 		 * DDI_SUCCESS), we will free up the command and return NULL in
1442 		 * hcicmd to indicate that we did not get a valid ARREQ to
1443 		 * process.
1444 		 */
1445 		status = hci1394_async_arreq_read_phy(async_handle, pkt,
1446 		    *hcicmd, size, &is_reset_token);
1447 		if (status != DDI_SUCCESS) {
1448 			hci1394_async_response_complete(async_handle, cmd,
1449 			    cmd_priv);
1450 			*hcicmd = NULL;
1451 			return (DDI_SUCCESS);
1452 		}
1453 
1454 		/*
1455 		 * If we got a bus reset token, free up the command and return
1456 		 * NULL in hcicmd to indicate that we did not get a valid ARREQ
1457 		 * to process.
1458 		 */
1459 		if (is_reset_token == B_TRUE) {
1460 			hci1394_async_response_complete(async_handle, cmd,
1461 			    cmd_priv);
1462 			*hcicmd = NULL;
1463 			return (DDI_SUCCESS);
1464 		}
1465 		break;
1466 
1467 	default:
1468 		/* we got a tcode that we don't know about. Return error */
1469 		return (DDI_FAILURE);
1470 	}
1471 
1472 	/*
1473 	 * If this command was broadcast and it was not a write, drop the
1474 	 * command since it's an invalid request. We will free up the command
1475 	 * and return NULL in hcicmd to indicate that we did not get a valid
1476 	 * ARREQ to process.
1477 	 */
1478 	if ((((*hcicmd)->ac_dest & IEEE1394_NODE_NUM_MASK) ==
1479 	    IEEE1394_BROADCAST_NODEID) && ((*tcode !=
1480 	    IEEE1394_TCODE_WRITE_QUADLET) && (*tcode !=
1481 	    IEEE1394_TCODE_WRITE_BLOCK))) {
1482 		hci1394_async_response_complete(async_handle, cmd, cmd_priv);
1483 		*hcicmd = NULL;
1484 		return (DDI_SUCCESS);
1485 
1486 	/*
1487 	 * It is a valid broadcast command, set that field in the public
1488 	 * command structure.
1489 	 */
1490 	} else if ((((*hcicmd)->ac_dest & IEEE1394_NODE_NUM_MASK) ==
1491 	    IEEE1394_BROADCAST_NODEID)) {
1492 		cmd->broadcast = 1;
1493 	}
1494 
1495 	return (DDI_SUCCESS);
1496 }
1497 
1498 
1499 /*
1500  * hci1394_async_arreq_read_qrd()
1501  *    Read ARREQ quadlet read into the 1394 Framework command. This routine will
1502  *    return DDI_FAILURE if it was not able to read the request succesfully.
1503  */
1504 static int
hci1394_async_arreq_read_qrd(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,hci1394_async_cmd_t * hcicmd,uint_t * size)1505 hci1394_async_arreq_read_qrd(hci1394_async_handle_t async_handle,
1506     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1507 {
1508 	h1394_cmd_priv_t *cmd_priv;
1509 	cmd1394_cmd_t *cmd;
1510 	uint32_t quadlet;
1511 
1512 
1513 	ASSERT(async_handle != NULL);
1514 	ASSERT(pkt != NULL);
1515 	ASSERT(hcicmd != NULL);
1516 	ASSERT(size != NULL);
1517 
1518 	/* Setup shortcuts, command type, and size of request */
1519 	cmd = hcicmd->ac_cmd;
1520 	cmd_priv = hcicmd->ac_priv;
1521 	cmd->cmd_type = CMD1394_ASYNCH_RD_QUAD;
1522 	*size = DESC_SZ_AR_READQUAD_REQ;
1523 
1524 	/*
1525 	 * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1526 	 * calculate the ATRESP timeout for when we send it.
1527 	 */
1528 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
1529 	hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1530 	cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1531 	cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1532 	hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1533 	    cmd_priv->recv_tstamp);
1534 
1535 	/*
1536 	 * if the ARREQ ACK was bad, we were unable to successfully read in this
1537 	 * request.  Return failure.
1538 	 */
1539 	if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1540 	    (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1541 		return (DDI_FAILURE);
1542 	}
1543 
1544 	/*
1545 	 * Read in the tlabel and destination. We don't use an mblk for this
1546 	 * request.
1547 	 */
1548 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1549 	hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
1550 	hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1551 	hcicmd->ac_mblk_alloc = B_FALSE;
1552 
1553 	/*
1554 	 * Read in the sender so we know who to send the ATRESP to and read in
1555 	 * the 1394 48-bit address for this request.
1556 	 */
1557 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1558 	cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
1559 	cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
1560 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1561 	cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
1562 
1563 	return (DDI_SUCCESS);
1564 }
1565 
1566 
1567 /*
1568  * hci1394_async_arreq_read_qwr()
1569  *    Read ARREQ quadlet write into the 1394 Framework command. This routine
1570  *    will return DDI_FAILURE if it was not able to read the request
1571  *    succesfully.
1572  */
1573 static int
hci1394_async_arreq_read_qwr(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,hci1394_async_cmd_t * hcicmd,uint_t * size)1574 hci1394_async_arreq_read_qwr(hci1394_async_handle_t async_handle,
1575     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1576 {
1577 	h1394_cmd_priv_t *cmd_priv;
1578 	cmd1394_cmd_t *cmd;
1579 	uint32_t quadlet;
1580 
1581 
1582 	ASSERT(async_handle != NULL);
1583 	ASSERT(pkt != NULL);
1584 	ASSERT(hcicmd != NULL);
1585 	ASSERT(size != NULL);
1586 
1587 	/* Setup shortcuts, command type, and size of request */
1588 	cmd = hcicmd->ac_cmd;
1589 	cmd_priv = hcicmd->ac_priv;
1590 	cmd->cmd_type = CMD1394_ASYNCH_WR_QUAD;
1591 	*size = DESC_SZ_AR_WRITEQUAD_REQ;
1592 
1593 	/*
1594 	 * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1595 	 * calculate the ATRESP timeout for when we send it.
1596 	 */
1597 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q5);
1598 	hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1599 	cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1600 	cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1601 	hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1602 	    cmd_priv->recv_tstamp);
1603 
1604 	/*
1605 	 * if the ARREQ ACK was bad, we were unable to successfully read in this
1606 	 * request.  Return failure.
1607 	 */
1608 	if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1609 	    (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1610 		return (DDI_FAILURE);
1611 	}
1612 
1613 	/*
1614 	 * Read in the tlabel and destination. We don't use an mblk for this
1615 	 * request.
1616 	 */
1617 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1618 	hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
1619 	hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1620 	hcicmd->ac_mblk_alloc = B_FALSE;
1621 
1622 	/*
1623 	 * Read in the sender so we know who to send the ATRESP to. Read in
1624 	 * the 1394 48-bit address for this request. Copy the data quadlet into
1625 	 * the command.  The data quadlet is treated like a byte stream.
1626 	 */
1627 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1628 	cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
1629 	cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
1630 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1631 	cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
1632 	hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
1633 	    (uint8_t *)&cmd->cmd_u.q.quadlet_data, (uint8_t *)&pkt->q4,
1634 	    IEEE1394_QUADLET);
1635 
1636 	return (DDI_SUCCESS);
1637 }
1638 
1639 
1640 /*
1641  * hci1394_async_arreq_read_brd()
1642  *    Read ARREQ block read into the 1394 Framework command. This routine will
1643  *    return DDI_FAILURE if it was not able to read the request succesfully.
1644  */
1645 static int
hci1394_async_arreq_read_brd(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,hci1394_async_cmd_t * hcicmd,uint_t * size)1646 hci1394_async_arreq_read_brd(hci1394_async_handle_t async_handle,
1647     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1648 {
1649 	h1394_cmd_priv_t *cmd_priv;
1650 	cmd1394_cmd_t *cmd;
1651 	uint32_t quadlet;
1652 
1653 
1654 	ASSERT(async_handle != NULL);
1655 	ASSERT(pkt != NULL);
1656 	ASSERT(hcicmd != NULL);
1657 	ASSERT(size != NULL);
1658 
1659 	/* Setup shortcuts, command type, and size of request */
1660 	cmd = hcicmd->ac_cmd;
1661 	cmd_priv = hcicmd->ac_priv;
1662 	cmd->cmd_type = CMD1394_ASYNCH_RD_BLOCK;
1663 	*size = DESC_SZ_AR_READBLOCK_REQ;
1664 
1665 	/*
1666 	 * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1667 	 * calculate the ATRESP timeout for when we send it.
1668 	 */
1669 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q5);
1670 	hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1671 	cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1672 	cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1673 	hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1674 	    cmd_priv->recv_tstamp);
1675 
1676 	/*
1677 	 * if the ARREQ ACK was bad, we were unable to successfully read in this
1678 	 * request.  Return failure.
1679 	 */
1680 	if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1681 	    (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1682 		return (DDI_FAILURE);
1683 	}
1684 
1685 	/* Read in the tlabel and destination */
1686 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1687 	hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
1688 	hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1689 
1690 	/*
1691 	 * Read in the sender so we know who to send the ATRESP to. Read in
1692 	 * the 1394 48-bit address for this request. Read in the block data size
1693 	 * and allocate an mblk of that size.
1694 	 */
1695 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1696 	cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
1697 	cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
1698 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1699 	cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
1700 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
1701 	cmd->cmd_u.b.blk_length = HCI1394_DESC_DATALEN_GET(quadlet);
1702 	cmd->cmd_u.b.data_block = allocb(cmd->cmd_u.b.blk_length, 0);
1703 	if (cmd->cmd_u.b.data_block == NULL) {
1704 		return (DDI_FAILURE);
1705 	}
1706 	hcicmd->ac_mblk_alloc = B_TRUE;
1707 
1708 	return (DDI_SUCCESS);
1709 }
1710 
1711 
1712 /*
1713  * hci1394_async_arreq_read_bwr()
1714  *    Read ARREQ block write into the 1394 Framework command. This routine will
1715  *    return DDI_FAILURE if it was not able to read the request succesfully.
1716  */
1717 static int
hci1394_async_arreq_read_bwr(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,hci1394_async_cmd_t * hcicmd,uint_t * size)1718 hci1394_async_arreq_read_bwr(hci1394_async_handle_t async_handle,
1719     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1720 {
1721 	h1394_cmd_priv_t *cmd_priv;
1722 	uint32_t *local_addr;
1723 	cmd1394_cmd_t *cmd;
1724 	uint32_t quadlet;
1725 
1726 
1727 	ASSERT(async_handle != NULL);
1728 	ASSERT(pkt != NULL);
1729 	ASSERT(hcicmd != NULL);
1730 	ASSERT(size != NULL);
1731 
1732 	/*
1733 	 * Setup shortcuts, command type, and size of request. The size of the
1734 	 * request is in quadlets, therefore we need to make sure we count in
1735 	 * the padding when figureing out the size (i.e. data may be in bytes
1736 	 * but the HW always pads to quadlets)
1737 	 */
1738 	cmd = hcicmd->ac_cmd;
1739 	cmd_priv = hcicmd->ac_priv;
1740 	cmd->cmd_type = CMD1394_ASYNCH_WR_BLOCK;
1741 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
1742 	cmd->cmd_u.b.blk_length = HCI1394_DESC_DATALEN_GET(quadlet);
1743 	*size = DESC_SZ_AR_WRITEBLOCK_REQ +
1744 	    HCI1394_ALIGN_QUAD(cmd->cmd_u.b.blk_length);
1745 
1746 	/*
1747 	 * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1748 	 * calculate the ATRESP timeout for when we send it. The status word is
1749 	 * the last quadlet in the packet.
1750 	 */
1751 	local_addr = (uint32_t *)(((uintptr_t)(&pkt->q5)) +
1752 	    ((uintptr_t)HCI1394_ALIGN_QUAD(cmd->cmd_u.b.blk_length)));
1753 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, local_addr);
1754 	hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1755 	cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1756 	cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1757 	hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1758 	    cmd_priv->recv_tstamp);
1759 
1760 	/*
1761 	 * if the ARREQ ACK was bad, we were unable to successfully read in this
1762 	 * request.  Return failure.
1763 	 */
1764 	if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1765 	    (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1766 		return (DDI_FAILURE);
1767 	}
1768 
1769 	/* Read in the tlabel and destination */
1770 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1771 	hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
1772 	hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1773 
1774 	/*
1775 	 * Read in the sender so we know who to send the ATRESP to. Read in
1776 	 * the 1394 48-bit address for this request. Read in the block data size
1777 	 * and allocate an mblk of that size.
1778 	 */
1779 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1780 	cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
1781 	cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
1782 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1783 	cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
1784 	cmd->cmd_u.b.data_block = allocb(cmd->cmd_u.b.blk_length, 0);
1785 	if (cmd->cmd_u.b.data_block == NULL) {
1786 		return (DDI_FAILURE);
1787 	}
1788 	hcicmd->ac_mblk_alloc = B_TRUE;
1789 
1790 	/* Copy ARREQ write data into mblk_t */
1791 	hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
1792 	    (uint8_t *)cmd->cmd_u.b.data_block->b_wptr,
1793 	    (uint8_t *)&pkt->q5, cmd->cmd_u.b.blk_length);
1794 
1795 	/* Update mblk_t wptr */
1796 	cmd->cmd_u.b.data_block->b_wptr += cmd->cmd_u.b.blk_length;
1797 
1798 	return (DDI_SUCCESS);
1799 }
1800 
1801 
1802 /*
1803  * hci1394_async_arreq_read_lck()
1804  *    Read ARREQ lock request into the 1394 Framework command. This routine will
1805  *    return DDI_FAILURE if it was not able to read the request succesfully.
1806  */
1807 static int
hci1394_async_arreq_read_lck(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,hci1394_async_cmd_t * hcicmd,uint_t * size)1808 hci1394_async_arreq_read_lck(hci1394_async_handle_t async_handle,
1809     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1810 {
1811 	h1394_cmd_priv_t *cmd_priv;
1812 	uint32_t *local_addr;
1813 	cmd1394_cmd_t *cmd;
1814 	uint8_t *data_addr;
1815 	uint32_t quadlet;
1816 	uint32_t length;
1817 
1818 
1819 	ASSERT(async_handle != NULL);
1820 	ASSERT(pkt != NULL);
1821 	ASSERT(hcicmd != NULL);
1822 	ASSERT(size != NULL);
1823 
1824 	/*
1825 	 * Setup shortcuts, command type, and size of request. The size of the
1826 	 * request is in quadlets, therefore we need to make sure we count in
1827 	 * the padding when figuring out the size (i.e. data may be in bytes
1828 	 * but the HW always pads to quadlets)
1829 	 */
1830 	cmd = hcicmd->ac_cmd;
1831 	cmd_priv = hcicmd->ac_priv;
1832 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
1833 	length = HCI1394_DESC_DATALEN_GET(quadlet);
1834 	*size = DESC_SZ_AR_LOCK_REQ + HCI1394_ALIGN_QUAD(length);
1835 
1836 	/* make sure the length is a valid lock request length */
1837 	if (length == DESC_TWO_QUADS) {
1838 		cmd->cmd_type = CMD1394_ASYNCH_LOCK_32;
1839 		cmd->cmd_u.l32.lock_type = HCI1394_DESC_EXTTCODE_GET(quadlet);
1840 	} else if (length == DESC_TWO_OCTLETS) {
1841 		cmd->cmd_type = CMD1394_ASYNCH_LOCK_64;
1842 		cmd->cmd_u.l64.lock_type = HCI1394_DESC_EXTTCODE_GET(quadlet);
1843 	} else {
1844 		return (DDI_FAILURE);
1845 	}
1846 
1847 	/*
1848 	 * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1849 	 * calculate the ATRESP timeout for when we send it. The status word is
1850 	 * the last quadlet in the packet.
1851 	 */
1852 	local_addr = (uint32_t *)(((uintptr_t)(&pkt->q5)) +
1853 	    ((uintptr_t)HCI1394_ALIGN_QUAD(length)));
1854 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, local_addr);
1855 	hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1856 	cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1857 	cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1858 	hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1859 	    cmd_priv->recv_tstamp);
1860 
1861 	/*
1862 	 * if the ARREQ ACK was bad, we were unable to successfully read in this
1863 	 * request.  Return failure.
1864 	 */
1865 	if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1866 	    (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1867 		return (DDI_FAILURE);
1868 	}
1869 
1870 	/* Read in the tlabel and destination */
1871 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1872 	hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
1873 	hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1874 	hcicmd->ac_mblk_alloc = B_FALSE;
1875 
1876 	/*
1877 	 * Read in the sender so we know who to send the ATRESP to. Read in
1878 	 * the 1394 48-bit address for this request.
1879 	 */
1880 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1881 	cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
1882 	cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
1883 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1884 	cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
1885 
1886 	/* Copy ARREQ lock data into 1394 framework command */
1887 	if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
1888 		data_addr = (uint8_t *)&pkt->q5;
1889 		hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
1890 		    (uint8_t *)&cmd->cmd_u.l32.arg_value, data_addr,
1891 		    IEEE1394_QUADLET);
1892 		data_addr = (uint8_t *)((uintptr_t)data_addr +
1893 		    (uintptr_t)IEEE1394_QUADLET);
1894 		hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
1895 		    (uint8_t *)&cmd->cmd_u.l32.data_value, data_addr,
1896 		    IEEE1394_QUADLET);
1897 		/*
1898 		 * swap these for our correct architecture if we are doing
1899 		 * arithmetic lock operations
1900 		 */
1901 		cmd->cmd_u.l32.arg_value = HCI1394_ARITH_LOCK_SWAP32(
1902 		    cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.arg_value);
1903 		cmd->cmd_u.l32.data_value = HCI1394_ARITH_LOCK_SWAP32(
1904 		    cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.data_value);
1905 	} else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
1906 		data_addr = (uint8_t *)&pkt->q5;
1907 		hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
1908 		    (uint8_t *)&cmd->cmd_u.l64.arg_value, data_addr,
1909 		    IEEE1394_OCTLET);
1910 		data_addr = (uint8_t *)((uintptr_t)data_addr +
1911 		    (uintptr_t)IEEE1394_OCTLET);
1912 		hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
1913 		    (uint8_t *)&cmd->cmd_u.l64.data_value, data_addr,
1914 		    IEEE1394_OCTLET);
1915 
1916 		/*
1917 		 * swap these for our correct architecture if we are doing
1918 		 * arithmetic lock operations
1919 		 */
1920 		cmd->cmd_u.l64.arg_value = HCI1394_ARITH_LOCK_SWAP64(
1921 		    cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.arg_value);
1922 		cmd->cmd_u.l64.data_value = HCI1394_ARITH_LOCK_SWAP64(
1923 		    cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.data_value);
1924 	}
1925 
1926 	return (DDI_SUCCESS);
1927 }
1928 
1929 
1930 /*
1931  * hci1394_async_arreq_read_phy()
1932  *    Read ARREQ PHY quadlet into the 1394 Framework command. This routine will
1933  *    return DDI_FAILURE if it was not able to read the request succesfully.
1934  */
1935 static int
hci1394_async_arreq_read_phy(hci1394_async_handle_t async_handle,hci1394_basic_pkt_t * pkt,hci1394_async_cmd_t * hcicmd,uint_t * size,boolean_t * bus_reset_token)1936 hci1394_async_arreq_read_phy(hci1394_async_handle_t async_handle,
1937     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size,
1938     boolean_t *bus_reset_token)
1939 {
1940 	cmd1394_cmd_t *cmd;
1941 	uint32_t quadlet;
1942 	uint32_t data1;
1943 	uint32_t data2;
1944 
1945 
1946 	ASSERT(async_handle != NULL);
1947 	ASSERT(pkt != NULL);
1948 	ASSERT(hcicmd != NULL);
1949 	ASSERT(size != NULL);
1950 
1951 	/* Setup shortcuts, command type, and size of request */
1952 	cmd = hcicmd->ac_cmd;
1953 	cmd->cmd_type = CMD1394_ASYNCH_WR_QUAD;
1954 	*size = DESC_SZ_AR_PHY;
1955 
1956 	/*
1957 	 * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1958 	 * set state that we do not use an mblk for this request.
1959 	 */
1960 	quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
1961 	hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1962 	hcicmd->ac_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1963 	hcicmd->ac_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1964 	hcicmd->ac_mblk_alloc = B_FALSE;
1965 
1966 	/* Read in the PHY packet quadlet and its check quadlet */
1967 	data1 = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1968 	data2 = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1969 
1970 	/*
1971 	 * if this is a bus reset token, save away the generation. If the bus
1972 	 * reset token is for the current generation, we do not need to flush
1973 	 * the ARREQ Q anymore.
1974 	 */
1975 	if (hcicmd->ac_status == OHCI_EVT_BUS_RESET) {
1976 		*bus_reset_token = B_TRUE;
1977 		async_handle->as_phy_reset = HCI1394_DESC_PHYGEN_GET(data2);
1978 		if (async_handle->as_phy_reset == hci1394_ohci_current_busgen(
1979 		    async_handle->as_ohci)) {
1980 			async_handle->as_flushing_arreq = B_FALSE;
1981 		}
1982 		return (DDI_SUCCESS);
1983 	}
1984 
1985 	*bus_reset_token = B_FALSE;
1986 
1987 	/* if there is a data error in the PHY packet, return failure */
1988 	if (data1 != ~data2) {
1989 		return (DDI_FAILURE);
1990 	}
1991 
1992 	/* Copy the PHY quadlet to the command */
1993 	cmd->cmd_u.q.quadlet_data = data1;
1994 
1995 	return (DDI_SUCCESS);
1996 }
1997 
1998 
1999 /*
2000  * hci1394_async_phy()
2001  *    Queue up ATREQ phy packet.
2002  */
2003 int
hci1394_async_phy(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,int * result)2004 hci1394_async_phy(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2005     h1394_cmd_priv_t *cmd_priv, int *result)
2006 {
2007 	hci1394_basic_pkt_t header;
2008 	hci1394_async_cmd_t *hcicmd;
2009 	int status;
2010 
2011 
2012 	ASSERT(async_handle != NULL);
2013 	ASSERT(cmd != NULL);
2014 	ASSERT(cmd_priv != NULL);
2015 	ASSERT(result != NULL);
2016 
2017 	/*
2018 	 * make sure this call is during the current bus generation (i.e. no
2019 	 * bus resets have occured since this request was made.
2020 	 */
2021 	if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2022 	    async_handle->as_ohci)) {
2023 		*result = H1394_STATUS_INVALID_BUSGEN;
2024 		return (DDI_FAILURE);
2025 	}
2026 
2027 	/* Initialize the private HAL command structure */
2028 	hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2029 
2030 	/* We do not allocate a tlabel for a PHY packet */
2031 	hcicmd->ac_tlabel_alloc = B_FALSE;
2032 
2033 	/*
2034 	 * Setup the packet header information for a ATREQ PHY packet Add in
2035 	 * the tcode, phy quadlet, and it's 1's complement.
2036 	 */
2037 	header.q1 = DESC_ATREQ_Q1_PHY;
2038 	header.q2 = cmd->cmd_u.q.quadlet_data;
2039 	header.q3 = ~header.q2;
2040 
2041 	/* Write request into the ATREQ Q. If we fail, we're out of space */
2042 	status = hci1394_q_at(async_handle->as_atreq_q, &hcicmd->ac_qcmd,
2043 	    &header, DESC_PKT_HDRLEN_AT_PHY, result);
2044 	if (status != DDI_SUCCESS) {
2045 		return (DDI_FAILURE);
2046 	}
2047 
2048 	return (DDI_SUCCESS);
2049 }
2050 
2051 
2052 /*
2053  * hci1394_async_write()
2054  *    Queue up ATREQ write. This could be either a block write or a quadlet
2055  *    write.
2056  */
2057 int
hci1394_async_write(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,int * result)2058 hci1394_async_write(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2059     h1394_cmd_priv_t *cmd_priv, int *result)
2060 {
2061 	hci1394_async_cmd_t *hcicmd;
2062 	hci1394_basic_pkt_t header;
2063 	int status;
2064 
2065 
2066 	ASSERT(async_handle != NULL);
2067 	ASSERT(cmd != NULL);
2068 	ASSERT(cmd_priv != NULL);
2069 	ASSERT(result != NULL);
2070 
2071 	/*
2072 	 * make sure this call is during the current bus generation (i.e. no
2073 	 * bus resets have occured since this request was made.
2074 	 */
2075 	if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2076 	    async_handle->as_ohci)) {
2077 		*result = H1394_STATUS_INVALID_BUSGEN;
2078 		return (DDI_FAILURE);
2079 	}
2080 
2081 	/* Initialize the private HAL command structure */
2082 	hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2083 	hcicmd->ac_dest = (uint_t)(cmd->cmd_addr >> IEEE1394_ADDR_PHY_ID_SHIFT);
2084 
2085 	/* allocate a tlabel for this request */
2086 	status = hci1394_tlabel_alloc(async_handle->as_tlabel, hcicmd->ac_dest,
2087 	    &hcicmd->ac_tlabel);
2088 	if (status != DDI_SUCCESS) {
2089 		*result = H1394_STATUS_EMPTY_TLABEL;
2090 		return (DDI_FAILURE);
2091 	}
2092 
2093 	/*
2094 	 * Setup the packet header information for a ATREQ write packet. We
2095 	 * will set the tcode later on since this could be a block write or
2096 	 * a quadlet write. Set SRCBusId if this write is not a local bus
2097 	 * access. Copy in the speed, tlabel, and destination address.
2098 	 */
2099 	header.q1 = 0;
2100 	if ((hcicmd->ac_dest & IEEE1394_BUS_NUM_MASK) !=
2101 	    IEEE1394_BUS_NUM_MASK) {
2102 		header.q1 |= DESC_AT_SRCBUSID;
2103 	}
2104 	header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2105 	    HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2106 	header.q2 = (uint32_t)(cmd->cmd_addr >> 32);
2107 	header.q3 = (uint32_t)(cmd->cmd_addr & DESC_PKT_DESTOFFLO_MASK);
2108 
2109 	/* Register this command w/ its tlabel */
2110 	hci1394_tlabel_register(async_handle->as_tlabel, &hcicmd->ac_tlabel,
2111 	    hcicmd);
2112 
2113 	/* If this is a quadlet write ATREQ */
2114 	if (cmd->cmd_type == CMD1394_ASYNCH_WR_QUAD) {
2115 		/*
2116 		 * setup the tcode for a quadlet write request and copy in
2117 		 * the quadlet data. Endian issues will be taken care of in
2118 		 * hci1394_q_at().
2119 		 */
2120 		header.q1 |= DESC_ATREQ_Q1_QWR;
2121 		header.q4 = cmd->cmd_u.q.quadlet_data;
2122 
2123 		/*
2124 		 * Write the request into the ATREQ Q. If we fail, we are out
2125 		 * of space.
2126 		 */
2127 		status = hci1394_q_at(async_handle->as_atreq_q,
2128 		    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_WRITEQUAD,
2129 		    result);
2130 		if (status != DDI_SUCCESS) {
2131 			return (DDI_FAILURE);
2132 		}
2133 
2134 	/* This is a block write ATREQ */
2135 	} else {
2136 		/* setup the tcode and the length of the block write */
2137 		header.q1 |= DESC_ATREQ_Q1_BWR;
2138 		header.q4 = HCI1394_DESC_DATALEN_SET(cmd_priv->mblk.length);
2139 
2140 		/*
2141 		 * Write the request into the ATREQ Q. If we fail, we are out
2142 		 * of space. The data is in a mblk(s). We use a special
2143 		 * interface in the HAL/SL private command block to handle
2144 		 * partial transfers out of the mblk due to packet size
2145 		 * restrictions.
2146 		 */
2147 		status = hci1394_q_at_with_mblk(async_handle->as_atreq_q,
2148 		    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_WRITEBLOCK,
2149 		    &cmd_priv->mblk, result);
2150 		if (status != DDI_SUCCESS) {
2151 			return (DDI_FAILURE);
2152 		}
2153 	}
2154 
2155 	return (DDI_SUCCESS);
2156 }
2157 
2158 
2159 /*
2160  * hci1394_async_read()
2161  *    Queue up ATREQ read. This could be either a block read or a quadlet
2162  *    read.
2163  */
2164 int
hci1394_async_read(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,int * result)2165 hci1394_async_read(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2166     h1394_cmd_priv_t *cmd_priv, int *result)
2167 {
2168 	hci1394_basic_pkt_t header;
2169 	int status;
2170 	hci1394_async_cmd_t *hcicmd;
2171 
2172 
2173 	ASSERT(async_handle != NULL);
2174 	ASSERT(cmd != NULL);
2175 	ASSERT(cmd_priv != NULL);
2176 	ASSERT(result != NULL);
2177 
2178 	/*
2179 	 * make sure this call is during the current bus generation (i.e. no
2180 	 * bus resets have occured since this request was made.
2181 	 */
2182 	if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2183 	    async_handle->as_ohci)) {
2184 		*result = H1394_STATUS_INVALID_BUSGEN;
2185 		return (DDI_FAILURE);
2186 	}
2187 
2188 	/* Initialize the private HAL command structure */
2189 	hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2190 	hcicmd->ac_dest = (uint_t)(cmd->cmd_addr >> IEEE1394_ADDR_PHY_ID_SHIFT);
2191 
2192 	/* allocate a tlabel for this request */
2193 	status = hci1394_tlabel_alloc(async_handle->as_tlabel, hcicmd->ac_dest,
2194 	    &hcicmd->ac_tlabel);
2195 	if (status != DDI_SUCCESS) {
2196 		*result = H1394_STATUS_EMPTY_TLABEL;
2197 		return (DDI_FAILURE);
2198 	}
2199 
2200 	/*
2201 	 * Setup the packet header information for a ATREQ read packet. We
2202 	 * will set the tcode later on since this could be a block read or
2203 	 * a quadlet read. Set SRCBusId if this read is not a local bus
2204 	 * access. Copy in the speed, tlabel, and destination address.
2205 	 */
2206 	header.q1 = 0;
2207 	if ((hcicmd->ac_dest & IEEE1394_BUS_NUM_MASK) !=
2208 	    IEEE1394_BUS_NUM_MASK) {
2209 		header.q1 |= DESC_AT_SRCBUSID;
2210 	}
2211 	header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2212 	    HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2213 	header.q2 = (uint32_t)(cmd->cmd_addr >> 32);
2214 	header.q3 = (uint32_t)(cmd->cmd_addr & DESC_PKT_DESTOFFLO_MASK);
2215 
2216 	/* Register this command w/ its tlabel */
2217 	hci1394_tlabel_register(async_handle->as_tlabel, &hcicmd->ac_tlabel,
2218 	    hcicmd);
2219 
2220 	/* If this is a quadlet read ATREQ */
2221 	if (cmd->cmd_type == CMD1394_ASYNCH_RD_QUAD) {
2222 		/* setup the tcode for a quadlet read request */
2223 		header.q1 |= DESC_ATREQ_Q1_QRD;
2224 		header.q4 = 0;
2225 
2226 		/*
2227 		 * Write the request into the ATREQ Q. If we fail, we are out
2228 		 * of space.
2229 		 */
2230 		status = hci1394_q_at(async_handle->as_atreq_q,
2231 		    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_READQUAD,
2232 		    result);
2233 		if (status != DDI_SUCCESS) {
2234 			return (DDI_FAILURE);
2235 		}
2236 
2237 	} else {
2238 		/* setup the tcode and the length of the block read */
2239 		header.q1 |= DESC_ATREQ_Q1_BRD;
2240 		header.q4 = HCI1394_DESC_DATALEN_SET(cmd_priv->mblk.length);
2241 
2242 		/*
2243 		 * Write the request into the ATREQ Q. If we fail, we are out
2244 		 * of space.
2245 		 */
2246 		status = hci1394_q_at(async_handle->as_atreq_q,
2247 		    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_READBLOCK,
2248 		    result);
2249 		if (status != DDI_SUCCESS) {
2250 			return (DDI_FAILURE);
2251 		}
2252 	}
2253 
2254 	return (DDI_SUCCESS);
2255 }
2256 
2257 
2258 /*
2259  * hci1394_async_lock()
2260  *    Queue up ATREQ lock. This could be either a 32-bit or 64-bit lock
2261  *    request.
2262  */
2263 int
hci1394_async_lock(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,int * result)2264 hci1394_async_lock(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2265     h1394_cmd_priv_t *cmd_priv, int *result)
2266 {
2267 	hci1394_basic_pkt_t header;
2268 	hci1394_async_cmd_t *hcicmd;
2269 	uint32_t data32[2];
2270 	uint64_t data64[2];
2271 	uint8_t *datap;
2272 	uint_t size;
2273 	int status;
2274 
2275 
2276 	ASSERT(async_handle != NULL);
2277 	ASSERT(cmd != NULL);
2278 	ASSERT(cmd_priv != NULL);
2279 	ASSERT(result != NULL);
2280 
2281 	/*
2282 	 * make sure this call is during the current bus generation (i.e. no
2283 	 * bus resets have occured since this request was made.
2284 	 */
2285 	if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2286 	    async_handle->as_ohci)) {
2287 		*result = H1394_STATUS_INVALID_BUSGEN;
2288 		return (DDI_FAILURE);
2289 	}
2290 
2291 	/* Initialize the private HAL command structure */
2292 	hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2293 	hcicmd->ac_dest = (uint_t)(cmd->cmd_addr >> IEEE1394_ADDR_PHY_ID_SHIFT);
2294 
2295 	/* allocate a tlabel for this request */
2296 	status = hci1394_tlabel_alloc(async_handle->as_tlabel, hcicmd->ac_dest,
2297 	    &hcicmd->ac_tlabel);
2298 	if (status != DDI_SUCCESS) {
2299 		*result = H1394_STATUS_EMPTY_TLABEL;
2300 		return (DDI_FAILURE);
2301 	}
2302 
2303 	/* Register this command w/ its tlabel */
2304 	hci1394_tlabel_register(async_handle->as_tlabel, &hcicmd->ac_tlabel,
2305 	    hcicmd);
2306 
2307 	/*
2308 	 * Setup the packet header information for a ATREQ lock packet. Set
2309 	 * the tcode up as a lock request. Set SRCBusId if this lock is not a
2310 	 * local bus access. Copy in the speed, tlabel, and destination
2311 	 * address.
2312 	 */
2313 	header.q1 = DESC_ATREQ_Q1_LCK;
2314 	if ((hcicmd->ac_dest & IEEE1394_BUS_NUM_MASK) !=
2315 	    IEEE1394_BUS_NUM_MASK) {
2316 		header.q1 |= DESC_AT_SRCBUSID;
2317 	}
2318 	header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2319 	    HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2320 	header.q2 = (uint32_t)(cmd->cmd_addr >> 32);
2321 	header.q3 = (uint32_t)(cmd->cmd_addr & DESC_PKT_DESTOFFLO_MASK);
2322 
2323 	/*
2324 	 * Setup the lock length based on what size lock operation we are
2325 	 * performing. If it isn't a lock32 or lock64, we have encountered an
2326 	 * internal error. Copy the lock data into a local data buffer. Perform
2327 	 * a byte swap if it is an arithmetic lock operation and we are on a
2328 	 * little endian machine.
2329 	 */
2330 	if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
2331 		size = DESC_TWO_QUADS;
2332 		header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2333 		    HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l32.lock_type);
2334 		data32[0] = HCI1394_ARITH_LOCK_SWAP32(
2335 		    cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.arg_value);
2336 		data32[1] = HCI1394_ARITH_LOCK_SWAP32(
2337 		    cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.data_value);
2338 		datap = (uint8_t *)data32;
2339 	} else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
2340 		size = DESC_TWO_OCTLETS;
2341 		header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2342 		    HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l64.lock_type);
2343 		data64[0] = HCI1394_ARITH_LOCK_SWAP64(
2344 		    cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.arg_value);
2345 		data64[1] = HCI1394_ARITH_LOCK_SWAP64(
2346 		    cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.data_value);
2347 		datap = (uint8_t *)data64;
2348 	} else {
2349 		*result = H1394_STATUS_INTERNAL_ERROR;
2350 		return (DDI_FAILURE);
2351 	}
2352 
2353 	/* Write request into the ATREQ Q. If we fail, we're out of space */
2354 	status = hci1394_q_at_with_data(async_handle->as_atreq_q,
2355 	    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_LOCK, datap, size,
2356 	    result);
2357 	if (status != DDI_SUCCESS) {
2358 		return (DDI_FAILURE);
2359 	}
2360 
2361 	return (DDI_SUCCESS);
2362 }
2363 
2364 
2365 /*
2366  * hci1394_async_write_response()
2367  *    Send a write ATRESP. This routine should be called from the Services
2368  *    layer to send a response to a received write request (ARREQ). The same
2369  *    response is sent to a quadlet and block write request.
2370  */
2371 int
hci1394_async_write_response(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,int * result)2372 hci1394_async_write_response(hci1394_async_handle_t async_handle,
2373     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result)
2374 {
2375 	hci1394_basic_pkt_t header;
2376 	int status;
2377 	hci1394_async_cmd_t *hcicmd;
2378 
2379 
2380 	ASSERT(async_handle != NULL);
2381 	ASSERT(cmd != NULL);
2382 	ASSERT(cmd_priv != NULL);
2383 	ASSERT(result != NULL);
2384 
2385 	/*
2386 	 * make sure this call is during the current bus generation (i.e. no
2387 	 * bus resets have occured since this request was made.
2388 	 */
2389 	if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2390 	    async_handle->as_ohci)) {
2391 		*result = H1394_STATUS_INVALID_BUSGEN;
2392 		return (DDI_FAILURE);
2393 	}
2394 
2395 	/*
2396 	 * setup a shortcut to the hal private command area. Copy the generation
2397 	 * to the Q area so that we can check the generation when the AT Q is
2398 	 * locked. This prevents us from loosing commands due to race
2399 	 * conditions.
2400 	 */
2401 	hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
2402 	hcicmd->ac_qcmd.qc_generation = cmd_priv->bus_generation;
2403 
2404 	/*
2405 	 * Setup the packet header information for a ATRESP write packet. Set
2406 	 * the tcode for a write response. Set SRCBusId if the addr is not a
2407 	 * local bus address. Copy in the speed, tlabel, and response code.
2408 	 */
2409 	header.q1 = DESC_ATRESP_Q1_WR;
2410 	if ((cmd->nodeID & IEEE1394_BUS_NUM_MASK) != IEEE1394_BUS_NUM_MASK) {
2411 		header.q1 |= DESC_AT_SRCBUSID;
2412 	}
2413 	header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2414 	    HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2415 	header.q2 = (HCI1394_DESC_DESTID_SET(cmd->nodeID) |
2416 	    HCI1394_DESC_RCODE_SET(cmd->cmd_result));
2417 	header.q3 = 0;
2418 
2419 	/* Write response into the ATRESP Q. If we fail, we're out of space */
2420 	status = hci1394_q_at(async_handle->as_atresp_q, &hcicmd->ac_qcmd,
2421 	    &header, DESC_PKT_HDRLEN_AT_WRITE_RESP, result);
2422 	if (status != DDI_SUCCESS) {
2423 		return (DDI_FAILURE);
2424 	}
2425 
2426 	return (DDI_SUCCESS);
2427 }
2428 
2429 
2430 /*
2431  * hci1394_async_read_response()
2432  *    Send a read ATRESP. This routine should be called from the Services
2433  *    layer to send a response to a received read request (ARREQ). The
2434  *    response will differ between quadlet/block read requests.
2435  */
2436 int
hci1394_async_read_response(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,int * result)2437 hci1394_async_read_response(hci1394_async_handle_t async_handle,
2438     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result)
2439 {
2440 	hci1394_basic_pkt_t header;
2441 	int status;
2442 	hci1394_async_cmd_t *hcicmd;
2443 
2444 
2445 	ASSERT(async_handle != NULL);
2446 	ASSERT(cmd != NULL);
2447 	ASSERT(cmd_priv != NULL);
2448 	ASSERT(result != NULL);
2449 
2450 	/*
2451 	 * make sure this call is during the current bus generation (i.e. no
2452 	 * bus resets have occured since this request was made.
2453 	 */
2454 	if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2455 	    async_handle->as_ohci)) {
2456 		*result = H1394_STATUS_INVALID_BUSGEN;
2457 		return (DDI_FAILURE);
2458 	}
2459 
2460 	/*
2461 	 * setup a shortcut to the hal private command area. Copy the generation
2462 	 * to the Q area so that we can check the generation when the AT Q is
2463 	 * locked. This prevents us from loosing commands due to race
2464 	 * conditions.
2465 	 */
2466 	hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
2467 	hcicmd->ac_qcmd.qc_generation = cmd_priv->bus_generation;
2468 
2469 	/*
2470 	 * Setup the packet header information for a ATRESP read packet. we
2471 	 * will set the tcode later based on type of read response. Set
2472 	 * SRCBusId if the addr is not a local bus address. Copy in the
2473 	 * speed, tlabel, and response code.
2474 	 */
2475 	header.q1 = 0;
2476 	if ((cmd->nodeID & IEEE1394_BUS_NUM_MASK) != IEEE1394_BUS_NUM_MASK) {
2477 		header.q1 |= DESC_AT_SRCBUSID;
2478 	}
2479 	header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2480 	    HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2481 	header.q2 = (uint32_t)(HCI1394_DESC_DESTID_SET(cmd->nodeID) |
2482 	    HCI1394_DESC_RCODE_SET(cmd->cmd_result));
2483 	header.q3 = 0;
2484 
2485 	/* if the response is a read quadlet response */
2486 	if (cmd->cmd_type == CMD1394_ASYNCH_RD_QUAD) {
2487 		/*
2488 		 * setup the tcode for a quadlet read response, If the
2489 		 * response code is not resp complete.
2490 		 */
2491 		header.q1 |= DESC_ATRESP_Q1_QRD;
2492 		if (cmd->cmd_result == IEEE1394_RESP_COMPLETE) {
2493 			header.q4 = cmd->cmd_u.q.quadlet_data;
2494 		} else {
2495 			header.q4 = 0x0;
2496 		}
2497 
2498 		/*
2499 		 * Write response into the ATRESP Q. If we fail, we're out of
2500 		 * space.
2501 		 */
2502 		status = hci1394_q_at(async_handle->as_atresp_q,
2503 		    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_READQUAD_RESP,
2504 		    result);
2505 		if (status != DDI_SUCCESS) {
2506 			return (DDI_FAILURE);
2507 		}
2508 
2509 	/*
2510 	 * the response is a block read response. If the result is not a
2511 	 * resp complete, we are not going to send any data back.
2512 	 */
2513 	} else if ((cmd->cmd_type == CMD1394_ASYNCH_RD_BLOCK) &&
2514 	    (cmd->cmd_result != IEEE1394_RESP_COMPLETE)) {
2515 		/*
2516 		 * Setup the tcode for a block read response, set the data
2517 		 * length to zero since we had an error.
2518 		 */
2519 		header.q1 |= DESC_ATRESP_Q1_BRD;
2520 		header.q4 = 0x0;
2521 
2522 		/*
2523 		 * Write response into the ATRESP Q. If we fail, we're out of
2524 		 * space.
2525 		 */
2526 		status = hci1394_q_at(async_handle->as_atresp_q,
2527 		    &hcicmd->ac_qcmd, &header,
2528 		    DESC_PKT_HDRLEN_AT_READBLOCK_RESP, result);
2529 		if (status != DDI_SUCCESS) {
2530 			return (DDI_FAILURE);
2531 		}
2532 
2533 	/*
2534 	 * the response is a block read response with a resp complete for the
2535 	 * response code. Send back the read data.
2536 	 */
2537 	} else {
2538 		/*
2539 		 * Setup the tcode for a block read response, setup the data
2540 		 * length.
2541 		 */
2542 		header.q1 |= DESC_ATRESP_Q1_BRD;
2543 		header.q4 = HCI1394_DESC_DATALEN_SET(cmd->cmd_u.b.blk_length);
2544 
2545 		/*
2546 		 * Write response into the ATRESP Q. If we fail, we're out of
2547 		 * space. Use the data in the mblk.
2548 		 */
2549 		status = hci1394_q_at_with_mblk(async_handle->as_atresp_q,
2550 		    &hcicmd->ac_qcmd, &header,
2551 		    DESC_PKT_HDRLEN_AT_READBLOCK_RESP, &cmd_priv->mblk, result);
2552 		if (status != DDI_SUCCESS) {
2553 			return (DDI_FAILURE);
2554 		}
2555 	}
2556 
2557 	return (DDI_SUCCESS);
2558 }
2559 
2560 
2561 /*
2562  * hci1394_async_lock_response()
2563  *    Send a lock ATRESP. This routine should be called from the Services
2564  *    layer to send a response to a received lock request (ARREQ). The
2565  *    response will differ between 32-bit/64-bit lock requests.
2566  */
2567 int
hci1394_async_lock_response(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,int * result)2568 hci1394_async_lock_response(hci1394_async_handle_t async_handle,
2569     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result)
2570 {
2571 	hci1394_basic_pkt_t header;
2572 	hci1394_async_cmd_t *hcicmd;
2573 	uint32_t data32;
2574 	uint64_t data64;
2575 	uint8_t *datap;
2576 	uint_t size;
2577 	int status;
2578 
2579 
2580 	ASSERT(async_handle != NULL);
2581 	ASSERT(cmd != NULL);
2582 	ASSERT(cmd_priv != NULL);
2583 	ASSERT(result != NULL);
2584 
2585 	/*
2586 	 * make sure this call is during the current bus generation (i.e. no
2587 	 * bus resets have occured since this request was made.
2588 	 */
2589 	if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2590 	    async_handle->as_ohci)) {
2591 		*result = H1394_STATUS_INVALID_BUSGEN;
2592 		return (DDI_FAILURE);
2593 	}
2594 
2595 	/*
2596 	 * setup a shortcut to the hal private command area. Copy the generation
2597 	 * to the Q area so that we can check the generation when the AT Q is
2598 	 * locked. This prevents us from loosing commands due to race
2599 	 * conditions.
2600 	 */
2601 	hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
2602 	hcicmd->ac_qcmd.qc_generation = cmd_priv->bus_generation;
2603 
2604 	/*
2605 	 * Setup the packet header information for a ATRESP lock packet. Set
2606 	 * the tcode for a lock response. Set SRCBusId if the addr is not a
2607 	 * local bus address. Copy in the speed, tlabel, and response code.
2608 	 */
2609 	header.q1 = DESC_ATRESP_Q1_LCK;
2610 	if ((cmd->nodeID & IEEE1394_BUS_NUM_MASK) != IEEE1394_BUS_NUM_MASK) {
2611 		header.q1 |= DESC_AT_SRCBUSID;
2612 	}
2613 	header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2614 	    HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2615 	header.q2 = (uint32_t)(HCI1394_DESC_DESTID_SET(cmd->nodeID) |
2616 	    HCI1394_DESC_RCODE_SET(cmd->cmd_result));
2617 	header.q3 = 0;
2618 
2619 	/*
2620 	 * If the lock result is not a resp complete, we are not going to send
2621 	 * any data back.with the response.
2622 	 */
2623 	if (cmd->cmd_result != IEEE1394_RESP_COMPLETE) {
2624 		/* set response size to 0 for error. Set the extended tcode */
2625 		size = 0;
2626 		if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
2627 			header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2628 			    HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l32.lock_type);
2629 		} else {
2630 			header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2631 			    HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l64.lock_type);
2632 		}
2633 
2634 		/*
2635 		 * Write response into the ATRESP Q. If we fail, we're out of
2636 		 * space.
2637 		 */
2638 		status = hci1394_q_at(async_handle->as_atresp_q,
2639 		    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_LOCK_RESP,
2640 		    result);
2641 		if (status != DDI_SUCCESS) {
2642 			return (DDI_FAILURE);
2643 		}
2644 		return (DDI_SUCCESS);
2645 	}
2646 
2647 	/*
2648 	 * if the lock result is resp complete, setup the size of the response
2649 	 * depending on the lock size and copy the lock response data into a
2650 	 * local buffer. If the lock response is an arithmetic operation, swap
2651 	 * the data on little endian machines. If we don't know what type of
2652 	 * lock operation it is, someone has corrupted the command since we
2653 	 * had received the ARREQ.
2654 	 */
2655 	if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
2656 		size = IEEE1394_QUADLET;
2657 		header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2658 		    HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l32.lock_type);
2659 		data32 = HCI1394_ARITH_LOCK_SWAP32(
2660 		    cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.old_value);
2661 		datap = (uint8_t *)&data32;
2662 	} else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
2663 		size = IEEE1394_OCTLET;
2664 		header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2665 		    HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l64.lock_type);
2666 		data64 = HCI1394_ARITH_LOCK_SWAP64(
2667 		    cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.old_value);
2668 		datap = (uint8_t *)&data64;
2669 	} else {
2670 		*result = H1394_STATUS_INTERNAL_ERROR;
2671 		return (DDI_FAILURE);
2672 	}
2673 
2674 	/*
2675 	 * Write response into the ATRESP Q. If we fail, we're out of space.
2676 	 * Use the local data buffer that we copied the data to above.
2677 	 */
2678 	status = hci1394_q_at_with_data(async_handle->as_atresp_q,
2679 	    &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_LOCK_RESP, datap,
2680 	    size, result);
2681 	if (status != DDI_SUCCESS) {
2682 		return (DDI_FAILURE);
2683 	}
2684 
2685 	return (DDI_SUCCESS);
2686 }
2687 
2688 
2689 /*
2690  * hci1394_async_response_complete()
2691  *    Free up space allocted during an ARREQ.  This is called when the target
2692  *    driver and Services Layer are done with a command which was by the HAL
2693  *    during ARREQ processing.  This routine will also free up any allocated
2694  *    mblks.
2695  *
2696  *    NOTE: a target driver can hold on to a block write ARREQ mblk by setting
2697  *    the mblk pointer to NULL.  This ONLY applies to block write ARREQs. The
2698  *    HAL will no longer track the mblk for this case.
2699  */
2700 void
hci1394_async_response_complete(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv)2701 hci1394_async_response_complete(hci1394_async_handle_t async_handle,
2702     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv)
2703 {
2704 	hci1394_async_cmd_t *hcicmd;
2705 
2706 
2707 	ASSERT(async_handle != NULL);
2708 	ASSERT(cmd != NULL);
2709 	ASSERT(cmd_priv != NULL);
2710 
2711 	hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
2712 
2713 	/* If we allocated an mblk for this command */
2714 	if (hcicmd->ac_mblk_alloc == B_TRUE) {
2715 		/*
2716 		 * Don't free mblk if it is set to NULL. This allows a target
2717 		 * driver to hold on to it in the case of a block write ARREQ.
2718 		 */
2719 		if (cmd->cmd_u.b.data_block != NULL) {
2720 			freeb(cmd->cmd_u.b.data_block);
2721 		}
2722 	}
2723 
2724 	/* free up the 1394 framework command */
2725 	(void) h1394_free_cmd((void *)async_handle->as_drvinfo->di_sl_private,
2726 	    &cmd);
2727 }
2728 
2729 
2730 /*
2731  * hci1394_async_pending_timeout()
2732  *    This is the ARREQ Pending timeout callback routine.  It is called from
2733  *    the tlist code. There is a race condition with the ARRESP interrupt
2734  *    handler (hci1394_async_arresp_process) which requires a mutex to
2735  *    lock around the mark of the bad tlabel.
2736  *
2737  *    Once we enter this routine, the command has timed out. If the command is
2738  *    in both the ARRESP handler and here, we will consider it to have timed
2739  *    out. That code path handles the race condition more easily.
2740  */
2741 static void
hci1394_async_pending_timeout(hci1394_tlist_node_t * node,void * arg)2742 hci1394_async_pending_timeout(hci1394_tlist_node_t *node, void *arg)
2743 {
2744 	hci1394_async_handle_t async_handle;
2745 	hci1394_async_cmd_t *hcicmd;
2746 
2747 
2748 	async_handle = (hci1394_async_handle_t)arg;
2749 	ASSERT(async_handle != NULL);
2750 	ASSERT(node != NULL);
2751 
2752 	hcicmd = (hci1394_async_cmd_t *)node->tln_addr;
2753 
2754 	/*
2755 	 * We do NOT want to set the command state here. That should only be
2756 	 * done in the ISR. The state does nothing for us here.
2757 	 */
2758 
2759 	/*
2760 	 * We want a lock around tlabel_lookup/reading data into the cmd in the
2761 	 * ARRESP ISR processing and a lock around the tlabel_bad in this
2762 	 * routine. This ensures that we will not be touching the command
2763 	 * structure after we pass it up to the Services Layer. If we mark it as
2764 	 * bad first, the lookup will fail. If we get to the lookup first, the
2765 	 * pending list delete will fail in arresp_process() which will tell
2766 	 * that guy that we are in the middle of doing the timeout processing
2767 	 * for this command.  The ARRESP logic will just drop the response and
2768 	 * continue on.
2769 	 */
2770 	mutex_enter(&hcicmd->ac_async->as_atomic_lookup);
2771 	hci1394_tlabel_bad(async_handle->as_tlabel, &hcicmd->ac_tlabel);
2772 	mutex_exit(&hcicmd->ac_async->as_atomic_lookup);
2773 
2774 	/* Tell the Services Layer that the command has timed out */
2775 	h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
2776 	    hcicmd->ac_cmd, H1394_AT_REQ, H1394_CMD_ETIMEOUT);
2777 }
2778 
2779 
2780 /*
2781  * hci1394_async_timeout_calc()
2782  *    Calculate the timeout for an ATRESP. When an ARREQ is received, this
2783  *    routine is called with the time the ARREQ was received. It returns the
2784  *    time when the ATRESP is considered to have timed out. We timeout after
2785  *    split_timeout has gone by. Split timeout and the returned value are in bus
2786  *    cycles.
2787  */
2788 static uint_t
hci1394_async_timeout_calc(hci1394_async_handle_t async_handle,uint_t current_time)2789 hci1394_async_timeout_calc(hci1394_async_handle_t async_handle,
2790     uint_t current_time)
2791 {
2792 	uint_t split_timeout;
2793 	uint_t temp;
2794 	uint_t carry;
2795 	uint_t z;
2796 
2797 	/* Get the current split timeout */
2798 	split_timeout = hci1394_csr_split_timeout_get(async_handle->as_csr);
2799 
2800 	/*
2801 	 * The cycle count is broken up into two sections, the 3-bit seconds
2802 	 * field and the 13-bit cycle count. The cycle count is in 125uS
2803 	 * increments.  The maximum value of cycle count is 7999 (8000 is one
2804 	 * second). With 13-bits, we could store up to 8191. Therefore, we don't
2805 	 * have a simple 16-bit addition. Hence, the code we see below.
2806 	 */
2807 
2808 	/*
2809 	 * calculate the new cycle count based on the cycle count from current
2810 	 * time and the split timeout. If this new value is not greater than the
2811 	 * maximum cycle count, we don't have a carry. Go to the next step.
2812 	 */
2813 	temp = (current_time & OHCI_CYCLE_CNT_MASK) + (split_timeout &
2814 	    OHCI_CYCLE_CNT_MASK);
2815 	if (temp < OHCI_MAX_CYCLE_CNT) {
2816 		carry = 0;
2817 
2818 	/*
2819 	 * the new cycle count adds up to more than the maximum cycle count,
2820 	 * set the carry state and adjust the total accordingly.
2821 	 */
2822 	} else {
2823 		temp = temp - OHCI_MAX_CYCLE_CNT;
2824 		carry = 1;
2825 	}
2826 
2827 	/*
2828 	 * The timeout time equals the seconds added with the carry (1 or 0
2829 	 * seconds), added with the adjusted (if necessary) cycle count.
2830 	 * Mask the final value to get rid of any second rollovers.
2831 	 */
2832 	z = (current_time & OHCI_CYCLE_SEC_MASK) + (split_timeout &
2833 	    OHCI_CYCLE_SEC_MASK) + (carry << OHCI_CYCLE_SEC_SHIFT) + temp;
2834 	z = z & OHCI_TIMESTAMP_MASK;
2835 
2836 	return (z);
2837 }
2838 
2839 
2840 /*
2841  * hci1394_async_arresp_size_get()
2842  *    Return the size of the arresp that was received in q_handle at addr.
2843  */
2844 static int
hci1394_async_arresp_size_get(uint_t tcode,hci1394_q_handle_t q_handle,uint32_t * addr,uint_t * size)2845 hci1394_async_arresp_size_get(uint_t tcode, hci1394_q_handle_t q_handle,
2846     uint32_t *addr, uint_t *size)
2847 {
2848 	uint_t data_length;
2849 	uint32_t quadlet;
2850 
2851 
2852 	ASSERT(q_handle != NULL);
2853 	ASSERT(addr != NULL);
2854 	ASSERT(size != NULL);
2855 
2856 	if (tcode == IEEE1394_TCODE_WRITE_RESP) {
2857 		*size = DESC_PKT_HDRLEN_AT_WRITE_RESP + IEEE1394_QUADLET;
2858 	} else if (tcode == IEEE1394_TCODE_READ_QUADLET_RESP) {
2859 		*size = DESC_PKT_HDRLEN_AT_READQUAD_RESP + IEEE1394_QUADLET;
2860 	} else if (tcode == IEEE1394_TCODE_READ_BLOCK_RESP) {
2861 		quadlet = hci1394_q_ar_get32(q_handle, &addr[3]);
2862 		data_length = HCI1394_DESC_DATALEN_GET(quadlet);
2863 		/*
2864 		 * response size is in quadlets, therefore we need to
2865 		 * make sure we count in the padding when figuring out
2866 		 * the size used up for this response
2867 		 */
2868 		*size = DESC_PKT_HDRLEN_AT_READBLOCK_RESP +
2869 		    HCI1394_ALIGN_QUAD(data_length) + IEEE1394_QUADLET;
2870 	} else if (tcode == IEEE1394_TCODE_LOCK_RESP) {
2871 		quadlet = hci1394_q_ar_get32(q_handle, &addr[3]);
2872 		data_length = HCI1394_DESC_DATALEN_GET(quadlet);
2873 		/*
2874 		 * response size is in quadlets, therefore we need to
2875 		 * make sure we count in the padding when figuring out
2876 		 * the size used up for this response
2877 		 */
2878 		*size = DESC_PKT_HDRLEN_AT_LOCK_RESP +
2879 		    HCI1394_ALIGN_QUAD(data_length) + IEEE1394_QUADLET;
2880 	} else {
2881 		return (DDI_FAILURE);
2882 	}
2883 
2884 	return (DDI_SUCCESS);
2885 }
2886 
2887 
2888 /*
2889  * hci1394_async_pending_list_flush()
2890  *    Flush out the ATREQ pending list. All commands still on the ATREQ pending
2891  *    list are considered to be completed due to a bus reset. The ATREQ and
2892  *    ARRESP Q's should be flushed before the pending Q is flushed. The ATREQ
2893  *    could have more ACK pendings and the ARRESP could have valid responses to
2894  *    pended requests.
2895  */
2896 void
hci1394_async_pending_list_flush(hci1394_async_handle_t async_handle)2897 hci1394_async_pending_list_flush(hci1394_async_handle_t async_handle)
2898 {
2899 	hci1394_tlist_node_t *node;
2900 	hci1394_async_cmd_t *hcicmd;
2901 
2902 
2903 	ASSERT(async_handle != NULL);
2904 
2905 	do {
2906 		/*
2907 		 * get the first node on the pending list. This routine also
2908 		 * removes the node from the list.
2909 		 */
2910 		hci1394_tlist_get(async_handle->as_pending_list, &node);
2911 		if (node != NULL) {
2912 			/* set the command state to completed */
2913 			hcicmd = (hci1394_async_cmd_t *)node->tln_addr;
2914 			hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
2915 
2916 			/*
2917 			 * Send the command up to the Services Layer with
2918 			 * completed due to the bus reset for status.
2919 			 */
2920 			h1394_cmd_is_complete(
2921 			    async_handle->as_drvinfo->di_sl_private,
2922 			    hcicmd->ac_cmd, H1394_AT_REQ,
2923 			    H1394_CMD_EBUSRESET);
2924 		}
2925 	} while (node != NULL);
2926 }
2927 
2928 
2929 /*
2930  * hci1394_async_atreq_start()
2931  *    Setup the command pointer for the first descriptor to be fetched and
2932  *    then set the run bit. This routine will be called the first time
2933  *    a descriptor is added to the Q.
2934  */
2935 static void
hci1394_async_atreq_start(void * async,uint32_t command_ptr)2936 hci1394_async_atreq_start(void *async, uint32_t command_ptr)
2937 {
2938 	hci1394_async_handle_t async_handle;
2939 	ASSERT(async != NULL);
2940 	async_handle = (hci1394_async_handle_t)async;
2941 	hci1394_ohci_atreq_start(async_handle->as_ohci, command_ptr);
2942 }
2943 
2944 
2945 /*
2946  * hci1394_async_atreq_wake()
2947  *    Set the wake bit for the ATREQ DMA engine. This routine will be called
2948  *    from the Q logic after placing a descriptor on the Q.
2949  */
2950 static void
hci1394_async_atreq_wake(void * async)2951 hci1394_async_atreq_wake(void *async)
2952 {
2953 	hci1394_async_handle_t async_handle;
2954 	ASSERT(async != NULL);
2955 	async_handle = (hci1394_async_handle_t)async;
2956 	hci1394_ohci_atreq_wake(async_handle->as_ohci);
2957 }
2958 
2959 
2960 /*
2961  * hci1394_async_atreq_reset()
2962  *    Reset the atreq Q.  The AT DMA engines must be stopped every bus reset.
2963  *    They will restart when the next descriptor is added to the Q. We will stop
2964  *    the DMA engine and then notify the Q logic that it has been stopped so it
2965  *    knows to do a start next time it puts a descriptor on the Q.
2966  */
2967 void
hci1394_async_atreq_reset(hci1394_async_handle_t async_handle)2968 hci1394_async_atreq_reset(hci1394_async_handle_t async_handle)
2969 {
2970 	ASSERT(async_handle != NULL);
2971 	hci1394_ohci_atreq_stop(async_handle->as_ohci);
2972 	hci1394_q_stop(async_handle->as_atreq_q);
2973 }
2974 
2975 
2976 /*
2977  * hci1394_async_atreq_flush()
2978  *    Flush out the atreq Q. This routine is called during bus reset processing.
2979  *    it should be called before arresp_flush() and pending_list_flush().
2980  */
2981 static void
hci1394_async_atreq_flush(hci1394_async_handle_t async_handle)2982 hci1394_async_atreq_flush(hci1394_async_handle_t async_handle)
2983 {
2984 	boolean_t request_available;
2985 
2986 	ASSERT(async_handle != NULL);
2987 
2988 	/* Clear reqTxComplete interrupt */
2989 	hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_REQ_TX_CMPLT);
2990 
2991 	/*
2992 	 * Processes all Q'd AT requests.  If the request is pended, it is
2993 	 * considered complete relative the the atreq engine.
2994 	 * flush_pending_list() will finish up the required processing for
2995 	 * pended requests.
2996 	 */
2997 	do {
2998 		/* Flush the atreq Q. Process all Q'd commands */
2999 		(void) hci1394_async_atreq_process(async_handle,
3000 		    B_TRUE, &request_available);
3001 	} while (request_available == B_TRUE);
3002 }
3003 
3004 
3005 /*
3006  * hci1394_async_arresp_start()
3007  *    Setup the command pointer for the first descriptor to be fetched and
3008  *    then set the run bit. This routine will be called the first time
3009  *    a descriptor is added to the Q.
3010  */
3011 static void
hci1394_async_arresp_start(void * async,uint32_t command_ptr)3012 hci1394_async_arresp_start(void *async, uint32_t command_ptr)
3013 {
3014 	hci1394_async_handle_t async_handle;
3015 	ASSERT(async != NULL);
3016 	async_handle = (hci1394_async_handle_t)async;
3017 	hci1394_ohci_arresp_start(async_handle->as_ohci, command_ptr);
3018 }
3019 
3020 
3021 /*
3022  * hci1394_async_arresp_wake()
3023  *    Set the wake bit for the ARRESP DMA engine. This routine will be called
3024  *    from the Q logic after placing a descriptor on the Q.
3025  */
3026 static void
hci1394_async_arresp_wake(void * async)3027 hci1394_async_arresp_wake(void *async)
3028 {
3029 	hci1394_async_handle_t async_handle;
3030 	ASSERT(async != NULL);
3031 	async_handle = (hci1394_async_handle_t)async;
3032 	hci1394_ohci_arresp_wake(async_handle->as_ohci);
3033 }
3034 
3035 
3036 /*
3037  * hci1394_async_arresp_flush()
3038  *    Flush out the arresp Q. This routine is called during bus reset
3039  *    processing. This should be called before pending_list_flush(). All
3040  *    receive responses will be processed normally. The tlabels should
3041  *    not be reset until after the ARRESP Q has been flushed. Otherwise
3042  *    we would reject valid responses.
3043  */
3044 static void
hci1394_async_arresp_flush(hci1394_async_handle_t async_handle)3045 hci1394_async_arresp_flush(hci1394_async_handle_t async_handle)
3046 {
3047 	boolean_t response_available;
3048 
3049 	ASSERT(async_handle != NULL);
3050 
3051 	/* Clear reqTxComplete interrupt */
3052 	hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_RSPKT);
3053 
3054 	do {
3055 		/* Flush the arresp Q. Process all received commands */
3056 		(void) hci1394_async_arresp_process(async_handle,
3057 		    &response_available);
3058 	} while (response_available == B_TRUE);
3059 }
3060 
3061 
3062 /*
3063  * hci1394_async_arreq_start()
3064  *    Setup the command pointer for the first descriptor to be fetched and
3065  *    then set the run bit. This routine will be called the first time
3066  *    a descriptor is added to the Q.
3067  */
3068 static void
hci1394_async_arreq_start(void * async,uint32_t command_ptr)3069 hci1394_async_arreq_start(void *async, uint32_t command_ptr)
3070 {
3071 	hci1394_async_handle_t async_handle;
3072 	ASSERT(async != NULL);
3073 	async_handle = (hci1394_async_handle_t)async;
3074 	hci1394_ohci_arreq_start(async_handle->as_ohci, command_ptr);
3075 }
3076 
3077 
3078 /*
3079  * hci1394_async_arreq_wake()
3080  *    Set the wake bit for the ARREQ DMA engine. This routine will be called
3081  *    from the Q logic after placing a descriptor on the Q.
3082  */
3083 static void
hci1394_async_arreq_wake(void * async)3084 hci1394_async_arreq_wake(void *async)
3085 {
3086 	hci1394_async_handle_t async_handle;
3087 	ASSERT(async != NULL);
3088 	async_handle = (hci1394_async_handle_t)async;
3089 	hci1394_ohci_arreq_wake(async_handle->as_ohci);
3090 }
3091 
3092 
3093 /*
3094  * hci1394_async_arreq_flush()
3095  *    Flush the ARREQ Q. This will flush up to the bus reset token in the
3096  *    ARREQ. There is no order dependency for when routine should get called
3097  *    (relative to the other Q flushing routines)
3098  */
3099 static void
hci1394_async_arreq_flush(hci1394_async_handle_t async_handle)3100 hci1394_async_arreq_flush(hci1394_async_handle_t async_handle)
3101 {
3102 	boolean_t request_available;
3103 
3104 	ASSERT(async_handle != NULL);
3105 
3106 	/*
3107 	 * If the last bus reset token we have seen in
3108 	 * hci1394_async_arreq_read_phy() matches the current generation, the
3109 	 * ARREQ is already flushed.  We have nothing further to do here so
3110 	 * return. This can happen if we are processing ARREQ's and a bus reset
3111 	 * occurs. Since we are already in the ISR, we will see the token before
3112 	 * the bus reset handler gets to run.
3113 	 */
3114 	if (async_handle->as_phy_reset == hci1394_ohci_current_busgen(
3115 	    async_handle->as_ohci)) {
3116 		return;
3117 	}
3118 
3119 	/*
3120 	 * set flag to tell hci1394_async_arreq_process() that we should not
3121 	 * pass ARREQ's up to the Services Layer.  This will be set to B_FALSE
3122 	 * in hci1394_async_arreq_read_phy() when a bus reset token matching
3123 	 * the current generation is found.
3124 	 */
3125 	async_handle->as_flushing_arreq = B_TRUE;
3126 
3127 	/*
3128 	 * Process all requests that have been received or until we find the
3129 	 * correct bus reset token.
3130 	 */
3131 	do {
3132 		(void) hci1394_async_arreq_process(async_handle,
3133 		    &request_available);
3134 	} while ((request_available == B_TRUE) &&
3135 	    (async_handle->as_flushing_arreq == B_TRUE));
3136 
3137 	/*
3138 	 * Clear the asserted interrupt if there are no more ARREQ's to process.
3139 	 * We could have ARREQ's in the Q after the bus reset token since we
3140 	 * will set as_flushing_arreq to FALSE when we see the correct bus reset
3141 	 * token in hci1394_async_arreq_read_phy(). If there are more ARREQ's,
3142 	 * we will process them later after finishing the reset of bus reset
3143 	 * processing.  That is why we will leave the interrupt asserted.
3144 	 */
3145 	if (request_available == B_FALSE) {
3146 		hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_RQPKT);
3147 	}
3148 }
3149 
3150 
3151 /*
3152  * hci1394_async_atresp_start()
3153  *    Setup the command pointer for the first descriptor to be fetched and
3154  *    then set the run bit. This routine will be called the first time
3155  *    a descriptor is added to the Q.
3156  */
3157 static void
hci1394_async_atresp_start(void * async,uint32_t command_ptr)3158 hci1394_async_atresp_start(void *async, uint32_t command_ptr)
3159 {
3160 	hci1394_async_handle_t async_handle;
3161 	ASSERT(async != NULL);
3162 	async_handle = (hci1394_async_handle_t)async;
3163 	hci1394_ohci_atresp_start(async_handle->as_ohci, command_ptr);
3164 }
3165 
3166 
3167 /*
3168  * hci1394_async_atresp_wake()
3169  *    Set the wake bit for the ATRESP DMA engine. This routine will be called
3170  *    from the Q logic after placing a descriptor on the Q.
3171  */
3172 static void
hci1394_async_atresp_wake(void * async)3173 hci1394_async_atresp_wake(void *async)
3174 {
3175 	hci1394_async_handle_t async_handle;
3176 	ASSERT(async != NULL);
3177 	async_handle = (hci1394_async_handle_t)async;
3178 	hci1394_ohci_atresp_wake(async_handle->as_ohci);
3179 }
3180 
3181 
3182 /*
3183  * hci1394_async_atresp_reset()
3184  *    Reset the atresp Q.  The AT DMA engines must be stopped every bus reset.
3185  *    They will restart when the next descriptor is added to the Q. We will stop
3186  *    the DMA engine and then notify the Q logic that it has been stopped so it
3187  *    knows to do a start next time it puts a descriptor on the Q.
3188  */
3189 void
hci1394_async_atresp_reset(hci1394_async_handle_t async_handle)3190 hci1394_async_atresp_reset(hci1394_async_handle_t async_handle)
3191 {
3192 	ASSERT(async_handle != NULL);
3193 	hci1394_ohci_atresp_stop(async_handle->as_ohci);
3194 	hci1394_q_stop(async_handle->as_atresp_q);
3195 }
3196 
3197 
3198 /*
3199  * hci1394_async_atresp_flush()
3200  *    Flush all commands out of the atresp Q. This routine will be called
3201  *    during bus reset processing. There is no order dependency for when
3202  *    routine should get called (relative to the other Q flushing routines)
3203  */
3204 static void
hci1394_async_atresp_flush(hci1394_async_handle_t async_handle)3205 hci1394_async_atresp_flush(hci1394_async_handle_t async_handle)
3206 {
3207 	boolean_t response_available;
3208 
3209 	ASSERT(async_handle != NULL);
3210 
3211 	/* Clear respTxComplete interrupt */
3212 	hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_RESP_TX_CMPLT);
3213 
3214 	/* Processes all AT responses */
3215 	do {
3216 		/* Flush the atresp Q. Process all Q'd commands */
3217 		(void) hci1394_async_atresp_process(async_handle,
3218 		    B_TRUE, &response_available);
3219 	} while (response_available == B_TRUE);
3220 }
3221 
3222 /*
3223  * hci1394_async_hcicmd_init()
3224  *    Initialize the private HAL command structure. This should be called from
3225  *    ATREQ and ARREQ routines.
3226  */
3227 static void
hci1394_async_hcicmd_init(hci1394_async_handle_t async_handle,cmd1394_cmd_t * cmd,h1394_cmd_priv_t * cmd_priv,hci1394_async_cmd_t ** hcicmd)3228 hci1394_async_hcicmd_init(hci1394_async_handle_t async_handle,
3229     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv,
3230     hci1394_async_cmd_t **hcicmd)
3231 {
3232 	*hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
3233 	(*hcicmd)->ac_cmd = cmd;
3234 	(*hcicmd)->ac_priv = cmd_priv;
3235 	(*hcicmd)->ac_async = async_handle;
3236 	(*hcicmd)->ac_state = HCI1394_CMD_STATE_IN_PROGRESS;
3237 	(*hcicmd)->ac_dest = 0;
3238 	(*hcicmd)->ac_tlabel_alloc = B_TRUE;
3239 	(*hcicmd)->ac_tlabel.tbi_tlabel = 0;
3240 	(*hcicmd)->ac_tlabel.tbi_destination = 0;
3241 	(*hcicmd)->ac_status = 0;
3242 	(*hcicmd)->ac_qcmd.qc_timestamp = 0;
3243 	(*hcicmd)->ac_qcmd.qc_arg = *hcicmd;
3244 	(*hcicmd)->ac_qcmd.qc_generation = cmd_priv->bus_generation;
3245 	(*hcicmd)->ac_mblk_alloc = B_FALSE;
3246 }
3247