Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

Loading...
   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
/*
 *  Copyright (C) 2004 - 2010 Vladislav Bolkhovitin <vst@vlnb.net>
 *  Copyright (C) 2004 - 2005 Leonid Stoljar
 *  Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
 *  Copyright (C) 2007 - 2010 ID7 Ltd.
 *
 *  Forward port and refactoring to modern qla2xxx and target/configfs
 *
 *  Copyright (C) 2010-2011 Nicholas A. Bellinger <nab@kernel.org>
 *
 *  Additional file for the target driver support.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 */
/*
 * This is the global def file that is useful for including from the
 * target portion.
 */

#ifndef __QLA_TARGET_H
#define __QLA_TARGET_H

#include "qla_def.h"

/*
 * Must be changed on any change in any initiator visible interfaces or
 * data in the target add-on
 */
#define QLA2XXX_TARGET_MAGIC	269

/*
 * Must be changed on any change in any target visible interfaces or
 * data in the initiator
 */
#define QLA2XXX_INITIATOR_MAGIC   57222

#define QLA2XXX_INI_MODE_STR_EXCLUSIVE	"exclusive"
#define QLA2XXX_INI_MODE_STR_DISABLED	"disabled"
#define QLA2XXX_INI_MODE_STR_ENABLED	"enabled"

#define QLA2XXX_INI_MODE_EXCLUSIVE	0
#define QLA2XXX_INI_MODE_DISABLED	1
#define QLA2XXX_INI_MODE_ENABLED	2

#define QLA2XXX_COMMAND_COUNT_INIT	250
#define QLA2XXX_IMMED_NOTIFY_COUNT_INIT 250

/*
 * Used to mark which completion handles (for RIO Status's) are for CTIO's
 * vs. regular (non-target) info. This is checked for in
 * qla2x00_process_response_queue() to see if a handle coming back in a
 * multi-complete should come to the tgt driver or be handled there by qla2xxx
 */
#define CTIO_COMPLETION_HANDLE_MARK	BIT_29
#if (CTIO_COMPLETION_HANDLE_MARK <= DEFAULT_OUTSTANDING_COMMANDS)
#error "CTIO_COMPLETION_HANDLE_MARK not larger than "
	"DEFAULT_OUTSTANDING_COMMANDS"
#endif
#define HANDLE_IS_CTIO_COMP(h) (h & CTIO_COMPLETION_HANDLE_MARK)

/* Used to mark CTIO as intermediate */
#define CTIO_INTERMEDIATE_HANDLE_MARK	BIT_30

#ifndef OF_SS_MODE_0
/*
 * ISP target entries - Flags bit definitions.
 */
#define OF_SS_MODE_0        0
#define OF_SS_MODE_1        1
#define OF_SS_MODE_2        2
#define OF_SS_MODE_3        3

#define OF_EXPL_CONF        BIT_5       /* Explicit Confirmation Requested */
#define OF_DATA_IN          BIT_6       /* Data in to initiator */
					/*  (data from target to initiator) */
#define OF_DATA_OUT         BIT_7       /* Data out from initiator */
					/*  (data from initiator to target) */
#define OF_NO_DATA          (BIT_7 | BIT_6)
#define OF_INC_RC           BIT_8       /* Increment command resource count */
#define OF_FAST_POST        BIT_9       /* Enable mailbox fast posting. */
#define OF_CONF_REQ         BIT_13      /* Confirmation Requested */
#define OF_TERM_EXCH        BIT_14      /* Terminate exchange */
#define OF_SSTS             BIT_15      /* Send SCSI status */
#endif

#ifndef QLA_TGT_DATASEGS_PER_CMD32
#define QLA_TGT_DATASEGS_PER_CMD32	3
#define QLA_TGT_DATASEGS_PER_CONT32	7
#define QLA_TGT_MAX_SG32(ql) \
	(((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD32 + \
		QLA_TGT_DATASEGS_PER_CONT32*((ql) - 1)) : 0)

#define QLA_TGT_DATASEGS_PER_CMD64	2
#define QLA_TGT_DATASEGS_PER_CONT64	5
#define QLA_TGT_MAX_SG64(ql) \
	(((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD64 + \
		QLA_TGT_DATASEGS_PER_CONT64*((ql) - 1)) : 0)
#endif

#ifndef QLA_TGT_DATASEGS_PER_CMD_24XX
#define QLA_TGT_DATASEGS_PER_CMD_24XX	1
#define QLA_TGT_DATASEGS_PER_CONT_24XX	5
#define QLA_TGT_MAX_SG_24XX(ql) \
	(min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \
		QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0))
#endif
#endif

#define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha))			\
			 ? le16_to_cpu((iocb)->u.isp2x.target.extended)	\
			 : (uint16_t)(iocb)->u.isp2x.target.id.standard)

