summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/1394/s1394.h
blob: a45e5b36d70b2c43bc114b226f4d88f6d1b440cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_1394_S1394_H
#define	_SYS_1394_S1394_H

/*
 * s1394.h
 *    Contains all of the structures used (internally) by the 1394
 *    Software Framework
 */

#include <sys/types.h>
#include <sys/dditypes.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sunndi.h>
#include <sys/callb.h>
#include <sys/note.h>

#include <sys/1394/s1394_impl.h>
#include <sys/1394/t1394.h>
#include <sys/1394/h1394.h>
#include <sys/1394/cmd1394.h>
#include <sys/1394/ieee1212.h>
#include <sys/1394/ieee1394.h>

#ifdef	__cplusplus
extern "C" {
#endif

/* SelfID buffer size */
#define	S1394_SELFID_BUF_SIZE		8192

/* Maximum number of allocated commands per target */
#define	MAX_NUMBER_ALLOC_CMDS		256

/* Maximum number of lock retries */
#define	MAX_NUMBER_OF_LOCK_RETRIES	256

#define	S1394_INITIAL_STATES		2

/* Invalid entry in the Speed Map */
#define	SPEED_MAP_INVALID		0xFF

/* Invalid node num */
#define	S1394_INVALID_NODE_NUM		0x3F

/* Node state */
#define	S1394_NODE_OFFLINE		1
#define	S1394_NODE_ONLINE		2

/* Where are commands inserted onto the pending Q? */
#define	S1394_PENDING_Q_FRONT		1
#define	S1394_PENDING_Q_REAR		2

/* Number of self-initiated bus resets until HAL fails */
#define	NUM_BR_FAIL			5

/* Reasons for Self-Initiated Bus Reset */
#define	NON_CRITICAL			0
#define	CRITICAL			1

/* Bus Mgr (IRM) defines */
#define	ROOT_HOLDOFF			(1 << 0)
#define	GAP_COUNT			(1 << 1)

/* Root Node has no parents */
#define	NO_PARENT			-1

/* Maximum number of Hops between Nodes on the Bus */
#define	MAX_HOPS			23

/* Invalid lo and hi addresses used in s1394_init_addr_space() */
#define	ADDR_LO_INVALID			0x0000000000000001
#define	ADDR_HI_INVALID			0x0000000000000000

/* Time to delay after CYCLE_TOO_LONG before enabling cycle master */
#define	CYCLE_MASTER_TIMER		1000	/* 1 second */

/* Size of directory stack used during config rom scan */
#define	S1394_DIR_STACK_SIZE		16

/*
 * P1394a (Draft 2.x) proposes to disallow a
 * Config ROM "generation" to be repeated within
 * a 60 second window.
 * Because of that, this value should not be set
 * to any value smaller than 5 seconds without
 * another method in place to ensure that this
 * "generation" reuse can not happen.
 */

/*
 * Time delay (in ms) from Config ROM update to
 * software-initiated bus reset.
 */
#define	CONFIG_ROM_UPDATE_DELAY		5000	/* 5 seconds */

#define	S1394_ROOT_TEXT_LEAF_SZ		36
#define	S1394_ROOT_TEXT_LEAF_QUAD_SZ	9
#define	S1394_ROOT_TEXT_KEY		0x81

#define	S1394_NODE_UNIQUE_ID_SZ		12
#define	S1394_NODE_UNIQUE_ID_QUAD_SZ	3
#define	S1394_NODE_UNIQUE_ID_KEY	0x8D

#define	S1394_UNIT_DIR_SZ		56
#define	S1394_UNIT_DIR_QUAD_SZ		14
#define	S1394_UNIT_DIR_KEY		0xD1

/* The Organizationally Unique Identifier for Sun Microsystems, Inc. */
#define	S1394_SUNW_OUI			0x080020

/* Number of retries in reading the Config ROM */
#define	CFGROM_READ_RETRIES		5

/* Delay time between reads of the Config ROM */
#define	CFGROM_READ_DELAY		20000	/* 20ms */

/* Error message for serious HBA hardware shutdowns */
#define	HALT_ERROR_MESSAGE	"%s%d: Unexpected Error: Shutting down HBA -" \
	" Hardware disabled until next reboot"

/* Command Transaction Type */
#define	S1394_CMD_READ		0
#define	S1394_CMD_WRITE		1
#define	S1394_CMD_LOCK		2

/* Channel allocations */
#define	S1394_CHANNEL_ALLOC_HI	1
#define	S1394_CHANNEL_ALLOC_LO	0

/* Maximum number of bus resets allowed in isoch rsrc alloc */
#define	S1394_ISOCH_ALLOC_RETRIES	5

#define	ADDR_RESERVED		1

/* Flags used by the used tree (red-black tree) */
#define	BLACK			0
#define	RED			1
#define	LEFT			0
#define	RIGHT			1

/* Isoch Bandwidth Allocation Units conversion */
#define	ISOCH_SPEED_FACTOR_S100		16
#define	ISOCH_SPEED_FACTOR_S200		8
#define	ISOCH_SPEED_FACTOR_S400		4

/* s1394_hal_state_t */
typedef enum {
	S1394_HAL_INIT,
	S1394_HAL_RESET,
	S1394_HAL_NORMAL,
	S1394_HAL_DREQ,
	S1394_HAL_SHUTDOWN
} s1394_hal_state_t;

/* s1394_isoch_cec_type_t */
typedef enum {
	S1394_SINGLE		= 1,
	S1394_PEER_TO_PEER	= 2
} s1394_isoch_cec_type_t;

/* s1394_isoch_cec_state_t */
typedef enum {
	ISOCH_CEC_FREE		= (1 << 0),
	ISOCH_CEC_JOIN		= (1 << 1),
	ISOCH_CEC_LEAVE		= (1 << 2),
	ISOCH_CEC_SETUP		= (1 << 3),
	ISOCH_CEC_TEARDOWN	= (1 << 4),
	ISOCH_CEC_START		= (1 << 5),
	ISOCH_CEC_STOP		= (1 << 6)
} s1394_isoch_cec_state_t;

/* s1394_status_t */
typedef enum {
	S1394_NOSTATUS		= (1 << 0),
	S1394_LOCK_FAILED	= (1 << 1),
	S1394_CMD_ALLOC_FAILED	= (1 << 2),
	S1394_XFER_FAILED	= (1 << 3),
	S1394_UNKNOWN		= (1 << 4),
	S1394_CMD_INFLIGHT	= (1 << 5)
} s1394_status_t;

/* s1394_free_cfgrom_t */
typedef enum {
	S1394_FREE_CFGROM_BOTH,
	S1394_FREE_CFGROM_NEW,
	S1394_FREE_CFGROM_OLD
} s1394_free_cfgrom_t;

typedef struct s1394_node_s		s1394_node_t;
typedef struct s1394_target_s		s1394_target_t;
typedef struct s1394_hal_s		s1394_hal_t;
typedef struct s1394_addr_space_blk_s	s1394_addr_space_blk_t;
typedef struct s1394_config_rom_s	s1394_config_rom_t;
typedef struct s1394_kstat_s		s1394_kstat_t;
typedef struct s1394_isoch_cec_s	s1394_isoch_cec_t;
typedef struct s1394_isoch_cec_member_s	s1394_isoch_cec_member_t;

/* cfgrom_dir_t */
typedef struct {
	ushort_t		dir_start;
	ushort_t		dir_size;
	ushort_t		dir_next_quad;
} cfgrom_dir_t;

/* s1394_selfid_pkt_t */
typedef struct s1394_selfid_pkt_s {
	uint32_t		spkt_data;
	uint32_t		spkt_inverse;
} s1394_selfid_pkt_t;

/* s1394_node_t */
struct s1394_node_s {
	s1394_selfid_pkt_t	*selfid_packet;
	s1394_node_t		*phy_port[IEEE1394_MAX_NUM_PORTS];
	s1394_node_t		*old_node;
	s1394_node_t		*cur_node;
	s1394_target_t		*target_list;
	ushort_t		cfgrom_size;		/* in quads */
	ushort_t		cfgrom_valid_size;	/* in quads */
	uchar_t			link_active;
	uchar_t			node_num;
	uchar_t			max_1st;
	uchar_t			max_2nd;
	uchar_t			last_port_checked;
	uchar_t			parent_port;
	uchar_t			is_a_leaf;
	/* All fields above can be zero'd while initing the topology tree */
	uint32_t		*cfgrom;
#define	node_guid_hi		cfgrom[3]
#define	node_guid_lo		cfgrom[4]
#define	node_root_dir		cfgrom[5]
	uint_t			node_state;
	uint_t			cfgrom_state;
	uint_t			bus_enum_flags;
	/* fields dir_stack through expected_dir_quad constitute dir stack */
	cfgrom_dir_t		dir_stack[S1394_DIR_STACK_SIZE];
	ushort_t		cur_dir_start;
	ushort_t		cur_dir_size;
	char			dir_stack_top;
	uchar_t			expected_type;
	uchar_t			expected_dir_quad;
	ushort_t		cfgrom_quad_to_read;
	ushort_t		cfgrom_quad_read_cnt; /* if rdg blk */
	uchar_t			rescan_cnt;
	uchar_t			cfgrom_read_fails;
	uchar_t			cfgrom_read_delay;	/* in ms */
};

/* defines used during enumeration */
#define	NODE_DIR_SIZE(data)		((data) & 0xff)
#define	NODE_DIR_START(data)		(((data) >> 8) & 0xff)
#define	NODE_DIR_QUAD(data)		(((data) >> 16) & 0xff)

/* defines for link_active */
#define	SET_LINK_ACTIVE(n)	((n)->link_active = 1)
#define	CLEAR_LINK_ACTIVE(n) 	((n)->link_active = 0)
#define	LINK_ACTIVE(n)			\
		(((n)->link_active == 0) ? B_FALSE : B_TRUE)
/* defines for state */
#define	S1394_NODE_CONSUMING_PWR	0x00000001
#define	S1394_NODE_ACTIVE		0x00000010
#define	S1394_NODE_BUS_PWR_CONSUMER(n)		\
	((IEEE1394_SELFID_POWER((n)->selfid_packet) > 0x3) ? B_TRUE : B_FALSE)

/* defines for cfgrom_state */
#define	S1394_CFGROM_NEW_ALLOC		0x00000001 /* fresh alloc */
#define	S1394_CFGROM_BIB_READ		0x00000002 /* bus info blocks read */
#define	S1394_CFGROM_ALL_READ		0x00000004 /* read all of it */
#define	S1394_CFGROM_BLK_READ_OK	0x00000008 /* can be read in blocks */
#define	S1394_CFGROM_GEN_CHANGED	0x00000010 /* config rom gen changed */
#define	S1394_CFGROM_PARSED		0x00000020 /* rom enumerated */
#define	S1394_CFGROM_DIR_STACK_OFF	0x00000040 /* dir stack turned off */
#define	S1394_CFGROM_SIZE_IS_CRCSIZE	0x00000080 /* crc size == cfgrom size */

#define	S1394_CFGROM_READ_MASK	(S1394_CFGROM_BIB_READ | S1394_CFGROM_ALL_READ)

#define	S1394_VALID_MASK			\
	(S1394_CFGROM_READ_MASK | S1394_CFGROM_BLK_READ_OK | \
	S1394_CFGROM_GEN_CHANGED | S1394_CFGROM_PARSED)

#define	CLEAR_CFGROM_STATE(n)	((n)->cfgrom_state &= ~S1394_VALID_MASK)
#define	CFGROM_VALID(n)				\
	((((n)->cfgrom_state & S1394_CFGROM_READ_MASK) != 0 && (n)->cfgrom != \
	    NULL) ? B_TRUE : B_FALSE)

/* macros for cfgrom_state */
#define	SET_CFGROM_NEW_ALLOC(n)	((n)->cfgrom_state |= S1394_CFGROM_NEW_ALLOC)
#define	CLEAR_CFGROM_NEW_ALLOC(n) ((n)->cfgrom_state &= ~S1394_CFGROM_NEW_ALLOC)
#define	CFGROM_NEW_ALLOC(n)			\
	(((n)->cfgrom_state & S1394_CFGROM_NEW_ALLOC) != 0 ? B_TRUE : B_FALSE)

#define	SET_CFGROM_BIB_READ(n)	((n)->cfgrom_state |= S1394_CFGROM_BIB_READ)
#define	CLEAR_CFGROM_BIB_READ(n) ((n)->cfgrom_state &= ~S1394_CFGROM_BIB_READ)
#define	CFGROM_BIB_READ(n)			\
	(((n)->cfgrom_state & S1394_CFGROM_BIB_READ) != 0 ? B_TRUE : B_FALSE)

#define	SET_CFGROM_ALL_READ(n)	((n)->cfgrom_state |= S1394_CFGROM_ALL_READ)
#define	CLEAR_CFGROM_ALL_READ(n)	((n)->cfgrom_state &= \
	~S1394_CFGROM_ALL_READ)
