summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_bsg.h
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-04-16 19:03:43 +0400
committerJames Bottomley <James.Bottomley@suse.de>2011-05-01 20:10:41 +0400
commitb6e3b9c606f271824bdeb6a40a080452eb086598 (patch)
tree9180f8036f9a729b40b2c8243e241c600d6afa12 /drivers/scsi/lpfc/lpfc_bsg.h
parentc31098cef5e091e22a02ff255f911e0ad71cc393 (diff)
downloadlinux-b6e3b9c606f271824bdeb6a40a080452eb086598.tar.xz
[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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_bsg.h')
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h
index a2c33e7c9152..b542aca6f5ae 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.h
+++ b/drivers/scsi/lpfc/lpfc_bsg.h
@@ -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;
+};