Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

   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
/* SPDX-License-Identifier: GPL-2.0
 *
 * Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 *
 * This driver supports the newer, SCSI-based firmware interface only.
 *
 * Copyright 2018 Hannes Reinecke, SUSE Linux GmbH <hare@suse.com>
 *
 * Based on the original DAC960 driver, which has
 * Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
 * Portions Copyright 2002 by Mylex (An IBM Business Unit)
 */

#ifndef _MYRS_H
#define _MYRS_H

#define MYRS_MAILBOX_TIMEOUT 1000000

#define MYRS_DCMD_TAG 1
#define MYRS_MCMD_TAG 2

#define MYRS_LINE_BUFFER_SIZE 128

#define MYRS_PRIMARY_MONITOR_INTERVAL (10 * HZ)
#define MYRS_SECONDARY_MONITOR_INTERVAL (60 * HZ)

/* Maximum number of Scatter/Gather Segments supported */
#define MYRS_SG_LIMIT		128

/*
 * Number of Command and Status Mailboxes used by the
 * DAC960 V2 Firmware Memory Mailbox Interface.
 */
#define MYRS_MAX_CMD_MBOX		512
#define MYRS_MAX_STAT_MBOX		512

#define MYRS_DCDB_SIZE			16
#define MYRS_SENSE_SIZE			14

/*
 * DAC960 V2 Firmware Command Opcodes.
 */
enum myrs_cmd_opcode {
	MYRS_CMD_OP_MEMCOPY		= 0x01,
	MYRS_CMD_OP_SCSI_10_PASSTHRU	= 0x02,
	MYRS_CMD_OP_SCSI_255_PASSTHRU	= 0x03,
	MYRS_CMD_OP_SCSI_10		= 0x04,
	MYRS_CMD_OP_SCSI_256		= 0x05,
	MYRS_CMD_OP_IOCTL		= 0x20,
} __packed;

/*
 * DAC960 V2 Firmware IOCTL Opcodes.
 */
enum myrs_ioctl_opcode {
	MYRS_IOCTL_GET_CTLR_INFO	= 0x01,
	MYRS_IOCTL_GET_LDEV_INFO_VALID	= 0x03,
	MYRS_IOCTL_GET_PDEV_INFO_VALID	= 0x05,
	MYRS_IOCTL_GET_HEALTH_STATUS	= 0x11,
	MYRS_IOCTL_GET_EVENT		= 0x15,
	MYRS_IOCTL_START_DISCOVERY	= 0x81,
	MYRS_IOCTL_SET_DEVICE_STATE	= 0x82,
	MYRS_IOCTL_INIT_PDEV_START	= 0x84,
	MYRS_IOCTL_INIT_PDEV_STOP	= 0x85,
	MYRS_IOCTL_INIT_LDEV_START	= 0x86,
	MYRS_IOCTL_INIT_LDEV_STOP	= 0x87,
	MYRS_IOCTL_RBLD_DEVICE_START	= 0x88,
	MYRS_IOCTL_RBLD_DEVICE_STOP	= 0x89,
	MYRS_IOCTL_MAKE_CONSISTENT_START = 0x8A,
	MYRS_IOCTL_MAKE_CONSISTENT_STOP = 0x8B,
	MYRS_IOCTL_CC_START		= 0x8C,
	MYRS_IOCTL_CC_STOP		= 0x8D,
	MYRS_IOCTL_SET_MEM_MBOX		= 0x8E,
	MYRS_IOCTL_RESET_DEVICE		= 0x90,
	MYRS_IOCTL_FLUSH_DEVICE_DATA	= 0x91,
	MYRS_IOCTL_PAUSE_DEVICE		= 0x92,
	MYRS_IOCTL_UNPAUS_EDEVICE	= 0x93,
	MYRS_IOCTL_LOCATE_DEVICE	= 0x94,
	MYRS_IOCTL_CREATE_CONFIGURATION = 0xC0,
	MYRS_IOCTL_DELETE_LDEV		= 0xC1,
	MYRS_IOCTL_REPLACE_INTERNALDEVICE = 0xC2,
	MYRS_IOCTL_RENAME_LDEV		= 0xC3,
	MYRS_IOCTL_ADD_CONFIGURATION	= 0xC4,
	MYRS_IOCTL_XLATE_PDEV_TO_LDEV	= 0xC5,
	MYRS_IOCTL_CLEAR_CONFIGURATION	= 0xCA,
} __packed;

/*
 * DAC960 V2 Firmware Command Status Codes.
 */
#define MYRS_STATUS_SUCCESS			0x00
#define MYRS_STATUS_FAILED			0x02
#define MYRS_STATUS_DEVICE_BUSY			0x08
#define MYRS_STATUS_DEVICE_NON_RESPONSIVE	0x0E
#define MYRS_STATUS_DEVICE_NON_RESPONSIVE2	0x0F
#define MYRS_STATUS_RESERVATION_CONFLICT	0x18

/*
 * DAC960 V2 Firmware Memory Type structure.
 */
struct myrs_mem_type {
	enum {
		MYRS_MEMTYPE_RESERVED	= 0x00,
		MYRS_MEMTYPE_DRAM	= 0x01,
		MYRS_MEMTYPE_EDRAM	= 0x02,
		MYRS_MEMTYPE_EDO	= 0x03,
		MYRS_MEMTYPE_SDRAM	= 0x04,
		MYRS_MEMTYPE_LAST	= 0x1F,
	} __packed mem_type:5;	/* Byte 0 Bits 0-4 */
	unsigned rsvd:1;			/* Byte 0 Bit 5 */
	unsigned mem_parity:1;			/* Byte 0 Bit 6 */
	unsigned mem_ecc:1;			/* Byte 0 Bit 7 */
};

/*
 * DAC960 V2 Firmware Processor Type structure.
 */
enum myrs_cpu_type {
	MYRS_CPUTYPE_i960CA	= 0x01,
	MYRS_CPUTYPE_i960RD	= 0x02,
	MYRS_CPUTYPE_i960RN	= 0x03,
	MYRS_CPUTYPE_i960RP	= 0x04,
	MYRS_CPUTYPE_NorthBay	= 0x05,
	MYRS_CPUTYPE_StrongArm	= 0x06,
	MYRS_CPUTYPE_i960RM	= 0x07,
} __packed;

/*
 * DAC960 V2 Firmware Get Controller Info reply structure.
 */
