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