fcpio.h 22.4 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
/*
 * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
 * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef _FCPIO_H_
#define _FCPIO_H_

#include <linux/if_ether.h>

/*
 * This header file includes all of the data structures used for
 * communication by the host driver to the fcp firmware.
 */

/*
 * Exchange and sequence id space allocated to the host driver
 */
#define FCPIO_HOST_EXCH_RANGE_START         0x1000
#define FCPIO_HOST_EXCH_RANGE_END           0x1fff
#define FCPIO_HOST_SEQ_ID_RANGE_START       0x80
#define FCPIO_HOST_SEQ_ID_RANGE_END         0xff

/*
 * Command entry type
 */
enum fcpio_type {
	/*
	 * Initiator request types
	 */
	FCPIO_ICMND_16 = 0x1,
	FCPIO_ICMND_32,
	FCPIO_ICMND_CMPL,
	FCPIO_ITMF,
	FCPIO_ITMF_CMPL,

	/*
	 * Target request types
	 */
	FCPIO_TCMND_16 = 0x11,
	FCPIO_TCMND_32,
	FCPIO_TDATA,
	FCPIO_TXRDY,
	FCPIO_TRSP,
	FCPIO_TDRSP_CMPL,
	FCPIO_TTMF,
	FCPIO_TTMF_ACK,
	FCPIO_TABORT,
	FCPIO_TABORT_CMPL,

	/*
	 * Misc request types
	 */
	FCPIO_ACK = 0x20,
	FCPIO_RESET,
	FCPIO_RESET_CMPL,
	FCPIO_FLOGI_REG,
	FCPIO_FLOGI_REG_CMPL,
	FCPIO_ECHO,
	FCPIO_ECHO_CMPL,
	FCPIO_LUNMAP_CHNG,
	FCPIO_LUNMAP_REQ,
	FCPIO_LUNMAP_REQ_CMPL,
	FCPIO_FLOGI_FIP_REG,
	FCPIO_FLOGI_FIP_REG_CMPL,
};

/*
 * Header status codes from the firmware
 */
enum fcpio_status {
	FCPIO_SUCCESS = 0,              /* request was successful */

	/*
	 * If a request to the firmware is rejected, the original request
	 * header will be returned with the status set to one of the following:
	 */
	FCPIO_INVALID_HEADER,    /* header contains invalid data */
	FCPIO_OUT_OF_RESOURCE,   /* out of resources to complete request */
	FCPIO_INVALID_PARAM,     /* some parameter in request is invalid */
	FCPIO_REQ_NOT_SUPPORTED, /* request type is not supported */
	FCPIO_IO_NOT_FOUND,      /* requested I/O was not found */

	/*
	 * Once a request is processed, the firmware will usually return
	 * a cmpl message type.  In cases where errors occurred,
	 * the header status field would be filled in with one of the following:
	 */
	FCPIO_ABORTED = 0x41,     /* request was aborted */
	FCPIO_TIMEOUT,            /* request was timed out */
	FCPIO_SGL_INVALID,        /* request was aborted due to sgl error */
	FCPIO_MSS_INVALID,        /* request was aborted due to mss error */
	FCPIO_DATA_CNT_MISMATCH,  /* recv/sent more/less data than exp. */
	FCPIO_FW_ERR,             /* request was terminated due to fw error */
	FCPIO_ITMF_REJECTED,      /* itmf req was rejected by remote node */
	FCPIO_ITMF_FAILED,        /* itmf req was failed by remote node */
	FCPIO_ITMF_INCORRECT_LUN, /* itmf req targeted incorrect LUN */
	FCPIO_CMND_REJECTED,      /* request was invalid and rejected */
	FCPIO_NO_PATH_AVAIL,      /* no paths to the lun was available */
	FCPIO_PATH_FAILED,        /* i/o sent to current path failed */
	FCPIO_LUNMAP_CHNG_PEND,   /* i/o rejected due to lunmap change */
};

/*
 * The header command tag.  All host requests will use the "tag" field
 * to mark commands with a unique tag.  When the firmware responds to
 * a host request, it will copy the tag field into the response.
 *
 * The only firmware requests that will use the rx_id/ox_id fields instead
 * of the tag field will be the target command and target task management
 * requests.  These two requests do not have corresponding host requests
 * since they come directly from the FC initiator on the network.
 */
struct fcpio_tag {
	union {
		u32 req_id;
		struct {
			u16 rx_id;
			u16 ox_id;
		} ex_id;
	} u;
};