struct myrs_ctlr_info {
	unsigned char rsvd1;				/* Byte 0 */
	enum {
		MYRS_SCSI_BUS	= 0x00,
		MYRS_Fibre_BUS	= 0x01,
		MYRS_PCI_BUS	= 0x03
	} __packed bus;	/* Byte 1 */
	enum {
		MYRS_CTLR_DAC960E	= 0x01,
		MYRS_CTLR_DAC960M	= 0x08,
		MYRS_CTLR_DAC960PD	= 0x10,
		MYRS_CTLR_DAC960PL	= 0x11,
		MYRS_CTLR_DAC960PU	= 0x12,
		MYRS_CTLR_DAC960PE	= 0x13,
		MYRS_CTLR_DAC960PG	= 0x14,
		MYRS_CTLR_DAC960PJ	= 0x15,
		MYRS_CTLR_DAC960PTL0	= 0x16,
		MYRS_CTLR_DAC960PR	= 0x17,
		MYRS_CTLR_DAC960PRL	= 0x18,
		MYRS_CTLR_DAC960PT	= 0x19,
		MYRS_CTLR_DAC1164P	= 0x1A,
		MYRS_CTLR_DAC960PTL1	= 0x1B,
		MYRS_CTLR_EXR2000P	= 0x1C,
		MYRS_CTLR_EXR3000P	= 0x1D,
		MYRS_CTLR_ACCELERAID352 = 0x1E,
		MYRS_CTLR_ACCELERAID170 = 0x1F,
		MYRS_CTLR_ACCELERAID160 = 0x20,
		MYRS_CTLR_DAC960S	= 0x60,
		MYRS_CTLR_DAC960SU	= 0x61,
		MYRS_CTLR_DAC960SX	= 0x62,
		MYRS_CTLR_DAC960SF	= 0x63,
		MYRS_CTLR_DAC960SS	= 0x64,
		MYRS_CTLR_DAC960FL	= 0x65,
		MYRS_CTLR_DAC960LL	= 0x66,
		MYRS_CTLR_DAC960FF	= 0x67,
		MYRS_CTLR_DAC960HP	= 0x68,
		MYRS_CTLR_RAIDBRICK	= 0x69,
		MYRS_CTLR_METEOR_FL	= 0x6A,
		MYRS_CTLR_METEOR_FF	= 0x6B
	} __packed ctlr_type;	/* Byte 2 */
	unsigned char rsvd2;			/* Byte 3 */
	unsigned short bus_speed_mhz;		/* Bytes 4-5 */
	unsigned char bus_width;		/* Byte 6 */
	unsigned char flash_code;		/* Byte 7 */
	unsigned char ports_present;		/* Byte 8 */
	unsigned char rsvd3[7];			/* Bytes 9-15 */
	unsigned char bus_name[16];		/* Bytes 16-31 */
	unsigned char ctlr_name[16];		/* Bytes 32-47 */
	unsigned char rsvd4[16];		/* Bytes 48-63 */
	/* Firmware Release Information */
	unsigned char fw_major_version;		/* Byte 64 */
	unsigned char fw_minor_version;		/* Byte 65 */
	unsigned char fw_turn_number;		/* Byte 66 */
	unsigned char fw_build_number;		/* Byte 67 */
	unsigned char fw_release_day;		/* Byte 68 */
	unsigned char fw_release_month;		/* Byte 69 */
	unsigned char fw_release_year_hi;	/* Byte 70 */
	unsigned char fw_release_year_lo;	/* Byte 71 */
	/* Hardware Release Information */
	unsigned char hw_rev;			/* Byte 72 */
	unsigned char rsvd5[3];			/* Bytes 73-75 */
	unsigned char hw_release_day;		/* Byte 76 */
	unsigned char hw_release_month;		/* Byte 77 */
	unsigned char hw_release_year_hi;	/* Byte 78 */
	unsigned char hw_release_year_lo;	/* Byte 79 */
	/* Hardware Manufacturing Information */
	unsigned char manuf_batch_num;		/* Byte 80 */
	unsigned char rsvd6;			/* Byte 81 */
	unsigned char manuf_plant_num;		/* Byte 82 */
	unsigned char rsvd7;			/* Byte 83 */
	unsigned char hw_manuf_day;		/* Byte 84 */
	unsigned char hw_manuf_month;		/* Byte 85 */
	unsigned char hw_manuf_year_hi;		/* Byte 86 */
	unsigned char hw_manuf_year_lo;		/* Byte 87 */
	unsigned char max_pd_per_xld;		/* Byte 88 */
	unsigned char max_ild_per_xld;		/* Byte 89 */
	unsigned short nvram_size_kb;		/* Bytes 90-91 */
	unsigned char max_xld;			/* Byte 92 */
	unsigned char rsvd8[3];			/* Bytes 93-95 */
	/* Unique Information per Controller */
	unsigned char serial_number[16];	/* Bytes 96-111 */
	unsigned char rsvd9[16];		/* Bytes 112-127 */
	/* Vendor Information */
	unsigned char rsvd10[3];		/* Bytes 128-130 */
	unsigned char oem_code;			/* Byte 131 */
	unsigned char vendor[16];		/* Bytes 132-147 */
	/* Other Physical/Controller/Operation Information */
	unsigned char bbu_present:1;		/* Byte 148 Bit 0 */
	unsigned char cluster_mode:1;		/* Byte 148 Bit 1 */
	unsigned char rsvd11:6;			/* Byte 148 Bits 2-7 */
	unsigned char rsvd12[3];		/* Bytes 149-151 */
	/* Physical Device Scan Information */
	unsigned char pscan_active:1;		/* Byte 152 Bit 0 */
	unsigned char rsvd13:7;			/* Byte 152 Bits 1-7 */
	unsigned char pscan_chan;		/* Byte 153 */
	unsigned char pscan_target;		/* Byte 154 */
	unsigned char pscan_lun;		/* Byte 155 */
	/* Maximum Command Data Transfer Sizes */
	unsigned short max_transfer_size;	/* Bytes 156-157 */
	unsigned short max_sge;			/* Bytes 158-159 */
	/* Logical/Physical Device Counts */
	unsigned short ldev_present;		/* Bytes 160-161 */
	unsigned short ldev_critical;		/* Bytes 162-163 */
	unsigned short ldev_offline;		/* Bytes 164-165 */
	unsigned short pdev_present;		/* Bytes 166-167 */
	unsigned short pdisk_present;		/* Bytes 168-169 */
	unsigned short pdisk_critical;		/* Bytes 170-171 */
	unsigned short pdisk_offline;		/* Bytes 172-173 */
	unsigned short max_tcq;			/* Bytes 174-175 */
	/* Channel and Target ID Information */
	unsigned char physchan_present;		/* Byte 176 */
	unsigned char virtchan_present;		/* Byte 177 */
	unsigned char physchan_max;		/* Byte 178 */
	unsigned char virtchan_max;		/* Byte 179 */
	unsigned char max_targets[16];		/* Bytes 180-195 */
	unsigned char rsvd14[12];		/* Bytes 196-207 */
	/* Memory/Cache Information */
	unsigned short mem_size_mb;		/* Bytes 208-209 */
	unsigned short cache_size_mb;		/* Bytes 210-211 */
	unsigned int valid_cache_bytes;		/* Bytes 212-215 */
	unsigned int dirty_cache_bytes;		/* Bytes 216-219 */
	unsigned short mem_speed_mhz;		/* Bytes 220-221 */
	unsigned char mem_data_width;		/* Byte 222 */
	struct myrs_mem_type mem_type;		/* Byte 223 */
	unsigned char cache_mem_type_name[16];	/* Bytes 224-239 */
	/* Execution Memory Information */
	unsigned short exec_mem_size_mb;	/* Bytes 240-241 */
	unsigned short exec_l2_cache_size_mb;	/* Bytes 242-243 */
	unsigned char rsvd15[8];		/* Bytes 244-251 */
	unsigned short exec_mem_speed_mhz;	/* Bytes 252-253 */
	unsigned char exec_mem_data_width;	/* Byte 254 */
	struct myrs_mem_type exec_mem_type;	/* Byte 255 */
	unsigned char exec_mem_type_name[16];	/* Bytes 256-271 */
	/* CPU Type Information */
	struct {				/* Bytes 272-335 */
		unsigned short cpu_speed_mhz;
		enum myrs_cpu_type cpu_type;
		unsigned char cpu_count;
		unsigned char rsvd16[12];
		unsigned char cpu_name[16];
	} __packed cpu[2];
	/* Debugging/Profiling/Command Time Tracing Information */
	unsigned short cur_prof_page_num;	/* Bytes 336-337 */
	unsigned short num_prof_waiters;	/* Bytes 338-339 */
	unsigned short cur_trace_page_num;	/* Bytes 340-341 */
	unsigned short num_trace_waiters;	/* Bytes 342-343 */
	unsigned char rsvd18[8];		/* Bytes 344-351 */
	/* Error Counters on Physical Devices */
	unsigned short pdev_bus_resets;		/* Bytes 352-353 */
	unsigned short pdev_parity_errors;	/* Bytes 355-355 */
	unsigned short pdev_soft_errors;	/* Bytes 356-357 */
	unsigned short pdev_cmds_failed;	/* Bytes 358-359 */
	unsigned short pdev_misc_errors;	/* Bytes 360-361 */
	unsigned short pdev_cmd_timeouts;	/* Bytes 362-363 */
	unsigned short pdev_sel_timeouts;	/* Bytes 364-365 */
	unsigned short pdev_retries_done;	/* Bytes 366-367 */
	unsigned short pdev_aborts_done;	/* Bytes 368-369 */
	unsigned short pdev_host_aborts_done;	/* Bytes 370-371 */
	unsigned short pdev_predicted_failures;	/* Bytes 372-373 */
	unsigned short pdev_host_cmds_failed;	/* Bytes 374-375 */
	unsigned short pdev_hard_errors;	/* Bytes 376-377 */
	unsigned char rsvd19[6];		/* Bytes 378-383 */
	/* Error Counters on Logical Devices */
	unsigned short ldev_soft_errors;	/* Bytes 384-385 */
	unsigned short ldev_cmds_failed;	/* Bytes 386-387 */
	unsigned short ldev_host_aborts_done;	/* Bytes 388-389 */
	unsigned char rsvd20[2];		/* Bytes 390-391 */
	/* Error Counters on Controller */
	unsigned short ctlr_mem_errors;		/* Bytes 392-393 */
	unsigned short ctlr_host_aborts_done;	/* Bytes 394-395 */
	unsigned char rsvd21[4];		/* Bytes 396-399 */
	/* Long Duration Activity Information */
	unsigned short bg_init_active;		/* Bytes 400-401 */
	unsigned short ldev_init_active;	/* Bytes 402-403 */
	unsigned short pdev_init_active;	/* Bytes 404-405 */
	unsigned short cc_active;		/* Bytes 406-407 */
	unsigned short rbld_active;		/* Bytes 408-409 */
	unsigned short exp_active;		/* Bytes 410-411 */
	unsigned short patrol_active;		/* Bytes 412-413 */
	unsigned char rsvd22[2];		/* Bytes 414-415 */
	/* Flash ROM Information */
	unsigned char flash_type;		/* Byte 416 */
	unsigned char rsvd23;			/* Byte 417 */
	unsigned short flash_size_MB;		/* Bytes 418-419 */
	unsigned int flash_limit;		/* Bytes 420-423 */
	unsigned int flash_count;		/* Bytes 424-427 */
	unsigned char rsvd24[4];		/* Bytes 428-431 */
	unsigned char flash_type_name[16];	/* Bytes 432-447 */
	/* Firmware Run Time Information */
	unsigned char rbld_rate;		/* Byte 448 */
	unsigned char bg_init_rate;		/* Byte 449 */
	unsigned char fg_init_rate;		/* Byte 450 */
	unsigned char cc_rate;			/* Byte 451 */
	unsigned char rsvd25[4];		/* Bytes 452-455 */
	unsigned int max_dp;			/* Bytes 456-459 */
	unsigned int free_dp;			/* Bytes 460-463 */
	unsigned int max_iop;			/* Bytes 464-467 */
	unsigned int free_iop;			/* Bytes 468-471 */
	unsigned short max_combined_len;	/* Bytes 472-473 */
	unsigned short num_cfg_groups;		/* Bytes 474-475 */
	unsigned installation_abort_status:1;	/* Byte 476 Bit 0 */
	unsigned maint_mode_status:1;		/* Byte 476 Bit 1 */
	unsigned rsvd26:6;			/* Byte 476 Bits 2-7 */
	unsigned char rsvd27[6];		/* Bytes 477-511 */
	unsigned char rsvd28[512];		/* Bytes 512-1023 */
};

