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