static inline void
fcpio_tag_id_enc(struct fcpio_tag *tag, u32 id)
{
	tag->u.req_id = id;
}

static inline void
fcpio_tag_id_dec(struct fcpio_tag *tag, u32 *id)
{
	*id = tag->u.req_id;
}

static inline void
fcpio_tag_exid_enc(struct fcpio_tag *tag, u16 ox_id, u16 rx_id)
{
	tag->u.ex_id.rx_id = rx_id;
	tag->u.ex_id.ox_id = ox_id;
}

static inline void
fcpio_tag_exid_dec(struct fcpio_tag *tag, u16 *ox_id, u16 *rx_id)
{
	*rx_id = tag->u.ex_id.rx_id;
	*ox_id = tag->u.ex_id.ox_id;
}

/*
 * The header for an fcpio request, whether from the firmware or from the
 * host driver
 */
struct fcpio_header {
	u8            type;           /* enum fcpio_type */
	u8            status;         /* header status entry */
	u16           _resvd;         /* reserved */
	struct fcpio_tag    tag;      /* header tag */
};

static inline void
fcpio_header_enc(struct fcpio_header *hdr,
		 u8 type, u8 status,
		 struct fcpio_tag tag)
{
	hdr->type = type;
	hdr->status = status;
	hdr->_resvd = 0;
	hdr->tag = tag;
}

static inline void
fcpio_header_dec(struct fcpio_header *hdr,
		 u8 *type, u8 *status,
		 struct fcpio_tag *tag)
{
	*type = hdr->type;
	*status = hdr->status;
	*tag = hdr->tag;
}

#define CDB_16      16
#define CDB_32      32
#define LUN_ADDRESS 8

/*
 * fcpio_icmnd_16: host -> firmware request
 *
 * used for sending out an initiator SCSI 16-byte command
 */
struct fcpio_icmnd_16 {
	u32	  lunmap_id;		/* index into lunmap table */
	u8	  special_req_flags;	/* special exchange request flags */
	u8	  _resvd0[3];	        /* reserved */
	u32	  sgl_cnt;		/* scatter-gather list count */
	u32	  sense_len;		/* sense buffer length */
	u64	  sgl_addr;		/* scatter-gather list addr */
	u64	  sense_addr;		/* sense buffer address */
	u8	  crn;			/* SCSI Command Reference No. */
	u8	  pri_ta;		/* SCSI Priority and Task attribute */
	u8	  _resvd1;		/* reserved: should be 0 */
	u8	  flags;		/* command flags */
	u8	  scsi_cdb[CDB_16];	/* SCSI Cmnd Descriptor Block */
	u32	  data_len;		/* length of data expected */
	u8	  lun[LUN_ADDRESS];	/* FC vNIC only: LUN address */
	u8	  _resvd2;		/* reserved */
	u8	  d_id[3];		/* FC vNIC only: Target D_ID */
	u16	  mss;			/* FC vNIC only: max burst */
	u16	  _resvd3;		/* reserved */
	u32	  r_a_tov;		/* FC vNIC only: Res. Alloc Timeout */
	u32	  e_d_tov;	        /* FC vNIC only: Err Detect Timeout */
};

/*
 * Special request flags
 */
#define FCPIO_ICMND_SRFLAG_RETRY 0x01   /* Enable Retry handling on exchange */

/*
 * Priority/Task Attribute settings
 */
#define FCPIO_ICMND_PTA_SIMPLE      0   /* simple task attribute */
#define FCPIO_ICMND_PTA_HEADQ       1   /* head of queue task attribute */
#define FCPIO_ICMND_PTA_ORDERED     2   /* ordered task attribute */
#define FCPIO_ICMND_PTA_ACA         4   /* auto contingent allegiance */
#define FCPIO_ICMND_PRI_SHIFT       3   /* priority field starts in bit 3 */

/*
 * Command flags
 */
#define FCPIO_ICMND_RDDATA      0x02    /* read data */
#define FCPIO_ICMND_WRDATA      0x01    /* write data */

/*
 * fcpio_icmnd_32: host -> firmware request
 *
 * used for sending out an initiator SCSI 32-byte command
 */