/*
 * DAC960 V2 Firmware Device State type.
 */
enum myrs_devstate {
	MYRS_DEVICE_UNCONFIGURED	= 0x00,
	MYRS_DEVICE_ONLINE		= 0x01,
	MYRS_DEVICE_REBUILD		= 0x03,
	MYRS_DEVICE_MISSING		= 0x04,
	MYRS_DEVICE_SUSPECTED_CRITICAL	= 0x05,
	MYRS_DEVICE_OFFLINE		= 0x08,
	MYRS_DEVICE_CRITICAL		= 0x09,
	MYRS_DEVICE_SUSPECTED_DEAD	= 0x0C,
	MYRS_DEVICE_COMMANDED_OFFLINE	= 0x10,
	MYRS_DEVICE_STANDBY		= 0x21,
	MYRS_DEVICE_INVALID_STATE	= 0xFF,
} __packed;

/*
 * DAC960 V2 RAID Levels
 */
enum myrs_raid_level {
	MYRS_RAID_LEVEL0	= 0x0,     /* RAID 0 */
	MYRS_RAID_LEVEL1	= 0x1,     /* RAID 1 */
	MYRS_RAID_LEVEL3	= 0x3,     /* RAID 3 right asymmetric parity */
	MYRS_RAID_LEVEL5	= 0x5,     /* RAID 5 right asymmetric parity */
	MYRS_RAID_LEVEL6	= 0x6,     /* RAID 6 (Mylex RAID 6) */
	MYRS_RAID_JBOD		= 0x7,     /* RAID 7 (JBOD) */
	MYRS_RAID_NEWSPAN	= 0x8,     /* New Mylex SPAN */
	MYRS_RAID_LEVEL3F	= 0x9,     /* RAID 3 fixed parity */
	MYRS_RAID_LEVEL3L	= 0xb,     /* RAID 3 left symmetric parity */
	MYRS_RAID_SPAN		= 0xc,     /* current spanning implementation */
	MYRS_RAID_LEVEL5L	= 0xd,     /* RAID 5 left symmetric parity */
	MYRS_RAID_LEVELE	= 0xe,     /* RAID E (concatenation) */
	MYRS_RAID_PHYSICAL	= 0xf,     /* physical device */
} __packed;

