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