struct fcpio_icmnd_32 {
	u32   lunmap_id;              /* index into lunmap table */
	u8    special_req_flags;      /* special exchange request flags */
	u8    _resvd0[3];             /* reserved */
	u32   sgl_cnt;                /* scatter-gather list count */
	u32   sense_len;              /* sense buffer length */
	u64   sgl_addr;               /* scatter-gather list addr */
	u64   sense_addr;             /* sense buffer address */
	u8    crn;                    /* SCSI Command Reference No. */
	u8    pri_ta;                 /* SCSI Priority and Task attribute */
	u8    _resvd1;                /* reserved: should be 0 */
	u8    flags;                  /* command flags */
	u8    scsi_cdb[CDB_32];       /* SCSI Cmnd Descriptor Block */
	u32   data_len;               /* length of data expected */
	u8    lun[LUN_ADDRESS];       /* FC vNIC only: LUN address */
	u8    _resvd2;                /* reserved */
	u8    d_id[3];		      /* FC vNIC only: Target D_ID */
	u16   mss;                    /* FC vNIC only: max burst */
	u16   _resvd3;                /* reserved */
	u32   r_a_tov;                /* FC vNIC only: Res. Alloc Timeout */
	u32   e_d_tov;                /* FC vNIC only: Error Detect Timeout */
};

/*
 * fcpio_itmf: host -> firmware request
 *
 * used for requesting the firmware to abort a request and/or send out
 * a task management function
 *
 * The t_tag field is only needed when the request type is ABT_TASK.
 */
struct fcpio_itmf {
	u32   lunmap_id;              /* index into lunmap table */
	u32   tm_req;                 /* SCSI Task Management request */
	u32   t_tag;                  /* header tag of fcpio to be aborted */
	u32   _resvd;                 /* _reserved */
	u8    lun[LUN_ADDRESS];       /* FC vNIC only: LUN address */
	u8    _resvd1;                /* reserved */
	u8    d_id[3];		      /* FC vNIC only: Target D_ID */
	u32   r_a_tov;                /* FC vNIC only: R_A_TOV in msec */
	u32   e_d_tov;                /* FC vNIC only: E_D_TOV in msec */
};

/*
 * Task Management request
 */
enum fcpio_itmf_tm_req_type {
	FCPIO_ITMF_ABT_TASK_TERM = 0x01,    /* abort task and terminate */
	FCPIO_ITMF_ABT_TASK,                /* abort task and issue abts */
	FCPIO_ITMF_ABT_TASK_SET,            /* abort task set */
	FCPIO_ITMF_CLR_TASK_SET,            /* clear task set */
	FCPIO_ITMF_LUN_RESET,               /* logical unit reset task mgmt */
	FCPIO_ITMF_CLR_ACA,                 /* Clear ACA condition */
};

/*
 * fcpio_tdata: host -> firmware request
 *
 * used for requesting the firmware to send out a read data transfer for a
 * target command
 */
struct fcpio_tdata {
	u16   rx_id;                  /* FC rx_id of target command */
	u16   flags;                  /* command flags */
	u32   rel_offset;             /* data sequence relative offset */
	u32   sgl_cnt;                /* scatter-gather list count */
	u32   data_len;               /* length of data expected to send */
	u64   sgl_addr;               /* scatter-gather list address */
};

/*
 * Command flags
 */
#define FCPIO_TDATA_SCSI_RSP    0x01    /* send a scsi resp. after last frame */

/*
 * fcpio_txrdy: host -> firmware request
 *
 * used for requesting the firmware to send out a write data transfer for a
 * target command
 */
struct fcpio_txrdy {
	u16   rx_id;                  /* FC rx_id of target command */
	u16   _resvd0;                /* reserved */
	u32   rel_offset;             /* data sequence relative offset */
	u32   sgl_cnt;                /* scatter-gather list count */
	u32   data_len;               /* length of data expected to send */
	u64   sgl_addr;               /* scatter-gather list address */
};

/*
 * fcpio_trsp: host -> firmware request
 *
 * used for requesting the firmware to send out a response for a target
 * command
 */
struct fcpio_trsp {
	u16   rx_id;                  /* FC rx_id of target command */
	u16   _resvd0;                /* reserved */
	u32   sense_len;              /* sense data buffer length */
	u64   sense_addr;             /* sense data buffer address */
	u16   _resvd1;                /* reserved */
	u8    flags;                  /* response request flags */
	u8    scsi_status;            /* SCSI status */
	u32   residual;               /* SCSI data residual value of I/O */
};

/*
 * resposnse request flags
 */
#define FCPIO_TRSP_RESID_UNDER  0x08   /* residual is valid and is underflow */
#define FCPIO_TRSP_RESID_OVER   0x04   /* residual is valid and is overflow */