#ifndef IMMED_NOTIFY_TYPE
#define IMMED_NOTIFY_TYPE 0x0D		/* Immediate notify entry. */
/*
 * ISP queue -	immediate notify entry structure definition.
 *		This is sent by the ISP to the Target driver.
 *		This IOCB would have report of events sent by the
 *		initiator, that needs to be handled by the target
 *		driver immediately.
 */
struct imm_ntfy_from_isp {
	uint8_t	 entry_type;		    /* Entry type. */
	uint8_t	 entry_count;		    /* Entry count. */
	uint8_t	 sys_define;		    /* System defined. */
	uint8_t	 entry_status;		    /* Entry Status. */
	union {
		struct {
			uint32_t sys_define_2; /* System defined. */
			target_id_t target;
			uint16_t lun;
			uint8_t  target_id;
			uint8_t  reserved_1;
			uint16_t status_modifier;
			uint16_t status;
			uint16_t task_flags;
			uint16_t seq_id;
			uint16_t srr_rx_id;
			uint32_t srr_rel_offs;
			uint16_t srr_ui;
#define SRR_IU_DATA_IN	0x1
#define SRR_IU_DATA_OUT	0x5
#define SRR_IU_STATUS	0x7
			uint16_t srr_ox_id;
			uint8_t reserved_2[28];
		} isp2x;
		struct {
			uint32_t reserved;
			uint16_t nport_handle;
			uint16_t reserved_2;
			uint16_t flags;
#define NOTIFY24XX_FLAGS_GLOBAL_TPRLO   BIT_1
#define NOTIFY24XX_FLAGS_PUREX_IOCB     BIT_0
			uint16_t srr_rx_id;
			uint16_t status;
			uint8_t  status_subcode;
			uint8_t  fw_handle;
			uint32_t exchange_address;
			uint32_t srr_rel_offs;
			uint16_t srr_ui;
			uint16_t srr_ox_id;
			uint8_t  reserved_4[19];
			uint8_t  vp_index;
			uint32_t reserved_5;
			uint8_t  port_id[3];
			uint8_t  reserved_6;
		} isp24;
	} u;
	uint16_t reserved_7;
	uint16_t ox_id;
} __packed;
#endif

#ifndef NOTIFY_ACK_TYPE
#define NOTIFY_ACK_TYPE 0x0E	  /* Notify acknowledge entry. */
/*
 * ISP queue -	notify acknowledge entry structure definition.
 *		This is sent to the ISP from the target driver.
 */
struct nack_to_isp {
	uint8_t	 entry_type;		    /* Entry type. */
	uint8_t	 entry_count;		    /* Entry count. */
	uint8_t	 sys_define;		    /* System defined. */
	uint8_t	 entry_status;		    /* Entry Status. */
	union {
		struct {
			uint32_t sys_define_2; /* System defined. */
			target_id_t target;
			uint8_t	 target_id;
			uint8_t	 reserved_1;
			uint16_t flags;
			uint16_t resp_code;
			uint16_t status;
			uint16_t task_flags;
			uint16_t seq_id;
			uint16_t srr_rx_id;
			uint32_t srr_rel_offs;
			uint16_t srr_ui;
			uint16_t srr_flags;
			uint16_t srr_reject_code;
			uint8_t  srr_reject_vendor_uniq;
			uint8_t  srr_reject_code_expl;
			uint8_t  reserved_2[24];
		} isp2x;
		struct {
			uint32_t handle;
			uint16_t nport_handle;
			uint16_t reserved_1;
			uint16_t flags;
			uint16_t srr_rx_id;
			uint16_t status;
			uint8_t  status_subcode;
			uint8_t  fw_handle;
			uint32_t exchange_address;
			uint32_t srr_rel_offs;
			uint16_t srr_ui;
			uint16_t srr_flags;
			uint8_t  reserved_4[19];
			uint8_t  vp_index;
			uint8_t  srr_reject_vendor_uniq;
			uint8_t  srr_reject_code_expl;
			uint8_t  srr_reject_code;
			uint8_t  reserved_5[5];
		} isp24;
	} u;
	uint8_t  reserved[2];
	uint16_t ox_id;
} __packed;
#define NOTIFY_ACK_SRR_FLAGS_ACCEPT	0
#define NOTIFY_ACK_SRR_FLAGS_REJECT	1

#define NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM	0x9

#define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL		0
#define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_UNABLE_TO_SUPPLY_DATA	0x2a

#define NOTIFY_ACK_SUCCESS      0x01
#endif

#ifndef ACCEPT_TGT_IO_TYPE
#define ACCEPT_TGT_IO_TYPE 0x16 /* Accept target I/O entry. */
#endif