enum myrs_stripe_size {
	MYRS_STRIPE_SIZE_0	= 0x0,	/* no stripe (RAID 1, RAID 7, etc) */
	MYRS_STRIPE_SIZE_512B	= 0x1,
	MYRS_STRIPE_SIZE_1K	= 0x2,
	MYRS_STRIPE_SIZE_2K	= 0x3,
	MYRS_STRIPE_SIZE_4K	= 0x4,
	MYRS_STRIPE_SIZE_8K	= 0x5,
	MYRS_STRIPE_SIZE_16K	= 0x6,
	MYRS_STRIPE_SIZE_32K	= 0x7,
	MYRS_STRIPE_SIZE_64K	= 0x8,
	MYRS_STRIPE_SIZE_128K	= 0x9,
	MYRS_STRIPE_SIZE_256K	= 0xa,
	MYRS_STRIPE_SIZE_512K	= 0xb,
	MYRS_STRIPE_SIZE_1M	= 0xc,
} __packed;

enum myrs_cacheline_size {
	MYRS_CACHELINE_ZERO	= 0x0,	/* caching cannot be enabled */
	MYRS_CACHELINE_512B	= 0x1,
	MYRS_CACHELINE_1K	= 0x2,
	MYRS_CACHELINE_2K	= 0x3,
	MYRS_CACHELINE_4K	= 0x4,
	MYRS_CACHELINE_8K	= 0x5,
	MYRS_CACHELINE_16K	= 0x6,
	MYRS_CACHELINE_32K	= 0x7,
	MYRS_CACHELINE_64K	= 0x8,
} __packed;

/*
 * DAC960 V2 Firmware Get Logical Device Info reply structure.
 */
struct myrs_ldev_info {
	unsigned char ctlr;			/* Byte 0 */
	unsigned char channel;			/* Byte 1 */
	unsigned char target;			/* Byte 2 */
	unsigned char lun;			/* Byte 3 */
	enum myrs_devstate dev_state;		/* Byte 4 */
	unsigned char raid_level;		/* Byte 5 */
	enum myrs_stripe_size stripe_size;	/* Byte 6 */
	enum myrs_cacheline_size cacheline_size; /* Byte 7 */
	struct {
		enum {
			MYRS_READCACHE_DISABLED		= 0x0,
			MYRS_READCACHE_ENABLED		= 0x1,
			MYRS_READAHEAD_ENABLED		= 0x2,
			MYRS_INTELLIGENT_READAHEAD_ENABLED = 0x3,
			MYRS_READCACHE_LAST		= 0x7,
		} __packed rce:3; /* Byte 8 Bits 0-2 */
		enum {
			MYRS_WRITECACHE_DISABLED	= 0x0,
			MYRS_LOGICALDEVICE_RO		= 0x1,
			MYRS_WRITECACHE_ENABLED		= 0x2,
			MYRS_INTELLIGENT_WRITECACHE_ENABLED = 0x3,
			MYRS_WRITECACHE_LAST		= 0x7,
		} __packed wce:3; /* Byte 8 Bits 3-5 */
		unsigned rsvd1:1;		/* Byte 8 Bit 6 */
		unsigned ldev_init_done:1;	/* Byte 8 Bit 7 */
	} ldev_control;				/* Byte 8 */
	/* Logical Device Operations Status */
	unsigned char cc_active:1;		/* Byte 9 Bit 0 */
	unsigned char rbld_active:1;		/* Byte 9 Bit 1 */
	unsigned char bg_init_active:1;		/* Byte 9 Bit 2 */
	unsigned char fg_init_active:1;		/* Byte 9 Bit 3 */
	unsigned char migration_active:1;	/* Byte 9 Bit 4 */
	unsigned char patrol_active:1;		/* Byte 9 Bit 5 */
	unsigned char rsvd2:2;			/* Byte 9 Bits 6-7 */
	unsigned char raid5_writeupdate;	/* Byte 10 */
	unsigned char raid5_algo;		/* Byte 11 */
	unsigned short ldev_num;		/* Bytes 12-13 */
	/* BIOS Info */
	unsigned char bios_disabled:1;		/* Byte 14 Bit 0 */
	unsigned char cdrom_boot:1;		/* Byte 14 Bit 1 */
	unsigned char drv_coercion:1;		/* Byte 14 Bit 2 */
	unsigned char write_same_disabled:1;	/* Byte 14 Bit 3 */
	unsigned char hba_mode:1;		/* Byte 14 Bit 4 */
	enum {
		MYRS_GEOMETRY_128_32	= 0x0,
		MYRS_GEOMETRY_255_63	= 0x1,
		MYRS_GEOMETRY_RSVD1	= 0x2,
		MYRS_GEOMETRY_RSVD2	= 0x3
	} __packed drv_geom:2;	/* Byte 14 Bits 5-6 */
	unsigned char super_ra_enabled:1;	/* Byte 14 Bit 7 */
	unsigned char rsvd3;			/* Byte 15 */
	/* Error Counters */
	unsigned short soft_errs;		/* Bytes 16-17 */
	unsigned short cmds_failed;		/* Bytes 18-19 */
	unsigned short cmds_aborted;		/* Bytes 20-21 */
	unsigned short deferred_write_errs;	/* Bytes 22-23 */
	unsigned int rsvd4;			/* Bytes 24-27 */
	unsigned int rsvd5;			/* Bytes 28-31 */
	/* Device Size Information */
	unsigned short rsvd6;			/* Bytes 32-33 */
	unsigned short devsize_bytes;		/* Bytes 34-35 */
	unsigned int orig_devsize;		/* Bytes 36-39 */
	unsigned int cfg_devsize;		/* Bytes 40-43 */
	unsigned int rsvd7;			/* Bytes 44-47 */
	unsigned char ldev_name[32];		/* Bytes 48-79 */
	unsigned char inquiry[36];		/* Bytes 80-115 */
	unsigned char rsvd8[12];		/* Bytes 116-127 */
	u64 last_read_lba;			/* Bytes 128-135 */
	u64 last_write_lba;			/* Bytes 136-143 */
	u64 cc_lba;				/* Bytes 144-151 */
	u64 rbld_lba;				/* Bytes 152-159 */
	u64 bg_init_lba;			/* Bytes 160-167 */
	u64 fg_init_lba;			/* Bytes 168-175 */
	u64 migration_lba;			/* Bytes 176-183 */
	u64 patrol_lba;				/* Bytes 184-191 */
	unsigned char rsvd9[64];		/* Bytes 192-255 */
};