#define	CFGROM_ALL_READ(n)				\
	(((n)->cfgrom_state & S1394_CFGROM_ALL_READ) != 0 ? B_TRUE : B_FALSE)

#define	SET_CFGROM_BLK_READ_OK(n)		\
	((n)->cfgrom_state |= S1394_CFGROM_BLK_READ_OK)
#define	CLEAR_CFGROM_BLK_READ_OK(n)		\
	((n)->cfgrom_state &= ~S1394_CFGROM_BLK_READ_OK)
#define	CFGROM_BLK_READ_OK(n)			\
	(((n)->cfgrom_state & S1394_CFGROM_BLK_READ_OK) != 0 : B_TRUE : B_FALSE)

#define	SET_CFGROM_GEN_CHANGED(n)		\
	((n)->cfgrom_state |= S1394_CFGROM_GEN_CHANGED)
#define	CLEAR_CFGROM_GEN_CHANGED(n)		\
	((n)->cfgrom_state &= ~S1394_CFGROM_GEN_CHANGED)
#define	CFGROM_GEN_CHANGED(n)			\
	(((n)->cfgrom_state & S1394_CFGROM_GEN_CHANGED) != 0 ? B_TRUE : B_FALSE)

#define	SET_CFGROM_PARSED(n)	((n)->cfgrom_state |= S1394_CFGROM_PARSED)
#define	CLEAR_CFGROM_PARSED(n)	((n)->cfgrom_state &= ~S1394_CFGROM_PARSED)
#define	CFGROM_PARSED(n)			\
	(((n)->cfgrom_state & S1394_CFGROM_PARSED) != 0 ? B_TRUE : B_FALSE)

#define	SET_CFGROM_DIR_STACK_OFF(n)		\
	((n)->cfgrom_state |= S1394_CFGROM_DIR_STACK_OFF)
#define	CLEAR_CFGROM_DIR_STACK_OFF(n)		\
	((n)->cfgrom_state &= ~S1394_CFGROM_DIR_STACK_OFF)
#define	CFGROM_DIR_STACK_OFF(n)			\
	(((n)->cfgrom_state & S1394_CFGROM_DIR_STACK_OFF) != 0 ? B_TRUE : \
	    B_FALSE)

#define	SET_CFGROM_SIZE_IS_CRCSIZE(n)		\
	((n)->cfgrom_state |= S1394_CFGROM_SIZE_IS_CRCSIZE)
#define	CLEAR_CFGROM_SIZE_IS_CRCSIZE(n)		\
	((n)->cfgrom_state &= ~S1394_CFGROM_SIZE_IS_CRCSIZE)
#define	CFGROM_SIZE_IS_CRCSIZE(n)			\
	(((n)->cfgrom_state & S1394_CFGROM_SIZE_IS_CRCSIZE) != 0 ? B_TRUE : \
	    B_FALSE)

/* defines for bus_enum_flags */
#define	S1394_NODE_VISITED		0x00000001
#define	S1394_NODE_MATCHED		0x00000010

/* macros that set/clear bus_enum_flags */
#define	SET_NODE_VISITED(n)	((n)->bus_enum_flags |= S1394_NODE_VISITED)
#define	CLEAR_NODE_VISITED(n)	((n)->bus_enum_flags &= ~S1394_NODE_VISITED)
#define	NODE_VISITED(n)				\
	(((n)->bus_enum_flags & S1394_NODE_VISITED) != 0 ? B_TRUE : B_FALSE)

#define	SET_NODE_MATCHED(n)	((n)->bus_enum_flags |= S1394_NODE_MATCHED)
#define	CLEAR_NODE_MATCHED(n)	((n)->bus_enum_flags &= ~S1394_NODE_MATCHED)
#define	NODE_MATCHED(n)				\
	(((n)->bus_enum_flags & S1394_NODE_MATCHED) != 0 ? B_TRUE : B_FALSE)

#define	SET_NODE_IDENTIFIED(n)	((n)->bus_enum_flags |= S1394_NODE_IDENTIFIED)
#define	CLEAR_NODE_IDENTIFIED(n) ((n)->bus_enum_flags &= ~S1394_NODE_IDENTIFIED)
#define	NODE_IDENTIFIED(n)			\
	(((n)->bus_enum_flags & S1394_NODE_IDENTIFIED) != 0 ? B_TRUE : B_FALSE)

/*
 * s1394_fa_type_t - FA types, used as index into target_fa and hal_fa
 */
typedef enum {
	S1394_FA_TYPE_FCP_CTL,		/* FCP controller */
	S1394_FA_TYPE_FCP_TGT,		/* FCP target */
	S1394_FA_TYPE_CMP_OMPR,		/* CMP oMPR */
	S1394_FA_TYPE_CMP_IMPR,		/* CMP iMPR */
	S1394_FA_NTYPES,		/* should remain the last field */
	S1394_FA_TYPE_CMP = S1394_FA_TYPE_CMP_OMPR	/* common CMP type */
} s1394_fa_type_t;


/*
 * s1394_fa_descr_t - FA type descriptor
 */
typedef struct s1394_fa_descr_s {
	uint64_t		fd_addr;	/* address space  */
	size_t			fd_size;	/* address space size */
	t1394_addr_enable_t	fd_enable;	/* access types */
	t1394_addr_evts_t	fd_evts;	/* event callbacks */
	uint64_t		fd_conv_base;	/* address conversion base */
} s1394_fa_descr_t;

/*
 * s1394_fcp_target_t - per-target data required for FCP support
 */
typedef struct s1394_fcp_target_s {
	t1394_fcp_evts_t	fc_evts;
} s1394_fcp_target_t;

/*
 * s1394_cmp_target_t - per-target data required for CMP support
 */
typedef struct s1394_cmp_target_s {
	t1394_cmp_evts_t	cm_evts;
} s1394_cmp_target_t;