#ifndef CONTINUE_TGT_IO_TYPE
#define CONTINUE_TGT_IO_TYPE 0x17
/*
 * ISP queue -	Continue Target I/O (CTIO) entry for status mode 0 structure.
 *		This structure is sent to the ISP 2xxx from target driver.
 */
struct ctio_to_2xxx {
	uint8_t	 entry_type;		/* Entry type. */
	uint8_t	 entry_count;		/* Entry count. */
	uint8_t	 sys_define;		/* System defined. */
	uint8_t	 entry_status;		/* Entry Status. */
	uint32_t handle;		/* System defined handle */
	target_id_t target;
	uint16_t rx_id;
	uint16_t flags;
	uint16_t status;
	uint16_t timeout;		/* 0 = 30 seconds, 0xFFFF = disable */
	uint16_t dseg_count;		/* Data segment count. */
	uint32_t relative_offset;
	uint32_t residual;
	uint16_t reserved_1[3];
	uint16_t scsi_status;
	uint32_t transfer_length;
	uint32_t dseg_0_address;	/* Data segment 0 address. */
	uint32_t dseg_0_length;		/* Data segment 0 length. */
	uint32_t dseg_1_address;	/* Data segment 1 address. */
	uint32_t dseg_1_length;		/* Data segment 1 length. */
	uint32_t dseg_2_address;	/* Data segment 2 address. */
	uint32_t dseg_2_length;		/* Data segment 2 length. */
} __packed;
#define ATIO_PATH_INVALID       0x07
#define ATIO_CANT_PROV_CAP      0x16
#define ATIO_CDB_VALID          0x3D

#define ATIO_EXEC_READ          BIT_1
#define ATIO_EXEC_WRITE         BIT_0
#endif

#ifndef CTIO_A64_TYPE
#define CTIO_A64_TYPE 0x1F
#define CTIO_SUCCESS			0x01
#define CTIO_ABORTED			0x02
#define CTIO_INVALID_RX_ID		0x08
#define CTIO_TIMEOUT			0x0B
#define CTIO_LIP_RESET			0x0E
#define CTIO_TARGET_RESET		0x17
#define CTIO_PORT_UNAVAILABLE		0x28
#define CTIO_PORT_LOGGED_OUT		0x29
#define CTIO_PORT_CONF_CHANGED		0x2A
#define CTIO_SRR_RECEIVED		0x45
#endif

#ifndef CTIO_RET_TYPE
#define CTIO_RET_TYPE	0x17		/* CTIO return entry */
#define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */

struct fcp_hdr {
	uint8_t  r_ctl;
	uint8_t  d_id[3];
	uint8_t  cs_ctl;
	uint8_t  s_id[3];
	uint8_t  type;
	uint8_t  f_ctl[3];
	uint8_t  seq_id;
	uint8_t  df_ctl;
	uint16_t seq_cnt;
	uint16_t ox_id;
	uint16_t rx_id;
	uint32_t parameter;
} __packed;

struct fcp_hdr_le {
	uint8_t  d_id[3];
	uint8_t  r_ctl;
	uint8_t  s_id[3];
	uint8_t  cs_ctl;
	uint8_t  f_ctl[3];
	uint8_t  type;
	uint16_t seq_cnt;
	uint8_t  df_ctl;
	uint8_t  seq_id;
	uint16_t rx_id;
	uint16_t ox_id;
	uint32_t parameter;
} __packed;

#define F_CTL_EXCH_CONTEXT_RESP	BIT_23
#define F_CTL_SEQ_CONTEXT_RESIP	BIT_22
#define F_CTL_LAST_SEQ		BIT_20
#define F_CTL_END_SEQ		BIT_19
#define F_CTL_SEQ_INITIATIVE	BIT_16

#define R_CTL_BASIC_LINK_SERV	0x80
#define R_CTL_B_ACC		0x4
#define R_CTL_B_RJT		0x5

struct atio7_fcp_cmnd {
	uint64_t lun;
	uint8_t  cmnd_ref;
	uint8_t  task_attr:3;
	uint8_t  reserved:5;
	uint8_t  task_mgmt_flags;
#define FCP_CMND_TASK_MGMT_CLEAR_ACA		6
#define FCP_CMND_TASK_MGMT_TARGET_RESET		5
#define FCP_CMND_TASK_MGMT_LU_RESET		4
#define FCP_CMND_TASK_MGMT_CLEAR_TASK_SET	2
#define FCP_CMND_TASK_MGMT_ABORT_TASK_SET	1
	uint8_t  wrdata:1;
	uint8_t  rddata:1;
	uint8_t  add_cdb_len:6;
	uint8_t  cdb[16];
	/*
	 * add_cdb is optional and can absent from struct atio7_fcp_cmnd. Size 4
	 * only to make sizeof(struct atio7_fcp_cmnd) be as expected by
	 * BUILD_BUG_ON in qlt_init().
	 */
	uint8_t  add_cdb[4];
	/* uint32_t data_length; */
} __packed;

