diff options
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcpim.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_fcpim.c | 736 |
1 files changed, 734 insertions, 2 deletions
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index a4e7951c6063..e07bd4745d8b 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 | */ |
26 | static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim); | 26 | static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim); |
27 | static bfa_boolean_t bfa_ioim_lm_proc_rpl_data(struct bfa_ioim_s *ioim); | ||
28 | static bfa_boolean_t bfa_ioim_lm_proc_inq_data(struct bfa_ioim_s *ioim); | ||
29 | static 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 | ||
80 | enum 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 | |||
87 | enum 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); | |||
219 | static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); | 245 | static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); |
220 | static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); | 246 | static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); |
221 | static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim); | 247 | static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim); |
248 | static void __bfa_cb_ioim_lm_lun_not_sup(void *cbarg, bfa_boolean_t complete); | ||
249 | static void __bfa_cb_ioim_lm_rpl_dc(void *cbarg, bfa_boolean_t complete); | ||
250 | static 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 | ||
421 | bfa_status_t | 456 | bfa_status_t |
@@ -437,6 +472,59 @@ bfa_fcpim_port_iostats(struct bfa_s *bfa, | |||
437 | return BFA_STATUS_OK; | 472 | return BFA_STATUS_OK; |
438 | } | 473 | } |
439 | 474 | ||
475 | void | ||
476 | bfa_ioim_profile_comp(struct bfa_ioim_s *ioim) | ||
477 | { | ||
478 | struct bfa_itnim_latency_s *io_lat = | ||
479 | &(ioim->itnim->ioprofile.io_latency); | ||
480 | u32 val, idx; | ||
481 | |||
482 | val = (u32)(jiffies - ioim->start_time); | ||
483 | idx = bfa_ioim_get_index(scsi_bufflen((struct scsi_cmnd *)ioim->dio)); | ||
484 | bfa_itnim_ioprofile_update(ioim->itnim, idx); | ||
485 | |||
486 | io_lat->count[idx]++; | ||
487 | io_lat->min[idx] = (io_lat->min[idx] < val) ? io_lat->min[idx] : val; | ||
488 | io_lat->max[idx] = (io_lat->max[idx] > val) ? io_lat->max[idx] : val; | ||
489 | io_lat->avg[idx] += val; | ||
490 | } | ||
491 | |||
492 | void | ||
493 | bfa_ioim_profile_start(struct bfa_ioim_s *ioim) | ||
494 | { | ||
495 | ioim->start_time = jiffies; | ||
496 | } | ||
497 | |||
498 | bfa_status_t | ||
499 | bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time) | ||
500 | { | ||
501 | struct bfa_itnim_s *itnim; | ||
502 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); | ||
503 | struct list_head *qe, *qen; | ||
504 | |||
505 | /* accumulate IO stats from itnim */ | ||
506 | list_for_each_safe(qe, qen, &fcpim->itnim_q) { | ||
507 | itnim = (struct bfa_itnim_s *) qe; | ||
508 | bfa_itnim_clear_stats(itnim); | ||
509 | } | ||
510 | fcpim->io_profile = BFA_TRUE; | ||
511 | fcpim->io_profile_start_time = time; | ||
512 | fcpim->profile_comp = bfa_ioim_profile_comp; | ||
513 | fcpim->profile_start = bfa_ioim_profile_start; | ||
514 | return BFA_STATUS_OK; | ||
515 | } | ||
516 | |||
517 | bfa_status_t | ||
518 | bfa_fcpim_profile_off(struct bfa_s *bfa) | ||
519 | { | ||
520 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); | ||
521 | fcpim->io_profile = BFA_FALSE; | ||
522 | fcpim->io_profile_start_time = 0; | ||
523 | fcpim->profile_comp = NULL; | ||
524 | fcpim->profile_start = NULL; | ||
525 | return BFA_STATUS_OK; | ||
526 | } | ||
527 | |||
440 | u16 | 528 | u16 |
441 | bfa_fcpim_qdepth_get(struct bfa_s *bfa) | 529 | bfa_fcpim_qdepth_get(struct bfa_s *bfa) |
442 | { | 530 | { |
@@ -1401,6 +1489,26 @@ bfa_itnim_hold_io(struct bfa_itnim_s *itnim) | |||
1401 | bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable)); | 1489 | bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable)); |
1402 | } | 1490 | } |
1403 | 1491 | ||
1492 | #define bfa_io_lat_clock_res_div HZ | ||
1493 | #define bfa_io_lat_clock_res_mul 1000 | ||
1494 | bfa_status_t | ||
1495 | bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim, | ||
1496 | struct bfa_itnim_ioprofile_s *ioprofile) | ||
1497 | { | ||
1498 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa); | ||
1499 | if (!fcpim->io_profile) | ||
1500 | return BFA_STATUS_IOPROFILE_OFF; | ||
1501 | |||
1502 | itnim->ioprofile.index = BFA_IOBUCKET_MAX; | ||
1503 | itnim->ioprofile.io_profile_start_time = | ||
1504 | bfa_io_profile_start_time(itnim->bfa); | ||
1505 | itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul; | ||
1506 | itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div; | ||
1507 | *ioprofile = itnim->ioprofile; | ||
1508 | |||
1509 | return BFA_STATUS_OK; | ||
1510 | } | ||
1511 | |||
1404 | void | 1512 | void |
1405 | bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) | 1513 | bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) |
1406 | { | 1514 | { |
@@ -1469,7 +1577,28 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
1469 | bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); | 1577 | bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); |
1470 | 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)); |
1471 | bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, | 1579 | bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, |
1472 | __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); | ||
1473 | break; | 1602 | break; |
1474 | 1603 | ||
1475 | default: | 1604 | default: |
@@ -2009,6 +2138,264 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
2009 | } | 2138 | } |
2010 | } | 2139 | } |
2011 | 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 | */ | ||
2146 | static void | ||
2147 | bfa_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 | */ | ||
2166 | static enum bfa_ioim_lm_status | ||
2167 | bfa_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 | |||
2222 | static bfa_boolean_t | ||
2223 | bfa_ioim_lm_proc_rsp_data_dummy(struct bfa_ioim_s *ioim) | ||
2224 | { | ||
2225 | return BFA_TRUE; | ||
2226 | } | ||
2227 | |||
2228 | static void | ||
2229 | bfa_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 | |||
2254 | static int | ||
2255 | bfa_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 | |||
2338 | static bfa_boolean_t | ||
2339 | bfa_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 | |||
2352 | static bfa_boolean_t | ||
2353 | bfa_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 | } | ||
2012 | 2399 | ||
2013 | static void | 2400 | static void |
2014 | __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete) | 2401 | __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete) |
@@ -2068,6 +2455,299 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete) | |||
2068 | } | 2455 | } |
2069 | 2456 | ||
2070 | static void | 2457 | static 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 | |||
2482 | static 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 | |||
2508 | static 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 | |||
2534 | void | ||
2535 | bfa_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 | |||
2556 | /* | ||
2557 | * set UA for all active luns in LM DB | ||
2558 | */ | ||
2559 | static void | ||
2560 | bfa_ioim_lm_set_ua(struct bfa_s *bfa) | ||
2561 | { | ||
2562 | struct bfa_lun_mask_s *lunm_list; | ||
2563 | int i; | ||
2564 | |||
2565 | lunm_list = bfa_get_lun_mask_list(bfa); | ||
2566 | for (i = 0; i < MAX_LUN_MASK_CFG; i++) { | ||
2567 | if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE) | ||
2568 | continue; | ||
2569 | lunm_list[i].ua = BFA_IOIM_LM_UA_SET; | ||
2570 | } | ||
2571 | } | ||
2572 | |||
2573 | bfa_status_t | ||
2574 | bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 update) | ||
2575 | { | ||
2576 | struct bfa_lunmask_cfg_s *lun_mask; | ||
2577 | |||
2578 | bfa_trc(bfa, bfa_get_lun_mask_status(bfa)); | ||
2579 | if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG) | ||
2580 | return BFA_STATUS_FAILED; | ||
2581 | |||
2582 | if (bfa_get_lun_mask_status(bfa) == update) | ||
2583 | return BFA_STATUS_NO_CHANGE; | ||
2584 | |||
2585 | lun_mask = bfa_get_lun_mask(bfa); | ||
2586 | lun_mask->status = update; | ||
2587 | |||
2588 | if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED) | ||
2589 | bfa_ioim_lm_set_ua(bfa); | ||
2590 | |||
2591 | return bfa_dconf_update(bfa); | ||
2592 | } | ||
2593 | |||
2594 | bfa_status_t | ||
2595 | bfa_fcpim_lunmask_clear(struct bfa_s *bfa) | ||
2596 | { | ||
2597 | int i; | ||
2598 | struct bfa_lun_mask_s *lunm_list; | ||
2599 | |||
2600 | bfa_trc(bfa, bfa_get_lun_mask_status(bfa)); | ||
2601 | if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG) | ||
2602 | return BFA_STATUS_FAILED; | ||
2603 | |||
2604 | lunm_list = bfa_get_lun_mask_list(bfa); | ||
2605 | for (i = 0; i < MAX_LUN_MASK_CFG; i++) { | ||
2606 | if (lunm_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) { | ||
2607 | if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID) | ||
2608 | bfa_rport_unset_lunmask(bfa, | ||
2609 | BFA_RPORT_FROM_TAG(bfa, lunm_list[i].rp_tag)); | ||
2610 | } | ||
2611 | } | ||
2612 | |||
2613 | memset(lunm_list, 0, sizeof(struct bfa_lun_mask_s) * MAX_LUN_MASK_CFG); | ||
2614 | return bfa_dconf_update(bfa); | ||
2615 | } | ||
2616 | |||
2617 | bfa_status_t | ||
2618 | bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf) | ||
2619 | { | ||
2620 | struct bfa_lunmask_cfg_s *lun_mask; | ||
2621 | |||
2622 | bfa_trc(bfa, bfa_get_lun_mask_status(bfa)); | ||
2623 | if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG) | ||
2624 | return BFA_STATUS_FAILED; | ||
2625 | |||
2626 | lun_mask = bfa_get_lun_mask(bfa); | ||
2627 | memcpy(buf, lun_mask, sizeof(struct bfa_lunmask_cfg_s)); | ||
2628 | return BFA_STATUS_OK; | ||
2629 | } | ||
2630 | |||
2631 | bfa_status_t | ||
2632 | bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn, | ||
2633 | wwn_t rpwwn, struct scsi_lun lun) | ||
2634 | { | ||
2635 | struct bfa_lun_mask_s *lunm_list; | ||
2636 | struct bfa_rport_s *rp = NULL; | ||
2637 | int i, free_index = MAX_LUN_MASK_CFG + 1; | ||
2638 | struct bfa_fcs_lport_s *port = NULL; | ||
2639 | struct bfa_fcs_rport_s *rp_fcs; | ||
2640 | |||
2641 | bfa_trc(bfa, bfa_get_lun_mask_status(bfa)); | ||
2642 | if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG) | ||
2643 | return BFA_STATUS_FAILED; | ||
2644 | |||
2645 | port = bfa_fcs_lookup_port(&((struct bfad_s *)bfa->bfad)->bfa_fcs, | ||
2646 | vf_id, *pwwn); | ||
2647 | if (port) { | ||
2648 | *pwwn = port->port_cfg.pwwn; | ||
2649 | rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn); | ||
2650 | rp = rp_fcs->bfa_rport; | ||
2651 | } | ||
2652 | |||
2653 | lunm_list = bfa_get_lun_mask_list(bfa); | ||
2654 | /* if entry exists */ | ||
2655 | for (i = 0; i < MAX_LUN_MASK_CFG; i++) { | ||
2656 | if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE) | ||
2657 | free_index = i; | ||
2658 | if ((lunm_list[i].lp_wwn == *pwwn) && | ||
2659 | (lunm_list[i].rp_wwn == rpwwn) && | ||
2660 | (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) == | ||
2661 | scsilun_to_int((struct scsi_lun *)&lun))) | ||
2662 | return BFA_STATUS_ENTRY_EXISTS; | ||
2663 | } | ||
2664 | |||
2665 | if (free_index > MAX_LUN_MASK_CFG) | ||
2666 | return BFA_STATUS_MAX_ENTRY_REACHED; | ||
2667 | |||
2668 | if (rp) { | ||
2669 | lunm_list[free_index].lp_tag = bfa_lps_get_tag_from_pid(bfa, | ||
2670 | rp->rport_info.local_pid); | ||
2671 | lunm_list[free_index].rp_tag = rp->rport_tag; | ||
2672 | } else { | ||
2673 | lunm_list[free_index].lp_tag = BFA_LP_TAG_INVALID; | ||
2674 | lunm_list[free_index].rp_tag = BFA_RPORT_TAG_INVALID; | ||
2675 | } | ||
2676 | |||
2677 | lunm_list[free_index].lp_wwn = *pwwn; | ||
2678 | lunm_list[free_index].rp_wwn = rpwwn; | ||
2679 | lunm_list[free_index].lun = lun; | ||
2680 | lunm_list[free_index].state = BFA_IOIM_LUN_MASK_ACTIVE; | ||
2681 | |||
2682 | /* set for all luns in this rp */ | ||
2683 | for (i = 0; i < MAX_LUN_MASK_CFG; i++) { | ||
2684 | if ((lunm_list[i].lp_wwn == *pwwn) && | ||
2685 | (lunm_list[i].rp_wwn == rpwwn)) | ||
2686 | lunm_list[i].ua = BFA_IOIM_LM_UA_SET; | ||
2687 | } | ||
2688 | |||
2689 | return bfa_dconf_update(bfa); | ||
2690 | } | ||
2691 | |||
2692 | bfa_status_t | ||
2693 | bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn, | ||
2694 | wwn_t rpwwn, struct scsi_lun lun) | ||
2695 | { | ||
2696 | struct bfa_lun_mask_s *lunm_list; | ||
2697 | struct bfa_rport_s *rp = NULL; | ||
2698 | struct bfa_fcs_lport_s *port = NULL; | ||
2699 | struct bfa_fcs_rport_s *rp_fcs; | ||
2700 | int i; | ||
2701 | |||
2702 | /* in min cfg lunm_list could be NULL but no commands should run. */ | ||
2703 | if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG) | ||
2704 | return BFA_STATUS_FAILED; | ||
2705 | |||
2706 | bfa_trc(bfa, bfa_get_lun_mask_status(bfa)); | ||
2707 | bfa_trc(bfa, *pwwn); | ||
2708 | bfa_trc(bfa, rpwwn); | ||
2709 | bfa_trc(bfa, scsilun_to_int((struct scsi_lun *)&lun)); | ||
2710 | |||
2711 | if (*pwwn == 0) { | ||
2712 | port = bfa_fcs_lookup_port( | ||
2713 | &((struct bfad_s *)bfa->bfad)->bfa_fcs, | ||
2714 | vf_id, *pwwn); | ||
2715 | if (port) { | ||
2716 | *pwwn = port->port_cfg.pwwn; | ||
2717 | rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn); | ||
2718 | rp = rp_fcs->bfa_rport; | ||
2719 | } | ||
2720 | } | ||
2721 | |||
2722 | lunm_list = bfa_get_lun_mask_list(bfa); | ||
2723 | for (i = 0; i < MAX_LUN_MASK_CFG; i++) { | ||
2724 | if ((lunm_list[i].lp_wwn == *pwwn) && | ||
2725 | (lunm_list[i].rp_wwn == rpwwn) && | ||
2726 | (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) == | ||
2727 | scsilun_to_int((struct scsi_lun *)&lun))) { | ||
2728 | lunm_list[i].lp_wwn = 0; | ||
2729 | lunm_list[i].rp_wwn = 0; | ||
2730 | int_to_scsilun(0, &lunm_list[i].lun); | ||
2731 | lunm_list[i].state = BFA_IOIM_LUN_MASK_INACTIVE; | ||
2732 | if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID) { | ||
2733 | lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID; | ||
2734 | lunm_list[i].lp_tag = BFA_LP_TAG_INVALID; | ||
2735 | } | ||
2736 | return bfa_dconf_update(bfa); | ||
2737 | } | ||
2738 | } | ||
2739 | |||
2740 | /* set for all luns in this rp */ | ||
2741 | for (i = 0; i < MAX_LUN_MASK_CFG; i++) { | ||
2742 | if ((lunm_list[i].lp_wwn == *pwwn) && | ||
2743 | (lunm_list[i].rp_wwn == rpwwn)) | ||
2744 | lunm_list[i].ua = BFA_IOIM_LM_UA_SET; | ||
2745 | } | ||
2746 | |||
2747 | return BFA_STATUS_ENTRY_NOT_EXISTS; | ||
2748 | } | ||
2749 | |||
2750 | static void | ||
2071 | __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete) | 2751 | __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete) |
2072 | { | 2752 | { |
2073 | struct bfa_ioim_s *ioim = cbarg; | 2753 | struct bfa_ioim_s *ioim = cbarg; |
@@ -2077,6 +2757,7 @@ __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete) | |||
2077 | return; | 2757 | return; |
2078 | } | 2758 | } |
2079 | 2759 | ||
2760 | ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy; | ||
2080 | bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED, | 2761 | bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED, |
2081 | 0, 0, NULL, 0); | 2762 | 0, 0, NULL, 0); |
2082 | } | 2763 | } |
@@ -2092,6 +2773,7 @@ __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete) | |||
2092 | return; | 2773 | return; |
2093 | } | 2774 | } |
2094 | 2775 | ||
2776 | ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy; | ||
2095 | bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV, | 2777 | bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV, |
2096 | 0, 0, NULL, 0); | 2778 | 0, 0, NULL, 0); |
2097 | } | 2779 | } |
@@ -2106,6 +2788,7 @@ __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete) | |||
2106 | return; | 2788 | return; |
2107 | } | 2789 | } |
2108 | 2790 | ||
2791 | ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy; | ||
2109 | bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio); | 2792 | bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio); |
2110 | } | 2793 | } |
2111 | 2794 | ||
@@ -2449,6 +3132,7 @@ bfa_ioim_attach(struct bfa_fcpim_s *fcpim) | |||
2449 | ioim->bfa = fcpim->bfa; | 3132 | ioim->bfa = fcpim->bfa; |
2450 | ioim->fcpim = fcpim; | 3133 | ioim->fcpim = fcpim; |
2451 | ioim->iosp = iosp; | 3134 | ioim->iosp = iosp; |
3135 | ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy; | ||
2452 | INIT_LIST_HEAD(&ioim->sgpg_q); | 3136 | INIT_LIST_HEAD(&ioim->sgpg_q); |
2453 | bfa_reqq_winit(&ioim->iosp->reqq_wait, | 3137 | bfa_reqq_winit(&ioim->iosp->reqq_wait, |
2454 | bfa_ioim_qresume, ioim); | 3138 | bfa_ioim_qresume, ioim); |
@@ -2486,6 +3170,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
2486 | evt = BFA_IOIM_SM_DONE; | 3170 | evt = BFA_IOIM_SM_DONE; |
2487 | else | 3171 | else |
2488 | evt = BFA_IOIM_SM_COMP; | 3172 | evt = BFA_IOIM_SM_COMP; |
3173 | ioim->proc_rsp_data(ioim); | ||
2489 | break; | 3174 | break; |
2490 | 3175 | ||
2491 | case BFI_IOIM_STS_TIMEDOUT: | 3176 | case BFI_IOIM_STS_TIMEDOUT: |
@@ -2521,6 +3206,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
2521 | if (rsp->abort_tag != ioim->abort_tag) { | 3206 | if (rsp->abort_tag != ioim->abort_tag) { |
2522 | bfa_trc(ioim->bfa, rsp->abort_tag); | 3207 | bfa_trc(ioim->bfa, rsp->abort_tag); |
2523 | bfa_trc(ioim->bfa, ioim->abort_tag); | 3208 | bfa_trc(ioim->bfa, ioim->abort_tag); |
3209 | ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy; | ||
2524 | return; | 3210 | return; |
2525 | } | 3211 | } |
2526 | 3212 | ||
@@ -2539,6 +3225,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
2539 | WARN_ON(1); | 3225 | WARN_ON(1); |
2540 | } | 3226 | } |
2541 | 3227 | ||
3228 | ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy; | ||
2542 | bfa_sm_send_event(ioim, evt); | 3229 | bfa_sm_send_event(ioim, evt); |
2543 | } | 3230 | } |
2544 | 3231 | ||
@@ -2556,7 +3243,16 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
2556 | WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag); | 3243 | WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag); |
2557 | 3244 | ||
2558 | bfa_ioim_cb_profile_comp(fcpim, ioim); | 3245 | bfa_ioim_cb_profile_comp(fcpim, ioim); |
2559 | bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); | 3246 | |
3247 | if (bfa_get_lun_mask_status(bfa) != BFA_LUNMASK_ENABLED) { | ||
3248 | bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); | ||
3249 | return; | ||
3250 | } | ||
3251 | |||
3252 | if (ioim->proc_rsp_data(ioim) == BFA_TRUE) | ||
3253 | bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); | ||
3254 | else | ||
3255 | bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP); | ||
2560 | } | 3256 | } |
2561 | 3257 | ||
2562 | /* | 3258 | /* |
@@ -2668,6 +3364,35 @@ bfa_ioim_free(struct bfa_ioim_s *ioim) | |||
2668 | void | 3364 | void |
2669 | bfa_ioim_start(struct bfa_ioim_s *ioim) | 3365 | bfa_ioim_start(struct bfa_ioim_s *ioim) |
2670 | { | 3366 | { |
3367 | struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio; | ||
3368 | struct bfa_lps_s *lps; | ||
3369 | enum bfa_ioim_lm_status status; | ||
3370 | struct scsi_lun scsilun; | ||
3371 | |||
3372 | if (bfa_get_lun_mask_status(ioim->bfa) == BFA_LUNMASK_ENABLED) { | ||
3373 | lps = BFA_IOIM_TO_LPS(ioim); | ||
3374 | int_to_scsilun(cmnd->device->lun, &scsilun); | ||
3375 | status = bfa_ioim_lm_check(ioim, lps, | ||
3376 | ioim->itnim->rport, scsilun); | ||
3377 | if (status == BFA_IOIM_LM_LUN_NOT_RDY) { | ||
3378 | bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_LUN_NOT_RDY); | ||
3379 | bfa_stats(ioim->itnim, lm_lun_not_rdy); | ||
3380 | return; | ||
3381 | } | ||
3382 | |||
3383 | if (status == BFA_IOIM_LM_LUN_NOT_SUP) { | ||
3384 | bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_LUN_NOT_SUP); | ||
3385 | bfa_stats(ioim->itnim, lm_lun_not_sup); | ||
3386 | return; | ||
3387 | } | ||
3388 | |||
3389 | if (status == BFA_IOIM_LM_RPL_DATA_CHANGED) { | ||
3390 | bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_RPL_DC); | ||
3391 | bfa_stats(ioim->itnim, lm_rpl_data_changed); | ||
3392 | return; | ||
3393 | } | ||
3394 | } | ||
3395 | |||
2671 | bfa_ioim_cb_profile_start(ioim->fcpim, ioim); | 3396 | bfa_ioim_cb_profile_start(ioim->fcpim, ioim); |
2672 | 3397 | ||
2673 | /* | 3398 | /* |
@@ -3411,6 +4136,13 @@ bfa_fcp_detach(struct bfa_s *bfa) | |||
3411 | static void | 4136 | static void |
3412 | bfa_fcp_start(struct bfa_s *bfa) | 4137 | bfa_fcp_start(struct bfa_s *bfa) |
3413 | { | 4138 | { |
4139 | struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); | ||
4140 | |||
4141 | /* | ||
4142 | * bfa_init() with flash read is complete. now invalidate the stale | ||
4143 | * content of lun mask like unit attention, rp tag and lp tag. | ||
4144 | */ | ||
4145 | bfa_ioim_lm_init(fcp->bfa); | ||
3414 | } | 4146 | } |
3415 | 4147 | ||
3416 | static void | 4148 | static void |