/*
 * s1394_fa_target_t - per-target data required for fixed address support
 */
typedef struct s1394_fa_target_s {
	s1394_target_t		*fat_next;	/* next in the list */
	/* type-specific data */
	union {
		s1394_fcp_target_t	fcp;
		s1394_cmp_target_t	cmp;
	} fat_u;
} s1394_fa_target_t;

/* s1394_target_t - fields protected by the HAL's target_list_rwlock */
struct s1394_target_s {
	int			target_version;

	dev_info_t		*target_dip;

	/* Pointers to the node and HAL on which the target exists */
	s1394_node_t		*on_node;
	s1394_hal_t		*on_hal;

	s1394_target_t		*target_next;
	s1394_target_t		*target_prev;

	/* target_list is a copy of target_list pointer in the node */
	s1394_target_t		*target_list;
	s1394_target_t		*target_sibling;

	uint_t			unit_dir;

	/* The max_payload sizes - max and current conditions */
	uint_t			dev_max_payload;
	uint_t			current_max_payload;

	/* Number of asynch command target has allocated */
	uint_t			target_num_cmds;

	/*
	 * Are physical AR requests allowed from this target's node?
	 * This field keeps track of the number of allocated blocks
	 * of physical memory the target has.
	 */
	uint_t			physical_arreq_enabled;

	uint_t			target_state;

	/* FCP controller and target */
	s1394_fa_target_t	target_fa[S1394_FA_NTYPES];
};
#define	S1394_TARG_HP_NODE		0x00000001	/* on a hp node */
#define	S1394_TARG_GONE			0x00000002	/* unplugged */
#define	S1394_TARG_USING_BUS_PWR	0x00000004	/* consuming pwr now */
#define	S1394_TARG_BUS_PWR_CONSUMER	0x00000008	/* power consumer */
#define	S1394_TARG_ACTIVE		0x00000010	/* active */

/*
 * s1394_fa_hal_t - per-hal data required for fixed address support
 */
typedef struct s1394_fa_hal_s {
	/*
	 * each hal keeps a list of registered fixed address clients
	 */
	s1394_target_t		*fal_head;
	s1394_target_t		*fal_tail;
	uint_t			fal_gen;	/* list generation */

	s1394_fa_descr_t	*fal_descr;	/* type descriptor */
	s1394_addr_space_blk_t	*fal_addr_blk;	/* address space block */
} s1394_fa_hal_t;

/*
 * s1394_cmp_hal_t - per-hal data required for fixed address support
 */
typedef struct s1394_cmp_hal_s {
	/* oMPR */
	krwlock_t		cmp_ompr_rwlock;
	uint32_t		cmp_ompr_val;
	/* iMPR */
	krwlock_t		cmp_impr_rwlock;
	uint32_t		cmp_impr_val;
} s1394_cmp_hal_t;

/* s1394_hal_t */
struct s1394_hal_s {
	s1394_hal_t		*hal_next;
	s1394_hal_t		*hal_prev;

	/* Target list */
	s1394_target_t		*target_head;
	s1394_target_t		*target_tail;
	krwlock_t		target_list_rwlock;

	/* halinfo structure given at attach time */
	h1394_halinfo_t		halinfo;

	boolean_t		hal_was_suspended;

	/* Bus reset thread */
	kthread_t		*br_thread;
	kmutex_t		br_thread_mutex;
	kcondvar_t		br_thread_cv;
	uint_t			br_thread_ev_type;
	uint32_t		br_cfgrom_read_gen;
	kmutex_t		br_cmplq_mutex;
	kcondvar_t		br_cmplq_cv;
	cmd1394_cmd_t		*br_cmplq_head;
	cmd1394_cmd_t		*br_cmplq_tail;

	s1394_hal_state_t	hal_state;

	/* kstats - kernel statistics for the Services Layer */
	s1394_kstat_t		*hal_kstats;
	kstat_t			*hal_ksp;

	/* CSR STATE register bits (DREQ and ABDICATE) */
	uint_t			disable_requests_bit;
	uint_t			abdicate_bus_mgr_bit;

	boolean_t		initiated_bus_reset;
	int			initiated_br_reason;
	uint32_t		num_bus_reset_till_fail;

	/* IRM and Bus Manager */
	int			IRM_node;
	kmutex_t		bus_mgr_node_mutex;
	kcondvar_t		bus_mgr_node_cv;
	int			bus_mgr_node;
	boolean_t		incumbent_bus_mgr;
	timeout_id_t		bus_mgr_timeout_id;
	timeout_id_t		bus_mgr_query_timeout_id;

	/* 1394 Bus stats */
	int			gap_count;
	int			optimum_gap_count;
	uint8_t			slowest_node_speed;

	/* Local Config ROM */
	kmutex_t		local_config_rom_mutex;
	uint32_t		*local_config_rom;
	uint32_t		*temp_config_rom_buf;
	s1394_config_rom_t	*root_directory;
	uint_t			free_space;
	uint_t			config_rom_update_amount;
	boolean_t		config_rom_timer_set;
	timeout_id_t		config_rom_timer;

	/* Cycle Master - CYCLE_TOO_LONG timer */
	kmutex_t		cm_timer_mutex;
	boolean_t		cm_timer_set;
	timeout_id_t		cm_timer;

	/* Incoming (AR) request and 1394 address space */
	kmutex_t		addr_space_free_mutex;
	s1394_addr_space_blk_t	*addr_space_free_list;
	kmutex_t		addr_space_used_mutex;
	s1394_addr_space_blk_t	*addr_space_used_tree;
	uint64_t		physical_addr_lo;
	uint64_t		physical_addr_hi;
	uint64_t		csr_addr_lo;
	uint64_t		csr_addr_hi;
	uint64_t		normal_addr_lo;
	uint64_t		normal_addr_hi;
	uint64_t		posted_write_addr_lo;
	uint64_t		posted_write_addr_hi;

	/* Outgoing (AT) request queues */
	kmutex_t		outstanding_q_mutex;
	cmd1394_cmd_t		*outstanding_q_head;
	cmd1394_cmd_t		*outstanding_q_tail;
	kmutex_t		pending_q_mutex;
	cmd1394_cmd_t		*pending_q_head;
	cmd1394_cmd_t		*pending_q_tail;

