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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * hci1394_isr.c
28 * Contains the core interrupt handling logic for the hci1394 driver.
29 * It also contains the routine which sets up the initial interrupt
30 * mask during HW init.
31 */
32
33 #include <sys/conf.h>
34 #include <sys/ddi.h>
35 #include <sys/modctl.h>
36 #include <sys/stat.h>
37 #include <sys/sunddi.h>
38 #include <sys/cmn_err.h>
39
40 #include <sys/1394/h1394.h>
41 #include <sys/1394/adapters/hci1394.h>
42
43
44 static uint_t hci1394_isr(caddr_t parm);
45 static void hci1394_isr_bus_reset(hci1394_state_t *soft_state);
46 static void hci1394_isr_self_id(hci1394_state_t *soft_state);
47 static void hci1394_isr_isoch_ir(hci1394_state_t *soft_state);
48 static void hci1394_isr_isoch_it(hci1394_state_t *soft_state);
49 static void hci1394_isr_atreq_complete(hci1394_state_t *soft_state);
50 static void hci1394_isr_arresp(hci1394_state_t *soft_state);
51 static void hci1394_isr_arreq(hci1394_state_t *soft_state);
52 static void hci1394_isr_atresp_complete(hci1394_state_t *soft_state);
53
54
55 /*
56 * hci1394_isr_init()
57 * Get the iblock_cookie, make sure we are not using a high level interrupt,
58 * register our interrupt service routine.
59 */
60 int
hci1394_isr_init(hci1394_state_t * soft_state)61 hci1394_isr_init(hci1394_state_t *soft_state)
62 {
63 int status;
64
65 ASSERT(soft_state != NULL);
66
67 /* This driver does not support running at a high level interrupt */
68 status = ddi_intr_hilevel(soft_state->drvinfo.di_dip, 0);
69 if (status != 0) {
70 return (DDI_FAILURE);
71 }
72
73 /* There should only be 1 1394 interrupt for an OpenHCI adapter */
74 status = ddi_get_iblock_cookie(soft_state->drvinfo.di_dip, 0,
75 &soft_state->drvinfo.di_iblock_cookie);
76 if (status != DDI_SUCCESS) {
77 return (DDI_FAILURE);
78 }
79
80 return (DDI_SUCCESS);
81 }
82
83
84 /*
85 * hci1394_isr_fini()
86 * un-register our interrupt service routine.
87 */
88 /* ARGSUSED */
89 void
hci1394_isr_fini(hci1394_state_t * soft_state)90 hci1394_isr_fini(hci1394_state_t *soft_state)
91 {
92 ASSERT(soft_state != NULL);
93
94 /* nothing to do right now */
95 }
96
97
98 /*
99 * hci1394_isr_handler_init()
100 * register our interrupt service routine.
101 */
102 int
hci1394_isr_handler_init(hci1394_state_t * soft_state)103 hci1394_isr_handler_init(hci1394_state_t *soft_state)
104 {
105 int status;
106
107 ASSERT(soft_state != NULL);
108
109 /* Initialize interrupt handler */
110 status = ddi_add_intr(soft_state->drvinfo.di_dip, 0, NULL, NULL,
111 hci1394_isr, (caddr_t)soft_state);
112 return (status);
113 }
114
115
116 /*
117 * hci1394_isr_handler_fini()
118 * un-register our interrupt service routine.
119 */
120 void
hci1394_isr_handler_fini(hci1394_state_t * soft_state)121 hci1394_isr_handler_fini(hci1394_state_t *soft_state)
122 {
123 ASSERT(soft_state != NULL);
124
125 /* Remove interrupt handler */
126 ddi_remove_intr(soft_state->drvinfo.di_dip, 0,
127 soft_state->drvinfo.di_iblock_cookie);
128 }
129
130
131 /*
132 * hci1394_isr_mask_setup()
133 * Setup the initial interrupt mask for OpenHCI. These are the interrupts
134 * that our interrupt handler is expected to handle.
135 */
136 void
hci1394_isr_mask_setup(hci1394_state_t * soft_state)137 hci1394_isr_mask_setup(hci1394_state_t *soft_state)
138 {
139 ASSERT(soft_state != NULL);
140
141 /* start off with all interrupts cleared/disabled */
142 hci1394_ohci_ir_intr_disable(soft_state->ohci, 0xFFFFFFFF);
143 hci1394_ohci_ir_intr_clear(soft_state->ohci, 0xFFFFFFFF);
144 hci1394_ohci_it_intr_disable(soft_state->ohci, 0xFFFFFFFF);
145 hci1394_ohci_it_intr_clear(soft_state->ohci, 0xFFFFFFFF);
146 hci1394_ohci_intr_disable(soft_state->ohci, 0xFFFFFFFF);
147 hci1394_ohci_intr_clear(soft_state->ohci, 0xFFFFFFFF);
148
149 /* Setup Interrupt Mask Register */
150 hci1394_ohci_intr_enable(soft_state->ohci,
151 (OHCI_INTR_UNRECOVERABLE_ERR | OHCI_INTR_CYC_TOO_LONG |
152 OHCI_INTR_BUS_RESET | OHCI_INTR_SELFID_CMPLT |
153 OHCI_INTR_REQ_TX_CMPLT | OHCI_INTR_RESP_TX_CMPLT |
154 OHCI_INTR_RQPKT | OHCI_INTR_RSPKT | OHCI_INTR_ISOCH_TX |
155 OHCI_INTR_ISOCH_RX | OHCI_INTR_POST_WR_ERR | OHCI_INTR_PHY |
156 OHCI_INTR_LOCK_RESP_ERR));
157 }
158
159
160 /*
161 * hci1394_isr()
162 * Core interrupt handler. Every interrupt enabled in
163 * hci1394_isr_mask_setup() should be covered here. There may be other
164 * interrupts supported in here even if they are not initially enabled
165 * (like OHCI_INTR_CYC_64_SECS) since they may be enabled later (i.e. due to
166 * CSR register write)
167 */
168 static uint_t
hci1394_isr(caddr_t parm)169 hci1394_isr(caddr_t parm)
170 {
171 hci1394_state_t *soft_state;
172 h1394_posted_wr_err_t posted_wr_err;
173 uint32_t interrupt_event;
174 uint_t status;
175
176
177 status = DDI_INTR_UNCLAIMED;
178 soft_state = (hci1394_state_t *)parm;
179
180 ASSERT(soft_state != NULL);
181
182 if (hci1394_state(&soft_state->drvinfo) == HCI1394_SHUTDOWN)
183 return (DDI_INTR_UNCLAIMED);
184
185 /*
186 * Get all of the enabled 1394 interrupts which are currently
187 * asserted.
188 */
189 interrupt_event = hci1394_ohci_intr_asserted(soft_state->ohci);
190 do {
191 /* handle the asserted interrupts */
192 if (interrupt_event & OHCI_INTR_BUS_RESET) {
193 hci1394_isr_bus_reset(soft_state);
194 status = DDI_INTR_CLAIMED;
195 }
196 if (interrupt_event & OHCI_INTR_SELFID_CMPLT) {
197 hci1394_isr_self_id(soft_state);
198 status = DDI_INTR_CLAIMED;
199 }
200 if (interrupt_event & OHCI_INTR_ISOCH_TX) {
201 hci1394_isr_isoch_it(soft_state);
202 status = DDI_INTR_CLAIMED;
203 }
204 if (interrupt_event & OHCI_INTR_ISOCH_RX) {
205 hci1394_isr_isoch_ir(soft_state);
206 status = DDI_INTR_CLAIMED;
207 }
208 if (interrupt_event & OHCI_INTR_REQ_TX_CMPLT) {
209 hci1394_isr_atreq_complete(soft_state);
210 status = DDI_INTR_CLAIMED;
211 }
212 if (interrupt_event & OHCI_INTR_RSPKT) {
213 hci1394_isr_arresp(soft_state);
214 status = DDI_INTR_CLAIMED;
215 }
216 if (interrupt_event & OHCI_INTR_RQPKT) {
217 hci1394_isr_arreq(soft_state);
218 status = DDI_INTR_CLAIMED;
219 }
220 if (interrupt_event & OHCI_INTR_RESP_TX_CMPLT) {
221 hci1394_isr_atresp_complete(soft_state);
222 status = DDI_INTR_CLAIMED;
223 }
224 if (interrupt_event & OHCI_INTR_CYC_64_SECS) {
225 hci1394_ohci_isr_cycle64seconds(soft_state->ohci);
226 status = DDI_INTR_CLAIMED;
227 }
228 if (interrupt_event & OHCI_INTR_UNRECOVERABLE_ERR) {
229 h1394_error_detected(soft_state->drvinfo.di_sl_private,
230 H1394_SELF_INITIATED_SHUTDOWN, NULL);
231 cmn_err(CE_WARN, "hci1394(%d): driver shutdown: "
232 "unrecoverable error interrupt detected",
233 soft_state->drvinfo.di_instance);
234 hci1394_shutdown(soft_state->drvinfo.di_dip);
235 status = DDI_INTR_CLAIMED;
236 }
237 if (interrupt_event & OHCI_INTR_CYC_LOST) {
238 hci1394_isoch_cycle_lost(soft_state);
239 status = DDI_INTR_CLAIMED;
240 }
241 if (interrupt_event & OHCI_INTR_CYC_INCONSISTENT) {
242 hci1394_isoch_cycle_inconsistent(soft_state);
243 status = DDI_INTR_CLAIMED;
244 }
245 if (interrupt_event & OHCI_INTR_CYC_TOO_LONG) {
246 hci1394_ohci_intr_clear(soft_state->ohci,
247 OHCI_INTR_CYC_TOO_LONG);
248 /* clear cycle master bit in csr state register */
249 hci1394_csr_state_bclr(soft_state->csr,
250 IEEE1394_CSR_STATE_CMSTR);
251 h1394_error_detected(soft_state->drvinfo.di_sl_private,
252 H1394_CYCLE_TOO_LONG, NULL);
253 status = DDI_INTR_CLAIMED;
254 }
255 if (interrupt_event & OHCI_INTR_POST_WR_ERR) {
256 hci1394_ohci_postwr_addr(soft_state->ohci,
257 &posted_wr_err.addr);
258 h1394_error_detected(soft_state->drvinfo.di_sl_private,
259 H1394_POSTED_WR_ERR, &posted_wr_err);
260 status = DDI_INTR_CLAIMED;
261 }
262 if (interrupt_event & OHCI_INTR_PHY) {
263 hci1394_ohci_isr_phy(soft_state->ohci);
264 status = DDI_INTR_CLAIMED;
265 }
266 if (interrupt_event & OHCI_INTR_LOCK_RESP_ERR) {
267 hci1394_ohci_intr_clear(soft_state->ohci,
268 OHCI_INTR_LOCK_RESP_ERR);
269 h1394_error_detected(soft_state->drvinfo.di_sl_private,
270 H1394_LOCK_RESP_ERR, NULL);
271 status = DDI_INTR_CLAIMED;
272 }
273
274 /*
275 * Check for self-id-complete interrupt disappearing. There is
276 * a chance in OpenHCI where it will assert the selfid
277 * interrupt and then take it away. We will look for this case
278 * and claim it just in case. We could possibly claim an
279 * interrupt that's not ours. We would have to be in the
280 * middle of a bus reset and a bunch of other weird stuff
281 * would have to align. It should not hurt anything if we do.
282 *
283 * This will very very rarely happen, if ever. We still have
284 * to handle the case, just in case. OpenHCI 1.1 should fix
285 * this problem.
286 */
287 if ((status == DDI_INTR_UNCLAIMED) &&
288 (hci1394_state(&soft_state->drvinfo) ==
289 HCI1394_BUS_RESET)) {
290 if (soft_state->drvinfo.di_gencnt !=
291 hci1394_ohci_current_busgen(soft_state->ohci)) {
292 status = DDI_INTR_CLAIMED;
293 }
294 }
295
296 /*
297 * See if any of the enabled 1394 interrupts have been asserted
298 * since we first checked.
299 */
300 interrupt_event = hci1394_ohci_intr_asserted(
301 soft_state->ohci);
302 } while (interrupt_event != 0);
303
304 return (status);
305 }
306
307
308 /*
309 * hci1394_isr_bus_reset()
310 * Process a 1394 bus reset. This signifies that a bus reset has started.
311 * A bus reset will not be complete until a selfid complete interrupt
312 * comes in.
313 */
314 static void
hci1394_isr_bus_reset(hci1394_state_t * soft_state)315 hci1394_isr_bus_reset(hci1394_state_t *soft_state)
316 {
317 int status;
318
319
320 ASSERT(soft_state != NULL);
321
322 /*
323 * Set the driver state to reset. If we cannot, we have been shutdown.
324 * The only way we can get in this code is if we have a multi-processor
325 * machine and the HAL is shutdown by one processor running in base
326 * context while this interrupt handler runs in another processor.
327 * We will disable all interrupts and just return. We shouldn't have
328 * to disable the interrupts, but we will just in case.
329 */
330 status = hci1394_state_set(&soft_state->drvinfo, HCI1394_BUS_RESET);
331 if (status != DDI_SUCCESS) {
332 hci1394_ohci_intr_master_disable(soft_state->ohci);
333 return;
334 }
335
336 /*
337 * Save away reset generation count so we can detect self-id-compete
338 * interrupt which disappears in event register. This is discussed in
339 * more detail in hci1394_isr()
340 */
341 soft_state->drvinfo.di_gencnt =
342 hci1394_ohci_current_busgen(soft_state->ohci);
343
344 soft_state->drvinfo.di_stats.st_bus_reset_count++;
345
346 /*
347 * Mask off busReset until SelfIdComplete comes in. The bus reset
348 * interrupt will be asserted until the SelfIdComplete interrupt
349 * comes in (i.e. you cannot clear the interrupt until a SelfIdComplete
350 * interrupt). Therefore, we disable the interrupt via its mask so we
351 * don't get stuck in the ISR indefinitely.
352 */
353 hci1394_ohci_intr_disable(soft_state->ohci, OHCI_INTR_BUS_RESET);
354
355 /* Reset the ATREQ and ATRESP Q's */
356 hci1394_async_atreq_reset(soft_state->async);
357 hci1394_async_atresp_reset(soft_state->async);
358
359 /* Inform Services Layer about Bus Reset */
360 h1394_bus_reset(soft_state->drvinfo.di_sl_private,
361 (void **)&soft_state->sl_selfid_buf);
362 }
363
364
365 /*
366 * hci1394_isr_self_id()
367 * Process the selfid complete interrupt. The bus reset has completed
368 * and the 1394 HW has finished it's bus enumeration. The SW needs to
369 * see what's changed and handle any hotplug conditions.
370 */
371 static void
hci1394_isr_self_id(hci1394_state_t * soft_state)372 hci1394_isr_self_id(hci1394_state_t *soft_state)
373 {
374 int status;
375 uint_t node_id;
376 uint_t selfid_size;
377 uint_t quadlet_count;
378 uint_t index;
379 uint32_t *selfid_buf_p;
380 boolean_t selfid_error;
381 boolean_t nodeid_error;
382 boolean_t saw_error = B_FALSE;
383 uint_t phy_status;
384
385
386 ASSERT(soft_state != NULL);
387
388 soft_state->drvinfo.di_stats.st_selfid_count++;
389
390 /*
391 * check for the bizarre case that we got both a bus reset and self id
392 * complete after checking for a bus reset
393 */
394 if (hci1394_state(&soft_state->drvinfo) != HCI1394_BUS_RESET) {
395 hci1394_isr_bus_reset(soft_state);
396 }
397
398 /*
399 * Clear any set PHY error status bits set. The PHY status bits
400 * may always be set (i.e. we removed cable power) so we do not want
401 * to clear them when we handle the interrupt. We will clear them
402 * every selfid complete interrupt so worst case we will get 1 PHY event
403 * interrupt every bus reset.
404 */
405 status = hci1394_ohci_phy_read(soft_state->ohci, 5, &phy_status);
406 if (status == DDI_SUCCESS) {
407 phy_status |= OHCI_PHY_LOOP_ERR | OHCI_PHY_PWRFAIL_ERR |
408 OHCI_PHY_TIMEOUT_ERR | OHCI_PHY_PORTEVT_ERR;
409 status = hci1394_ohci_phy_write(soft_state->ohci, 5,
410 phy_status);
411 if (status == DDI_SUCCESS) {
412 /*
413 * Re-enable PHY interrupt. We disable the PHY interrupt
414 * when we get one so that we do not get stuck in the
415 * ISR.
416 */
417 hci1394_ohci_intr_enable(soft_state->ohci,
418 OHCI_INTR_PHY);
419 }
420 }
421
422 /* See if either AT active bit is set */
423 if (hci1394_ohci_at_active(soft_state->ohci) == B_TRUE) {
424 saw_error = B_TRUE;
425 }
426
427 /* Clear busReset and selfIdComplete interrupts */
428 hci1394_ohci_intr_clear(soft_state->ohci, (OHCI_INTR_BUS_RESET |
429 OHCI_INTR_SELFID_CMPLT));
430
431 /* Read node info and test for Invalid Node ID */
432 hci1394_ohci_nodeid_info(soft_state->ohci, &node_id, &nodeid_error);
433 if (nodeid_error == B_TRUE) {
434 saw_error = B_TRUE;
435 }
436
437 /* Sync Selfid Buffer */
438 hci1394_ohci_selfid_sync(soft_state->ohci);
439
440 /* store away selfid info */
441 hci1394_ohci_selfid_info(soft_state->ohci,
442 &soft_state->drvinfo.di_gencnt, &selfid_size, &selfid_error);
443
444 /* Test for selfid error */
445 if (selfid_error == B_TRUE) {
446 saw_error = B_TRUE;
447 }
448
449 /*
450 * selfid size could be 0 if a bus reset has occurred. If this occurs,
451 * we should have another selfid int coming later.
452 */
453 if ((saw_error == B_FALSE) && (selfid_size == 0)) {
454 return;
455 }
456
457 /*
458 * make sure generation count in buffer matches generation
459 * count in register.
460 */
461 if (hci1394_ohci_selfid_buf_current(soft_state->ohci) == B_FALSE) {
462 return;
463 }
464
465 /*
466 * Skip over first quadlet in selfid buffer, this is OpenHCI specific
467 * data.
468 */
469 selfid_size = selfid_size - IEEE1394_QUADLET;
470 quadlet_count = selfid_size >> 2;
471
472 /* Copy selfid buffer to Services Layer buffer */
473 for (index = 0; index < quadlet_count; index++) {
474 hci1394_ohci_selfid_read(soft_state->ohci, index + 1,
475 &soft_state->sl_selfid_buf[index]);
476 }
477
478 /*
479 * Put our selfID info into the Services Layer's selfid buffer if we
480 * have a 1394-1995 PHY.
481 */
482 if (soft_state->halinfo.phy == H1394_PHY_1995) {
483 selfid_buf_p = (uint32_t *)(
484 (uintptr_t)soft_state->sl_selfid_buf +
485 (uintptr_t)selfid_size);
486 status = hci1394_ohci_phy_info(soft_state->ohci,
487 &selfid_buf_p[0]);
488 if (status != DDI_SUCCESS) {
489 /*
490 * If we fail reading from PHY, put invalid data into
491 * the selfid buffer so the SL will reset the bus again.
492 */
493 selfid_buf_p[0] = 0xFFFFFFFF;
494 selfid_buf_p[1] = 0xFFFFFFFF;
495 } else {
496 selfid_buf_p[1] = ~selfid_buf_p[0];
497 }
498 selfid_size = selfid_size + 8;
499 }
500
501 /* Flush out async DMA Q's */
502 hci1394_async_flush(soft_state->async);
503
504 /*
505 * Make sure generation count is still valid. i.e. we have not gotten
506 * another bus reset since the last time we checked. If we have gotten
507 * another bus reset, we should have another selfid interrupt coming.
508 */
509 if (soft_state->drvinfo.di_gencnt !=
510 hci1394_ohci_current_busgen(soft_state->ohci)) {
511 return;
512 }
513
514 /*
515 * do whatever CSR register processing that needs to be done.
516 */
517 hci1394_csr_bus_reset(soft_state->csr);
518
519 /*
520 * do whatever management may be necessary for the CYCLE_LOST and
521 * CYCLE_INCONSISTENT interrupts.
522 */
523 hci1394_isoch_error_ints_enable(soft_state);
524
525 /*
526 * See if we saw an error. If we did, tell the services layer that we
527 * finished selfid processing and give them an illegal selfid buffer
528 * size of 0. The Services Layer will try to reset the bus again to
529 * see if we can recover from this problem. It will threshold after
530 * a finite number of errors.
531 */
532 if (saw_error == B_TRUE) {
533 h1394_self_ids(soft_state->drvinfo.di_sl_private,
534 soft_state->sl_selfid_buf, 0, node_id,
535 soft_state->drvinfo.di_gencnt);
536
537 /*
538 * Take ourself out of Bus Reset processing mode
539 *
540 * Set the driver state to normal. If we cannot, we have been
541 * shutdown. The only way we can get in this code is if we have
542 * a multi-processor machine and the HAL is shutdown by one
543 * processor running in base context while this interrupt
544 * handler runs in another processor. We will disable all
545 * interrupts and just return. We shouldn't have to disable
546 * the interrupts, but we will just in case.
547 */
548 status = hci1394_state_set(&soft_state->drvinfo,
549 HCI1394_NORMAL);
550 if (status != DDI_SUCCESS) {
551 hci1394_ohci_intr_master_disable(soft_state->ohci);
552 return;
553 }
554 } else if (IEEE1394_NODE_NUM(node_id) != 63) {
555 /*
556 * Notify services layer about self-id-complete. Don't notify
557 * the services layer if there are too many devices on the bus.
558 */
559 h1394_self_ids(soft_state->drvinfo.di_sl_private,
560 soft_state->sl_selfid_buf, selfid_size,
561 node_id, soft_state->drvinfo.di_gencnt);
562
563 /*
564 * Take ourself out of Bus Reset processing mode
565 *
566 * Set the driver state to normal. If we cannot, we have been
567 * shutdown. The only way we can get in this code is if we have
568 * a multi-processor machine and the HAL is shutdown by one
569 * processor running in base context while this interrupt
570 * handler runs in another processor. We will disable all
571 * interrupts and just return. We shouldn't have to disable
572 * the interrupts, but we will just in case.
573 */
574 status = hci1394_state_set(&soft_state->drvinfo,
575 HCI1394_NORMAL);
576 if (status != DDI_SUCCESS) {
577 hci1394_ohci_intr_master_disable(soft_state->ohci);
578 return;
579 }
580 } else {
581 cmn_err(CE_NOTE, "hci1394(%d): Too many devices on the 1394 "
582 "bus", soft_state->drvinfo.di_instance);
583 }
584
585 /* enable bus reset interrupt */
586 hci1394_ohci_intr_enable(soft_state->ohci, OHCI_INTR_BUS_RESET);
587 }
588
589
590 /*
591 * hci1394_isr_isoch_ir()
592 * Process each isoch recv context which has its interrupt asserted. The
593 * interrupt will be asserted when an isoch recv descriptor with the
594 * interrupt bits enabled have finished being processed.
595 */
596 static void
hci1394_isr_isoch_ir(hci1394_state_t * soft_state)597 hci1394_isr_isoch_ir(hci1394_state_t *soft_state)
598 {
599 uint32_t i;
600 uint32_t mask = 0x00000001;
601 uint32_t ev;
602 int num_ir_contexts;
603 hci1394_iso_ctxt_t *ctxtp;
604
605
606 ASSERT(soft_state != NULL);
607
608 num_ir_contexts = hci1394_isoch_recv_count_get(soft_state->isoch);
609
610 /*
611 * Main isochRx int is not clearable. it is automatically
612 * cleared by the hw when the ir_intr_event is cleared
613 */
614 /* loop until no more IR events */
615 while ((ev = hci1394_ohci_ir_intr_asserted(soft_state->ohci)) != 0) {
616
617 /* clear the events we just learned about */
618 hci1394_ohci_ir_intr_clear(soft_state->ohci, ev);
619
620 /* for each interrupting IR context, process the interrupt */
621 for (i = 0; i < num_ir_contexts; i++) {
622 /*
623 * if the intr bit is on for a context,
624 * call xmit/recv common processing code
625 */
626 if (ev & mask) {
627 ctxtp = hci1394_isoch_recv_ctxt_get(
628 soft_state->isoch, i);
629 hci1394_ixl_interrupt(soft_state, ctxtp,
630 B_FALSE);
631 }
632 mask <<= 1;
633 }
634 }
635 }
636
637
638 /*
639 * hci1394_isr_isoch_it()
640 * Process each isoch transmit context which has its interrupt asserted. The
641 * interrupt will be asserted when an isoch transmit descriptor with the
642 * interrupt bit is finished being processed.
643 */
644 static void
hci1394_isr_isoch_it(hci1394_state_t * soft_state)645 hci1394_isr_isoch_it(hci1394_state_t *soft_state)
646 {
647 uint32_t i;
648 uint32_t mask = 0x00000001;
649 uint32_t ev;
650 int num_it_contexts;
651 hci1394_iso_ctxt_t *ctxtp;
652
653
654 ASSERT(soft_state != NULL);
655
656 num_it_contexts = hci1394_isoch_xmit_count_get(soft_state->isoch);
657
658 /*
659 * Main isochTx int is not clearable. it is automatically
660 * cleared by the hw when the it_intr_event is cleared.
661 */
662
663 /* loop until no more IT events */
664 while ((ev = hci1394_ohci_it_intr_asserted(soft_state->ohci)) != 0) {
665
666 /* clear the events we just learned about */
667 hci1394_ohci_it_intr_clear(soft_state->ohci, ev);
668
669 /* for each interrupting IR context, process the interrupt */
670 for (i = 0; i < num_it_contexts; i++) {
671 /*
672 * if the intr bit is on for a context,
673 * call xmit/recv common processing code
674 */
675 if (ev & mask) {
676 ctxtp = hci1394_isoch_xmit_ctxt_get(
677 soft_state->isoch, i);
678 hci1394_ixl_interrupt(soft_state, ctxtp,
679 B_FALSE);
680 }
681 mask <<= 1;
682 }
683 }
684 }
685
686
687 /*
688 * hci1394_isr_atreq_complete()
689 * Process all completed requests that we have sent out (i.e. HW gave us
690 * an ack).
691 */
692 static void
hci1394_isr_atreq_complete(hci1394_state_t * soft_state)693 hci1394_isr_atreq_complete(hci1394_state_t *soft_state)
694 {
695 boolean_t request_available;
696
697 ASSERT(soft_state != NULL);
698
699 hci1394_ohci_intr_clear(soft_state->ohci, OHCI_INTR_REQ_TX_CMPLT);
700
701 /*
702 * Processes all ack'd AT requests. If the request is pended, it is
703 * considered complete relative the the atreq engine. AR response
704 * processing will make sure we track the response.
705 */
706 do {
707 /*
708 * Process a single request. Do not flush Q. That is only
709 * done during bus reset processing.
710 */
711 (void) hci1394_async_atreq_process(soft_state->async, B_FALSE,
712 &request_available);
713 } while (request_available == B_TRUE);
714 }
715
716
717 /*
718 * hci1394_isr_arresp()
719 * Process all responses that have come in off the bus and send then up to
720 * the services layer. We send out a request on the bus (atreq) and some time
721 * later a response comes in. We send this response up to the services
722 * layer.
723 */
724 static void
hci1394_isr_arresp(hci1394_state_t * soft_state)725 hci1394_isr_arresp(hci1394_state_t *soft_state)
726 {
727 boolean_t response_available;
728
729 ASSERT(soft_state != NULL);
730
731 hci1394_ohci_intr_clear(soft_state->ohci, OHCI_INTR_RSPKT);
732
733 /*
734 * Process all responses that have been received. If more responses
735 * come in we will stay in interrupt handler and re-run this routine.
736 * It is possible that we will call hci1394_async_arresp_process()
737 * even though there are no more AR responses to process. This would
738 * be because we have processed them earlier on. (i.e. we cleared
739 * interrupt, then got another response and processed it. The interrupt
740 * would still be pending.
741 */
742 do {
743 (void) hci1394_async_arresp_process(soft_state->async,
744 &response_available);
745 } while (response_available == B_TRUE);
746 }
747
748
749 /*
750 * hci1394_isr_arreq()
751 * Process all requests that have come in off the bus and send then up to
752 * the services layer.
753 */
754 static void
hci1394_isr_arreq(hci1394_state_t * soft_state)755 hci1394_isr_arreq(hci1394_state_t *soft_state)
756 {
757 boolean_t request_available;
758
759 ASSERT(soft_state != NULL);
760
761 hci1394_ohci_intr_clear(soft_state->ohci, OHCI_INTR_RQPKT);
762
763 /*
764 * Process all requests that have been received. It is possible that we
765 * will call hci1394_async_arreq_process() even though there are no
766 * more requests to process. This would be because we have processed
767 * them earlier on. (i.e. we cleared interrupt, got another request
768 * and processed it. The interrupt would still be pending.
769 */
770 do {
771 (void) hci1394_async_arreq_process(soft_state->async,
772 &request_available);
773 } while (request_available == B_TRUE);
774 }
775
776
777 /*
778 * hci1394_isr_atresp_complete()
779 * Process all completed responses that we have sent out (i.e. HW gave us
780 * an ack). We get in a request off the bus (arreq) and send it up to the
781 * services layer, they send down a response to that request some time
782 * later. This interrupt signifies that the HW is done with the response.
783 * (i.e. it sent it out or failed it)
784 */
785 static void
hci1394_isr_atresp_complete(hci1394_state_t * soft_state)786 hci1394_isr_atresp_complete(hci1394_state_t *soft_state)
787 {
788 boolean_t response_available;
789
790 ASSERT(soft_state != NULL);
791
792 hci1394_ohci_intr_clear(soft_state->ohci, OHCI_INTR_RESP_TX_CMPLT);
793
794 /*
795 * Processes all ack'd AT responses It is possible that we will call
796 * hci1394_async_atresp_process() even thought there are no more
797 * responses to process. This would be because we have processed
798 * them earlier on. (i.e. we cleared interrupt, then got another
799 * response and processed it. The interrupt would still be pending.
800 */
801 do {
802 /*
803 * Process a single response. Do not flush Q. That is only
804 * done during bus reset processing.
805 */
806 (void) hci1394_async_atresp_process(soft_state->async,
807 B_FALSE, &response_available);
808 } while (response_available == B_TRUE);
809 }
810