/*
 * fcpio_ttmf_ack: host -> firmware response
 *
 * used by the host to indicate to the firmware it has received and processed
 * the target tmf request
 */
struct fcpio_ttmf_ack {
	u16   rx_id;                  /* FC rx_id of target command */
	u16   _resvd0;                /* reserved */
	u32   tmf_status;             /* SCSI task management status */
};

/*
 * fcpio_tabort: host -> firmware request
 *
 * used by the host to request the firmware to abort a target request that was
 * received by the firmware
 */
struct fcpio_tabort {
	u16   rx_id;                  /* rx_id of the target request */
};

/*
 * fcpio_reset: host -> firmware request
 *
 * used by the host to signal a reset of the driver to the firmware
 * and to request firmware to clean up all outstanding I/O
 */
struct fcpio_reset {
	u32   _resvd;
};

enum fcpio_flogi_reg_format_type {
	FCPIO_FLOGI_REG_DEF_DEST = 0,    /* Use the oui | s_id mac format */
	FCPIO_FLOGI_REG_GW_DEST,         /* Use the fixed gateway mac */
};

/*
 * fcpio_flogi_reg: host -> firmware request
 *
 * fc vnic only
 * used by the host to notify the firmware of the lif's s_id
 * and destination mac address format
 */
struct fcpio_flogi_reg {
	u8 format;
	u8 s_id[3];			/* FC vNIC only: Source S_ID */
	u8 gateway_mac[ETH_ALEN];	/* Destination gateway mac */
	u16 _resvd;
	u32 r_a_tov;			/* R_A_TOV in msec */
	u32 e_d_tov;			/* E_D_TOV in msec */
};

/*
 * fcpio_echo: host -> firmware request
 *
 * sends a heartbeat echo request to the firmware
 */
struct fcpio_echo {
	u32 _resvd;
};

/*
 * fcpio_lunmap_req: host -> firmware request
 *
 * scsi vnic only
 * sends a request to retrieve the lunmap table for scsi vnics
 */
struct fcpio_lunmap_req {
	u64 addr;                     /* address of the buffer */
	u32 len;                      /* len of the buffer */
};

/*
 * fcpio_flogi_fip_reg: host -> firmware request
 *
 * fc vnic only
 * used by the host to notify the firmware of the lif's s_id
 * and destination mac address format
 */
struct fcpio_flogi_fip_reg {
	u8    _resvd0;
	u8     s_id[3];               /* FC vNIC only: Source S_ID */
	u8     fcf_mac[ETH_ALEN];     /* FCF Target destination mac */
	u16   _resvd1;
	u32   r_a_tov;                /* R_A_TOV in msec */
	u32   e_d_tov;                /* E_D_TOV in msec */
	u8    ha_mac[ETH_ALEN];       /* Host adapter source mac */
	u16   _resvd2;
};

/*
 * Basic structure for all fcpio structures that are sent from the host to the
 * firmware.  They are 128 bytes per structure.
 */
#define FCPIO_HOST_REQ_LEN      128     /* expected length of host requests */

struct fcpio_host_req {
	struct fcpio_header hdr;

	union {
		/*
		 * Defines space needed for request
		 */
		u8 buf[FCPIO_HOST_REQ_LEN - sizeof(struct fcpio_header)];

		/*
		 * Initiator host requests
		 */
		struct fcpio_icmnd_16               icmnd_16;
		struct fcpio_icmnd_32               icmnd_32;
		struct fcpio_itmf                   itmf;

		/*
		 * Target host requests
		 */
		struct fcpio_tdata                  tdata;
		struct fcpio_txrdy                  txrdy;
		struct fcpio_trsp                   trsp;
		struct fcpio_ttmf_ack               ttmf_ack;
		struct fcpio_tabort                 tabort;

		/*
		 * Misc requests
		 */
		struct fcpio_reset                  reset;
		struct fcpio_flogi_reg              flogi_reg;
		struct fcpio_echo                   echo;
		struct fcpio_lunmap_req             lunmap_req;
		struct fcpio_flogi_fip_reg          flogi_fip_reg;
	} u;
};

/*
 * fcpio_icmnd_cmpl: firmware -> host response
 *
 * used for sending the host a response to an initiator command
 */
struct fcpio_icmnd_cmpl {
	u8    _resvd0[6];             /* reserved */
	u8    flags;                  /* response flags */
	u8    scsi_status;            /* SCSI status */
	u32   residual;               /* SCSI data residual length */
	u32   sense_len;              /* SCSI sense length */
};