	/* SelfID buffers */
	void			*selfid_buf0;
	void			*selfid_buf1;
	int			current_buffer;
	s1394_selfid_pkt_t	*selfid_ptrs[IEEE1394_MAX_NODES];

	/* Topology trees and local bus stats */
	kmutex_t		topology_tree_mutex;
	uint32_t		cfgroms_being_read;
	s1394_node_t		*topology_tree;
	s1394_node_t		*old_tree;
	uint32_t		generation_count;
	ushort_t		number_of_nodes;
	ushort_t		node_id;
	boolean_t		topology_tree_valid;
	boolean_t		topology_tree_processed;
	uint32_t		old_generation_count;
	ushort_t		old_number_of_nodes;
	ushort_t		old_node_id;
	s1394_node_t		current_tree[IEEE1394_MAX_NODES];
	s1394_node_t		last_valid_tree[IEEE1394_MAX_NODES];
	boolean_t		old_tree_valid;

	/* TOPOLOGY_MAP backing store buffer */
	uint32_t		*CSR_topology_map;

	/* Speed Map */
	uint8_t		speed_map[IEEE1394_MAX_NODES][IEEE1394_MAX_NODES];

	/* Stack, Queue, and Node Number list */
	void 			*hal_stack[IEEE1394_MAX_NODES];
	int			hal_stack_depth;
	void 			*hal_queue[IEEE1394_MAX_NODES];
	int   			hal_queue_front;
	int   			hal_queue_back;
	int			hal_node_number_list[IEEE1394_MAX_NODES];
	int 			hal_node_number_list_size;

	/* Isoch CEC list */
	kmutex_t		isoch_cec_list_mutex;
	s1394_isoch_cec_t	*isoch_cec_list_head;
	s1394_isoch_cec_t	*isoch_cec_list_tail;

	struct kmem_cache	*hal_kmem_cachep;

	ndi_event_hdl_t		hal_ndi_event_hdl;

	callb_cpr_t		hal_cprinfo;

	/* FCP controllers and targets */
	s1394_fa_hal_t		hal_fa[S1394_FA_NTYPES];

	/* CMP support */
	s1394_cmp_hal_t		hal_cmp;
};

_NOTE(SCHEME_PROTECTS_DATA("No lock needed to start/stop timer", \
	s1394_hal_s::cm_timer))

/* defines for br_thread_ev_type */
#define	BR_THR_CFGROM_SCAN		0x00000001	/* start reading */
#define	BR_THR_GO_AWAY			0x00000002	/* clean & exit */

/*
 * FCP command and response address space
 */
#define	IEC61883_FCP_BASE_ADDR	0xFFFFF0000B00
#define	IEC61883_FCP_CMD_ADDR	IEC61883_FCP_BASE_ADDR
#define	IEC61883_FCP_CMD_SIZE	0x200
#define	IEC61883_FCP_RESP_ADDR	(IEC61883_FCP_CMD_ADDR + IEC61883_FCP_CMD_SIZE)
#define	IEC61883_FCP_RESP_SIZE	0x200
#define	IEC61883_FCP_END_ADDR (IEC61883_FCP_RESP_ADDR + IEC61883_FCP_RESP_SIZE)

/* CMP master plugs */
#define	IEC61883_CMP_OMPR_ADDR		0xFFFFF0000900
#define	IEC61883_CMP_IMPR_ADDR		0xFFFFF0000980
#define	IEC61883_CMP_OMPR_INIT_VAL	0xBFFFFF00
#define	IEC61883_CMP_IMPR_INIT_VAL	0x80FFFF00
#define	IEC61883_CMP_OMPR_LOCK_MASK	0x3FFFFF00
#define	IEC61883_CMP_IMPR_LOCK_MASK	0x00FFFF00

/* s1394_addr_space_blk_t */
struct s1394_addr_space_blk_s {
	/* Pointers and coloring for Red-Black tree */
	s1394_addr_space_blk_t		*asb_parent;
	s1394_addr_space_blk_t		*asb_left;
	s1394_addr_space_blk_t		*asb_right;
	uint32_t			asb_color;
	boolean_t			free_kmem_bufp;

	/* Addr Blk info - callbacks, permissions, backing store, etc. */
	uint64_t			addr_lo;
	uint64_t			addr_hi;
	uint32_t			addr_reserved;
	t1394_addr_enable_t		addr_enable;
	t1394_addr_type_t		addr_type;
	t1394_addr_evts_t		addr_events;
	caddr_t				kmem_bufp;
	void				*addr_arg;
};

/* s1394_config_rom_t */
struct s1394_config_rom_s {
	boolean_t		cfgrom_used;
	uint32_t		cfgrom_addr_lo;
	uint32_t		cfgrom_addr_hi;

	uint_t			root_dir_offset;

	s1394_config_rom_t	*cfgrom_next;
	s1394_config_rom_t	*cfgrom_prev;
};

/* s1394_kstat_t */
struct s1394_kstat_s {
	/* Asynch Receive (AR) requests */
	uint_t			arreq_quad_rd;
	uint_t			arreq_blk_rd;
	uint_t			arreq_quad_wr;
	uint_t			arreq_blk_wr;
	uint_t			arreq_lock32;
	uint_t			arreq_lock64;

	uint_t			arreq_blk_rd_size;
	uint_t			arreq_blk_wr_size;

	uint_t			arreq_posted_write_error;

	/* Failure responses to AR requests (sent) */
	uint_t			arresp_quad_rd_fail;
	uint_t			arresp_blk_rd_fail;
	uint_t			arresp_quad_wr_fail;
	uint_t			arresp_blk_wr_fail;
	uint_t			arresp_lock32_fail;
	uint_t			arresp_lock64_fail;

	/* Asynch Transmit (AT) requests */
	uint_t			atreq_quad_rd;
	uint_t			atreq_blk_rd;
	uint_t			atreq_quad_wr;
	uint_t			atreq_blk_wr;
	uint_t			atreq_lock32;
	uint_t			atreq_lock64;

	uint_t			atreq_blk_rd_size;
	uint_t			atreq_blk_wr_size;

	/* Failure responses to AT requests (received) */
	uint_t			atresp_quad_rd_fail;
	uint_t			atresp_blk_rd_fail;
	uint_t			atresp_quad_wr_fail;
	uint_t			atresp_blk_wr_fail;
	uint_t			atresp_lock32_fail;
	uint_t			atresp_lock64_fail;