/*
 * ISP queue -	Accept Target I/O (ATIO) type entry IOCB structure.
 *		This is sent from the ISP to the target driver.
 */
struct atio_from_isp {
	union {
		struct {
			uint16_t entry_hdr;
			uint8_t  sys_define;   /* System defined. */
			uint8_t  entry_status; /* Entry Status.   */
			uint32_t sys_define_2; /* System defined. */
			target_id_t target;
			uint16_t rx_id;
			uint16_t flags;
			uint16_t status;
			uint8_t  command_ref;
			uint8_t  task_codes;
			uint8_t  task_flags;
			uint8_t  execution_codes;
			uint8_t  cdb[MAX_CMDSZ];
			uint32_t data_length;
			uint16_t lun;
			uint8_t  initiator_port_name[WWN_SIZE]; /* on qla23xx */
			uint16_t reserved_32[6];
			uint16_t ox_id;
		} isp2x;
		struct {
			uint16_t entry_hdr;
			uint8_t  fcp_cmnd_len_low;
			uint8_t  fcp_cmnd_len_high:4;
			uint8_t  attr:4;
			uint32_t exchange_addr;
#define ATIO_EXCHANGE_ADDRESS_UNKNOWN	0xFFFFFFFF
			struct fcp_hdr fcp_hdr;
			struct atio7_fcp_cmnd fcp_cmnd;
		} isp24;
		struct {
			uint8_t  entry_type;	/* Entry type. */
			uint8_t  entry_count;	/* Entry count. */
			uint8_t  data[58];
			uint32_t signature;
#define ATIO_PROCESSED 0xDEADDEAD		/* Signature */
		} raw;
	} u;
} __packed;

#define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */

/*
 * ISP queue -	Continue Target I/O (ATIO) type 7 entry (for 24xx) structure.
 *		This structure is sent to the ISP 24xx from the target driver.
 */

struct ctio7_to_24xx {
	uint8_t	 entry_type;		    /* Entry type. */
	uint8_t	 entry_count;		    /* Entry count. */
	uint8_t	 sys_define;		    /* System defined. */
	uint8_t	 entry_status;		    /* Entry Status. */
	uint32_t handle;		    /* System defined handle */
	uint16_t nport_handle;
#define CTIO7_NHANDLE_UNRECOGNIZED	0xFFFF
	uint16_t timeout;
	uint16_t dseg_count;		    /* Data segment count. */
	uint8_t  vp_index;
	uint8_t  add_flags;
	uint8_t  initiator_id[3];
	uint8_t  reserved;
	uint32_t exchange_addr;
	union {
		struct {
			uint16_t reserved1;
			uint16_t flags;
			uint32_t residual;
			uint16_t ox_id;
			uint16_t scsi_status;
			uint32_t relative_offset;
			uint32_t reserved2;
			uint32_t transfer_length;
			uint32_t reserved3;
			/* Data segment 0 address. */
			uint32_t dseg_0_address[2];
			/* Data segment 0 length. */
			uint32_t dseg_0_length;
		} status0;
		struct {
			uint16_t sense_length;
			uint16_t flags;
			uint32_t residual;
			uint16_t ox_id;
			uint16_t scsi_status;
			uint16_t response_len;
			uint16_t reserved;
			uint8_t sense_data[24];
		} status1;
	} u;
} __packed;

/*
 * ISP queue - CTIO type 7 from ISP 24xx to target driver
 * returned entry structure.
 */
struct ctio7_from_24xx {
	uint8_t	 entry_type;		    /* Entry type. */
	uint8_t	 entry_count;		    /* Entry count. */
	uint8_t	 sys_define;		    /* System defined. */
	uint8_t	 entry_status;		    /* Entry Status. */
	uint32_t handle;		    /* System defined handle */
	uint16_t status;
	uint16_t timeout;
	uint16_t dseg_count;		    /* Data segment count. */
	uint8_t  vp_index;
	uint8_t  reserved1[5];
	uint32_t exchange_address;
	uint16_t reserved2;
	uint16_t flags;
	uint32_t residual;
	uint16_t ox_id;
	uint16_t reserved3;
	uint32_t relative_offset;
	uint8_t  reserved4[24];
} __packed;

