xref: /illumos-gate/usr/src/uts/common/io/1394/s1394_misc.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, 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