	/* Allocate & free requests */
	uint_t			cmd_alloc;
	uint_t			cmd_alloc_fail;
	uint_t			cmd_free;
	uint_t			addr_phys_alloc;
	uint_t			addr_posted_alloc;
	uint_t			addr_normal_alloc;
	uint_t			addr_csr_alloc;
	uint_t			addr_alloc_fail;
	uint_t			addr_space_free;

	/* Bus reset and miscellaneous */
	uint_t			bus_reset;
	uint_t			selfid_complete;
	uint_t			selfid_buffer_error;
	uint_t			pending_q_insert;
	uint64_t		guid;
};

_NOTE(SCHEME_PROTECTS_DATA("Statistics", \
	s1394_kstat_s::{arreq_blk_rd arreq_blk_wr arreq_quad_rd arreq_quad_wr \
	cmd_free selfid_buffer_error arreq_posted_write_error}))

/* s1394_isoch_cec_t */
struct s1394_isoch_cec_s {
	s1394_isoch_cec_t		*cec_next;
	s1394_isoch_cec_t		*cec_prev;

	kmutex_t			isoch_cec_mutex;

	/* Isoch CEC member list */
	s1394_isoch_cec_type_t		cec_type;
	s1394_isoch_cec_member_t	*cec_member_list_head;
	s1394_isoch_cec_member_t	*cec_member_list_tail;
	s1394_isoch_cec_member_t	*cec_member_talker;

	/* Properties given in t1394_alloc_isoch_cec() */
	t1394_isoch_cec_props_t		cec_alloc_props;

	/* Current state of Isoch CEC */
	uint_t				filter_min_speed;
	uint_t				filter_max_speed;
	uint_t				filter_current_speed;
	uint64_t			filter_channel_mask;
	uint_t				bandwidth;
	t1394_cec_options_t		cec_options;
	s1394_isoch_cec_state_t		state_transitions;
	boolean_t			in_callbacks;
	boolean_t			in_fail_callbacks;
	kcondvar_t			in_callbacks_cv;
	boolean_t			cec_want_wakeup;

	boolean_t			realloc_valid;
	boolean_t			realloc_failed;
	t1394_isoch_rsrc_error_t	realloc_fail_reason;
	uint_t				realloc_chnl_num;
	uint_t				realloc_bandwidth;
	uint_t				realloc_speed;
};
#define	CEC_IN_ANY_CALLBACKS(cec)	(((cec)->in_callbacks == B_TRUE) || \
					((cec)->in_fail_callbacks == B_TRUE))

#define	CEC_TRANSITION_LEGAL(cec, tran)	((cec)->state_transitions & (tran))
#define	CEC_SET_LEGAL(cec, tran)	((cec)->state_transitions |= (tran))
#define	CEC_SET_ILLEGAL(cec, tran)	((cec)->state_transitions &= ~(tran))


/* s1394_isoch_cec_member_t */
struct s1394_isoch_cec_member_s {
	s1394_isoch_cec_member_t	*cec_mem_next;
	s1394_isoch_cec_member_t	*cec_mem_prev;

	/* Events for Isoch CEC member - given in t1394_join_isoch_cec() */
	t1394_isoch_cec_evts_t		isoch_cec_evts;
	opaque_t			isoch_cec_evts_arg;
	uint64_t			req_channel_mask;
	uint_t				req_max_speed;
	t1394_jii_options_t		cec_mem_options;
	s1394_target_t			*cec_mem_target;
};

/* cmd1394_fa_cmd_priv_t - per-command data for fixed address support */
typedef struct s1394_fa_cmd_priv_s {
	s1394_fa_type_t		type;
	void			(*completion_callback)();
	opaque_t		callback_arg;
} s1394_fa_cmd_priv_t;

/* s1394_cmd_priv_t */
typedef struct s1394_cmd_priv_s {
	/* Services Layer private structure for asynch commands */
	cmd1394_cmd_t		*cmd_priv_next;
	cmd1394_cmd_t		*cmd_priv_prev;

	uint32_t		cmd_priv_xfer_type;
	s1394_target_t		*sent_by_target;
	s1394_hal_t		*sent_on_hal;

	int			lock_req_step;
	int			temp_num_retries;

	size_t			data_remaining;

	kmutex_t		blocking_mutex;
	kcondvar_t		blocking_cv;
	boolean_t		blocking_flag;

	boolean_t		cmd_in_use;
	boolean_t		posted_write;
	boolean_t		arreq_valid_addr;

	/*
	 * Commands can be extended to support additional functionality.
	 * The only extension at this time is FA (currently used only for FCP).
	 * The downside here is that every command should carry FA overhead
	 * even if the target doesn't use FA. However, alternative approaches
	 * would require separate allocation of FA overhead per command, which
	 * complicates the code and fragments the memory -- seems not worth it
	 * given that FA overhead is just a few bytes and there's a limit of
	 * 256 commands per target.
	 */
	int			cmd_ext_type;
	union {
		s1394_fa_cmd_priv_t	fa;
	} cmd_ext;

	h1394_cmd_priv_t	hal_cmd_private;
} s1394_cmd_priv_t;
#define	S1394_GET_CMD_PRIV(cmd)	\
	((s1394_cmd_priv_t *)((uchar_t *)(cmd) + sizeof (cmd1394_cmd_t)))

/* command extension types */
enum {
	S1394_CMD_EXT_FA	= 1
};
#define	S1394_GET_FA_CMD_PRIV(cmd)	(&(S1394_GET_CMD_PRIV(cmd)->cmd_ext.fa))

#define	S1394_IS_CMD_FCP(s_priv) \
	((s_priv->cmd_ext.fa.type == S1394_FA_TYPE_FCP_CTL) || \
	(s_priv->cmd_ext.fa.type == S1394_FA_TYPE_FCP_TGT))

_NOTE(SCHEME_PROTECTS_DATA("Unique per command", \
	s1394_cmd_priv_s::cmd_priv_xfer_type))


/* s1394_state_t */
typedef struct s1394_state_s {
	/* HAL list */
	kmutex_t	hal_list_mutex;
	s1394_hal_t	*hal_head;
	s1394_hal_t	*hal_tail;
} s1394_state_t;

/* Service Layer Global State Pointer */
extern   s1394_state_t  *s1394_statep;