/* CTIO7 flags values */
#define CTIO7_FLAGS_SEND_STATUS		BIT_15
#define CTIO7_FLAGS_TERMINATE		BIT_14
#define CTIO7_FLAGS_CONFORM_REQ		BIT_13
#define CTIO7_FLAGS_DONT_RET_CTIO	BIT_8
#define CTIO7_FLAGS_STATUS_MODE_0	0
#define CTIO7_FLAGS_STATUS_MODE_1	BIT_6
#define CTIO7_FLAGS_EXPLICIT_CONFORM	BIT_5
#define CTIO7_FLAGS_CONFIRM_SATISF	BIT_4
#define CTIO7_FLAGS_DSD_PTR		BIT_2
#define CTIO7_FLAGS_DATA_IN		BIT_1
#define CTIO7_FLAGS_DATA_OUT		BIT_0

#define ELS_PLOGI			0x3
#define ELS_FLOGI			0x4
#define ELS_LOGO			0x5
#define ELS_PRLI			0x20
#define ELS_PRLO			0x21
#define ELS_TPRLO			0x24
#define ELS_PDISC			0x50
#define ELS_ADISC			0x52

/*
 * ISP queue - ABTS received/response entries structure definition for 24xx.
 */
#define ABTS_RECV_24XX		0x54 /* ABTS received (for 24xx) */
#define ABTS_RESP_24XX		0x55 /* ABTS responce (for 24xx) */

/*
 * ISP queue -	ABTS received IOCB entry structure definition for 24xx.
 *		The ABTS BLS received from the wire is sent to the
 *		target driver by the ISP 24xx.
 *		The IOCB is placed on the response queue.
 */
struct abts_recv_from_24xx {
	uint8_t	 entry_type;		    /* Entry type. */
	uint8_t	 entry_count;		    /* Entry count. */
	uint8_t	 sys_define;		    /* System defined. */
	uint8_t	 entry_status;		    /* Entry Status. */
	uint8_t  reserved_1[6];
	uint16_t nport_handle;
	uint8_t  reserved_2[2];
	uint8_t  vp_index;
	uint8_t  reserved_3:4;
	uint8_t  sof_type:4;
	uint32_t exchange_address;
	struct fcp_hdr_le fcp_hdr_le;
	uint8_t  reserved_4[16];
	uint32_t exchange_addr_to_abort;
} __packed;

#define ABTS_PARAM_ABORT_SEQ		BIT_0

struct ba_acc_le {
	uint16_t reserved;
	uint8_t  seq_id_last;
	uint8_t  seq_id_valid;
#define SEQ_ID_VALID	0x80
#define SEQ_ID_INVALID	0x00
	uint16_t rx_id;
	uint16_t ox_id;
	uint16_t high_seq_cnt;
	uint16_t low_seq_cnt;
} __packed;

struct ba_rjt_le {
	uint8_t vendor_uniq;
	uint8_t reason_expl;
	uint8_t reason_code;
#define BA_RJT_REASON_CODE_INVALID_COMMAND	0x1
#define BA_RJT_REASON_CODE_UNABLE_TO_PERFORM	0x9
	uint8_t reserved;
} __packed;

/*
 * ISP queue -	ABTS Response IOCB entry structure definition for 24xx.
 *		The ABTS response to the ABTS received is sent by the
 *		target driver to the ISP 24xx.
 *		The IOCB is placed on the request queue.
 */
struct abts_resp_to_24xx {
	uint8_t	 entry_type;		    /* Entry type. */
	uint8_t	 entry_count;		    /* Entry count. */
	uint8_t	 sys_define;		    /* System defined. */
	uint8_t	 entry_status;		    /* Entry Status. */
	uint32_t handle;
	uint16_t reserved_1;
	uint16_t nport_handle;
	uint16_t control_flags;
#define ABTS_CONTR_FLG_TERM_EXCHG	BIT_0
	uint8_t  vp_index;
	uint8_t  reserved_3:4;
	uint8_t  sof_type:4;
	uint32_t exchange_address;
	struct fcp_hdr_le fcp_hdr_le;
	union {
		struct ba_acc_le ba_acct;
		struct ba_rjt_le ba_rjt;
	} __packed payload;
	uint32_t reserved_4;
	uint32_t exchange_addr_to_abort;
} __packed;

/*
 * ISP queue -	ABTS Response IOCB from ISP24xx Firmware entry structure.
 *		The ABTS response with completion status to the ABTS response
 *		(sent by the target driver to the ISP 24xx) is sent by the
 *		ISP24xx firmware to the target driver.
 *		The IOCB is placed on the response queue.
 */
