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) | ||