/*
 * DAC960 V2 Firmware Get Physical Device Info reply structure.
 */
struct myrs_pdev_info {
	unsigned char rsvd1;			/* Byte 0 */
	unsigned char channel;			/* Byte 1 */
	unsigned char target;			/* Byte 2 */
	unsigned char lun;			/* Byte 3 */
	/* Configuration Status Bits */
	unsigned char pdev_fault_tolerant:1;	/* Byte 4 Bit 0 */
	unsigned char pdev_connected:1;		/* Byte 4 Bit 1 */
	unsigned char pdev_local_to_ctlr:1;	/* Byte 4 Bit 2 */
	unsigned char rsvd2:5;			/* Byte 4 Bits 3-7 */
	/* Multiple Host/Controller Status Bits */
	unsigned char remote_host_dead:1;	/* Byte 5 Bit 0 */
	unsigned char remove_ctlr_dead:1;	/* Byte 5 Bit 1 */
	unsigned char rsvd3:6;			/* Byte 5 Bits 2-7 */
	enum myrs_devstate dev_state;		/* Byte 6 */
	unsigned char nego_data_width;		/* Byte 7 */
	unsigned short nego_sync_rate;		/* Bytes 8-9 */
	/* Multiported Physical Device Information */
	unsigned char num_ports;		/* Byte 10 */
	unsigned char drv_access_bitmap;	/* Byte 11 */
	unsigned int rsvd4;			/* Bytes 12-15 */
	unsigned char ip_address[16];		/* Bytes 16-31 */
	unsigned short max_tags;		/* Bytes 32-33 */
	/* Physical Device Operations Status */
	unsigned char cc_in_progress:1;		/* Byte 34 Bit 0 */
	unsigned char rbld_in_progress:1;	/* Byte 34 Bit 1 */
	unsigned char makecc_in_progress:1;	/* Byte 34 Bit 2 */
	unsigned char pdevinit_in_progress:1;	/* Byte 34 Bit 3 */
	unsigned char migration_in_progress:1;	/* Byte 34 Bit 4 */
	unsigned char patrol_in_progress:1;	/* Byte 34 Bit 5 */
	unsigned char rsvd5:2;			/* Byte 34 Bits 6-7 */
	unsigned char long_op_status;		/* Byte 35 */
	unsigned char parity_errs;		/* Byte 36 */
	unsigned char soft_errs;		/* Byte 37 */
	unsigned char hard_errs;		/* Byte 38 */
	unsigned char misc_errs;		/* Byte 39 */
	unsigned char cmd_timeouts;		/* Byte 40 */
	unsigned char retries;			/* Byte 41 */
	unsigned char aborts;			/* Byte 42 */
	unsigned char pred_failures;		/* Byte 43 */
	unsigned int rsvd6;			/* Bytes 44-47 */
	unsigned short rsvd7;			/* Bytes 48-49 */
	unsigned short devsize_bytes;		/* Bytes 50-51 */
	unsigned int orig_devsize;		/* Bytes 52-55 */
	unsigned int cfg_devsize;		/* Bytes 56-59 */
	unsigned int rsvd8;			/* Bytes 60-63 */
	unsigned char pdev_name[16];		/* Bytes 64-79 */
	unsigned char rsvd9[16];		/* Bytes 80-95 */
	unsigned char rsvd10[32];		/* Bytes 96-127 */
	unsigned char inquiry[36];		/* Bytes 128-163 */
	unsigned char rsvd11[20];		/* Bytes 164-183 */
	unsigned char rsvd12[8];		/* Bytes 184-191 */
	u64 last_read_lba;			/* Bytes 192-199 */
	u64 last_write_lba;			/* Bytes 200-207 */
	u64 cc_lba;				/* Bytes 208-215 */
	u64 rbld_lba;				/* Bytes 216-223 */
	u64 makecc_lba;				/* Bytes 224-231 */
	u64 devinit_lba;			/* Bytes 232-239 */
	u64 migration_lba;			/* Bytes 240-247 */
	u64 patrol_lba;				/* Bytes 248-255 */
	unsigned char rsvd13[256];		/* Bytes 256-511 */
};

/*
 * DAC960 V2 Firmware Health Status Buffer structure.
 */
struct myrs_fwstat {
	unsigned int uptime_usecs;		/* Bytes 0-3 */
	unsigned int uptime_msecs;		/* Bytes 4-7 */
	unsigned int seconds;			/* Bytes 8-11 */
	unsigned char rsvd1[4];			/* Bytes 12-15 */
	unsigned int epoch;			/* Bytes 16-19 */
	unsigned char rsvd2[4];			/* Bytes 20-23 */
	unsigned int dbg_msgbuf_idx;		/* Bytes 24-27 */
	unsigned int coded_msgbuf_idx;		/* Bytes 28-31 */
	unsigned int cur_timetrace_page;	/* Bytes 32-35 */
	unsigned int cur_prof_page;		/* Bytes 36-39 */
	unsigned int next_evseq;		/* Bytes 40-43 */
	unsigned char rsvd3[4];			/* Bytes 44-47 */
	unsigned char rsvd4[16];		/* Bytes 48-63 */
	unsigned char rsvd5[64];		/* Bytes 64-127 */
};