struct abts_resp_from_24xx_fw {
	uint8_t	 entry_type;		    /* Entry type. */
	uint8_t	 entry_count;		    /* Entry count. */
	uint8_t	 sys_define;		    /* System defined. */
	uint8_t	 entry_status;		    /* Entry Status. */
	uint32_t handle;
	uint16_t compl_status;
#define ABTS_RESP_COMPL_SUCCESS		0
#define ABTS_RESP_COMPL_SUBCODE_ERROR	0x31
	uint16_t nport_handle;
	uint16_t reserved_1;
	uint8_t  reserved_2;
	uint8_t  reserved_3:4;
	uint8_t  sof_type:4;
	uint32_t exchange_address;
	struct fcp_hdr_le fcp_hdr_le;
	uint8_t reserved_4[8];
	uint32_t error_subcode1;
#define ABTS_RESP_SUBCODE_ERR_ABORTED_EXCH_NOT_TERM	0x1E
	uint32_t error_subcode2;
	uint32_t exchange_addr_to_abort;
} __packed;

/********************************************************************\
 * Type Definitions used by initiator & target halves
\********************************************************************/

struct qla_tgt_mgmt_cmd;
struct qla_tgt_sess;

/*
 * This structure provides a template of function calls that the
 * target driver (from within qla_target.c) can issue to the
 * target module (tcm_qla2xxx).
 */
struct qla_tgt_func_tmpl {

	int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *,
			unsigned char *, uint32_t, int, int, int);
	void (*handle_data)(struct qla_tgt_cmd *);
	int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t,
			uint32_t);
	void (*free_cmd)(struct qla_tgt_cmd *);
	void (*free_mcmd)(struct qla_tgt_mgmt_cmd *);
	void (*free_session)(struct qla_tgt_sess *);

	int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *,
					void *, uint8_t *, uint16_t);
	void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool);
	struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *,
						const uint16_t);
	struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *,
						const uint8_t *);
	void (*clear_nacl_from_fcport_map)(struct qla_tgt_sess *);
	void (*put_sess)(struct qla_tgt_sess *);
	void (*shutdown_sess)(struct qla_tgt_sess *);
};

int qla2x00_wait_for_hba_online(struct scsi_qla_host *);

#include <target/target_core_base.h>

#define QLA_TGT_TIMEOUT			10	/* in seconds */

#define QLA_TGT_MAX_HW_PENDING_TIME	60 /* in seconds */

/* Immediate notify status constants */
#define IMM_NTFY_LIP_RESET          0x000E
#define IMM_NTFY_LIP_LINK_REINIT    0x000F
#define IMM_NTFY_IOCB_OVERFLOW      0x0016
#define IMM_NTFY_ABORT_TASK         0x0020
#define IMM_NTFY_PORT_LOGOUT        0x0029
#define IMM_NTFY_PORT_CONFIG        0x002A
#define IMM_NTFY_GLBL_TPRLO         0x002D
#define IMM_NTFY_GLBL_LOGO          0x002E
#define IMM_NTFY_RESOURCE           0x0034
#define IMM_NTFY_MSG_RX             0x0036
#define IMM_NTFY_SRR                0x0045
#define IMM_NTFY_ELS                0x0046

/* Immediate notify task flags */
#define IMM_NTFY_TASK_MGMT_SHIFT    8

#define QLA_TGT_CLEAR_ACA               0x40
#define QLA_TGT_TARGET_RESET            0x20
#define QLA_TGT_LUN_RESET               0x10
#define QLA_TGT_CLEAR_TS                0x04
#define QLA_TGT_ABORT_TS                0x02
#define QLA_TGT_ABORT_ALL_SESS          0xFFFF
#define QLA_TGT_ABORT_ALL               0xFFFE
#define QLA_TGT_NEXUS_LOSS_SESS         0xFFFD
#define QLA_TGT_NEXUS_LOSS              0xFFFC

/* Notify Acknowledge flags */
#define NOTIFY_ACK_RES_COUNT        BIT_8
#define NOTIFY_ACK_CLEAR_LIP_RESET  BIT_5
#define NOTIFY_ACK_TM_RESP_CODE_VALID BIT_4

/* Command's states */
#define QLA_TGT_STATE_NEW		0 /* New command + target processing */
#define QLA_TGT_STATE_NEED_DATA		1 /* target needs data to continue */
#define QLA_TGT_STATE_DATA_IN		2 /* Data arrived + target processing */
#define QLA_TGT_STATE_PROCESSED		3 /* target done processing */
#define QLA_TGT_STATE_ABORTED		4 /* Command aborted */

/* Special handles */
#define QLA_TGT_NULL_HANDLE	0
#define QLA_TGT_SKIP_HANDLE	(0xFFFFFFFF & ~CTIO_COMPLETION_HANDLE_MARK)

/* ATIO task_codes field */
#define ATIO_SIMPLE_QUEUE           0
#define ATIO_HEAD_OF_QUEUE          1
#define ATIO_ORDERED_QUEUE          2
#define ATIO_ACA_QUEUE              4
#define ATIO_UNTAGGED               5

