myrs.h 36.9 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
/* 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 */