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