/* 1394 Services Layer Internals - 1394 Address Space Routines */
int s1394_request_addr_blk(s1394_hal_t *hal, t1394_alloc_addr_t *addr_allocp);

int s1394_claim_addr_blk(s1394_hal_t *hal, t1394_alloc_addr_t *addr_allocp);

int s1394_free_addr_blk(s1394_hal_t *hal, s1394_addr_space_blk_t *blk);

int s1394_reserve_addr_blk(s1394_hal_t *hal, t1394_alloc_addr_t *addr_allocp);

int s1394_init_addr_space(s1394_hal_t *hal);

void s1394_destroy_addr_space(s1394_hal_t *hal);

void s1394_free_list_insert(s1394_hal_t *hal, s1394_addr_space_blk_t *new_blk);

s1394_addr_space_blk_t *s1394_used_tree_search(s1394_hal_t *hal,
    uint64_t addr);

s1394_addr_space_blk_t *s1394_used_tree_delete(s1394_hal_t *hal,
    s1394_addr_space_blk_t *z);

boolean_t s1394_is_posted_write(s1394_hal_t *hal, uint64_t addr);

boolean_t s1394_is_physical_addr(s1394_hal_t *hal, uint64_t addr);

boolean_t s1394_is_csr_addr(s1394_hal_t *hal, uint64_t addr);

boolean_t s1394_is_normal_addr(s1394_hal_t *hal, uint64_t addr);

/* 1394 Services Layer Internals - Asynchronous Communications Routines */
int s1394_alloc_cmd(s1394_hal_t *hal, uint_t flags, cmd1394_cmd_t **cmdp);

int s1394_free_cmd(s1394_hal_t *hal, cmd1394_cmd_t **cmdp);

int s1394_xfer_asynch_command(s1394_hal_t *hal, cmd1394_cmd_t *cmd, int *err);

int s1394_setup_asynch_command(s1394_hal_t *hal, s1394_target_t *target,
    cmd1394_cmd_t *cmd, uint32_t xfer_type, int *err);

void s1394_insert_q_asynch_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd);

void s1394_remove_q_asynch_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd);

void s1394_atreq_cmd_complete(s1394_hal_t *hal, cmd1394_cmd_t *req,
    int status);

void s1394_atresp_cmd_complete(s1394_hal_t *hal, cmd1394_cmd_t *resp,
    int status);

int s1394_send_response(s1394_hal_t *hal, cmd1394_cmd_t *resp);

int s1394_compare_swap(s1394_hal_t *hal, s1394_target_t *target,
    cmd1394_cmd_t *cmd);

int s1394_split_lock_req(s1394_hal_t *hal, s1394_target_t *target,
    cmd1394_cmd_t *cmd);

void s1394_pending_q_insert(s1394_hal_t *hal, cmd1394_cmd_t *cmd, uint_t flags);

void s1394_resend_pending_cmds(s1394_hal_t *hal);

/* 1394 Services Layer Internals - Bus Reset Routines */
int s1394_parse_selfid_buffer(s1394_hal_t *hal, void *selfid_buf_addr,
    uint32_t selfid_size);

void s1394_sort_selfids(s1394_hal_t *hal);

void s1394_init_topology_tree(s1394_hal_t *hal, boolean_t copied,
    ushort_t number_of_nodes);

int s1394_topology_tree_build(s1394_hal_t *hal);

void s1394_topology_tree_mark_all_unvisited(s1394_hal_t *hal);

void s1394_old_tree_mark_all_unvisited(s1394_hal_t *hal);

void s1394_old_tree_mark_all_unmatched(s1394_hal_t *hal);

void s1394_copy_old_tree(s1394_hal_t *hal);

void s1394_match_tree_nodes(s1394_hal_t *hal);

int s1394_topology_tree_calculate_diameter(s1394_hal_t *hal);

int s1394_gap_count_optimize(int diameter);

int s1394_get_current_gap_count(s1394_hal_t *hal);

void s1394_speed_map_fill(s1394_hal_t *hal);

uint8_t s1394_speed_map_get(s1394_hal_t *hal, uint32_t from_node,
    uint32_t to_node);

void s1394_update_speed_map_link_speeds(s1394_hal_t *hal);

int s1394_get_isoch_rsrc_mgr(s1394_hal_t *hal);

void s1394_physical_arreq_setup_all(s1394_hal_t *hal);

void s1394_physical_arreq_set_one(s1394_target_t *target);

void s1394_physical_arreq_clear_one(s1394_target_t *target);

s1394_node_t *s1394_topology_tree_get_root_node(s1394_hal_t *hal);

/* 1394 Services Layer Internals - CSR and Config ROM Routines */
int s1394_setup_CSR_space(s1394_hal_t *hal);

void s1394_CSR_topology_map_update(s1394_hal_t *hal);

void s1394_CSR_topology_map_disable(s1394_hal_t *hal);

int s1394_init_local_config_rom(s1394_hal_t *hal);

void s1394_destroy_local_config_rom(s1394_hal_t *hal);

int s1394_add_config_rom_entry(s1394_hal_t *hal, uint8_t key,
    uint32_t *buffer, uint_t size, void **handle, int *status);

int s1394_remove_config_rom_entry(s1394_hal_t *hal, void **handle,
    int *status);

void s1394_update_config_rom_callback(void *arg);

/* In s1394_dev_disc.c */
void s1394_br_thread(s1394_hal_t *hal);

void s1394_free_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
    s1394_free_cfgrom_t options);

void s1394_copy_cfgrom(s1394_node_t *to, s1394_node_t *from);

int s1394_read_rest_of_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
    s1394_status_t *status);

void s1394_cfgrom_parse_unit_dir(uint32_t *unit_dir, uint32_t *addr_hi,
    uint32_t *addr_lo, uint32_t *size_hi, uint32_t *size_lo);

boolean_t s1394_valid_cfgrom(s1394_hal_t *hal, s1394_node_t *node);

boolean_t s1394_valid_dir(s1394_hal_t *hal, s1394_node_t *node, uint32_t key,
    uint32_t *dir);

void s1394_get_maxpayload(s1394_target_t *target, uint_t *dev_max_payload,
    uint_t *current_max_payload);

int s1394_lock_tree(s1394_hal_t *hal);

void s1394_unlock_tree(s1394_hal_t *hal);

