aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/bfa/bfa.h16
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h30
-rw-r--r--drivers/scsi/bfa/bfa_fc.h156
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c469
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.h12
-rw-r--r--drivers/scsi/bfa/bfa_svc.c33
-rw-r--r--drivers/scsi/bfa/bfa_svc.h15
7 files changed, 726 insertions, 5 deletions
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h
index 76300befffbe..a796de935054 100644
--- a/drivers/scsi/bfa/bfa.h
+++ b/drivers/scsi/bfa/bfa.h
@@ -382,6 +382,22 @@ int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
382#define bfa_get_fw_clock_res(__bfa) \ 382#define bfa_get_fw_clock_res(__bfa) \
383 ((__bfa)->iocfc.cfgrsp->fwcfg.fw_tick_res) 383 ((__bfa)->iocfc.cfgrsp->fwcfg.fw_tick_res)
384 384
385/*
386 * lun mask macros return NULL when min cfg is enabled and there is
387 * no memory allocated for lunmask.
388 */
389#define bfa_get_lun_mask(__bfa) \
390 ((&(__bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
391 (&(BFA_DCONF_MOD(__bfa)->dconf->lun_mask))
392
393#define bfa_get_lun_mask_list(_bfa) \
394 ((&(_bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
395 (bfa_get_lun_mask(_bfa)->lun_list)
396
397#define bfa_get_lun_mask_status(_bfa) \
398 (((&(_bfa)->modules.dconf_mod)->min_cfg) \
399 ? BFA_LUNMASK_MINCFG : ((bfa_get_lun_mask(_bfa))->status))
400
385void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids); 401void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids);
386void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg); 402void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg);
387void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg); 403void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg);
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index 202cb692f981..863c6ba7d5eb 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -672,6 +672,12 @@ struct bfa_itnim_iostats_s {
672 u32 tm_iocdowns; /* TM cleaned-up due to IOC down */ 672 u32 tm_iocdowns; /* TM cleaned-up due to IOC down */
673 u32 tm_cleanups; /* TM cleanup requests */ 673 u32 tm_cleanups; /* TM cleanup requests */
674 u32 tm_cleanup_comps; /* TM cleanup completions */ 674 u32 tm_cleanup_comps; /* TM cleanup completions */
675 u32 lm_lun_across_sg; /* LM lun is across sg data buf */
676 u32 lm_lun_not_sup; /* LM lun not supported */
677 u32 lm_rpl_data_changed; /* LM report-lun data changed */
678 u32 lm_wire_residue_changed; /* LM report-lun rsp residue changed */
679 u32 lm_small_buf_addresidue; /* LM buf smaller than reported cnt */
680 u32 lm_lun_not_rdy; /* LM lun not ready */
675}; 681};
676 682
677/* Modify char* port_stt[] in bfal_port.c if a new state was added */ 683/* Modify char* port_stt[] in bfal_port.c if a new state was added */
@@ -787,6 +793,28 @@ enum bfa_port_linkstate_rsn {
787 CEE_ISCSI_PRI_PFC_OFF = 42, 793 CEE_ISCSI_PRI_PFC_OFF = 42,
788 CEE_ISCSI_PRI_OVERLAP_FCOE_PRI = 43 794 CEE_ISCSI_PRI_OVERLAP_FCOE_PRI = 43
789}; 795};
796
797#define MAX_LUN_MASK_CFG 16
798
799/*
800 * Initially flash content may be fff. On making LUN mask enable and disable
801 * state chnage. when report lun command is being processed it goes from
802 * BFA_LUN_MASK_ACTIVE to BFA_LUN_MASK_FETCH and comes back to
803 * BFA_LUN_MASK_ACTIVE.
804 */
805enum bfa_ioim_lun_mask_state_s {
806 BFA_IOIM_LUN_MASK_INACTIVE = 0,
807 BFA_IOIM_LUN_MASK_ACTIVE = 1,
808 BFA_IOIM_LUN_MASK_FETCHED = 2,
809};
810
811enum bfa_lunmask_state_s {
812 BFA_LUNMASK_DISABLED = 0x00,
813 BFA_LUNMASK_ENABLED = 0x01,
814 BFA_LUNMASK_MINCFG = 0x02,
815 BFA_LUNMASK_UNINITIALIZED = 0xff,
816};
817
790#pragma pack(1) 818#pragma pack(1)
791/* 819/*
792 * LUN mask configuration 820 * LUN mask configuration
@@ -794,7 +822,7 @@ enum bfa_port_linkstate_rsn {
794struct bfa_lun_mask_s { 822struct bfa_lun_mask_s {
795 wwn_t lp_wwn; 823 wwn_t lp_wwn;
796 wwn_t rp_wwn; 824 wwn_t rp_wwn;
797 lun_t lun; 825 struct scsi_lun lun;
798 u8 ua; 826 u8 ua;
799 u8 rsvd[3]; 827 u8 rsvd[3];
800 u16 rp_tag; 828 u16 rp_tag;
diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h
index a007345e472a..50b6a1c86195 100644
--- a/drivers/scsi/bfa/bfa_fc.h
+++ b/drivers/scsi/bfa/bfa_fc.h
@@ -21,7 +21,6 @@
21#include "bfad_drv.h" 21#include "bfad_drv.h"
22 22
23typedef u64 wwn_t; 23typedef u64 wwn_t;
24typedef u64 lun_t;
25 24
26#define WWN_NULL (0) 25#define WWN_NULL (0)
27#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */ 26#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
@@ -57,6 +56,161 @@ struct scsi_cdb_s {
57 56
58#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length */ 57#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length */
59 58
59#define SCSI_SENSE_CUR_ERR 0x70
60#define SCSI_SENSE_DEF_ERR 0x71
61
62/*
63 * SCSI additional sense codes
64 */
65#define SCSI_ASC_LUN_NOT_READY 0x04
66#define SCSI_ASC_LUN_NOT_SUPPORTED 0x25
67#define SCSI_ASC_TOCC 0x3F
68
69/*
70 * SCSI additional sense code qualifiers
71 */
72#define SCSI_ASCQ_MAN_INTR_REQ 0x03 /* manual intervention req */
73#define SCSI_ASCQ_RL_DATA_CHANGED 0x0E /* report luns data changed */
74
75/*
76 * Methods of reporting informational exceptions
77 */
78#define SCSI_MP_IEC_UNIT_ATTN 0x2 /* generate unit attention */
79
80struct scsi_report_luns_data_s {
81 u32 lun_list_length; /* length of LUN list length */
82 u32 reserved;
83 struct scsi_lun lun[1]; /* first LUN in lun list */
84};
85
86struct scsi_inquiry_vendor_s {
87 u8 vendor_id[8];
88};
89
90struct scsi_inquiry_prodid_s {
91 u8 product_id[16];
92};
93
94struct scsi_inquiry_prodrev_s {
95 u8 product_rev[4];
96};
97
98struct scsi_inquiry_data_s {
99#ifdef __BIG_ENDIAN
100 u8 peripheral_qual:3; /* peripheral qualifier */
101 u8 device_type:5; /* peripheral device type */
102 u8 rmb:1; /* removable medium bit */
103 u8 device_type_mod:7; /* device type modifier */
104 u8 version;
105 u8 aenc:1; /* async evt notification capability */
106 u8 trm_iop:1; /* terminate I/O process */
107 u8 norm_aca:1; /* normal ACA supported */
108 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
109 u8 rsp_data_format:4;
110 u8 additional_len;
111 u8 sccs:1;
112 u8 reserved1:7;
113 u8 reserved2:1;
114 u8 enc_serv:1; /* enclosure service component */
115 u8 reserved3:1;
116 u8 multi_port:1; /* multi-port device */
117 u8 m_chngr:1; /* device in medium transport element */
118 u8 ack_req_q:1; /* SIP specific bit */
119 u8 addr32:1; /* SIP specific bit */
120 u8 addr16:1; /* SIP specific bit */
121 u8 rel_adr:1; /* relative address */
122 u8 w_bus32:1;
123 u8 w_bus16:1;
124 u8 synchronous:1;
125 u8 linked_commands:1;
126 u8 trans_dis:1;
127 u8 cmd_queue:1; /* command queueing supported */
128 u8 soft_reset:1; /* soft reset alternative (VS) */
129#else
130 u8 device_type:5; /* peripheral device type */
131 u8 peripheral_qual:3; /* peripheral qualifier */
132 u8 device_type_mod:7; /* device type modifier */
133 u8 rmb:1; /* removable medium bit */
134 u8 version;
135 u8 rsp_data_format:4;
136 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
137 u8 norm_aca:1; /* normal ACA supported */
138 u8 terminate_iop:1;/* terminate I/O process */
139 u8 aenc:1; /* async evt notification capability */
140 u8 additional_len;
141 u8 reserved1:7;
142 u8 sccs:1;
143 u8 addr16:1; /* SIP specific bit */
144 u8 addr32:1; /* SIP specific bit */
145 u8 ack_req_q:1; /* SIP specific bit */
146 u8 m_chngr:1; /* device in medium transport element */
147 u8 multi_port:1; /* multi-port device */
148 u8 reserved3:1; /* TBD - Vendor Specific */
149 u8 enc_serv:1; /* enclosure service component */
150 u8 reserved2:1;
151 u8 soft_seset:1; /* soft reset alternative (VS) */
152 u8 cmd_queue:1; /* command queueing supported */
153 u8 trans_dis:1;
154 u8 linked_commands:1;
155 u8 synchronous:1;
156 u8 w_bus16:1;
157 u8 w_bus32:1;
158 u8 rel_adr:1; /* relative address */
159#endif
160 struct scsi_inquiry_vendor_s vendor_id;
161 struct scsi_inquiry_prodid_s product_id;
162 struct scsi_inquiry_prodrev_s product_rev;
163 u8 vendor_specific[20];
164 u8 reserved4[40];
165};
166
167/*
168 * SCSI sense data format
169 */
170struct scsi_sense_s {
171#ifdef __BIG_ENDIAN
172 u8 valid:1;
173 u8 rsp_code:7;
174#else
175 u8 rsp_code:7;
176 u8 valid:1;
177#endif
178 u8 seg_num;
179#ifdef __BIG_ENDIAN
180 u8 file_mark:1;
181 u8 eom:1; /* end of media */
182 u8 ili:1; /* incorrect length indicator */
183 u8 reserved:1;
184 u8 sense_key:4;
185#else
186 u8 sense_key:4;
187 u8 reserved:1;
188 u8 ili:1; /* incorrect length indicator */
189 u8 eom:1; /* end of media */
190 u8 file_mark:1;
191#endif
192 u8 information[4]; /* device-type or cmd specific info */
193 u8 add_sense_length; /* additional sense length */
194 u8 command_info[4];/* command specific information */
195 u8 asc; /* additional sense code */
196 u8 ascq; /* additional sense code qualifier */
197 u8 fru_code; /* field replaceable unit code */
198#ifdef __BIG_ENDIAN
199 u8 sksv:1; /* sense key specific valid */
200 u8 c_d:1; /* command/data bit */
201 u8 res1:2;
202 u8 bpv:1; /* bit pointer valid */
203 u8 bpointer:3; /* bit pointer */
204#else
205 u8 bpointer:3; /* bit pointer */
206 u8 bpv:1; /* bit pointer valid */
207 u8 res1:2;
208 u8 c_d:1; /* command/data bit */
209 u8 sksv:1; /* sense key specific valid */
210#endif
211 u8 fpointer[2]; /* field pointer */
212};
213
60/* 214/*
61 * Fibre Channel Header Structure (FCHS) definition 215 * Fibre Channel Header Structure (FCHS) definition
62 */ 216 */
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index 7bc010dc17b1..e601f178c5a6 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -24,6 +24,9 @@ BFA_TRC_FILE(HAL, FCPIM);
24 * BFA ITNIM Related definitions 24 * BFA ITNIM Related definitions
25 */ 25 */
26static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim); 26static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
27static bfa_boolean_t bfa_ioim_lm_proc_rpl_data(struct bfa_ioim_s *ioim);
28static bfa_boolean_t bfa_ioim_lm_proc_inq_data(struct bfa_ioim_s *ioim);
29static void bfa_ioim_lm_init(struct bfa_s *bfa);
27 30
28#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \ 31#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \
29 (((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1)))) 32 (((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1))))
@@ -57,6 +60,14 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
57 } \ 60 } \
58} while (0) 61} while (0)
59 62
63#define bfa_ioim_rp_wwn(__ioim) \
64 (((struct bfa_fcs_rport_s *) \
65 (__ioim)->itnim->rport->rport_drv)->pwwn)
66
67#define bfa_ioim_lp_wwn(__ioim) \
68 ((BFA_LPS_FROM_TAG(BFA_LPS_MOD((__ioim)->bfa), \
69 (__ioim)->itnim->rport->rport_info.lp_tag))->pwwn) \
70
60#define bfa_itnim_sler_cb(__itnim) do { \ 71#define bfa_itnim_sler_cb(__itnim) do { \
61 if ((__itnim)->bfa->fcs) \ 72 if ((__itnim)->bfa->fcs) \
62 bfa_cb_itnim_sler((__itnim)->ditn); \ 73 bfa_cb_itnim_sler((__itnim)->ditn); \
@@ -66,6 +77,18 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
66 } \ 77 } \
67} while (0) 78} while (0)
68 79
80enum bfa_ioim_lm_status {
81 BFA_IOIM_LM_PRESENT = 1,
82 BFA_IOIM_LM_LUN_NOT_SUP = 2,
83 BFA_IOIM_LM_RPL_DATA_CHANGED = 3,
84 BFA_IOIM_LM_LUN_NOT_RDY = 4,
85};
86
87enum bfa_ioim_lm_ua_status {
88 BFA_IOIM_LM_UA_RESET = 0,
89 BFA_IOIM_LM_UA_SET = 1,
90};
91
69/* 92/*
70 * itnim state machine event 93 * itnim state machine event
71 */ 94 */
@@ -122,6 +145,9 @@ enum bfa_ioim_event {
122 BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */ 145 BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */
123 BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */ 146 BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */
124 BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */ 147 BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */
148 BFA_IOIM_SM_LM_LUN_NOT_SUP = 19,/* lunmask lun not supported */
149 BFA_IOIM_SM_LM_RPL_DC = 20, /* lunmask report-lun data changed */
150 BFA_IOIM_SM_LM_LUN_NOT_RDY = 21,/* lunmask lun not ready */
125}; 151};
126 152
127 153
@@ -219,6 +245,9 @@ static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete);
219static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); 245static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
220static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); 246static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
221static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim); 247static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
248static void __bfa_cb_ioim_lm_lun_not_sup(void *cbarg, bfa_boolean_t complete);
249static void __bfa_cb_ioim_lm_rpl_dc(void *cbarg, bfa_boolean_t complete);
250static void __bfa_cb_ioim_lm_lun_not_rdy(void *cbarg, bfa_boolean_t complete);
222 251
223/* 252/*
224 * forward declaration of BFA IO state machine 253 * forward declaration of BFA IO state machine
@@ -416,6 +445,12 @@ bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats,
416 bfa_fcpim_add_iostats(lstats, rstats, output_reqs); 445 bfa_fcpim_add_iostats(lstats, rstats, output_reqs);
417 bfa_fcpim_add_iostats(lstats, rstats, rd_throughput); 446 bfa_fcpim_add_iostats(lstats, rstats, rd_throughput);
418 bfa_fcpim_add_iostats(lstats, rstats, wr_throughput); 447 bfa_fcpim_add_iostats(lstats, rstats, wr_throughput);
448 bfa_fcpim_add_iostats(lstats, rstats, lm_lun_across_sg);
449 bfa_fcpim_add_iostats(lstats, rstats, lm_lun_not_sup);
450 bfa_fcpim_add_iostats(lstats, rstats, lm_rpl_data_changed);
451 bfa_fcpim_add_iostats(lstats, rstats, lm_wire_residue_changed);
452 bfa_fcpim_add_iostats(lstats, rstats, lm_small_buf_addresidue);
453 bfa_fcpim_add_iostats(lstats, rstats, lm_lun_not_rdy);
419} 454}
420 455
421bfa_status_t 456bfa_status_t
@@ -1542,7 +1577,28 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1542 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1577 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1543 WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim)); 1578 WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
1544 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1579 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1545 __bfa_cb_ioim_abort, ioim); 1580 __bfa_cb_ioim_abort, ioim);
1581 break;
1582
1583 case BFA_IOIM_SM_LM_LUN_NOT_SUP:
1584 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1585 bfa_ioim_move_to_comp_q(ioim);
1586 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1587 __bfa_cb_ioim_lm_lun_not_sup, ioim);
1588 break;
1589
1590 case BFA_IOIM_SM_LM_RPL_DC:
1591 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1592 bfa_ioim_move_to_comp_q(ioim);
1593 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1594 __bfa_cb_ioim_lm_rpl_dc, ioim);
1595 break;
1596
1597 case BFA_IOIM_SM_LM_LUN_NOT_RDY:
1598 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1599 bfa_ioim_move_to_comp_q(ioim);
1600 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1601 __bfa_cb_ioim_lm_lun_not_rdy, ioim);
1546 break; 1602 break;
1547 1603
1548 default: 1604 default:
@@ -2082,6 +2138,264 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2082 } 2138 }
2083} 2139}
2084 2140
2141/*
2142 * This is called from bfa_fcpim_start after the bfa_init() with flash read
2143 * is complete by driver. now invalidate the stale content of lun mask
2144 * like unit attention, rp tag and lp tag.
2145 */
2146static void
2147bfa_ioim_lm_init(struct bfa_s *bfa)
2148{
2149 struct bfa_lun_mask_s *lunm_list;
2150 int i;
2151
2152 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2153 return;
2154
2155 lunm_list = bfa_get_lun_mask_list(bfa);
2156 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2157 lunm_list[i].ua = BFA_IOIM_LM_UA_RESET;
2158 lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
2159 lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
2160 }
2161}
2162
2163/*
2164 * Validate LUN for LUN masking
2165 */
2166static enum bfa_ioim_lm_status
2167bfa_ioim_lm_check(struct bfa_ioim_s *ioim, struct bfa_lps_s *lps,
2168 struct bfa_rport_s *rp, struct scsi_lun lun)
2169{
2170 u8 i;
2171 struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(ioim->bfa);
2172 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
2173 struct scsi_cdb_s *cdb = (struct scsi_cdb_s *)cmnd->cmnd;
2174
2175 if ((cdb->scsi_cdb[0] == REPORT_LUNS) &&
2176 (scsilun_to_int((struct scsi_lun *)&lun) == 0)) {
2177 ioim->proc_rsp_data = bfa_ioim_lm_proc_rpl_data;
2178 return BFA_IOIM_LM_PRESENT;
2179 }
2180
2181 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2182
2183 if (lun_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2184 continue;
2185
2186 if ((scsilun_to_int((struct scsi_lun *)&lun_list[i].lun) ==
2187 scsilun_to_int((struct scsi_lun *)&lun))
2188 && (rp->rport_tag == lun_list[i].rp_tag)
2189 && ((u8)ioim->itnim->rport->rport_info.lp_tag ==
2190 lun_list[i].lp_tag)) {
2191 bfa_trc(ioim->bfa, lun_list[i].rp_tag);
2192 bfa_trc(ioim->bfa, lun_list[i].lp_tag);
2193 bfa_trc(ioim->bfa, scsilun_to_int(
2194 (struct scsi_lun *)&lun_list[i].lun));
2195
2196 if ((lun_list[i].ua == BFA_IOIM_LM_UA_SET) &&
2197 ((cdb->scsi_cdb[0] != INQUIRY) ||
2198 (cdb->scsi_cdb[0] != REPORT_LUNS))) {
2199 lun_list[i].ua = BFA_IOIM_LM_UA_RESET;
2200 return BFA_IOIM_LM_RPL_DATA_CHANGED;
2201 }
2202
2203 if (cdb->scsi_cdb[0] == REPORT_LUNS)
2204 ioim->proc_rsp_data = bfa_ioim_lm_proc_rpl_data;
2205
2206 return BFA_IOIM_LM_PRESENT;
2207 }
2208 }
2209
2210 if ((cdb->scsi_cdb[0] == INQUIRY) &&
2211 (scsilun_to_int((struct scsi_lun *)&lun) == 0)) {
2212 ioim->proc_rsp_data = bfa_ioim_lm_proc_inq_data;
2213 return BFA_IOIM_LM_PRESENT;
2214 }
2215
2216 if (cdb->scsi_cdb[0] == TEST_UNIT_READY)
2217 return BFA_IOIM_LM_LUN_NOT_RDY;
2218
2219 return BFA_IOIM_LM_LUN_NOT_SUP;
2220}
2221
2222static bfa_boolean_t
2223bfa_ioim_lm_proc_rsp_data_dummy(struct bfa_ioim_s *ioim)
2224{
2225 return BFA_TRUE;
2226}
2227
2228static void
2229bfa_ioim_lm_fetch_lun(struct bfa_ioim_s *ioim, u8 *rl_data, int offset,
2230 int buf_lun_cnt)
2231{
2232 struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(ioim->bfa);
2233 struct scsi_lun *lun_data = (struct scsi_lun *)(rl_data + offset);
2234 struct scsi_lun lun;
2235 int i, j;
2236
2237 bfa_trc(ioim->bfa, buf_lun_cnt);
2238 for (j = 0; j < buf_lun_cnt; j++) {
2239 lun = *((struct scsi_lun *)(lun_data + j));
2240 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2241 if (lun_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2242 continue;
2243 if ((lun_list[i].rp_wwn == bfa_ioim_rp_wwn(ioim)) &&
2244 (lun_list[i].lp_wwn == bfa_ioim_lp_wwn(ioim)) &&
2245 (scsilun_to_int((struct scsi_lun *)&lun_list[i].lun)
2246 == scsilun_to_int((struct scsi_lun *)&lun))) {
2247 lun_list[i].state = BFA_IOIM_LUN_MASK_FETCHED;
2248 break;
2249 }
2250 } /* next lun in mask DB */
2251 } /* next lun in buf */
2252}
2253
2254static int
2255bfa_ioim_lm_update_lun_sg(struct bfa_ioim_s *ioim, u32 *pgdlen,
2256 struct scsi_report_luns_data_s *rl)
2257{
2258 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
2259 struct scatterlist *sg = scsi_sglist(cmnd);
2260 struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(ioim->bfa);
2261 struct scsi_lun *prev_rl_data = NULL, *base_rl_data;
2262 int i, j, sgeid, lun_fetched_cnt = 0, prev_sg_len = 0, base_count;
2263 int lun_across_sg_bytes, bytes_from_next_buf;
2264 u64 last_lun, temp_last_lun;
2265
2266 /* fetch luns from the first sg element */
2267 bfa_ioim_lm_fetch_lun(ioim, (u8 *)(rl->lun), 0,
2268 (sg_dma_len(sg) / sizeof(struct scsi_lun)) - 1);
2269
2270 /* fetch luns from multiple sg elements */
2271 scsi_for_each_sg(cmnd, sg, scsi_sg_count(cmnd), sgeid) {
2272 if (sgeid == 0) {
2273 prev_sg_len = sg_dma_len(sg);
2274 prev_rl_data = (struct scsi_lun *)
2275 phys_to_virt(sg_dma_address(sg));
2276 continue;
2277 }
2278
2279 /* if the buf is having more data */
2280 lun_across_sg_bytes = prev_sg_len % sizeof(struct scsi_lun);
2281 if (lun_across_sg_bytes) {
2282 bfa_trc(ioim->bfa, lun_across_sg_bytes);
2283 bfa_stats(ioim->itnim, lm_lun_across_sg);
2284 bytes_from_next_buf = sizeof(struct scsi_lun) -
2285 lun_across_sg_bytes;
2286
2287 /* from next buf take higher bytes */
2288 temp_last_lun = *((u64 *)
2289 phys_to_virt(sg_dma_address(sg)));
2290 last_lun |= temp_last_lun >>
2291 (lun_across_sg_bytes * BITS_PER_BYTE);
2292
2293 /* from prev buf take higher bytes */
2294 temp_last_lun = *((u64 *)(prev_rl_data +
2295 (prev_sg_len - lun_across_sg_bytes)));
2296 temp_last_lun >>= bytes_from_next_buf * BITS_PER_BYTE;
2297 last_lun = last_lun | (temp_last_lun <<
2298 (bytes_from_next_buf * BITS_PER_BYTE));
2299
2300 bfa_ioim_lm_fetch_lun(ioim, (u8 *)&last_lun, 0, 1);
2301 } else
2302 bytes_from_next_buf = 0;
2303
2304 *pgdlen += sg_dma_len(sg);
2305 prev_sg_len = sg_dma_len(sg);
2306 prev_rl_data = (struct scsi_lun *)
2307 phys_to_virt(sg_dma_address(sg));
2308 bfa_ioim_lm_fetch_lun(ioim, (u8 *)prev_rl_data,
2309 bytes_from_next_buf,
2310 sg_dma_len(sg) / sizeof(struct scsi_lun));
2311 }
2312
2313 /* update the report luns data - based on fetched luns */
2314 sg = scsi_sglist(cmnd);
2315 base_rl_data = (struct scsi_lun *)rl->lun;
2316 base_count = (sg_dma_len(sg) / sizeof(struct scsi_lun)) - 1;
2317 for (i = 0, j = 0; i < MAX_LUN_MASK_CFG; i++) {
2318 if (lun_list[i].state == BFA_IOIM_LUN_MASK_FETCHED) {
2319 base_rl_data[j] = lun_list[i].lun;
2320 lun_list[i].state = BFA_IOIM_LUN_MASK_ACTIVE;
2321 j++;
2322 lun_fetched_cnt++;
2323 }
2324
2325 if (j > base_count) {
2326 j = 0;
2327 sg = sg_next(sg);
2328 base_rl_data = (struct scsi_lun *)
2329 phys_to_virt(sg_dma_address(sg));
2330 base_count = sg_dma_len(sg) / sizeof(struct scsi_lun);
2331 }
2332 }
2333
2334 bfa_trc(ioim->bfa, lun_fetched_cnt);
2335 return lun_fetched_cnt;
2336}
2337
2338static bfa_boolean_t
2339bfa_ioim_lm_proc_inq_data(struct bfa_ioim_s *ioim)
2340{
2341 struct scsi_inquiry_data_s *inq;
2342 struct scatterlist *sg = scsi_sglist((struct scsi_cmnd *)ioim->dio);
2343
2344 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2345 inq = (struct scsi_inquiry_data_s *)phys_to_virt(sg_dma_address(sg));
2346
2347 bfa_trc(ioim->bfa, inq->device_type);
2348 inq->peripheral_qual = SCSI_INQ_PQ_NOT_CON;
2349 return 0;
2350}
2351
2352static bfa_boolean_t
2353bfa_ioim_lm_proc_rpl_data(struct bfa_ioim_s *ioim)
2354{
2355 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
2356 struct scatterlist *sg = scsi_sglist(cmnd);
2357 struct bfi_ioim_rsp_s *m;
2358 struct scsi_report_luns_data_s *rl = NULL;
2359 int lun_count = 0, lun_fetched_cnt = 0;
2360 u32 residue, pgdlen = 0;
2361
2362 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2363 if (bfa_get_lun_mask_status(ioim->bfa) != BFA_LUNMASK_ENABLED)
2364 return BFA_TRUE;
2365
2366 m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
2367 if (m->scsi_status == SCSI_STATUS_CHECK_CONDITION)
2368 return BFA_TRUE;
2369
2370 pgdlen = sg_dma_len(sg);
2371 bfa_trc(ioim->bfa, pgdlen);
2372 rl = (struct scsi_report_luns_data_s *)phys_to_virt(sg_dma_address(sg));
2373 lun_count = cpu_to_be32(rl->lun_list_length) / sizeof(struct scsi_lun);
2374 lun_fetched_cnt = bfa_ioim_lm_update_lun_sg(ioim, &pgdlen, rl);
2375
2376 if (lun_count == lun_fetched_cnt)
2377 return BFA_TRUE;
2378
2379 bfa_trc(ioim->bfa, lun_count);
2380 bfa_trc(ioim->bfa, lun_fetched_cnt);
2381 bfa_trc(ioim->bfa, be32_to_cpu(rl->lun_list_length));
2382
2383 if (be32_to_cpu(rl->lun_list_length) <= pgdlen)
2384 rl->lun_list_length = be32_to_cpu(lun_fetched_cnt) *
2385 sizeof(struct scsi_lun);
2386 else
2387 bfa_stats(ioim->itnim, lm_small_buf_addresidue);
2388
2389 bfa_trc(ioim->bfa, be32_to_cpu(rl->lun_list_length));
2390 bfa_trc(ioim->bfa, be32_to_cpu(m->residue));
2391
2392 residue = be32_to_cpu(m->residue);
2393 residue += (lun_count - lun_fetched_cnt) * sizeof(struct scsi_lun);
2394 bfa_stats(ioim->itnim, lm_wire_residue_changed);
2395 m->residue = be32_to_cpu(residue);
2396 bfa_trc(ioim->bfa, ioim->nsges);
2397 return BFA_FALSE;
2398}
2085 2399
2086static void 2400static void
2087__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete) 2401__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
@@ -2141,6 +2455,105 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
2141} 2455}
2142 2456
2143static void 2457static void
2458__bfa_cb_ioim_lm_lun_not_sup(void *cbarg, bfa_boolean_t complete)
2459{
2460 struct bfa_ioim_s *ioim = cbarg;
2461 int sns_len = 0xD;
2462 u32 residue = scsi_bufflen((struct scsi_cmnd *)ioim->dio);
2463 struct scsi_sense_s *snsinfo;
2464
2465 if (!complete) {
2466 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2467 return;
2468 }
2469
2470 snsinfo = (struct scsi_sense_s *)BFA_SNSINFO_FROM_TAG(
2471 ioim->fcpim->fcp, ioim->iotag);
2472 snsinfo->rsp_code = SCSI_SENSE_CUR_ERR;
2473 snsinfo->add_sense_length = 0xa;
2474 snsinfo->asc = SCSI_ASC_LUN_NOT_SUPPORTED;
2475 snsinfo->sense_key = ILLEGAL_REQUEST;
2476 bfa_trc(ioim->bfa, residue);
2477 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_OK,
2478 SCSI_STATUS_CHECK_CONDITION, sns_len,
2479 (u8 *)snsinfo, residue);
2480}
2481
2482static void
2483__bfa_cb_ioim_lm_rpl_dc(void *cbarg, bfa_boolean_t complete)
2484{
2485 struct bfa_ioim_s *ioim = cbarg;
2486 int sns_len = 0xD;
2487 u32 residue = scsi_bufflen((struct scsi_cmnd *)ioim->dio);
2488 struct scsi_sense_s *snsinfo;
2489
2490 if (!complete) {
2491 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2492 return;
2493 }
2494
2495 snsinfo = (struct scsi_sense_s *)BFA_SNSINFO_FROM_TAG(ioim->fcpim->fcp,
2496 ioim->iotag);
2497 snsinfo->rsp_code = SCSI_SENSE_CUR_ERR;
2498 snsinfo->sense_key = SCSI_MP_IEC_UNIT_ATTN;
2499 snsinfo->asc = SCSI_ASC_TOCC;
2500 snsinfo->add_sense_length = 0x6;
2501 snsinfo->ascq = SCSI_ASCQ_RL_DATA_CHANGED;
2502 bfa_trc(ioim->bfa, residue);
2503 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_OK,
2504 SCSI_STATUS_CHECK_CONDITION, sns_len,
2505 (u8 *)snsinfo, residue);
2506}
2507
2508static void
2509__bfa_cb_ioim_lm_lun_not_rdy(void *cbarg, bfa_boolean_t complete)
2510{
2511 struct bfa_ioim_s *ioim = cbarg;
2512 int sns_len = 0xD;
2513 u32 residue = scsi_bufflen((struct scsi_cmnd *)ioim->dio);
2514 struct scsi_sense_s *snsinfo;
2515
2516 if (!complete) {
2517 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2518 return;
2519 }
2520
2521 snsinfo = (struct scsi_sense_s *)BFA_SNSINFO_FROM_TAG(
2522 ioim->fcpim->fcp, ioim->iotag);
2523 snsinfo->rsp_code = SCSI_SENSE_CUR_ERR;
2524 snsinfo->add_sense_length = 0xa;
2525 snsinfo->sense_key = NOT_READY;
2526 snsinfo->asc = SCSI_ASC_LUN_NOT_READY;
2527 snsinfo->ascq = SCSI_ASCQ_MAN_INTR_REQ;
2528 bfa_trc(ioim->bfa, residue);
2529 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_OK,
2530 SCSI_STATUS_CHECK_CONDITION, sns_len,
2531 (u8 *)snsinfo, residue);
2532}
2533
2534void
2535bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn, wwn_t rp_wwn,
2536 u16 rp_tag, u8 lp_tag)
2537{
2538 struct bfa_lun_mask_s *lun_list;
2539 u8 i;
2540
2541 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2542 return;
2543
2544 lun_list = bfa_get_lun_mask_list(bfa);
2545 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2546 if (lun_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
2547 if ((lun_list[i].lp_wwn == lp_wwn) &&
2548 (lun_list[i].rp_wwn == rp_wwn)) {
2549 lun_list[i].rp_tag = rp_tag;
2550 lun_list[i].lp_tag = lp_tag;
2551 }
2552 }
2553 }
2554}
2555
2556static void
2144__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete) 2557__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
2145{ 2558{
2146 struct bfa_ioim_s *ioim = cbarg; 2559 struct bfa_ioim_s *ioim = cbarg;
@@ -2150,6 +2563,7 @@ __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
2150 return; 2563 return;
2151 } 2564 }
2152 2565
2566 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2153 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED, 2567 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
2154 0, 0, NULL, 0); 2568 0, 0, NULL, 0);
2155} 2569}
@@ -2165,6 +2579,7 @@ __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
2165 return; 2579 return;
2166 } 2580 }
2167 2581
2582 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2168 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV, 2583 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
2169 0, 0, NULL, 0); 2584 0, 0, NULL, 0);
2170} 2585}
@@ -2179,6 +2594,7 @@ __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
2179 return; 2594 return;
2180 } 2595 }
2181 2596
2597 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2182 bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio); 2598 bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
2183} 2599}
2184 2600
@@ -2522,6 +2938,7 @@ bfa_ioim_attach(struct bfa_fcpim_s *fcpim)
2522 ioim->bfa = fcpim->bfa; 2938 ioim->bfa = fcpim->bfa;
2523 ioim->fcpim = fcpim; 2939 ioim->fcpim = fcpim;
2524 ioim->iosp = iosp; 2940 ioim->iosp = iosp;
2941 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2525 INIT_LIST_HEAD(&ioim->sgpg_q); 2942 INIT_LIST_HEAD(&ioim->sgpg_q);
2526 bfa_reqq_winit(&ioim->iosp->reqq_wait, 2943 bfa_reqq_winit(&ioim->iosp->reqq_wait,
2527 bfa_ioim_qresume, ioim); 2944 bfa_ioim_qresume, ioim);
@@ -2559,6 +2976,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2559 evt = BFA_IOIM_SM_DONE; 2976 evt = BFA_IOIM_SM_DONE;
2560 else 2977 else
2561 evt = BFA_IOIM_SM_COMP; 2978 evt = BFA_IOIM_SM_COMP;
2979 ioim->proc_rsp_data(ioim);
2562 break; 2980 break;
2563 2981
2564 case BFI_IOIM_STS_TIMEDOUT: 2982 case BFI_IOIM_STS_TIMEDOUT:
@@ -2594,6 +3012,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2594 if (rsp->abort_tag != ioim->abort_tag) { 3012 if (rsp->abort_tag != ioim->abort_tag) {
2595 bfa_trc(ioim->bfa, rsp->abort_tag); 3013 bfa_trc(ioim->bfa, rsp->abort_tag);
2596 bfa_trc(ioim->bfa, ioim->abort_tag); 3014 bfa_trc(ioim->bfa, ioim->abort_tag);
3015 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2597 return; 3016 return;
2598 } 3017 }
2599 3018
@@ -2612,6 +3031,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2612 WARN_ON(1); 3031 WARN_ON(1);
2613 } 3032 }
2614 3033
3034 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2615 bfa_sm_send_event(ioim, evt); 3035 bfa_sm_send_event(ioim, evt);
2616} 3036}
2617 3037
@@ -2629,7 +3049,16 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2629 WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag); 3049 WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag);
2630 3050
2631 bfa_ioim_cb_profile_comp(fcpim, ioim); 3051 bfa_ioim_cb_profile_comp(fcpim, ioim);
2632 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); 3052
3053 if (bfa_get_lun_mask_status(bfa) != BFA_LUNMASK_ENABLED) {
3054 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
3055 return;
3056 }
3057
3058 if (ioim->proc_rsp_data(ioim) == BFA_TRUE)
3059 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
3060 else
3061 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP);
2633} 3062}
2634 3063
2635/* 3064/*
@@ -2741,6 +3170,35 @@ bfa_ioim_free(struct bfa_ioim_s *ioim)
2741void 3170void
2742bfa_ioim_start(struct bfa_ioim_s *ioim) 3171bfa_ioim_start(struct bfa_ioim_s *ioim)
2743{ 3172{
3173 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
3174 struct bfa_lps_s *lps;
3175 enum bfa_ioim_lm_status status;
3176 struct scsi_lun scsilun;
3177
3178 if (bfa_get_lun_mask_status(ioim->bfa) == BFA_LUNMASK_ENABLED) {
3179 lps = BFA_IOIM_TO_LPS(ioim);
3180 int_to_scsilun(cmnd->device->lun, &scsilun);
3181 status = bfa_ioim_lm_check(ioim, lps,
3182 ioim->itnim->rport, scsilun);
3183 if (status == BFA_IOIM_LM_LUN_NOT_RDY) {
3184 bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_LUN_NOT_RDY);
3185 bfa_stats(ioim->itnim, lm_lun_not_rdy);
3186 return;
3187 }
3188
3189 if (status == BFA_IOIM_LM_LUN_NOT_SUP) {
3190 bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_LUN_NOT_SUP);
3191 bfa_stats(ioim->itnim, lm_lun_not_sup);
3192 return;
3193 }
3194
3195 if (status == BFA_IOIM_LM_RPL_DATA_CHANGED) {
3196 bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_RPL_DC);
3197 bfa_stats(ioim->itnim, lm_rpl_data_changed);
3198 return;
3199 }
3200 }
3201
2744 bfa_ioim_cb_profile_start(ioim->fcpim, ioim); 3202 bfa_ioim_cb_profile_start(ioim->fcpim, ioim);
2745 3203
2746 /* 3204 /*
@@ -3484,6 +3942,13 @@ bfa_fcp_detach(struct bfa_s *bfa)
3484static void 3942static void
3485bfa_fcp_start(struct bfa_s *bfa) 3943bfa_fcp_start(struct bfa_s *bfa)
3486{ 3944{
3945 struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3946
3947 /*
3948 * bfa_init() with flash read is complete. now invalidate the stale
3949 * content of lun mask like unit attention, rp tag and lp tag.
3950 */
3951 bfa_ioim_lm_init(fcp->bfa);
3487} 3952}
3488 3953
3489static void 3954static void
diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h
index c224987b9c30..99fc913929b6 100644
--- a/drivers/scsi/bfa/bfa_fcpim.h
+++ b/drivers/scsi/bfa/bfa_fcpim.h
@@ -110,6 +110,7 @@ struct bfad_ioim_s;
110struct bfad_tskim_s; 110struct bfad_tskim_s;
111 111
112typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim); 112typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim);
113typedef bfa_boolean_t (*bfa_ioim_lm_proc_rsp_data_t) (struct bfa_ioim_s *ioim);
113 114
114struct bfa_fcpim_s { 115struct bfa_fcpim_s {
115 struct bfa_s *bfa; 116 struct bfa_s *bfa;
@@ -123,7 +124,7 @@ struct bfa_fcpim_s {
123 u32 path_tov; 124 u32 path_tov;
124 u16 q_depth; 125 u16 q_depth;
125 u8 reqq; /* Request queue to be used */ 126 u8 reqq; /* Request queue to be used */
126 u8 rsvd; 127 u8 lun_masking_pending;
127 struct list_head itnim_q; /* queue of active itnim */ 128 struct list_head itnim_q; /* queue of active itnim */
128 struct list_head ioim_resfree_q; /* IOs waiting for f/w */ 129 struct list_head ioim_resfree_q; /* IOs waiting for f/w */
129 struct list_head ioim_comp_q; /* IO global comp Q */ 130 struct list_head ioim_comp_q; /* IO global comp Q */
@@ -178,7 +179,9 @@ struct bfa_ioim_s {
178 bfa_cb_cbfn_t io_cbfn; /* IO completion handler */ 179 bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
179 struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */ 180 struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
180 u8 reqq; /* Request queue for I/O */ 181 u8 reqq; /* Request queue for I/O */
182 u8 mode; /* IO is passthrough or not */
181 u64 start_time; /* IO's Profile start val */ 183 u64 start_time; /* IO's Profile start val */
184 bfa_ioim_lm_proc_rsp_data_t proc_rsp_data; /* RSP data adjust */
182}; 185};
183 186
184struct bfa_ioim_sp_s { 187struct bfa_ioim_sp_s {
@@ -258,6 +261,10 @@ struct bfa_itnim_s {
258 (__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET; \ 261 (__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET; \
259} while (0) 262} while (0)
260 263
264#define BFA_IOIM_TO_LPS(__ioim) \
265 BFA_LPS_FROM_TAG(BFA_LPS_MOD(__ioim->bfa), \
266 __ioim->itnim->rport->rport_info.lp_tag)
267
261static inline bfa_boolean_t 268static inline bfa_boolean_t
262bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim) 269bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim)
263{ 270{
@@ -407,4 +414,7 @@ void bfa_tskim_start(struct bfa_tskim_s *tskim,
407void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk, 414void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
408 enum bfi_tskim_status tsk_status); 415 enum bfi_tskim_status tsk_status);
409 416
417void bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn,
418 wwn_t rp_wwn, u16 rp_tag, u8 lp_tag);
419
410#endif /* __BFA_FCPIM_H__ */ 420#endif /* __BFA_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index d0ed4dd6f35a..aa8a0eaf91f9 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -4677,6 +4677,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
4677 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle); 4677 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
4678 rp->fw_handle = msg.create_rsp->fw_handle; 4678 rp->fw_handle = msg.create_rsp->fw_handle;
4679 rp->qos_attr = msg.create_rsp->qos_attr; 4679 rp->qos_attr = msg.create_rsp->qos_attr;
4680 bfa_rport_set_lunmask(bfa, rp);
4680 WARN_ON(msg.create_rsp->status != BFA_STATUS_OK); 4681 WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
4681 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4682 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4682 break; 4683 break;
@@ -4684,6 +4685,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
4684 case BFI_RPORT_I2H_DELETE_RSP: 4685 case BFI_RPORT_I2H_DELETE_RSP:
4685 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle); 4686 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
4686 WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK); 4687 WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
4688 bfa_rport_unset_lunmask(bfa, rp);
4687 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4689 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4688 break; 4690 break;
4689 4691
@@ -4764,6 +4766,37 @@ bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
4764 bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 4766 bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
4765} 4767}
4766 4768
4769/* Set Rport LUN Mask */
4770void
4771bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
4772{
4773 struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa);
4774 wwn_t lp_wwn, rp_wwn;
4775 u8 lp_tag = (u8)rp->rport_info.lp_tag;
4776
4777 rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
4778 lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
4779
4780 BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
4781 rp->lun_mask = BFA_TRUE;
4782 bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, rp->rport_tag, lp_tag);
4783}
4784
4785/* Unset Rport LUN mask */
4786void
4787bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
4788{
4789 struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa);
4790 wwn_t lp_wwn, rp_wwn;
4791
4792 rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
4793 lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
4794
4795 BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
4796 rp->lun_mask = BFA_FALSE;
4797 bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn,
4798 BFA_RPORT_TAG_INVALID, BFA_LP_TAG_INVALID);
4799}
4767 4800
4768/* 4801/*
4769 * SGPG related functions 4802 * SGPG related functions
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index 01db3520070f..95adb86d3769 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -297,6 +297,7 @@ struct bfa_rport_s {
297 void *rport_drv; /* fcs/driver rport object */ 297 void *rport_drv; /* fcs/driver rport object */
298 u16 fw_handle; /* firmware rport handle */ 298 u16 fw_handle; /* firmware rport handle */
299 u16 rport_tag; /* BFA rport tag */ 299 u16 rport_tag; /* BFA rport tag */
300 u8 lun_mask; /* LUN mask flag */
300 struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */ 301 struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */
301 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ 302 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
302 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */ 303 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */
@@ -404,6 +405,7 @@ struct bfa_lps_s {
404 u8 bb_scn; /* local BB_SCN */ 405 u8 bb_scn; /* local BB_SCN */
405 u8 lsrjt_rsn; /* LSRJT reason */ 406 u8 lsrjt_rsn; /* LSRJT reason */
406 u8 lsrjt_expl; /* LSRJT explanation */ 407 u8 lsrjt_expl; /* LSRJT explanation */
408 u8 lun_mask; /* LUN mask flag */
407 wwn_t pwwn; /* port wwn of lport */ 409 wwn_t pwwn; /* port wwn of lport */
408 wwn_t nwwn; /* node wwn of lport */ 410 wwn_t nwwn; /* node wwn of lport */
409 wwn_t pr_pwwn; /* port wwn of lport peer */ 411 wwn_t pr_pwwn; /* port wwn of lport peer */
@@ -574,6 +576,19 @@ void bfa_cb_rport_qos_scn_prio(void *rport,
574 struct bfa_rport_qos_attr_s new_qos_attr); 576 struct bfa_rport_qos_attr_s new_qos_attr);
575 577
576/* 578/*
579 * Rport LUN masking related
580 */
581#define BFA_RPORT_TAG_INVALID 0xffff
582#define BFA_LP_TAG_INVALID 0xff
583void bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
584void bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
585bfa_boolean_t bfa_rport_lunmask_active(struct bfa_rport_s *rp);
586wwn_t bfa_rport_get_pwwn(struct bfa_s *bfa, struct bfa_rport_s *rp);
587struct bfa_rport_s *bfa_rport_get_by_wwn(struct bfa_s *bfa, u16 vf_id,
588 wwn_t *lpwwn, wwn_t rpwwn);
589void *bfa_cb_get_rp_by_wwn(void *arg, u16 vf_id, wwn_t *lpwwn, wwn_t rpwwn);
590
591/*
577 * bfa fcxp API functions 592 * bfa fcxp API functions
578 */ 593 */
579struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa, 594struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa,