From: Paul <paul....@tw.promise.com> 1.Send command add P3 write reg 2.In get intr, read P3 reg & clear interrupt reg 3.Abort read & clear reg same as getting intr 4.Reset flow add P3 reset function because P3 don't need read back reg
Signed-off-by: Paul <paul....@tw.promise.com> --- drivers/scsi/stex.c | 68 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 921f4e3..4d74905 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -548,11 +548,15 @@ stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) ++hba->req_head; hba->req_head %= hba->rq_count+1; - - writel((addr >> 16) >> 16, hba->mmio_base + YH2I_REQ_HI); - readl(hba->mmio_base + YH2I_REQ_HI); /* flush */ - writel(addr, hba->mmio_base + YH2I_REQ); - readl(hba->mmio_base + YH2I_REQ); /* flush */ + if (hba->cardtype == st_P3) { + writel((addr >> 16) >> 16, hba->mmio_base + YH2I_REQ_HI); + writel(addr, hba->mmio_base + YH2I_REQ); + } else { + writel((addr >> 16) >> 16, hba->mmio_base + YH2I_REQ_HI); + readl(hba->mmio_base + YH2I_REQ_HI); /* flush */ + writel(addr, hba->mmio_base + YH2I_REQ); + readl(hba->mmio_base + YH2I_REQ); /* flush */ + } } static void return_abnormal_state(struct st_hba *hba, int status) @@ -982,15 +986,31 @@ static irqreturn_t stex_ss_intr(int irq, void *__hba) spin_lock_irqsave(hba->host->host_lock, flags); - data = readl(base + YI2H_INT); - if (data && data != 0xffffffff) { - /* clear the interrupt */ - writel(data, base + YI2H_INT_C); - stex_ss_mu_intr(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); - if (unlikely(data & SS_I2H_REQUEST_RESET)) - queue_work(hba->work_q, &hba->reset_work); - return IRQ_HANDLED; + if (hba->cardtype == st_yel) { + data = readl(base + YI2H_INT); + if (data && data != 0xffffffff) { + /* clear the interrupt */ + writel(data, base + YI2H_INT_C); + stex_ss_mu_intr(hba); + spin_unlock_irqrestore(hba->host->host_lock, flags); + if (unlikely(data & SS_I2H_REQUEST_RESET)) + queue_work(hba->work_q, &hba->reset_work); + return IRQ_HANDLED; + } + } else { + data = readl(base + PSCRATCH4); + if (data != 0xffffffff) { + if (data != 0) { + /* clear the interrupt */ + writel(data, base + PSCRATCH1); + writel((1 << 22), base + YH2I_INT); + } + stex_ss_mu_intr(hba); + spin_unlock_irqrestore(hba->host->host_lock, flags); + if (unlikely(data & SS_I2H_REQUEST_RESET)) + queue_work(hba->work_q, &hba->reset_work); + return IRQ_HANDLED; + } } spin_unlock_irqrestore(hba->host->host_lock, flags); @@ -1240,6 +1260,15 @@ static int stex_abort(struct scsi_cmnd *cmd) writel(data, base + YI2H_INT_C); stex_ss_mu_intr(hba); + } else if (hba->cardtype == st_P3) { + data = readl(base + PSCRATCH4); + if (data == 0xffffffff) + goto fail_out; + if (data != 0) { + writel(data, base + PSCRATCH1); + writel((1 << 22), base + YH2I_INT); + } + stex_ss_mu_intr(hba); } else { data = readl(base + ODBL); if (data == 0 || data == 0xffffffff) @@ -1247,9 +1276,9 @@ static int stex_abort(struct scsi_cmnd *cmd) writel(data, base + ODBL); readl(base + ODBL); /* flush */ - stex_mu_intr(hba, data); } + if (hba->wait_ccb == NULL) { printk(KERN_WARNING DRV_NAME "(%s): lost interrupt\n", pci_name(hba->pdev)); @@ -1343,6 +1372,12 @@ static void stex_ss_reset(struct st_hba *hba) ssleep(5); } +static void stex_p3_reset(struct st_hba *hba) +{ + writel(SS_H2I_INT_RESET, hba->mmio_base + YH2I_INT); + ssleep(5); +} + static int stex_do_reset(struct st_hba *hba) { unsigned long flags; @@ -1379,7 +1414,8 @@ static int stex_do_reset(struct st_hba *hba) stex_hard_reset(hba); else if (hba->cardtype == st_yel) stex_ss_reset(hba); - + else if (hba->cardtype == st_P3) + stex_p3_reset(hba); return_abnormal_state(hba, DID_RESET); -- 1.9.1