/* 1394 Services Layer Driver - Hotplug Routines */
dev_info_t *s1394_devi_find(dev_info_t *pdip, char *name, char *caddr);

int s1394_update_devinfo_tree(s1394_hal_t *hal, s1394_node_t *node);

int s1394_offline_node(s1394_hal_t *hal, s1394_node_t *node);

int s1394_process_topology_tree(s1394_hal_t *hal, int *wait_for_cbs,
    uint_t *wait_gen);

int s1394_process_old_tree(s1394_hal_t *hal);

void s1394_add_target_to_node(s1394_target_t *target);

void s1394_remove_target_from_node(s1394_target_t *target);

/* fixed address support */
int s1394_fa_claim_addr(s1394_hal_t *hal, s1394_fa_type_t type,
    s1394_fa_descr_t *descr);

void s1394_fa_free_addr(s1394_hal_t *hal, s1394_fa_type_t type);

void s1394_fa_list_add(s1394_hal_t *hal, s1394_target_t *target,
    s1394_fa_type_t type);

int s1394_fa_list_remove(s1394_hal_t *hal, s1394_target_t *target,
    s1394_fa_type_t type);

boolean_t s1394_fa_list_is_empty(s1394_hal_t *hal, s1394_fa_type_t type);

uint_t s1394_fa_list_gen(s1394_hal_t *hal, s1394_fa_type_t type);

void s1394_fa_init_cmd(s1394_cmd_priv_t *s_priv, s1394_fa_type_t type);

void s1394_fa_convert_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd);

void s1394_fa_restore_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd);

void s1394_fa_check_restore_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd);

/* FCP */
int s1394_fcp_hal_init(s1394_hal_t *hal);

int s1394_fcp_register_ctl(s1394_target_t *target, t1394_fcp_evts_t *evts);

int s1394_fcp_register_tgt(s1394_target_t *target, t1394_fcp_evts_t *evts);

int s1394_fcp_unregister_ctl(s1394_target_t *target);

int s1394_fcp_unregister_tgt(s1394_target_t *target);

int s1394_fcp_write_check_cmd(cmd1394_cmd_t *cmd);

/* CMP */
int s1394_cmp_register(s1394_target_t *target, t1394_cmp_evts_t *evts);

int s1394_cmp_unregister(s1394_target_t *target);

int s1394_cmp_read(s1394_target_t *target, t1394_cmp_reg_t reg, uint32_t *valp);

int s1394_cmp_cas(s1394_target_t *target, t1394_cmp_reg_t reg, uint32_t arg_val,
    uint32_t new_val, uint32_t *old_valp);

/* 1394 Services Layer Internals - Isochronous Communication Routines */
void s1394_isoch_rsrc_realloc(s1394_hal_t *hal);

void s1394_isoch_rsrc_realloc_notify(s1394_hal_t *hal);

int s1394_channel_alloc(s1394_hal_t *hal, uint32_t channel_mask,
    uint_t generation, uint_t flags, uint32_t *old_channels, int *result);

int s1394_channel_free(s1394_hal_t *hal, uint32_t channel_mask,
    uint_t generation, uint_t flags, uint32_t *old_channels, int *result);

int s1394_bandwidth_alloc(s1394_hal_t *hal, uint32_t bw_alloc_units,
    uint_t generation, int *result);

uint_t s1394_compute_bw_alloc_units(s1394_hal_t *hal, uint_t bandwidth,
    uint_t speed);

int s1394_bandwidth_free(s1394_hal_t *hal, uint32_t bw_alloc_units,
    uint_t generation, int *result);

void s1394_isoch_cec_list_insert(s1394_hal_t *hal, s1394_isoch_cec_t *cec);

void s1394_isoch_cec_list_remove(s1394_hal_t *hal, s1394_isoch_cec_t *cec);

void s1394_isoch_cec_member_list_insert(s1394_hal_t *hal,
    s1394_isoch_cec_t *cec, s1394_isoch_cec_member_t *member);

void s1394_isoch_cec_member_list_remove(s1394_hal_t *hal,
    s1394_isoch_cec_t *cec, s1394_isoch_cec_member_t *member);

/* 1394 Services Layer Internals - Miscellaneous Routines */
void s1394_cleanup_for_detach(s1394_hal_t *hal, uint_t cleanup_level);

void s1394_hal_shutdown(s1394_hal_t *hal, boolean_t disable_hal);

void s1394_initiate_hal_reset(s1394_hal_t *hal, int reason);

boolean_t s1394_on_br_thread(s1394_hal_t *hal);

void s1394_destroy_br_thread(s1394_hal_t *hal);

void s1394_tickle_bus_reset_thread(s1394_hal_t *hal);

void s1394_block_on_asynch_cmd(cmd1394_cmd_t *cmd);

int s1394_HAL_asynch_error(s1394_hal_t *hal, cmd1394_cmd_t *cmd,
    s1394_hal_state_t state);

boolean_t s1394_mblk_too_small(cmd1394_cmd_t *cmd);

boolean_t s1394_address_rollover(cmd1394_cmd_t *cmd);

uint_t s1394_stoi(char *p, int len, int base);

uint_t s1394_CRC16(uint_t *d, uint_t crc_length);

uint_t s1394_CRC16_old(uint_t *d, uint_t crc_length);

int s1394_ioctl(s1394_hal_t *hal, int cmd, intptr_t arg, int mode,
    cred_t *cred_p, int *rval_p);

void s1394_check_pwr_mgmt(s1394_hal_t *hal, s1394_target_t *target,
    boolean_t add);

int s1394_kstat_init(s1394_hal_t *hal);

int s1394_kstat_delete(s1394_hal_t *hal);

int s1394_kstat_update(kstat_t *ksp, int rw);

void s1394_addr_alloc_kstat(s1394_hal_t *hal, uint64_t addr);

void s1394_print_node_info(s1394_hal_t *hal);

s1394_hal_t *s1394_dip_to_hal(dev_info_t *dip);

s1394_target_t *s1394_target_from_dip(s1394_hal_t *hal, dev_info_t *tdip);
s1394_target_t *s1394_target_from_dip_locked(s1394_hal_t *hal,
    dev_info_t *tdip);

void s1394_destroy_timers(s1394_hal_t *hal);

void s1394_cycle_too_long_callback(void *arg);

#ifdef __cplusplus
}
#endif

#endif	/* _SYS_1394_S1394_H */