diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2010-02-04 17:17:59 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-08 14:45:55 -0500 |
commit | a67093d46e3caed1a42d694a7de452b61db30562 (patch) | |
tree | 092ef591331f99807fee2fb67bdc7efc2dfb2cc7 /drivers/scsi/qla2xxx | |
parent | 84eb8fb42c120ff32b201c1cdd910033c888f699 (diff) |
[SCSI] qla2xxx: Obtain proper host structure during response-queue processing.
Original code incorrectly assumed only status-type-0
IOCBs would be queued to the response-queue, and thus all
entries would safely reference a VHA from the IOCB
'handle.'
Cc: stable@kernel.org
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 29 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 8 |
3 files changed, 6 insertions, 32 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f61fb8d01330..8bc6f53691e9 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -453,6 +453,5 @@ extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | |||
453 | extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | 453 | extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); |
454 | extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | 454 | extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); |
455 | extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | 455 | extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); |
456 | extern struct scsi_qla_host * qla25xx_get_host(struct rsp_que *); | ||
457 | 456 | ||
458 | #endif /* _QLA_GBL_H */ | 457 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 0ced91c5ebd3..6fc63b98818c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1930,7 +1930,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1930 | 1930 | ||
1931 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1931 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1932 | 1932 | ||
1933 | vha = qla25xx_get_host(rsp); | 1933 | vha = pci_get_drvdata(ha->pdev); |
1934 | qla24xx_process_response_queue(vha, rsp); | 1934 | qla24xx_process_response_queue(vha, rsp); |
1935 | if (!ha->flags.disable_msix_handshake) { | 1935 | if (!ha->flags.disable_msix_handshake) { |
1936 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1936 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
@@ -2280,30 +2280,3 @@ int qla25xx_request_irq(struct rsp_que *rsp) | |||
2280 | msix->rsp = rsp; | 2280 | msix->rsp = rsp; |
2281 | return ret; | 2281 | return ret; |
2282 | } | 2282 | } |
2283 | |||
2284 | struct scsi_qla_host * | ||
2285 | qla25xx_get_host(struct rsp_que *rsp) | ||
2286 | { | ||
2287 | srb_t *sp; | ||
2288 | struct qla_hw_data *ha = rsp->hw; | ||
2289 | struct scsi_qla_host *vha = NULL; | ||
2290 | struct sts_entry_24xx *pkt; | ||
2291 | struct req_que *req; | ||
2292 | uint16_t que; | ||
2293 | uint32_t handle; | ||
2294 | |||
2295 | pkt = (struct sts_entry_24xx *) rsp->ring_ptr; | ||
2296 | que = MSW(pkt->handle); | ||
2297 | handle = (uint32_t) LSW(pkt->handle); | ||
2298 | req = ha->req_q_map[que]; | ||
2299 | if (handle < MAX_OUTSTANDING_COMMANDS) { | ||
2300 | sp = req->outstanding_cmds[handle]; | ||
2301 | if (sp) | ||
2302 | return sp->fcport->vha; | ||
2303 | else | ||
2304 | goto base_que; | ||
2305 | } | ||
2306 | base_que: | ||
2307 | vha = pci_get_drvdata(ha->pdev); | ||
2308 | return vha; | ||
2309 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index b901aa267e7d..ff17dee28613 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -636,13 +636,15 @@ failed: | |||
636 | 636 | ||
637 | static void qla_do_work(struct work_struct *work) | 637 | static void qla_do_work(struct work_struct *work) |
638 | { | 638 | { |
639 | unsigned long flags; | ||
639 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); | 640 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); |
640 | struct scsi_qla_host *vha; | 641 | struct scsi_qla_host *vha; |
642 | struct qla_hw_data *ha = rsp->hw; | ||
641 | 643 | ||
642 | spin_lock_irq(&rsp->hw->hardware_lock); | 644 | spin_lock_irqsave(&rsp->hw->hardware_lock, flags); |
643 | vha = qla25xx_get_host(rsp); | 645 | vha = pci_get_drvdata(ha->pdev); |
644 | qla24xx_process_response_queue(vha, rsp); | 646 | qla24xx_process_response_queue(vha, rsp); |
645 | spin_unlock_irq(&rsp->hw->hardware_lock); | 647 | spin_unlock_irqrestore(&rsp->hw->hardware_lock, flags); |
646 | } | 648 | } |
647 | 649 | ||
648 | /* create response queue */ | 650 | /* create response queue */ |