/*
 * response flags
 */
#define FCPIO_ICMND_CMPL_RESID_UNDER    0x08    /* resid under and valid */
#define FCPIO_ICMND_CMPL_RESID_OVER     0x04    /* resid over and valid */

/*
 * fcpio_itmf_cmpl: firmware -> host response
 *
 * used for sending the host a response for a itmf request
 */
struct fcpio_itmf_cmpl {
	u32    _resvd;                /* reserved */
};

/*
 * fcpio_tcmnd_16: firmware -> host request
 *
 * used by the firmware to notify the host of an incoming target SCSI 16-Byte
 * request
 */
struct fcpio_tcmnd_16 {
	u8    lun[LUN_ADDRESS];       /* FC vNIC only: LUN address */
	u8    crn;                    /* SCSI Command Reference No. */
	u8    pri_ta;                 /* SCSI Priority and Task attribute */
	u8    _resvd2;                /* reserved: should be 0 */
	u8    flags;                  /* command flags */
	u8    scsi_cdb[CDB_16];       /* SCSI Cmnd Descriptor Block */
	u32   data_len;               /* length of data expected */
	u8    _resvd1;                /* reserved */
	u8    s_id[3];		      /* FC vNIC only: Source S_ID */
};

/*
 * Priority/Task Attribute settings
 */
#define FCPIO_TCMND_PTA_SIMPLE      0   /* simple task attribute */
#define FCPIO_TCMND_PTA_HEADQ       1   /* head of queue task attribute */
#define FCPIO_TCMND_PTA_ORDERED     2   /* ordered task attribute */
#define FCPIO_TCMND_PTA_ACA         4   /* auto contingent allegiance */
#define FCPIO_TCMND_PRI_SHIFT       3   /* priority field starts in bit 3 */

/*
 * Command flags
 */
#define FCPIO_TCMND_RDDATA      0x02    /* read data */
#define FCPIO_TCMND_WRDATA      0x01    /* write data */

/*
 * fcpio_tcmnd_32: firmware -> host request
 *
 * used by the firmware to notify the host of an incoming target SCSI 32-Byte
 * request
 */
struct fcpio_tcmnd_32 {
	u8    lun[LUN_ADDRESS];       /* FC vNIC only: LUN address */
	u8    crn;                    /* SCSI Command Reference No. */
	u8    pri_ta;                 /* SCSI Priority and Task attribute */
	u8    _resvd2;                /* reserved: should be 0 */
	u8    flags;                  /* command flags */
	u8    scsi_cdb[CDB_32];       /* SCSI Cmnd Descriptor Block */
	u32   data_len;               /* length of data expected */
	u8    _resvd0;                /* reserved */
	u8    s_id[3];		      /* FC vNIC only: Source S_ID */
};

/*
 * fcpio_tdrsp_cmpl: firmware -> host response
 *
 * used by the firmware to notify the host of a response to a host target
 * command
 */
struct fcpio_tdrsp_cmpl {
	u16   rx_id;                  /* rx_id of the target request */
	u16   _resvd0;                /* reserved */
};

/*
 * fcpio_ttmf: firmware -> host request
 *
 * used by the firmware to notify the host of an incoming task management
 * function request
 */
struct fcpio_ttmf {
	u8    _resvd0;                /* reserved */
	u8    s_id[3];		      /* FC vNIC only: Source S_ID */
	u8    lun[LUN_ADDRESS];       /* FC vNIC only: LUN address */
	u8    crn;                    /* SCSI Command Reference No. */
	u8    _resvd2[3];             /* reserved */
	u32   tmf_type;               /* task management request type */
};

/*
 * Task Management request
 */
#define FCPIO_TTMF_CLR_ACA      0x40    /* Clear ACA condition */
#define FCPIO_TTMF_LUN_RESET    0x10    /* logical unit reset task mgmt */
#define FCPIO_TTMF_CLR_TASK_SET 0x04    /* clear task set */
#define FCPIO_TTMF_ABT_TASK_SET 0x02    /* abort task set */
#define FCPIO_TTMF_ABT_TASK     0x01    /* abort task */

/*
 * fcpio_tabort_cmpl: firmware -> host response
 *
 * used by the firmware to respond to a host's tabort request
 */
struct fcpio_tabort_cmpl {
	u16   rx_id;                  /* rx_id of the target request */
	u16   _resvd0;                /* reserved */
};