/* TM failed response codes, see FCP (9.4.11 FCP_RSP_INFO) */
#define	FC_TM_SUCCESS               0
#define	FC_TM_BAD_FCP_DATA          1
#define	FC_TM_BAD_CMD               2
#define	FC_TM_FCP_DATA_MISMATCH     3
#define	FC_TM_REJECT                4
#define FC_TM_FAILED                5

/*
 * Error code of qlt_pre_xmit_response() meaning that cmd's exchange was
 * terminated, so no more actions is needed and success should be returned
 * to target.
 */
#define QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED	0x1717

#if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G)
#define pci_dma_lo32(a) (a & 0xffffffff)
#define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff)
#else
#define pci_dma_lo32(a) (a & 0xffffffff)
#define pci_dma_hi32(a) 0
#endif

#define QLA_TGT_SENSE_VALID(sense)  ((sense != NULL) && \
				(((const uint8_t *)(sense))[0] & 0x70) == 0x70)

struct qla_port_24xx_data {
	uint8_t port_name[WWN_SIZE];
	uint16_t loop_id;
	uint16_t reserved;
};

struct qla_tgt {
	struct scsi_qla_host *vha;
	struct qla_hw_data *ha;

	/*
	 * To sync between IRQ handlers and qlt_target_release(). Needed,
	 * because req_pkt() can drop/reaquire HW lock inside. Protected by
	 * HW lock.
	 */
	int irq_cmd_count;

	int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;

	/* Target's flags, serialized by pha->hardware_lock */
	unsigned int tgt_enable_64bit_addr:1; /* 64-bits PCI addr enabled */
	unsigned int link_reinit_iocb_pending:1;

	/*
	 * Protected by tgt_mutex AND hardware_lock for writing and tgt_mutex
	 * OR hardware_lock for reading.
	 */
	int tgt_stop; /* the target mode driver is being stopped */
	int tgt_stopped; /* the target mode driver has been stopped */

	/* Count of sessions refering qla_tgt. Protected by hardware_lock. */
	int sess_count;

	/* Protected by hardware_lock. Addition also protected by tgt_mutex. */
	struct list_head sess_list;

	/* Protected by hardware_lock */
	struct list_head del_sess_list;
	struct delayed_work sess_del_work;

	spinlock_t sess_work_lock;
	struct list_head sess_works_list;
	struct work_struct sess_work;

	struct imm_ntfy_from_isp link_reinit_iocb;
	wait_queue_head_t waitQ;
	int notify_ack_expected;
	int abts_resp_expected;
	int modify_lun_expected;

	int ctio_srr_id;
	int imm_srr_id;
	spinlock_t srr_lock;
	struct list_head srr_ctio_list;
	struct list_head srr_imm_list;
	struct work_struct srr_work;

	atomic_t tgt_global_resets_count;

	struct list_head tgt_list_entry;
};

/*
 * Equivilant to IT Nexus (Initiator-Target)
 */
struct qla_tgt_sess {
	uint16_t loop_id;
	port_id_t s_id;

	unsigned int conf_compl_supported:1;
	unsigned int deleted:1;
	unsigned int local:1;

	struct se_session *se_sess;
	struct scsi_qla_host *vha;
	struct qla_tgt *tgt;

	struct list_head sess_list_entry;
	unsigned long expires;
	struct list_head del_list_entry;

	uint8_t port_name[WWN_SIZE];
	struct work_struct free_work;
};

struct qla_tgt_cmd {
	struct qla_tgt_sess *sess;
	int state;
	struct se_cmd se_cmd;
	struct work_struct free_work;
	struct work_struct work;
	/* Sense buffer that will be mapped into outgoing status */
	unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];

	/* to save extra sess dereferences */
	unsigned int conf_compl_supported:1;
	unsigned int sg_mapped:1;
	unsigned int free_sg:1;
	unsigned int aborted:1; /* Needed in case of SRR */
	unsigned int write_data_transferred:1;

	struct scatterlist *sg;	/* cmd data buffer SG vector */
	int sg_cnt;		/* SG segments count */
	int bufflen;		/* cmd buffer length */
	int offset;
	uint32_t tag;
	uint32_t unpacked_lun;
	enum dma_data_direction dma_data_direction;

	uint16_t loop_id;	/* to save extra sess dereferences */
	struct qla_tgt *tgt;	/* to save extra sess dereferences */
	struct scsi_qla_host *vha;

	struct atio_from_isp atio;
};

struct qla_tgt_sess_work_param {
	struct list_head sess_works_list_entry;

#define QLA_TGT_SESS_WORK_ABORT	1
#define QLA_TGT_SESS_WORK_TM	2
	int type;

	union {
		struct abts_recv_from_24xx abts;
		struct imm_ntfy_from_isp tm_iocb;
		struct atio_from_isp tm_iocb2;
	};
};

