diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-30 18:06:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-30 18:06:25 -0400 |
| commit | 4b483802fddf74d8dae5970d7fcd55525c7cfa17 (patch) | |
| tree | f2b52fbbd99b3da437a411c78cea4e083645fe80 | |
| parent | 6c355beafdbd0a62add3a3d89825ca87cf8ecec0 (diff) | |
| parent | a9e94ec3504ead4b87a929bc57f5aa99a6590437 (diff) | |
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley:
"This is a set of seven bug fixes. Several fcoe fixes for locking
problems, initiator issues and a VLAN API change, all of which could
eventually lead to data corruption, one fix for a qla2xxx locking
problem which could lead to multiple completions of the same request
(and subsequent data corruption) and a use after free in the ipr
driver. Plus one minor MAINTAINERS file update"
(only six bugfixes in this pull, since I had already pulled the fcoe API
fix directly from Robert Love)
* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
[SCSI] ipr: Avoid target_destroy accessing memory after it was freed
[SCSI] qla2xxx: Fix for locking issue between driver ISR and mailbox routines
MAINTAINERS: Fix fcoe mailing list
libfc: extend ex_lock to protect all of fc_seq_send
libfc: Correct check for initiator role
libfcoe: Fix Conflicting FCFs issue in the fabric
| -rw-r--r-- | MAINTAINERS | 2 | ||||
| -rw-r--r-- | drivers/scsi/fcoe/fcoe_ctlr.c | 15 | ||||
| -rw-r--r-- | drivers/scsi/ipr.c | 16 | ||||
| -rw-r--r-- | drivers/scsi/ipr.h | 6 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 37 | ||||
| -rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_inline.h | 11 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 27 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mr.c | 10 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 26 |
11 files changed, 61 insertions, 93 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 5be702cc8449..ad7e322ad17b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3220,7 +3220,7 @@ F: lib/fault-inject.c | |||
| 3220 | 3220 | ||
| 3221 | FCOE SUBSYSTEM (libfc, libfcoe, fcoe) | 3221 | FCOE SUBSYSTEM (libfc, libfcoe, fcoe) |
| 3222 | M: Robert Love <robert.w.love@intel.com> | 3222 | M: Robert Love <robert.w.love@intel.com> |
| 3223 | L: devel@open-fcoe.org | 3223 | L: fcoe-devel@open-fcoe.org |
| 3224 | W: www.Open-FCoE.org | 3224 | W: www.Open-FCoE.org |
| 3225 | S: Supported | 3225 | S: Supported |
| 3226 | F: drivers/scsi/libfc/ | 3226 | F: drivers/scsi/libfc/ |
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index cd743c545ce9..795843dde8ec 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c | |||
| @@ -1548,9 +1548,6 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip) | |||
| 1548 | { | 1548 | { |
| 1549 | struct fcoe_fcf *fcf; | 1549 | struct fcoe_fcf *fcf; |
| 1550 | struct fcoe_fcf *best = fip->sel_fcf; | 1550 | struct fcoe_fcf *best = fip->sel_fcf; |
| 1551 | struct fcoe_fcf *first; | ||
| 1552 | |||
| 1553 | first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list); | ||
| 1554 | 1551 | ||
| 1555 | list_for_each_entry(fcf, &fip->fcfs, list) { | 1552 | list_for_each_entry(fcf, &fip->fcfs, list) { |
| 1556 | LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx " | 1553 | LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx " |
| @@ -1568,17 +1565,15 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip) | |||
| 1568 | "" : "un"); | 1565 | "" : "un"); |
| 1569 | continue; | 1566 | continue; |
| 1570 | } | 1567 | } |
| 1571 | if (fcf->fabric_name != first->fabric_name || | 1568 | if (!best || fcf->pri < best->pri || best->flogi_sent) |
| 1572 | fcf->vfid != first->vfid || | 1569 | best = fcf; |
| 1573 | fcf->fc_map != first->fc_map) { | 1570 | if (fcf->fabric_name != best->fabric_name || |
| 1571 | fcf->vfid != best->vfid || | ||
| 1572 | fcf->fc_map != best->fc_map) { | ||
| 1574 | LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, " | 1573 | LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, " |
| 1575 | "or FC-MAP\n"); | 1574 | "or FC-MAP\n"); |
| 1576 | return NULL; | 1575 | return NULL; |
| 1577 | } | 1576 | } |
| 1578 | if (fcf->flogi_sent) | ||
| 1579 | continue; | ||
| 1580 | if (!best || fcf->pri < best->pri || best->flogi_sent) | ||
| 1581 | best = fcf; | ||
| 1582 | } | 1577 | } |
| 1583 | fip->sel_fcf = best; | 1578 | fip->sel_fcf = best; |
| 1584 | if (best) { | 1579 | if (best) { |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 82a3c1ec8706..6c4cedb44c07 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
| @@ -8980,19 +8980,6 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
| 8980 | if (!ioa_cfg->res_entries) | 8980 | if (!ioa_cfg->res_entries) |
| 8981 | goto out; | 8981 | goto out; |
| 8982 | 8982 | ||
| 8983 | if (ioa_cfg->sis64) { | ||
| 8984 | ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) * | ||
| 8985 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
| 8986 | ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) * | ||
| 8987 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
| 8988 | ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) * | ||
| 8989 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
| 8990 | |||
| 8991 | if (!ioa_cfg->target_ids || !ioa_cfg->array_ids | ||
| 8992 | || !ioa_cfg->vset_ids) | ||
| 8993 | goto out_free_res_entries; | ||
| 8994 | } | ||
| 8995 | |||
| 8996 | for (i = 0; i < ioa_cfg->max_devs_supported; i++) { | 8983 | for (i = 0; i < ioa_cfg->max_devs_supported; i++) { |
| 8997 | list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); | 8984 | list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); |
| 8998 | ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg; | 8985 | ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg; |
| @@ -9089,9 +9076,6 @@ out_free_vpd_cbs: | |||
| 9089 | ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma); | 9076 | ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma); |
| 9090 | out_free_res_entries: | 9077 | out_free_res_entries: |
| 9091 | kfree(ioa_cfg->res_entries); | 9078 | kfree(ioa_cfg->res_entries); |
| 9092 | kfree(ioa_cfg->target_ids); | ||
| 9093 | kfree(ioa_cfg->array_ids); | ||
| 9094 | kfree(ioa_cfg->vset_ids); | ||
| 9095 | goto out; | 9079 | goto out; |
| 9096 | } | 9080 | } |
| 9097 | 9081 | ||
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index a1fb840596ef..07a85ce41782 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
| @@ -1440,9 +1440,9 @@ struct ipr_ioa_cfg { | |||
| 1440 | /* | 1440 | /* |
| 1441 | * Bitmaps for SIS64 generated target values | 1441 | * Bitmaps for SIS64 generated target values |
| 1442 | */ | 1442 | */ |
| 1443 | unsigned long *target_ids; | 1443 | unsigned long target_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)]; |
| 1444 | unsigned long *array_ids; | 1444 | unsigned long array_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)]; |
| 1445 | unsigned long *vset_ids; | 1445 | unsigned long vset_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)]; |
| 1446 | 1446 | ||
| 1447 | u16 type; /* CCIN of the card */ | 1447 | u16 type; /* CCIN of the card */ |
| 1448 | 1448 | ||
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index c772d8d27159..8b928c67e4b9 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
| @@ -463,13 +463,7 @@ static void fc_exch_delete(struct fc_exch *ep) | |||
| 463 | fc_exch_release(ep); /* drop hold for exch in mp */ | 463 | fc_exch_release(ep); /* drop hold for exch in mp */ |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | /** | 466 | static int fc_seq_send_locked(struct fc_lport *lport, struct fc_seq *sp, |
| 467 | * fc_seq_send() - Send a frame using existing sequence/exchange pair | ||
| 468 | * @lport: The local port that the exchange will be sent on | ||
| 469 | * @sp: The sequence to be sent | ||
| 470 | * @fp: The frame to be sent on the exchange | ||
| 471 | */ | ||
| 472 | static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | ||
| 473 | struct fc_frame *fp) | 467 | struct fc_frame *fp) |
| 474 | { | 468 | { |
| 475 | struct fc_exch *ep; | 469 | struct fc_exch *ep; |
| @@ -479,7 +473,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | |||
| 479 | u8 fh_type = fh->fh_type; | 473 | u8 fh_type = fh->fh_type; |
| 480 | 474 | ||
| 481 | ep = fc_seq_exch(sp); | 475 | ep = fc_seq_exch(sp); |
| 482 | WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT); | 476 | WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT)); |
| 483 | 477 | ||
| 484 | f_ctl = ntoh24(fh->fh_f_ctl); | 478 | f_ctl = ntoh24(fh->fh_f_ctl); |
| 485 | fc_exch_setup_hdr(ep, fp, f_ctl); | 479 | fc_exch_setup_hdr(ep, fp, f_ctl); |
| @@ -502,17 +496,34 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | |||
| 502 | error = lport->tt.frame_send(lport, fp); | 496 | error = lport->tt.frame_send(lport, fp); |
| 503 | 497 | ||
| 504 | if (fh_type == FC_TYPE_BLS) | 498 | if (fh_type == FC_TYPE_BLS) |
| 505 | return error; | 499 | goto out; |
| 506 | 500 | ||
| 507 | /* | 501 | /* |
| 508 | * Update the exchange and sequence flags, | 502 | * Update the exchange and sequence flags, |
| 509 | * assuming all frames for the sequence have been sent. | 503 | * assuming all frames for the sequence have been sent. |
| 510 | * We can only be called to send once for each sequence. | 504 | * We can only be called to send once for each sequence. |
| 511 | */ | 505 | */ |
| 512 | spin_lock_bh(&ep->ex_lock); | ||
| 513 | ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ | 506 | ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ |
| 514 | if (f_ctl & FC_FC_SEQ_INIT) | 507 | if (f_ctl & FC_FC_SEQ_INIT) |
| 515 | ep->esb_stat &= ~ESB_ST_SEQ_INIT; | 508 | ep->esb_stat &= ~ESB_ST_SEQ_INIT; |
| 509 | out: | ||
| 510 | return error; | ||
| 511 | } | ||
| 512 | |||
| 513 | /** | ||
| 514 | * fc_seq_send() - Send a frame using existing sequence/exchange pair | ||
| 515 | * @lport: The local port that the exchange will be sent on | ||
| 516 | * @sp: The sequence to be sent | ||
| 517 | * @fp: The frame to be sent on the exchange | ||
| 518 | */ | ||
| 519 | static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | ||
| 520 | struct fc_frame *fp) | ||
| 521 | { | ||
| 522 | struct fc_exch *ep; | ||
| 523 | int error; | ||
| 524 | ep = fc_seq_exch(sp); | ||
| 525 | spin_lock_bh(&ep->ex_lock); | ||
| 526 | error = fc_seq_send_locked(lport, sp, fp); | ||
| 516 | spin_unlock_bh(&ep->ex_lock); | 527 | spin_unlock_bh(&ep->ex_lock); |
| 517 | return error; | 528 | return error; |
| 518 | } | 529 | } |
| @@ -629,7 +640,7 @@ static int fc_exch_abort_locked(struct fc_exch *ep, | |||
| 629 | if (fp) { | 640 | if (fp) { |
| 630 | fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid, | 641 | fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid, |
| 631 | FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); | 642 | FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); |
| 632 | error = fc_seq_send(ep->lp, sp, fp); | 643 | error = fc_seq_send_locked(ep->lp, sp, fp); |
| 633 | } else | 644 | } else |
| 634 | error = -ENOBUFS; | 645 | error = -ENOBUFS; |
| 635 | return error; | 646 | return error; |
| @@ -1132,7 +1143,7 @@ static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp, | |||
| 1132 | f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; | 1143 | f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; |
| 1133 | f_ctl |= ep->f_ctl; | 1144 | f_ctl |= ep->f_ctl; |
| 1134 | fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0); | 1145 | fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0); |
| 1135 | fc_seq_send(ep->lp, sp, fp); | 1146 | fc_seq_send_locked(ep->lp, sp, fp); |
| 1136 | } | 1147 | } |
| 1137 | 1148 | ||
| 1138 | /** | 1149 | /** |
| @@ -1307,8 +1318,8 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) | |||
| 1307 | ap->ba_low_seq_cnt = htons(sp->cnt); | 1318 | ap->ba_low_seq_cnt = htons(sp->cnt); |
| 1308 | } | 1319 | } |
| 1309 | sp = fc_seq_start_next_locked(sp); | 1320 | sp = fc_seq_start_next_locked(sp); |
| 1310 | spin_unlock_bh(&ep->ex_lock); | ||
| 1311 | fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS); | 1321 | fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS); |
| 1322 | spin_unlock_bh(&ep->ex_lock); | ||
| 1312 | fc_frame_free(rx_fp); | 1323 | fc_frame_free(rx_fp); |
| 1313 | return; | 1324 | return; |
| 1314 | 1325 | ||
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index d518d17e940f..6bbb9447b75d 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
| @@ -1962,7 +1962,7 @@ static int fc_rport_fcp_prli(struct fc_rport_priv *rdata, u32 spp_len, | |||
| 1962 | rdata->flags |= FC_RP_FLAGS_RETRY; | 1962 | rdata->flags |= FC_RP_FLAGS_RETRY; |
| 1963 | rdata->supported_classes = FC_COS_CLASS3; | 1963 | rdata->supported_classes = FC_COS_CLASS3; |
| 1964 | 1964 | ||
| 1965 | if (!(lport->service_params & FC_RPORT_ROLE_FCP_INITIATOR)) | 1965 | if (!(lport->service_params & FCP_SPPF_INIT_FCN)) |
| 1966 | return 0; | 1966 | return 0; |
| 1967 | 1967 | ||
| 1968 | spp->spp_flags |= rspp->spp_flags & FC_SPP_EST_IMG_PAIR; | 1968 | spp->spp_flags |= rspp->spp_flags & FC_SPP_EST_IMG_PAIR; |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 98ab921070d2..0a5c8951cebb 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
| @@ -278,3 +278,14 @@ qla2x00_do_host_ramp_up(scsi_qla_host_t *vha) | |||
| 278 | 278 | ||
| 279 | set_bit(HOST_RAMP_UP_QUEUE_DEPTH, &vha->dpc_flags); | 279 | set_bit(HOST_RAMP_UP_QUEUE_DEPTH, &vha->dpc_flags); |
| 280 | } | 280 | } |
| 281 | |||
| 282 | static inline void | ||
| 283 | qla2x00_handle_mbx_completion(struct qla_hw_data *ha, int status) | ||
| 284 | { | ||
| 285 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | ||
| 286 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | ||
| 287 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 288 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | ||
| 289 | complete(&ha->mbx_intr_comp); | ||
| 290 | } | ||
| 291 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 259d9205d876..d2a4c75e5b8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
| @@ -104,14 +104,9 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
| 104 | RD_REG_WORD(®->hccr); | 104 | RD_REG_WORD(®->hccr); |
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | qla2x00_handle_mbx_completion(ha, status); | ||
| 107 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 108 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 108 | 109 | ||
| 109 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | ||
| 110 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | ||
| 111 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 112 | complete(&ha->mbx_intr_comp); | ||
| 113 | } | ||
| 114 | |||
| 115 | return (IRQ_HANDLED); | 110 | return (IRQ_HANDLED); |
| 116 | } | 111 | } |
| 117 | 112 | ||
| @@ -221,14 +216,9 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
| 221 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 216 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
| 222 | RD_REG_WORD_RELAXED(®->hccr); | 217 | RD_REG_WORD_RELAXED(®->hccr); |
| 223 | } | 218 | } |
| 219 | qla2x00_handle_mbx_completion(ha, status); | ||
| 224 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 220 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 225 | 221 | ||
| 226 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | ||
| 227 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | ||
| 228 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 229 | complete(&ha->mbx_intr_comp); | ||
| 230 | } | ||
| 231 | |||
| 232 | return (IRQ_HANDLED); | 222 | return (IRQ_HANDLED); |
| 233 | } | 223 | } |
| 234 | 224 | ||
| @@ -2613,14 +2603,9 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
| 2613 | if (unlikely(IS_QLA83XX(ha) && (ha->pdev->revision == 1))) | 2603 | if (unlikely(IS_QLA83XX(ha) && (ha->pdev->revision == 1))) |
| 2614 | ndelay(3500); | 2604 | ndelay(3500); |
| 2615 | } | 2605 | } |
| 2606 | qla2x00_handle_mbx_completion(ha, status); | ||
| 2616 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2607 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 2617 | 2608 | ||
| 2618 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | ||
| 2619 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | ||
| 2620 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 2621 | complete(&ha->mbx_intr_comp); | ||
| 2622 | } | ||
| 2623 | |||
| 2624 | return IRQ_HANDLED; | 2609 | return IRQ_HANDLED; |
| 2625 | } | 2610 | } |
| 2626 | 2611 | ||
| @@ -2763,13 +2748,9 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
| 2763 | } | 2748 | } |
| 2764 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 2749 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
| 2765 | } while (0); | 2750 | } while (0); |
| 2751 | qla2x00_handle_mbx_completion(ha, status); | ||
| 2766 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2752 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 2767 | 2753 | ||
| 2768 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | ||
| 2769 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | ||
| 2770 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 2771 | complete(&ha->mbx_intr_comp); | ||
| 2772 | } | ||
| 2773 | return IRQ_HANDLED; | 2754 | return IRQ_HANDLED; |
| 2774 | } | 2755 | } |
| 2775 | 2756 | ||
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 9e5d89db7272..3587ec267fa6 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
| @@ -179,8 +179,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
| 179 | 179 | ||
| 180 | wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ); | 180 | wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ); |
| 181 | 181 | ||
| 182 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | ||
| 183 | |||
| 184 | } else { | 182 | } else { |
| 185 | ql_dbg(ql_dbg_mbx, vha, 0x1011, | 183 | ql_dbg(ql_dbg_mbx, vha, 0x1011, |
| 186 | "Cmd=%x Polling Mode.\n", command); | 184 | "Cmd=%x Polling Mode.\n", command); |
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 937fed8cb038..a6df55838365 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c | |||
| @@ -148,9 +148,6 @@ qlafx00_mailbox_command(scsi_qla_host_t *vha, struct mbx_cmd_32 *mcp) | |||
| 148 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 148 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 149 | 149 | ||
| 150 | wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ); | 150 | wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ); |
| 151 | |||
| 152 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | ||
| 153 | |||
| 154 | } else { | 151 | } else { |
| 155 | ql_dbg(ql_dbg_mbx, vha, 0x112c, | 152 | ql_dbg(ql_dbg_mbx, vha, 0x112c, |
| 156 | "Cmd=%x Polling Mode.\n", command); | 153 | "Cmd=%x Polling Mode.\n", command); |
| @@ -2934,13 +2931,10 @@ qlafx00_intr_handler(int irq, void *dev_id) | |||
| 2934 | QLAFX00_CLR_INTR_REG(ha, clr_intr); | 2931 | QLAFX00_CLR_INTR_REG(ha, clr_intr); |
| 2935 | QLAFX00_RD_INTR_REG(ha); | 2932 | QLAFX00_RD_INTR_REG(ha); |
| 2936 | } | 2933 | } |
| 2934 | |||
| 2935 | qla2x00_handle_mbx_completion(ha, status); | ||
| 2937 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2936 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 2938 | 2937 | ||
| 2939 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | ||
| 2940 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | ||
| 2941 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
| 2942 | complete(&ha->mbx_intr_comp); | ||
| 2943 | } | ||
| 2944 | return IRQ_HANDLED; | 2938 | return IRQ_HANDLED; |
| 2945 | } | 2939 | } |
| 2946 | 2940 | ||
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 10754f518303..cce0cd0d7ec4 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
| @@ -2074,9 +2074,6 @@ qla82xx_intr_handler(int irq, void *dev_id) | |||
| 2074 | } | 2074 | } |
| 2075 | WRT_REG_DWORD(®->host_int, 0); | 2075 | WRT_REG_DWORD(®->host_int, 0); |
| 2076 | } | 2076 | } |
| 2077 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
| 2078 | if (!ha->flags.msi_enabled) | ||
| 2079 | qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff); | ||
| 2080 | 2077 | ||
| 2081 | #ifdef QL_DEBUG_LEVEL_17 | 2078 | #ifdef QL_DEBUG_LEVEL_17 |
| 2082 | if (!irq && ha->flags.eeh_busy) | 2079 | if (!irq && ha->flags.eeh_busy) |
| @@ -2085,11 +2082,12 @@ qla82xx_intr_handler(int irq, void *dev_id) | |||
| 2085 | status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat); | 2082 | status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat); |
| 2086 | #endif | 2083 | #endif |
| 2087 | 2084 | ||
| 2088 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 2085 | qla2x00_handle_mbx_completion(ha, status); |
| 2089 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 2086 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 2090 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 2087 | |
| 2091 | complete(&ha->mbx_intr_comp); | 2088 | if (!ha->flags.msi_enabled) |
| 2092 | } | 2089 | qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff); |
| 2090 | |||
| 2093 | return IRQ_HANDLED; | 2091 | return IRQ_HANDLED; |
| 2094 | } | 2092 | } |
| 2095 | 2093 | ||
| @@ -2149,8 +2147,6 @@ qla82xx_msix_default(int irq, void *dev_id) | |||
| 2149 | WRT_REG_DWORD(®->host_int, 0); | 2147 | WRT_REG_DWORD(®->host_int, 0); |
| 2150 | } while (0); | 2148 | } while (0); |
| 2151 | 2149 | ||
| 2152 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
| 2153 | |||
| 2154 | #ifdef QL_DEBUG_LEVEL_17 | 2150 | #ifdef QL_DEBUG_LEVEL_17 |
| 2155 | if (!irq && ha->flags.eeh_busy) | 2151 | if (!irq && ha->flags.eeh_busy) |
| 2156 | ql_log(ql_log_warn, vha, 0x5044, | 2152 | ql_log(ql_log_warn, vha, 0x5044, |
| @@ -2158,11 +2154,9 @@ qla82xx_msix_default(int irq, void *dev_id) | |||
| 2158 | status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat); | 2154 | status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat); |
| 2159 | #endif | 2155 | #endif |
| 2160 | 2156 | ||
| 2161 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 2157 | qla2x00_handle_mbx_completion(ha, status); |
| 2162 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 2158 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 2163 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 2159 | |
| 2164 | complete(&ha->mbx_intr_comp); | ||
| 2165 | } | ||
| 2166 | return IRQ_HANDLED; | 2160 | return IRQ_HANDLED; |
| 2167 | } | 2161 | } |
| 2168 | 2162 | ||
| @@ -3345,7 +3339,7 @@ void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha) | |||
| 3345 | ha->flags.mbox_busy = 0; | 3339 | ha->flags.mbox_busy = 0; |
| 3346 | ql_log(ql_log_warn, vha, 0x6010, | 3340 | ql_log(ql_log_warn, vha, 0x6010, |
| 3347 | "Doing premature completion of mbx command.\n"); | 3341 | "Doing premature completion of mbx command.\n"); |
| 3348 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) | 3342 | if (test_and_clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) |
| 3349 | complete(&ha->mbx_intr_comp); | 3343 | complete(&ha->mbx_intr_comp); |
| 3350 | } | 3344 | } |
| 3351 | } | 3345 | } |
