Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / 1394 / s1394_misc.c
blob728693395abf2c259a4427dfdd9bd6cf3bbd8c38
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * s1394_misc.c
31 * 1394 Services Layer Miscellaneous Routines
32 * This file contains miscellaneous routines used as "helper" functions
33 * by various other files in the Services Layer.
36 #include <sys/conf.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 #include <sys/cmn_err.h>
40 #include <sys/types.h>
41 #include <sys/kmem.h>
42 #include <sys/kstat.h>
43 #include <sys/tnf_probe.h>
45 #include <sys/1394/t1394.h>
46 #include <sys/1394/s1394.h>
47 #include <sys/1394/h1394.h>
48 #include <sys/1394/ieee1394.h>
50 int s1394_print_guids = 0; /* patch to print GUIDs */
52 extern void nx1394_undefine_events(s1394_hal_t *hal);
53 static void s1394_cleanup_node_cfgrom(s1394_hal_t *hal);
56 * s1394_cleanup_for_detach()
57 * is used to do all of the necessary cleanup to handle a detach or a
58 * failure in h1394_attach(). The cleanup_level specifies how far we
59 * got in h1394_attach() before failure.
61 void
62 s1394_cleanup_for_detach(s1394_hal_t *hal, uint_t cleanup_level)
65 switch (cleanup_level) {
66 case H1394_CLEANUP_LEVEL7:
67 /* remove HAL from the global HAL list */
68 mutex_enter(&s1394_statep->hal_list_mutex);
69 if ((s1394_statep->hal_head == hal) &&
70 (s1394_statep->hal_tail == hal)) {
71 s1394_statep->hal_head = NULL;
72 s1394_statep->hal_tail = NULL;
73 } else {
74 if (hal->hal_prev)
75 hal->hal_prev->hal_next = hal->hal_next;
76 if (hal->hal_next)
77 hal->hal_next->hal_prev = hal->hal_prev;
78 if (s1394_statep->hal_head == hal)
79 s1394_statep->hal_head = hal->hal_next;
80 if (s1394_statep->hal_tail == hal)
81 s1394_statep->hal_tail = hal->hal_prev;
83 mutex_exit(&s1394_statep->hal_list_mutex);
85 * No FCP cleanup needed at this time -- the following call
86 * to s1394_destroy_addr_space() takes care of everything.
88 /* FALLTHROUGH */
90 case H1394_CLEANUP_LEVEL6:
91 s1394_destroy_addr_space(hal);
92 /* FALLTHROUGH */
94 case H1394_CLEANUP_LEVEL5:
95 s1394_destroy_local_config_rom(hal);
96 /* FALLTHROUGH */
98 case H1394_CLEANUP_LEVEL4:
99 /* Undo all the kstat stuff */
100 (void) s1394_kstat_delete(hal);
101 /* FALLTHROUGH */
103 case H1394_CLEANUP_LEVEL3:
104 /* Free up the memory for selfID buffer #1 */
105 kmem_free(hal->selfid_buf1, S1394_SELFID_BUF_SIZE);
106 /* Free up the memory for selfID buffer #0 */
107 kmem_free(hal->selfid_buf0, S1394_SELFID_BUF_SIZE);
108 /* Turn off any timers that might be set */
109 s1394_destroy_timers(hal);
110 /* Destroy the bus_reset thread */
111 s1394_destroy_br_thread(hal);
112 /* Cleanup the Config ROM buffers in the topology_tree */
113 s1394_cleanup_node_cfgrom(hal);
114 /* FALLTHROUGH */
116 case H1394_CLEANUP_LEVEL2:
117 /* Destroy the br_cmplq_cv and br_cmplq_mutex */
118 cv_destroy(&hal->br_cmplq_cv);
119 mutex_destroy(&hal->br_cmplq_mutex);
120 /* Destroy the br_thread_cv and br_thread_mutex */
121 cv_destroy(&hal->br_thread_cv);
122 mutex_destroy(&hal->br_thread_mutex);
123 /* FALLTHROUGH */
125 case H1394_CLEANUP_LEVEL1:
126 (void) ddi_prop_remove_all(hal->halinfo.dip);
127 nx1394_undefine_events(hal);
128 /* FALLTHROUGH */
130 case H1394_CLEANUP_LEVEL0:
131 kmem_cache_destroy(hal->hal_kmem_cachep);
132 /* Destroy pending_q_mutex and outstanding_q_mutex */
133 mutex_destroy(&hal->pending_q_mutex);
134 mutex_destroy(&hal->outstanding_q_mutex);
135 /* Destroy target_list_rwlock */
136 rw_destroy(&hal->target_list_rwlock);
137 /* Destroy bus_mgr_node_mutex and bus_mgr_node_cv */
138 cv_destroy(&hal->bus_mgr_node_cv);
139 mutex_destroy(&hal->bus_mgr_node_mutex);
140 /* Destroy isoch_cec_list_mutex */
141 mutex_destroy(&hal->isoch_cec_list_mutex);
142 /* Destroy the Cycle Master timer mutex */
143 mutex_destroy(&hal->cm_timer_mutex);
144 /* Destroy topology_tree_mutex */
145 mutex_destroy(&hal->topology_tree_mutex);
146 /* Free the hal structure */
147 kmem_free(hal, sizeof (s1394_hal_t));
148 break;
150 default:
151 /* Error */
152 break;
157 * s1394_hal_shutdown()
158 * is used to shutdown the HAL. If the HAL indicates that an error
159 * condition (hardware or software) has occurred, it is shutdown. This
160 * routine is also called when HAL informs the services layer of a shutdown
161 * (due an internal shutdown, for eg). disable_hal indicates whether the
162 * caller intends to inform the hal of the (services layer) shutdown or not.
164 void
165 s1394_hal_shutdown(s1394_hal_t *hal, boolean_t disable_hal)
167 ddi_eventcookie_t cookie;
168 t1394_localinfo_t localinfo;
170 mutex_enter(&hal->topology_tree_mutex);
172 if (hal->hal_state == S1394_HAL_SHUTDOWN) {
173 mutex_exit(&hal->topology_tree_mutex);
174 if (disable_hal == B_TRUE)
175 HAL_CALL(hal).shutdown(hal->halinfo.hal_private);
177 return;
180 hal->hal_state = S1394_HAL_SHUTDOWN;
181 mutex_exit(&hal->topology_tree_mutex);
182 /* Disable the HAL */
183 if (disable_hal == B_TRUE)
184 HAL_CALL(hal).shutdown(hal->halinfo.hal_private);
187 * Send a remove event to all interested parties
189 mutex_enter(&hal->topology_tree_mutex);
190 localinfo.bus_generation = hal->generation_count;
191 localinfo.local_nodeID = hal->node_id;
192 mutex_exit(&hal->topology_tree_mutex);
194 if (ndi_event_retrieve_cookie(hal->hal_ndi_event_hdl, NULL,
195 DDI_DEVI_REMOVE_EVENT, &cookie, NDI_EVENT_NOPASS) ==
196 NDI_SUCCESS)
197 (void) ndi_event_run_callbacks(hal->hal_ndi_event_hdl, NULL,
198 cookie, &localinfo);
202 * s1394_initiate_hal_reset()
203 * sets up the HAL structure to indicate a self-initiated bus reset and
204 * calls the appropriate HAL entry point. If too many bus resets have
205 * happened, a message is printed out and the call is ignored.
207 void
208 s1394_initiate_hal_reset(s1394_hal_t *hal, int reason)
210 int ret;
212 if (hal->num_bus_reset_till_fail > 0) {
213 hal->initiated_bus_reset = B_TRUE;
214 hal->initiated_br_reason = reason;
216 /* Reset the bus */
217 ret = HAL_CALL(hal).bus_reset(hal->halinfo.hal_private);
218 if (ret != DDI_SUCCESS) {
220 } else {
221 cmn_err(CE_NOTE, "Unable to reenumerate the 1394 bus - If new"
222 " devices have recently been added, remove them.");
227 * s1394_on_br_thread()
228 * is used to determine if the current thread of execution is the same
229 * as the bus reset thread. This is useful during bus reset callbacks
230 * to determine whether or not a target may block.
232 boolean_t
233 s1394_on_br_thread(s1394_hal_t *hal)
235 if (hal->br_thread == curthread)
236 return (B_TRUE);
237 else
238 return (B_FALSE);
242 * s1394_destroy_br_thread()
243 * is used in h1394_detach() to signal the bus reset thread to go away.
245 void
246 s1394_destroy_br_thread(s1394_hal_t *hal)
248 /* Send the signal to the reset thread to go away */
249 mutex_enter(&hal->br_thread_mutex);
250 hal->br_thread_ev_type |= BR_THR_GO_AWAY;
251 cv_signal(&hal->br_thread_cv);
252 mutex_exit(&hal->br_thread_mutex);
254 /* Wakeup the bus_reset thread if waiting for bus_mgr timer */
255 mutex_enter(&hal->bus_mgr_node_mutex);
256 hal->bus_mgr_node = S1394_INVALID_NODE_NUM;
257 cv_signal(&hal->bus_mgr_node_cv);
258 mutex_exit(&hal->bus_mgr_node_mutex);
260 mutex_enter(&hal->br_cmplq_mutex);
261 cv_signal(&hal->br_cmplq_cv);
262 mutex_exit(&hal->br_cmplq_mutex);
264 /* Wait for the br_thread to be done */
265 while (hal->br_thread_ev_type & BR_THR_GO_AWAY)
266 delay(drv_usectohz(10));
270 * s1394_tickle_bus_reset_thread()
271 * is used to wakeup the bus reset thread after the interrupt routine
272 * has completed its bus reset processing.
274 void
275 s1394_tickle_bus_reset_thread(s1394_hal_t *hal)
277 if (hal->topology_tree_processed != B_TRUE) {
278 /* Send the signal to the reset thread */
279 mutex_enter(&hal->br_thread_mutex);
280 hal->br_thread_ev_type |= BR_THR_CFGROM_SCAN;
281 cv_signal(&hal->br_thread_cv);
282 mutex_exit(&hal->br_thread_mutex);
284 /* Signal the msgq wait, too (just in case) */
285 mutex_enter(&hal->br_cmplq_mutex);
286 cv_signal(&hal->br_cmplq_cv);
287 mutex_exit(&hal->br_cmplq_mutex);
289 /* Signal the bus_mgr wait, too (just in case) */
290 mutex_enter(&hal->bus_mgr_node_mutex);
291 cv_signal(&hal->bus_mgr_node_cv);
292 mutex_exit(&hal->bus_mgr_node_mutex);
297 * s1394_block_on_asynch_cmd()
298 * is used by many of the asynch routines to block (if necessary)
299 * while waiting for command completion.
301 void
302 s1394_block_on_asynch_cmd(cmd1394_cmd_t *cmd)
304 s1394_cmd_priv_t *s_priv;
306 /* Get the Services Layer private area */
307 s_priv = S1394_GET_CMD_PRIV(cmd);
309 /* Is this a blocking command? */
310 if (cmd->cmd_options & CMD1394_BLOCKING) {
311 /* Block until command completes */
312 mutex_enter(&s_priv->blocking_mutex);
313 while (s_priv->blocking_flag != B_TRUE)
314 cv_wait(&s_priv->blocking_cv, &s_priv->blocking_mutex);
315 s_priv->blocking_flag = B_FALSE;
316 mutex_exit(&s_priv->blocking_mutex);
321 * s1394_HAL_asynch_error()
322 * is used by many of the asynch routines to determine what error
323 * code is expected in a given situation (based on HAL state).
325 /* ARGSUSED */
327 s1394_HAL_asynch_error(s1394_hal_t *hal, cmd1394_cmd_t *cmd,
328 s1394_hal_state_t state)
331 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
333 switch (state) {
334 case S1394_HAL_RESET:
335 /* "dreq" bit is set (CSR) */
336 if (hal->disable_requests_bit == 1)
337 return (CMD1394_ENO_ATREQ);
338 else
339 return (CMD1394_CMDSUCCESS);
341 case S1394_HAL_DREQ:
342 /* "dreq" bit is set (CSR) */
343 return (CMD1394_ENO_ATREQ);
345 case S1394_HAL_SHUTDOWN:
346 return (CMD1394_EFATAL_ERROR);
348 default:
349 return (CMD1394_CMDSUCCESS);
354 * s1394_mblk_too_small()
355 * is used to determine if the mlbk_t structure(s) given in an asynch
356 * block request are sufficient to hold the amount of data requested.
358 boolean_t
359 s1394_mblk_too_small(cmd1394_cmd_t *cmd)
361 mblk_t *curr_blk;
362 boolean_t flag;
363 size_t msgb_len;
364 size_t size;
366 curr_blk = cmd->cmd_u.b.data_block;
367 msgb_len = 0;
368 flag = B_TRUE;
369 size = cmd->cmd_u.b.blk_length;
371 while (curr_blk != NULL) {
372 if (cmd->cmd_type == CMD1394_ASYNCH_WR_BLOCK) {
373 msgb_len += (curr_blk->b_wptr - curr_blk->b_rptr);
374 } else {
375 msgb_len +=
376 (curr_blk->b_datap->db_lim - curr_blk->b_wptr);
379 if (msgb_len >= size) {
380 flag = B_FALSE;
381 break;
384 curr_blk = curr_blk->b_cont;
387 return (flag);
391 * s1394_address_rollover()
392 * is used to determine if the address given will rollover the 48-bit
393 * address space.
395 boolean_t
396 s1394_address_rollover(cmd1394_cmd_t *cmd)
398 uint64_t addr_before;
399 uint64_t addr_after;
400 size_t length;
402 switch (cmd->cmd_type) {
403 case CMD1394_ASYNCH_RD_QUAD:
404 case CMD1394_ASYNCH_WR_QUAD:
405 case CMD1394_ASYNCH_LOCK_32:
406 length = IEEE1394_QUADLET;
407 break;
409 case CMD1394_ASYNCH_LOCK_64:
410 length = IEEE1394_OCTLET;
411 break;
413 case CMD1394_ASYNCH_RD_BLOCK:
414 case CMD1394_ASYNCH_WR_BLOCK:
415 length = cmd->cmd_u.b.blk_length;
416 break;
419 addr_before = cmd->cmd_addr & IEEE1394_ADDR_OFFSET_MASK;
420 addr_after = (addr_before + length) & IEEE1394_ADDR_OFFSET_MASK;
422 if (addr_after < addr_before) {
423 return (B_TRUE);
426 return (B_FALSE);
430 * s1394_stoi()
431 * returns the integer value of the string of hex/dec/oct numeric characters
432 * beginning at *p. Does no overflow checking.
434 uint_t
435 s1394_stoi(char *p, int len, int base)
437 int n;
438 int c;
440 if (len == 0)
441 return (0);
443 for (n = 0; len && (c = *p); p++, len--) {
444 if (c >= '0' && c <= '9')
445 c = c - '0';
446 else if (c >= 'a' && c <= 'f')
447 c = c - 'a' + 10;
448 else if (c >= 'A' && c <= 'F')
449 c = c - 'F' + 10;
450 n = (n * base) + c;
453 return (n);
457 * s1394_CRC16()
458 * implements ISO/IEC 13213:1994, ANSI/IEEE Std 1212, 1994 - 8.1.5
460 uint_t
461 s1394_CRC16(uint_t *d, uint_t crc_length)
463 uint_t CRC = 0;
464 uint_t data;
465 uint_t next;
466 uint_t sum;
467 int shift;
468 int i;
470 for (i = 0; i < crc_length; i++) {
471 data = d[i];
473 /* Another check should be made with "shift > 0" in */
474 /* order to support any devices that coded it wrong. */
475 for (next = CRC, shift = 28; shift >= 0; shift -= 4) {
476 sum = ((next >> 12) ^ (data >> shift)) & 0xF;
477 next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
479 CRC = next & IEEE1394_CRC16_MASK;
482 return (CRC);
486 * s1394_CRC16_old()
487 * implements a slightly modified version of ISO/IEC 13213:1994,
488 * ANSI/IEEE Std 1212, 1994 - 8.1.5. In the original IEEE 1212-1994
489 * specification the C code example was incorrect and some devices
490 * were manufactured using this incorrect CRC. On CRC16 failures
491 * this CRC is tried in case it is a legacy device.
493 uint_t
494 s1394_CRC16_old(uint_t *d, uint_t crc_length)
496 uint_t CRC = 0;
497 uint_t data;
498 uint_t next;
499 uint_t sum;
500 int shift;
501 int i;
503 for (i = 0; i < crc_length; i++) {
504 data = d[i];
505 for (next = CRC, shift = 28; shift > 0; shift -= 4) {
506 sum = ((next >> 12) ^ (data >> shift)) & 0xF;
507 next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
509 CRC = next & IEEE1394_CRC16_MASK;
512 return (CRC);
516 * s1394_ioctl()
517 * implements generic ioctls (eg. devctl support) and any non-HAL ioctls.
518 * Only ioctls required for devctl support are implemented at present.
520 /* ARGSUSED */
522 s1394_ioctl(s1394_hal_t *hal, int cmd, intptr_t arg, int mode, cred_t *cred_p,
523 int *rval_p)
525 struct devctl_iocdata *dcp;
526 dev_info_t *self;
527 int rv = 0;
528 int ret;
530 self = hal->halinfo.dip;
533 * We can use the generic implementation for these ioctls
535 switch (cmd) {
536 case DEVCTL_DEVICE_GETSTATE:
537 case DEVCTL_DEVICE_ONLINE:
538 case DEVCTL_DEVICE_OFFLINE:
539 case DEVCTL_DEVICE_REMOVE:
540 case DEVCTL_BUS_GETSTATE:
541 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0));
544 /* Read devctl ioctl data */
545 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) {
546 return (EFAULT);
549 switch (cmd) {
551 case DEVCTL_DEVICE_RESET:
552 case DEVCTL_DEVICE_REMOVE:
553 rv = ENOTSUP;
554 break;
556 case DEVCTL_BUS_CONFIGURE:
557 case DEVCTL_BUS_UNCONFIGURE:
558 rv = ENOTSUP;
559 break;
561 case DEVCTL_BUS_QUIESCE:
562 case DEVCTL_BUS_UNQUIESCE:
563 rv = ENOTSUP; /* Or call up the tree? */
564 break;
566 case DEVCTL_BUS_RESET:
567 case DEVCTL_BUS_RESETALL:
568 if (hal->halinfo.phy == H1394_PHY_1394A) {
569 ret = HAL_CALL(hal).short_bus_reset(
570 hal->halinfo.hal_private);
571 if (ret != DDI_SUCCESS) {
573 } else {
574 ret = HAL_CALL(hal).bus_reset(hal->halinfo.hal_private);
575 if (ret != DDI_SUCCESS) {
578 break;
580 default:
581 rv = ENOTTY;
584 ndi_dc_freehdl(dcp);
586 return (rv);
590 * s1394_kstat_init()
591 * is used to initialize and the Services Layer's kernel statistics.
594 s1394_kstat_init(s1394_hal_t *hal)
596 int instance;
598 hal->hal_kstats = (s1394_kstat_t *)kmem_zalloc(sizeof (s1394_kstat_t),
599 KM_SLEEP);
601 instance = ddi_get_instance(hal->halinfo.dip);
603 hal->hal_ksp = kstat_create("s1394", instance, "stats", "misc",
604 KSTAT_TYPE_RAW, sizeof (s1394_kstat_t), KSTAT_FLAG_VIRTUAL);
605 if (hal->hal_ksp != NULL) {
606 hal->hal_ksp->ks_private = (void *)hal;
607 hal->hal_ksp->ks_update = s1394_kstat_update;
608 kstat_install(hal->hal_ksp);
610 return (DDI_SUCCESS);
611 } else {
612 kmem_free((void *)hal->hal_kstats, sizeof (s1394_kstat_t));
613 return (DDI_FAILURE);
618 * s1394_kstat_delete()
619 * is used (in h1394_detach()) to cleanup/free and the Services Layer's
620 * kernel statistics.
623 s1394_kstat_delete(s1394_hal_t *hal)
625 kstat_delete(hal->hal_ksp);
626 kmem_free((void *)hal->hal_kstats, sizeof (s1394_kstat_t));
628 return (DDI_SUCCESS);
632 * s1394_kstat_update()
633 * is a callback that is called whenever a request to read the kernel
634 * statistics is made.
637 s1394_kstat_update(kstat_t *ksp, int rw)
639 s1394_hal_t *hal;
641 hal = ksp->ks_private;
643 if (rw == KSTAT_WRITE) {
644 return (EACCES);
645 } else {
646 ksp->ks_data = hal->hal_kstats;
649 return (0);
653 * s1394_addr_alloc_kstat()
654 * is used by the kernel statistics to update the count for each type of
655 * address allocation.
657 void
658 s1394_addr_alloc_kstat(s1394_hal_t *hal, uint64_t addr)
660 /* kstats - number of addr allocs */
661 if (s1394_is_posted_write(hal, addr) == B_TRUE)
662 hal->hal_kstats->addr_posted_alloc++;
663 else if (s1394_is_normal_addr(hal, addr) == B_TRUE)
664 hal->hal_kstats->addr_normal_alloc++;
665 else if (s1394_is_csr_addr(hal, addr) == B_TRUE)
666 hal->hal_kstats->addr_csr_alloc++;
667 else if (s1394_is_physical_addr(hal, addr) == B_TRUE)
668 hal->hal_kstats->addr_phys_alloc++;
672 * s1394_print_node_info()
673 * is used to print speed map and GUID information on the console.
675 void
676 s1394_print_node_info(s1394_hal_t *hal)
678 int i, j;
679 uint_t hal_node_num;
680 char str[200], tmp[200];
682 /* These are in kernel/os/logsubr.c */
683 extern void log_enter(void);
684 extern void log_exit(void);
686 if (s1394_print_guids == 0)
687 return;
689 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
691 log_enter();
693 cmn_err(CE_CONT, "Speed Map (%d):\n",
694 ddi_get_instance(hal->halinfo.dip));
696 (void) strcpy(str, " |");
697 for (i = 0; i < hal->number_of_nodes; i++) {
698 (void) sprintf(tmp, " %2d ", i);
699 (void) strcat(str, tmp);
701 (void) strcat(str, " | GUID\n");
702 cmn_err(CE_CONT, str);
704 (void) strcpy(str, "----|");
705 for (i = 0; i < hal->number_of_nodes; i++) {
706 (void) sprintf(tmp, "----");
707 (void) strcat(str, tmp);
709 (void) strcat(str, "--|------------------\n");
710 cmn_err(CE_CONT, str);
712 for (i = 0; i < hal->number_of_nodes; i++) {
714 (void) sprintf(str, " %2d |", i);
716 for (j = 0; j < hal->number_of_nodes; j++) {
717 (void) sprintf(tmp, " %3d", hal->speed_map[i][j]);
718 (void) strcat(str, tmp);
721 if (i == hal_node_num) {
723 (void) strcat(str, " | Local OHCI Card\n");
725 } else if (CFGROM_BIB_READ(&hal->topology_tree[i])) {
727 (void) sprintf(tmp, " | %08x%08x\n",
728 hal->topology_tree[i].node_guid_hi,
729 hal->topology_tree[i].node_guid_lo);
730 (void) strcat(str, tmp);
732 } else if (hal->topology_tree[i].link_active == 0) {
734 (void) strcat(str, " | Link off\n");
736 } else {
738 (void) strcat(str, " | ????????????????\n");
740 cmn_err(CE_CONT, str);
742 cmn_err(CE_CONT, "\n");
744 log_exit();
748 * s1394_dip_to_hal()
749 * is used to lookup a HAL's structure pointer by its dip.
751 s1394_hal_t *
752 s1394_dip_to_hal(dev_info_t *hal_dip)
754 s1394_hal_t *current_hal = NULL;
756 mutex_enter(&s1394_statep->hal_list_mutex);
758 /* Search the HAL list for this dip */
759 current_hal = s1394_statep->hal_head;
760 while (current_hal != NULL) {
761 if (current_hal->halinfo.dip == hal_dip) {
762 break;
764 current_hal = current_hal->hal_next;
767 mutex_exit(&s1394_statep->hal_list_mutex);
769 return (current_hal);
773 * s1394_target_from_dip_locked()
774 * searches target_list on the HAL for target corresponding to tdip;
775 * if found, target is returned, else returns NULL. This routine assumes
776 * target_list_rwlock is locked.
777 * NOTE: the callers may have the list locked in either write mode or read
778 * mode. Currently, there is no ddi-compliant way we can assert on the lock
779 * being held in write mode.
781 s1394_target_t *
782 s1394_target_from_dip_locked(s1394_hal_t *hal, dev_info_t *tdip)
784 s1394_target_t *temp;
786 temp = hal->target_head;
787 while (temp != NULL) {
788 if (temp->target_dip == tdip) {
789 return (temp);
791 temp = temp->target_next;
794 return (NULL);
797 * s1394_target_from_dip()
798 * searches target_list on the HAL for target corresponding to tdip;
799 * if found, target is returned locked.
801 s1394_target_t *
802 s1394_target_from_dip(s1394_hal_t *hal, dev_info_t *tdip)
804 s1394_target_t *target;
806 rw_enter(&hal->target_list_rwlock, RW_READER);
807 target = s1394_target_from_dip_locked(hal, tdip);
808 rw_exit(&hal->target_list_rwlock);
810 return (target);
814 * s1394_destroy_timers()
815 * turns off any outstanding timers in preparation for detach or suspend.
817 void
818 s1394_destroy_timers(s1394_hal_t *hal)
820 /* Destroy both of the Bus Mgr timers */
821 (void) untimeout(hal->bus_mgr_timeout_id);
822 (void) untimeout(hal->bus_mgr_query_timeout_id);
824 /* Destroy the Cycle Master timer */
825 (void) untimeout(hal->cm_timer);
827 /* Wait for the Config ROM timer (if necessary) */
828 while (hal->config_rom_timer_set == B_TRUE) {
829 delay(drv_usectohz(10));
835 * s1394_cleanup_node_cfgrom()
836 * frees up all of the Config ROM in use by nodes in the topology_tree
838 static void
839 s1394_cleanup_node_cfgrom(s1394_hal_t *hal)
841 uint32_t *cfgrom;
842 int i;
844 for (i = 0; i < IEEE1394_MAX_NODES; i++) {
845 if ((cfgrom = hal->topology_tree[i].cfgrom) != NULL)
846 kmem_free(cfgrom, IEEE1394_CONFIG_ROM_SZ);
851 * s1394_cycle_too_long_callback()
852 * turns on the cycle master bit of the root node (current Cycle Master)
854 void
855 s1394_cycle_too_long_callback(void *arg)
857 s1394_hal_t *hal;
858 ushort_t root_node_num;
859 ushort_t hal_node_num;
860 uint32_t data;
861 uint_t offset;
863 hal = (s1394_hal_t *)arg;
865 /* Clear the cm_timer_cet bit */
866 mutex_enter(&hal->topology_tree_mutex);
867 mutex_enter(&hal->cm_timer_mutex);
868 hal->cm_timer_set = B_FALSE;
869 mutex_exit(&hal->cm_timer_mutex);
871 /* Get the root node and host node numbers */
872 root_node_num = hal->number_of_nodes - 1;
873 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
874 mutex_exit(&hal->topology_tree_mutex);
876 /* If we are the root node, set the cycle master bit */
877 if (hal_node_num == root_node_num) {
878 data = IEEE1394_CSR_STATE_CMSTR;
879 offset = (IEEE1394_CSR_STATE_SET & IEEE1394_CSR_OFFSET_MASK);
880 (void) HAL_CALL(hal).csr_write(hal->halinfo.hal_private,
881 offset, data);