/*
 * DAC960 V2 Firmware Get Event reply structure.
 */
struct myrs_event {
	unsigned int ev_seq;			/* Bytes 0-3 */
	unsigned int ev_time;			/* Bytes 4-7 */
	unsigned int ev_code;			/* Bytes 8-11 */
	unsigned char rsvd1;			/* Byte 12 */
	unsigned char channel;			/* Byte 13 */
	unsigned char target;			/* Byte 14 */
	unsigned char lun;			/* Byte 15 */
	unsigned int rsvd2;			/* Bytes 16-19 */
	unsigned int ev_parm;			/* Bytes 20-23 */
	unsigned char sense_data[40];		/* Bytes 24-63 */
};

/*
 * DAC960 V2 Firmware Command Control Bits structure.
 */
struct myrs_cmd_ctrl {
	unsigned char fua:1;			/* Byte 0 Bit 0 */
	unsigned char disable_pgout:1;		/* Byte 0 Bit 1 */
	unsigned char rsvd1:1;			/* Byte 0 Bit 2 */
	unsigned char add_sge_mem:1;		/* Byte 0 Bit 3 */
	unsigned char dma_ctrl_to_host:1;	/* Byte 0 Bit 4 */
	unsigned char rsvd2:1;			/* Byte 0 Bit 5 */
	unsigned char no_autosense:1;		/* Byte 0 Bit 6 */
	unsigned char disc_prohibited:1;	/* Byte 0 Bit 7 */
};

/*
 * DAC960 V2 Firmware Command Timeout structure.
 */
struct myrs_cmd_tmo {
	unsigned char tmo_val:6;			/* Byte 0 Bits 0-5 */
	enum {
		MYRS_TMO_SCALE_SECONDS	= 0,
		MYRS_TMO_SCALE_MINUTES	= 1,
		MYRS_TMO_SCALE_HOURS	= 2,
		MYRS_TMO_SCALE_RESERVED = 3
	} __packed tmo_scale:2;		/* Byte 0 Bits 6-7 */
};

/*
 * DAC960 V2 Firmware Physical Device structure.
 */
struct myrs_pdev {
	unsigned char lun;			/* Byte 0 */
	unsigned char target;			/* Byte 1 */
	unsigned char channel:3;		/* Byte 2 Bits 0-2 */
	unsigned char ctlr:5;			/* Byte 2 Bits 3-7 */
} __packed;

/*
 * DAC960 V2 Firmware Logical Device structure.
 */
struct myrs_ldev {
	unsigned short ldev_num;		/* Bytes 0-1 */
	unsigned char rsvd:3;			/* Byte 2 Bits 0-2 */
	unsigned char ctlr:5;			/* Byte 2 Bits 3-7 */
} __packed;

/*
 * DAC960 V2 Firmware Operation Device type.
 */
enum myrs_opdev {
	MYRS_PHYSICAL_DEVICE	= 0x00,
	MYRS_RAID_DEVICE	= 0x01,
	MYRS_PHYSICAL_CHANNEL	= 0x02,
	MYRS_RAID_CHANNEL	= 0x03,
	MYRS_PHYSICAL_CONTROLLER = 0x04,
	MYRS_RAID_CONTROLLER	= 0x05,
	MYRS_CONFIGURATION_GROUP = 0x10,
	MYRS_ENCLOSURE		= 0x11,
} __packed;

/*
 * DAC960 V2 Firmware Translate Physical To Logical Device structure.
 */
struct myrs_devmap {
	unsigned short ldev_num;		/* Bytes 0-1 */
	unsigned short rsvd;			/* Bytes 2-3 */
	unsigned char prev_boot_ctlr;		/* Byte 4 */
	unsigned char prev_boot_channel;	/* Byte 5 */
	unsigned char prev_boot_target;		/* Byte 6 */
	unsigned char prev_boot_lun;		/* Byte 7 */
};

/*
 * DAC960 V2 Firmware Scatter/Gather List Entry structure.
 */
struct myrs_sge {
	u64 sge_addr;			/* Bytes 0-7 */
	u64 sge_count;			/* Bytes 8-15 */
};

/*
 * DAC960 V2 Firmware Data Transfer Memory Address structure.
 */
union myrs_sgl {
	struct myrs_sge sge[2]; /* Bytes 0-31 */
	struct {
		unsigned short sge0_len;	/* Bytes 0-1 */
		unsigned short sge1_len;	/* Bytes 2-3 */
		unsigned short sge2_len;	/* Bytes 4-5 */
		unsigned short rsvd;		/* Bytes 6-7 */
		u64 sge0_addr;			/* Bytes 8-15 */
		u64 sge1_addr;			/* Bytes 16-23 */
		u64 sge2_addr;			/* Bytes 24-31 */
	} ext;
};

/*
 * 64 Byte DAC960 V2 Firmware Command Mailbox structure.
 */
