|
root / base / usr / src / uts / common / sys / 1394 / s1394.h
s1394.h C 1212 lines 35.4 KB
   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 */