[SCSI] lpfc 8.3.23: BSG additions and fixes

- Fixed the mixed declarations and codes which violate ISO C90
   (declarations in subsections that assign at declaration)
- Add BSG data transfer size protection in mailbox command pass-through path
- Invoke BSG job_done while holding spinlock to fix deadlock
- Added support for checking SLI_CONFIG subcommands
- Fixed bug in BSG mailbox size check to non-embedded external buffer

Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
James Smart
2011-04-16 11:03:43 -04:00
committed by James Bottomley
parent c31098cef5
commit b6e3b9c606
2 changed files with 164 additions and 25 deletions

View File

@@ -109,3 +109,133 @@ struct menlo_response {
uint32_t xri; /* return the xri of the iocb exchange */
};
/*
* macros and data structures for handling sli-config mailbox command
* pass-through support, this header file is shared between user and
* kernel spaces, note the set of macros are duplicates from lpfc_hw4.h,
* with macro names prefixed with bsg_, as the macros defined in
* lpfc_hw4.h are not accessible from user space.
*/
/* Macros to deal with bit fields. Each bit field must have 3 #defines
* associated with it (_SHIFT, _MASK, and _WORD).
* EG. For a bit field that is in the 7th bit of the "field4" field of a
* structure and is 2 bits in size the following #defines must exist:
* struct temp {
* uint32_t field1;
* uint32_t field2;
* uint32_t field3;
* uint32_t field4;
* #define example_bit_field_SHIFT 7
* #define example_bit_field_MASK 0x03
* #define example_bit_field_WORD field4
* uint32_t field5;
* };
* Then the macros below may be used to get or set the value of that field.
* EG. To get the value of the bit field from the above example:
* struct temp t1;
* value = bsg_bf_get(example_bit_field, &t1);
* And then to set that bit field:
* bsg_bf_set(example_bit_field, &t1, 2);
* Or clear that bit field:
* bsg_bf_set(example_bit_field, &t1, 0);
*/
#define bsg_bf_get_le32(name, ptr) \
((le32_to_cpu((ptr)->name##_WORD) >> name##_SHIFT) & name##_MASK)
#define bsg_bf_get(name, ptr) \
(((ptr)->name##_WORD >> name##_SHIFT) & name##_MASK)
#define bsg_bf_set_le32(name, ptr, value) \
((ptr)->name##_WORD = cpu_to_le32(((((value) & \
name##_MASK) << name##_SHIFT) | (le32_to_cpu((ptr)->name##_WORD) & \
~(name##_MASK << name##_SHIFT)))))
#define bsg_bf_set(name, ptr, value) \
((ptr)->name##_WORD = ((((value) & name##_MASK) << name##_SHIFT) | \
((ptr)->name##_WORD & ~(name##_MASK << name##_SHIFT))))
/*
* The sli_config structure specified here is based on the following
* restriction:
*
* -- SLI_CONFIG EMB=0, carrying MSEs, will carry subcommands without
* carrying HBD.
* -- SLI_CONFIG EMB=1, not carrying MSE, will carry subcommands with or
* without carrying HBDs.
*/
struct lpfc_sli_config_mse {
uint32_t pa_lo;
uint32_t pa_hi;
uint32_t buf_len;
#define lpfc_mbox_sli_config_mse_len_SHIFT 0
#define lpfc_mbox_sli_config_mse_len_MASK 0xffffff
#define lpfc_mbox_sli_config_mse_len_WORD buf_len
};
struct lpfc_sli_config_subcmd_hbd {
uint32_t buf_len;
#define lpfc_mbox_sli_config_ecmn_hbd_len_SHIFT 0
#define lpfc_mbox_sli_config_ecmn_hbd_len_MASK 0xffffff
#define lpfc_mbox_sli_config_ecmn_hbd_len_WORD buf_len
uint32_t pa_lo;
uint32_t pa_hi;
};
struct lpfc_sli_config_hdr {
uint32_t word1;
#define lpfc_mbox_hdr_emb_SHIFT 0
#define lpfc_mbox_hdr_emb_MASK 0x00000001
#define lpfc_mbox_hdr_emb_WORD word1
#define lpfc_mbox_hdr_mse_cnt_SHIFT 3
#define lpfc_mbox_hdr_mse_cnt_MASK 0x0000001f
#define lpfc_mbox_hdr_mse_cnt_WORD word1
uint32_t payload_length;
uint32_t tag_lo;
uint32_t tag_hi;
uint32_t reserved5;
};
struct lpfc_sli_config_generic {
struct lpfc_sli_config_hdr sli_config_hdr;
#define LPFC_MBX_SLI_CONFIG_MAX_MSE 19
struct lpfc_sli_config_mse mse[LPFC_MBX_SLI_CONFIG_MAX_MSE];
};
struct lpfc_sli_config_subcmnd {
struct lpfc_sli_config_hdr sli_config_hdr;
uint32_t word6;
#define lpfc_subcmnd_opcode_SHIFT 0
#define lpfc_subcmnd_opcode_MASK 0xff
#define lpfc_subcmnd_opcode_WORD word6
#define lpfc_subcmnd_subsys_SHIFT 8
#define lpfc_subcmnd_subsys_MASK 0xff
#define lpfc_subcmnd_subsys_WORD word6
uint32_t timeout;
uint32_t request_length;
uint32_t word9;
#define lpfc_subcmnd_version_SHIFT 0
#define lpfc_subcmnd_version_MASK 0xff
#define lpfc_subcmnd_version_WORD word9
uint32_t word10;
#define lpfc_subcmnd_ask_rd_len_SHIFT 0
#define lpfc_subcmnd_ask_rd_len_MASK 0xffffff
#define lpfc_subcmnd_ask_rd_len_WORD word10
uint32_t rd_offset;
uint32_t obj_name[26];
uint32_t hbd_count;
#define LPFC_MBX_SLI_CONFIG_MAX_HBD 10
struct lpfc_sli_config_subcmd_hbd hbd[LPFC_MBX_SLI_CONFIG_MAX_HBD];
};
struct lpfc_sli_config_mbox {
uint32_t word0;
#define lpfc_mqe_status_SHIFT 16
#define lpfc_mqe_status_MASK 0x0000FFFF
#define lpfc_mqe_status_WORD word0
#define lpfc_mqe_command_SHIFT 8
#define lpfc_mqe_command_MASK 0x000000FF
#define lpfc_mqe_command_WORD word0
union {
struct lpfc_sli_config_generic sli_config_generic;
struct lpfc_sli_config_subcmnd sli_config_subcmnd;
} un;
};