union myrs_cmd_mbox {
	unsigned int words[16];				/* Words 0-15 */
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		unsigned int rsvd1:24;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		unsigned char rsvd2[10];		/* Bytes 22-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} common;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size;				/* Bytes 4-7 */
		u64 sense_addr;				/* Bytes 8-15 */
		struct myrs_pdev pdev;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		unsigned char cdb_len;			/* Byte 21 */
		unsigned char cdb[10];			/* Bytes 22-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} SCSI_10;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size;				/* Bytes 4-7 */
		u64 sense_addr;				/* Bytes 8-15 */
		struct myrs_pdev pdev;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		unsigned char cdb_len;			/* Byte 21 */
		unsigned short rsvd;			/* Bytes 22-23 */
		u64 cdb_addr;				/* Bytes 24-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} SCSI_255;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		unsigned short rsvd1;			/* Bytes 16-17 */
		unsigned char ctlr_num;			/* Byte 18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		unsigned char rsvd2[10];		/* Bytes 22-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} ctlr_info;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		struct myrs_ldev ldev;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		unsigned char rsvd[10];			/* Bytes 22-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} ldev_info;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		struct myrs_pdev pdev;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		unsigned char rsvd[10];			/* Bytes 22-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} pdev_info;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		unsigned short evnum_upper;		/* Bytes 16-17 */
		unsigned char ctlr_num;			/* Byte 18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		unsigned short evnum_lower;		/* Bytes 22-23 */
		unsigned char rsvd[8];			/* Bytes 24-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} get_event;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		union {
			struct myrs_ldev ldev;		/* Bytes 16-18 */
			struct myrs_pdev pdev;		/* Bytes 16-18 */
		};
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		enum myrs_devstate state;		/* Byte 22 */
		unsigned char rsvd[9];			/* Bytes 23-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} set_devstate;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		struct myrs_ldev ldev;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		unsigned char restore_consistency:1;	/* Byte 22 Bit 0 */
		unsigned char initialized_area_only:1;	/* Byte 22 Bit 1 */
		unsigned char rsvd1:6;			/* Byte 22 Bits 2-7 */
		unsigned char rsvd2[9];			/* Bytes 23-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} cc;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		unsigned char first_cmd_mbox_size_kb;	/* Byte 4 */
		unsigned char first_stat_mbox_size_kb;	/* Byte 5 */
		unsigned char second_cmd_mbox_size_kb;	/* Byte 6 */
		unsigned char second_stat_mbox_size_kb;	/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		unsigned int rsvd1:24;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		unsigned char fwstat_buf_size_kb;	/* Byte 22 */
		unsigned char rsvd2;			/* Byte 23 */
		u64 fwstat_buf_addr;			/* Bytes 24-31 */
		u64 first_cmd_mbox_addr;		/* Bytes 32-39 */
		u64 first_stat_mbox_addr;		/* Bytes 40-47 */
		u64 second_cmd_mbox_addr;		/* Bytes 48-55 */
		u64 second_stat_mbox_addr;		/* Bytes 56-63 */
	} set_mbox;
	struct {
		unsigned short id;			/* Bytes 0-1 */
		enum myrs_cmd_opcode opcode;		/* Byte 2 */
		struct myrs_cmd_ctrl control;		/* Byte 3 */
		u32 dma_size:24;			/* Bytes 4-6 */
		unsigned char dma_num;			/* Byte 7 */
		u64 sense_addr;				/* Bytes 8-15 */
		struct myrs_pdev pdev;			/* Bytes 16-18 */
		struct myrs_cmd_tmo tmo;		/* Byte 19 */
		unsigned char sense_len;		/* Byte 20 */
		enum myrs_ioctl_opcode ioctl_opcode;	/* Byte 21 */
		enum myrs_opdev opdev;			/* Byte 22 */
		unsigned char rsvd[9];			/* Bytes 23-31 */
		union myrs_sgl dma_addr;		/* Bytes 32-63 */
	} dev_op;
};

/*
 * DAC960 V2 Firmware Controller Status Mailbox structure.
 */
struct myrs_stat_mbox {
	unsigned short id;		/* Bytes 0-1 */
	unsigned char status;		/* Byte 2 */
	unsigned char sense_len;	/* Byte 3 */
	int residual;			/* Bytes 4-7 */
};

struct myrs_cmdblk {
	union myrs_cmd_mbox mbox;
	unsigned char status;
	unsigned char sense_len;
	int residual;
	struct completion *complete;
	struct myrs_sge *sgl;
	dma_addr_t sgl_addr;
	unsigned char *dcdb;
	dma_addr_t dcdb_dma;
	unsigned char *sense;
	dma_addr_t sense_addr;
};

/*
 * DAC960 Driver Controller structure.
 */
struct myrs_hba {
	void __iomem *io_base;
	void __iomem *mmio_base;
	phys_addr_t io_addr;
	phys_addr_t pci_addr;
	unsigned int irq;

	unsigned char model_name[28];
	unsigned char fw_version[12];

	struct Scsi_Host *host;
	struct pci_dev *pdev;

	unsigned int epoch;
	unsigned int next_evseq;
	/* Monitor flags */
	bool needs_update;
	bool disable_enc_msg;

	struct workqueue_struct *work_q;
	char work_q_name[20];
	struct delayed_work monitor_work;
	unsigned long primary_monitor_time;
	unsigned long secondary_monitor_time;

	spinlock_t queue_lock;

	struct dma_pool *sg_pool;
	struct dma_pool *sense_pool;
	struct dma_pool *dcdb_pool;

	void (*write_cmd_mbox)(union myrs_cmd_mbox *next_mbox,
			       union myrs_cmd_mbox *cmd_mbox);
	void (*get_cmd_mbox)(void __iomem *base);
	void (*disable_intr)(void __iomem *base);
	void (*reset)(void __iomem *base);

	dma_addr_t cmd_mbox_addr;
	size_t cmd_mbox_size;
	union myrs_cmd_mbox *first_cmd_mbox;
	union myrs_cmd_mbox *last_cmd_mbox;
	union myrs_cmd_mbox *next_cmd_mbox;
	union myrs_cmd_mbox *prev_cmd_mbox1;
	union myrs_cmd_mbox *prev_cmd_mbox2;

	dma_addr_t stat_mbox_addr;
	size_t stat_mbox_size;
	struct myrs_stat_mbox *first_stat_mbox;
	struct myrs_stat_mbox *last_stat_mbox;
	struct myrs_stat_mbox *next_stat_mbox;

	struct myrs_cmdblk dcmd_blk;
	struct myrs_cmdblk mcmd_blk;
	struct mutex dcmd_mutex;

	struct myrs_fwstat *fwstat_buf;
	dma_addr_t fwstat_addr;

	struct myrs_ctlr_info *ctlr_info;
	struct mutex cinfo_mutex;

	struct myrs_event *event_buf;
};

typedef unsigned char (*enable_mbox_t)(void __iomem *base, dma_addr_t addr);
typedef int (*myrs_hwinit_t)(struct pci_dev *pdev,
			     struct myrs_hba *c, void __iomem *base);

struct myrs_privdata {
	myrs_hwinit_t		hw_init;
	irq_handler_t		irq_handler;
	unsigned int		mmio_size;
};

/*
 * DAC960 GEM Series Controller Interface Register Offsets.
 */

#define DAC960_GEM_mmio_size	0x600

enum DAC960_GEM_reg_offset {
	DAC960_GEM_IDB_READ_OFFSET	= 0x214,
	DAC960_GEM_IDB_CLEAR_OFFSET	= 0x218,
	DAC960_GEM_ODB_READ_OFFSET	= 0x224,
	DAC960_GEM_ODB_CLEAR_OFFSET	= 0x228,
	DAC960_GEM_IRQSTS_OFFSET	= 0x208,
	DAC960_GEM_IRQMASK_READ_OFFSET	= 0x22C,
	DAC960_GEM_IRQMASK_CLEAR_OFFSET	= 0x230,
	DAC960_GEM_CMDMBX_OFFSET	= 0x510,
	DAC960_GEM_CMDSTS_OFFSET	= 0x518,
	DAC960_GEM_ERRSTS_READ_OFFSET	= 0x224,
	DAC960_GEM_ERRSTS_CLEAR_OFFSET	= 0x228,
};

