xref: /illumos-gate/usr/src/uts/common/io/1394/adapters/hci1394_isr.c (revision 2570281cf351044b6936651ce26dbe1f801dcbd8)
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