/*
 * fcpio_ack: firmware -> host response
 *
 * used by firmware to notify the host of the last work request received
 */
struct fcpio_ack {
	u16  request_out;             /* last host entry received */
	u16  _resvd;
};

/*
 * fcpio_reset_cmpl: firmware -> host response
 *
 * use by firmware to respond to the host's reset request
 */
struct fcpio_reset_cmpl {
	u16   vnic_id;
};

/*
 * fcpio_flogi_reg_cmpl: firmware -> host response
 *
 * fc vnic only
 * response to the fcpio_flogi_reg request
 */
struct fcpio_flogi_reg_cmpl {
	u32 _resvd;
};

/*
 * fcpio_echo_cmpl: firmware -> host response
 *
 * response to the fcpio_echo request
 */
struct fcpio_echo_cmpl {
	u32 _resvd;
};

/*
 * fcpio_lunmap_chng: firmware -> host notification
 *
 * scsi vnic only
 * notifies the host that the lunmap tables have changed
 */
struct fcpio_lunmap_chng {
	u32 _resvd;
};

/*
 * fcpio_lunmap_req_cmpl: firmware -> host response
 *
 * scsi vnic only
 * response for lunmap table request from the host
 */
struct fcpio_lunmap_req_cmpl {
	u32 _resvd;
};

/*
 * Basic structure for all fcpio structures that are sent from the firmware to
 * the host.  They are 64 bytes per structure.
 */
#define FCPIO_FW_REQ_LEN        64      /* expected length of fw requests */
struct fcpio_fw_req {
	struct fcpio_header hdr;

	union {
		/*
		 * Defines space needed for request
		 */
		u8 buf[FCPIO_FW_REQ_LEN - sizeof(struct fcpio_header)];

		/*
		 * Initiator firmware responses
		 */
		struct fcpio_icmnd_cmpl         icmnd_cmpl;
		struct fcpio_itmf_cmpl          itmf_cmpl;

		/*
		 * Target firmware new requests
		 */
		struct fcpio_tcmnd_16           tcmnd_16;
		struct fcpio_tcmnd_32           tcmnd_32;

		/*
		 * Target firmware responses
		 */
		struct fcpio_tdrsp_cmpl         tdrsp_cmpl;
		struct fcpio_ttmf               ttmf;
		struct fcpio_tabort_cmpl        tabort_cmpl;

		/*
		 * Firmware response to work received
		 */
		struct fcpio_ack                ack;

		/*
		 * Misc requests
		 */
		struct fcpio_reset_cmpl         reset_cmpl;
		struct fcpio_flogi_reg_cmpl     flogi_reg_cmpl;
		struct fcpio_echo_cmpl          echo_cmpl;
		struct fcpio_lunmap_chng        lunmap_chng;
		struct fcpio_lunmap_req_cmpl    lunmap_req_cmpl;
	} u;
};

/*
 * Access routines to encode and decode the color bit, which is the most
 * significant bit of the MSB of the structure
 */
static inline void fcpio_color_enc(struct fcpio_fw_req *fw_req, u8 color)
{
	u8 *c = ((u8 *) fw_req) + sizeof(struct fcpio_fw_req) - 1;

	if (color)
		*c |= 0x80;
	else
		*c &= ~0x80;
}

static inline void fcpio_color_dec(struct fcpio_fw_req *fw_req, u8 *color)
{
	u8 *c = ((u8 *) fw_req) + sizeof(struct fcpio_fw_req) - 1;

	*color = *c >> 7;

	/*
	 * Make sure color bit is read from desc *before* other fields
	 * are read from desc.  Hardware guarantees color bit is last
	 * bit (byte) written.  Adding the rmb() prevents the compiler
	 * and/or CPU from reordering the reads which would potentially
	 * result in reading stale values.
	 */

	rmb();

}

/*
 * Lunmap table entry for scsi vnics
 */
#define FCPIO_LUNMAP_TABLE_SIZE     256
#define FCPIO_FLAGS_LUNMAP_VALID    0x80
#define FCPIO_FLAGS_BOOT            0x01
struct fcpio_lunmap_entry {
	u8    bus;
	u8    target;
	u8    lun;
	u8    path_cnt;
	u16   flags;
	u16   update_cnt;
};

struct fcpio_lunmap_tbl {
	u32                   update_cnt;
	struct fcpio_lunmap_entry   lunmaps[FCPIO_LUNMAP_TABLE_SIZE];
};

#endif /* _FCPIO_H_ */