diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1692a883f4de..6fc63b98818c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -152,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
152 | for (iter = 50; iter--; ) { | 152 | for (iter = 50; iter--; ) { |
153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
154 | if (stat & HSR_RISC_PAUSED) { | 154 | if (stat & HSR_RISC_PAUSED) { |
155 | if (pci_channel_offline(ha->pdev)) | 155 | if (unlikely(pci_channel_offline(ha->pdev))) |
156 | break; | 156 | break; |
157 | 157 | ||
158 | hccr = RD_REG_WORD(®->hccr); | 158 | hccr = RD_REG_WORD(®->hccr); |
@@ -1846,12 +1846,15 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1846 | reg = &ha->iobase->isp24; | 1846 | reg = &ha->iobase->isp24; |
1847 | status = 0; | 1847 | status = 0; |
1848 | 1848 | ||
1849 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
1850 | return IRQ_HANDLED; | ||
1851 | |||
1849 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1852 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1850 | vha = pci_get_drvdata(ha->pdev); | 1853 | vha = pci_get_drvdata(ha->pdev); |
1851 | for (iter = 50; iter--; ) { | 1854 | for (iter = 50; iter--; ) { |
1852 | stat = RD_REG_DWORD(®->host_status); | 1855 | stat = RD_REG_DWORD(®->host_status); |
1853 | if (stat & HSRX_RISC_PAUSED) { | 1856 | if (stat & HSRX_RISC_PAUSED) { |
1854 | if (pci_channel_offline(ha->pdev)) | 1857 | if (unlikely(pci_channel_offline(ha->pdev))) |
1855 | break; | 1858 | break; |
1856 | 1859 | ||
1857 | hccr = RD_REG_DWORD(®->hccr); | 1860 | hccr = RD_REG_DWORD(®->hccr); |
@@ -1914,6 +1917,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1914 | struct rsp_que *rsp; | 1917 | struct rsp_que *rsp; |
1915 | struct device_reg_24xx __iomem *reg; | 1918 | struct device_reg_24xx __iomem *reg; |
1916 | struct scsi_qla_host *vha; | 1919 | struct scsi_qla_host *vha; |
1920 | unsigned long flags; | ||
1917 | 1921 | ||
1918 | rsp = (struct rsp_que *) dev_id; | 1922 | rsp = (struct rsp_que *) dev_id; |
1919 | if (!rsp) { | 1923 | if (!rsp) { |
@@ -1924,15 +1928,15 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1924 | ha = rsp->hw; | 1928 | ha = rsp->hw; |
1925 | reg = &ha->iobase->isp24; | 1929 | reg = &ha->iobase->isp24; |
1926 | 1930 | ||
1927 | spin_lock_irq(&ha->hardware_lock); | 1931 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1928 | 1932 | ||
1929 | vha = qla25xx_get_host(rsp); | 1933 | vha = pci_get_drvdata(ha->pdev); |
1930 | qla24xx_process_response_queue(vha, rsp); | 1934 | qla24xx_process_response_queue(vha, rsp); |
1931 | if (!ha->flags.disable_msix_handshake) { | 1935 | if (!ha->flags.disable_msix_handshake) { |
1932 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1936 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1933 | RD_REG_DWORD_RELAXED(®->hccr); | 1937 | RD_REG_DWORD_RELAXED(®->hccr); |
1934 | } | 1938 | } |
1935 | spin_unlock_irq(&ha->hardware_lock); | 1939 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1936 | 1940 | ||
1937 | return IRQ_HANDLED; | 1941 | return IRQ_HANDLED; |
1938 | } | 1942 | } |
@@ -1943,6 +1947,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1943 | struct qla_hw_data *ha; | 1947 | struct qla_hw_data *ha; |
1944 | struct rsp_que *rsp; | 1948 | struct rsp_que *rsp; |
1945 | struct device_reg_24xx __iomem *reg; | 1949 | struct device_reg_24xx __iomem *reg; |
1950 | unsigned long flags; | ||
1946 | 1951 | ||
1947 | rsp = (struct rsp_que *) dev_id; | 1952 | rsp = (struct rsp_que *) dev_id; |
1948 | if (!rsp) { | 1953 | if (!rsp) { |
@@ -1955,10 +1960,10 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1955 | /* Clear the interrupt, if enabled, for this response queue */ | 1960 | /* Clear the interrupt, if enabled, for this response queue */ |
1956 | if (rsp->options & ~BIT_6) { | 1961 | if (rsp->options & ~BIT_6) { |
1957 | reg = &ha->iobase->isp24; | 1962 | reg = &ha->iobase->isp24; |
1958 | spin_lock_irq(&ha->hardware_lock); | 1963 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1959 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1964 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1960 | RD_REG_DWORD_RELAXED(®->hccr); | 1965 | RD_REG_DWORD_RELAXED(®->hccr); |
1961 | spin_unlock_irq(&ha->hardware_lock); | 1966 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1962 | } | 1967 | } |
1963 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); | 1968 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); |
1964 | 1969 | ||
@@ -1976,6 +1981,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1976 | uint32_t stat; | 1981 | uint32_t stat; |
1977 | uint32_t hccr; | 1982 | uint32_t hccr; |
1978 | uint16_t mb[4]; | 1983 | uint16_t mb[4]; |
1984 | unsigned long flags; | ||
1979 | 1985 | ||
1980 | rsp = (struct rsp_que *) dev_id; | 1986 | rsp = (struct rsp_que *) dev_id; |
1981 | if (!rsp) { | 1987 | if (!rsp) { |
@@ -1987,12 +1993,12 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1987 | reg = &ha->iobase->isp24; | 1993 | reg = &ha->iobase->isp24; |
1988 | status = 0; | 1994 | status = 0; |
1989 | 1995 | ||
1990 | spin_lock_irq(&ha->hardware_lock); | 1996 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1991 | vha = pci_get_drvdata(ha->pdev); | 1997 | vha = pci_get_drvdata(ha->pdev); |
1992 | do { | 1998 | do { |
1993 | stat = RD_REG_DWORD(®->host_status); | 1999 | stat = RD_REG_DWORD(®->host_status); |
1994 | if (stat & HSRX_RISC_PAUSED) { | 2000 | if (stat & HSRX_RISC_PAUSED) { |
1995 | if (pci_channel_offline(ha->pdev)) | 2001 | if (unlikely(pci_channel_offline(ha->pdev))) |
1996 | break; | 2002 | break; |
1997 | 2003 | ||
1998 | hccr = RD_REG_DWORD(®->hccr); | 2004 | hccr = RD_REG_DWORD(®->hccr); |
@@ -2036,7 +2042,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
2036 | } | 2042 | } |
2037 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 2043 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
2038 | } while (0); | 2044 | } while (0); |
2039 | spin_unlock_irq(&ha->hardware_lock); | 2045 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
2040 | 2046 | ||
2041 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 2047 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
2042 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 2048 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -2274,30 +2280,3 @@ int qla25xx_request_irq(struct rsp_que *rsp) | |||
2274 | msix->rsp = rsp; | 2280 | msix->rsp = rsp; |
2275 | return ret; | 2281 | return ret; |
2276 | } | 2282 | } |
2277 | |||
2278 | struct scsi_qla_host * | ||
2279 | qla25xx_get_host(struct rsp_que *rsp) | ||
2280 | { | ||
2281 | srb_t *sp; | ||
2282 | struct qla_hw_data *ha = rsp->hw; | ||
2283 | struct scsi_qla_host *vha = NULL; | ||
2284 | struct sts_entry_24xx *pkt; | ||
2285 | struct req_que *req; | ||
2286 | uint16_t que; | ||
2287 | uint32_t handle; | ||
2288 | |||
2289 | pkt = (struct sts_entry_24xx *) rsp->ring_ptr; | ||
2290 | que = MSW(pkt->handle); | ||
2291 | handle = (uint32_t) LSW(pkt->handle); | ||
2292 | req = ha->req_q_map[que]; | ||
2293 | if (handle < MAX_OUTSTANDING_COMMANDS) { | ||
2294 | sp = req->outstanding_cmds[handle]; | ||
2295 | if (sp) | ||
2296 | return sp->fcport->vha; | ||
2297 | else | ||
2298 | goto base_que; | ||
2299 | } | ||
2300 | base_que: | ||
2301 | vha = pci_get_drvdata(ha->pdev); | ||
2302 | return vha; | ||
2303 | } | ||