struct qla_tgt_mgmt_cmd {
	uint8_t tmr_func;
	uint8_t fc_tm_rsp;
	struct qla_tgt_sess *sess;
	struct se_cmd se_cmd;
	struct work_struct free_work;
	unsigned int flags;
#define QLA24XX_MGMT_SEND_NACK	1
	union {
		struct atio_from_isp atio;
		struct imm_ntfy_from_isp imm_ntfy;
		struct abts_recv_from_24xx abts;
	} __packed orig_iocb;
};

struct qla_tgt_prm {
	struct qla_tgt_cmd *cmd;
	struct qla_tgt *tgt;
	void *pkt;
	struct scatterlist *sg;	/* cmd data buffer SG vector */
	int seg_cnt;
	int req_cnt;
	uint16_t rq_result;
	uint16_t scsi_status;
	unsigned char *sense_buffer;
	int sense_buffer_len;
	int residual;
	int add_status_pkt;
};

struct qla_tgt_srr_imm {
	struct list_head srr_list_entry;
	int srr_id;
	struct imm_ntfy_from_isp imm_ntfy;
};

struct qla_tgt_srr_ctio {
	struct list_head srr_list_entry;
	int srr_id;
	struct qla_tgt_cmd *cmd;
};

#define QLA_TGT_XMIT_DATA		1
#define QLA_TGT_XMIT_STATUS		2
#define QLA_TGT_XMIT_ALL		(QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA)


extern struct qla_tgt_data qla_target;
/*
 * Internal function prototypes
 */
void qlt_disable_vha(struct scsi_qla_host *);

/*
 * Function prototypes for qla_target.c logic used by qla2xxx LLD code.
 */
extern int qlt_add_target(struct qla_hw_data *, struct scsi_qla_host *);
extern int qlt_remove_target(struct qla_hw_data *, struct scsi_qla_host *);
extern int qlt_lport_register(void *, u64, u64, u64,
			int (*callback)(struct scsi_qla_host *, void *, u64, u64));
extern void qlt_lport_deregister(struct scsi_qla_host *);
extern void qlt_unreg_sess(struct qla_tgt_sess *);
extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *);
extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *);
extern void qlt_set_mode(struct scsi_qla_host *ha);
extern void qlt_clear_mode(struct scsi_qla_host *ha);
extern int __init qlt_init(void);
extern void qlt_exit(void);
extern void qlt_update_vp_map(struct scsi_qla_host *, int);

/*
 * This macro is used during early initializations when host->active_mode
 * is not set. Right now, ha value is ignored.
 */
#define QLA_TGT_MODE_ENABLED() (ql2x_ini_mode != QLA2XXX_INI_MODE_ENABLED)
extern int ql2x_ini_mode;

static inline bool qla_tgt_mode_enabled(struct scsi_qla_host *ha)
{
	return ha->host->active_mode & MODE_TARGET;
}

static inline bool qla_ini_mode_enabled(struct scsi_qla_host *ha)
{
	return ha->host->active_mode & MODE_INITIATOR;
}

static inline void qla_reverse_ini_mode(struct scsi_qla_host *ha)
{
	if (ha->host->active_mode & MODE_INITIATOR)
		ha->host->active_mode &= ~MODE_INITIATOR;
	else
		ha->host->active_mode |= MODE_INITIATOR;
}

/*
 * Exported symbols from qla_target.c LLD logic used by qla2xxx code..
 */
extern void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *,
	struct atio_from_isp *);
extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *);
extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *);
extern void qlt_enable_vha(struct scsi_qla_host *);
extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *);
extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *);
extern void qlt_init_atio_q_entries(struct scsi_qla_host *);
extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *);
extern void qlt_24xx_config_rings(struct scsi_qla_host *);
extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *,
	struct nvram_24xx *);
extern void qlt_24xx_config_nvram_stage2(struct scsi_qla_host *,
	struct init_cb_24xx *);
extern void qlt_81xx_config_nvram_stage2(struct scsi_qla_host *,
	struct init_cb_81xx *);
extern void qlt_81xx_config_nvram_stage1(struct scsi_qla_host *,
	struct nvram_81xx *);
extern int qlt_24xx_process_response_error(struct scsi_qla_host *,
	struct sts_entry_24xx *);
extern void qlt_modify_vp_config(struct scsi_qla_host *,
	struct vp_config_entry_24xx *);
extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *);
extern int qlt_mem_alloc(struct qla_hw_data *);
extern void qlt_mem_free(struct qla_hw_data *);
extern int qlt_stop_phase1(struct qla_tgt *);
extern void qlt_stop_phase2(struct qla_tgt *);
extern irqreturn_t qla83xx_msix_atio_q(int, void *);
extern void qlt_83xx_iospace_config(struct qla_hw_data *);

#endif /* __QLA_TARGET_H */