/*
 * DAC960 GEM Series Inbound Door Bell Register.
 */
#define DAC960_GEM_IDB_HWMBOX_NEW_CMD	0x01
#define DAC960_GEM_IDB_HWMBOX_ACK_STS	0x02
#define DAC960_GEM_IDB_GEN_IRQ		0x04
#define DAC960_GEM_IDB_CTRL_RESET	0x08
#define DAC960_GEM_IDB_MMBOX_NEW_CMD	0x10

#define DAC960_GEM_IDB_HWMBOX_FULL	0x01
#define DAC960_GEM_IDB_INIT_IN_PROGRESS	0x02

/*
 * DAC960 GEM Series Outbound Door Bell Register.
 */
#define DAC960_GEM_ODB_HWMBOX_ACK_IRQ	0x01
#define DAC960_GEM_ODB_MMBOX_ACK_IRQ	0x02
#define DAC960_GEM_ODB_HWMBOX_STS_AVAIL 0x01
#define DAC960_GEM_ODB_MMBOX_STS_AVAIL	0x02

/*
 * DAC960 GEM Series Interrupt Mask Register.
 */
#define DAC960_GEM_IRQMASK_HWMBOX_IRQ	0x01
#define DAC960_GEM_IRQMASK_MMBOX_IRQ	0x02

/*
 * DAC960 GEM Series Error Status Register.
 */
#define DAC960_GEM_ERRSTS_PENDING	0x20

/*
 * dma_addr_writeql is provided to write dma_addr_t types
 * to a 64-bit pci address space register.  The controller
 * will accept having the register written as two 32-bit
 * values.
 *
 * In HIGHMEM kernels, dma_addr_t is a 64-bit value.
 * without HIGHMEM,  dma_addr_t is a 32-bit value.
 *
 * The compiler should always fix up the assignment
 * to u.wq appropriately, depending upon the size of
 * dma_addr_t.
 */
static inline
void dma_addr_writeql(dma_addr_t addr, void __iomem *write_address)
{
	union {
		u64 wq;
		uint wl[2];
	} u;

	u.wq = addr;

	writel(u.wl[0], write_address);
	writel(u.wl[1], write_address + 4);
}

/*
 * DAC960 BA Series Controller Interface Register Offsets.
 */

#define DAC960_BA_mmio_size		0x80

enum DAC960_BA_reg_offset {
	DAC960_BA_IRQSTS_OFFSET	= 0x30,
	DAC960_BA_IRQMASK_OFFSET = 0x34,
	DAC960_BA_CMDMBX_OFFSET = 0x50,
	DAC960_BA_CMDSTS_OFFSET = 0x58,
	DAC960_BA_IDB_OFFSET	= 0x60,
	DAC960_BA_ODB_OFFSET	= 0x61,
	DAC960_BA_ERRSTS_OFFSET = 0x63,
};

/*
 * DAC960 BA Series Inbound Door Bell Register.
 */
#define DAC960_BA_IDB_HWMBOX_NEW_CMD	0x01
#define DAC960_BA_IDB_HWMBOX_ACK_STS	0x02
#define DAC960_BA_IDB_GEN_IRQ		0x04
#define DAC960_BA_IDB_CTRL_RESET	0x08
#define DAC960_BA_IDB_MMBOX_NEW_CMD	0x10

#define DAC960_BA_IDB_HWMBOX_EMPTY	0x01
#define DAC960_BA_IDB_INIT_DONE		0x02

/*
 * DAC960 BA Series Outbound Door Bell Register.
 */
#define DAC960_BA_ODB_HWMBOX_ACK_IRQ	0x01
#define DAC960_BA_ODB_MMBOX_ACK_IRQ	0x02

#define DAC960_BA_ODB_HWMBOX_STS_AVAIL	0x01
#define DAC960_BA_ODB_MMBOX_STS_AVAIL	0x02

/*
 * DAC960 BA Series Interrupt Mask Register.
 */
#define DAC960_BA_IRQMASK_DISABLE_IRQ	0x04
#define DAC960_BA_IRQMASK_DISABLEW_I2O	0x08

/*
 * DAC960 BA Series Error Status Register.
 */
#define DAC960_BA_ERRSTS_PENDING	0x04

/*
 * DAC960 LP Series Controller Interface Register Offsets.
 */

#define DAC960_LP_mmio_size		0x80

enum DAC960_LP_reg_offset {
	DAC960_LP_CMDMBX_OFFSET = 0x10,
	DAC960_LP_CMDSTS_OFFSET = 0x18,
	DAC960_LP_IDB_OFFSET	= 0x20,
	DAC960_LP_ODB_OFFSET	= 0x2C,
	DAC960_LP_ERRSTS_OFFSET = 0x2E,
	DAC960_LP_IRQSTS_OFFSET	= 0x30,
	DAC960_LP_IRQMASK_OFFSET = 0x34,
};

/*
 * DAC960 LP Series Inbound Door Bell Register.
 */
#define DAC960_LP_IDB_HWMBOX_NEW_CMD	0x01
#define DAC960_LP_IDB_HWMBOX_ACK_STS	0x02
#define DAC960_LP_IDB_GEN_IRQ		0x04
#define DAC960_LP_IDB_CTRL_RESET	0x08
#define DAC960_LP_IDB_MMBOX_NEW_CMD	0x10

#define DAC960_LP_IDB_HWMBOX_FULL	0x01
#define DAC960_LP_IDB_INIT_IN_PROGRESS	0x02

/*
 * DAC960 LP Series Outbound Door Bell Register.
 */
#define DAC960_LP_ODB_HWMBOX_ACK_IRQ	0x01
#define DAC960_LP_ODB_MMBOX_ACK_IRQ	0x02

#define DAC960_LP_ODB_HWMBOX_STS_AVAIL	0x01
#define DAC960_LP_ODB_MMBOX_STS_AVAIL	0x02

/*
 * DAC960 LP Series Interrupt Mask Register.
 */
#define DAC960_LP_IRQMASK_DISABLE_IRQ	0x04

/*
 * DAC960 LP Series Error Status Register.
 */
#define DAC960_LP_ERRSTS_PENDING	0x04

#endif /* _MYRS_H */