From: Charles
Pegasus series is a RAID support product by using Thunderbolt technology.
The newest product, Pegasus 3(P3) is support Thunderbolt 3 technology with
another chip.
1.Change driver version.
2.Add P3 VID, DID and define it's device address.
3.P3 use msi interrupt, so stex_request_irq P3 type enable msi.
4.For hibernation, use msi_lock in stex_ss_handshake to prevent msi register
write again when handshaking.
5.P3 doesn't need read() as flush.
6.In stex_ss_intr & stex_abort, P3 only clear interrupt register when getting
vendor defined interrupt.
Signed-off-by: Charles.Chiou
Signed-off-by: Paul.Lyu
---
drivers/scsi/stex.c | 262 ++--
1 file changed, 195 insertions(+), 67 deletions(-)
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 5b23175..e177dfe 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -38,9 +38,9 @@
#include
#define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "5.00..01"
-#define ST_VER_MAJOR 5
-#define ST_VER_MINOR 00
+#define ST_DRIVER_VERSION "6.02..01"
+#define ST_VER_MAJOR 6
+#define ST_VER_MINOR 02
#define ST_OEM
#define ST_BUILD_VER 01
@@ -64,6 +64,13 @@ enum {
YI2H_INT_C = 0xa0,
YH2I_REQ= 0xc0,
YH2I_REQ_HI = 0xc4,
+ PSCRATCH0 = 0xb0,
+ PSCRATCH1 = 0xb4,
+ PSCRATCH2 = 0xb8,
+ PSCRATCH3 = 0xbc,
+ PSCRATCH4 = 0xc8,
+ MAILBOX_BASE= 0x1000,
+ MAILBOX_HNDSHK_STS = 0x0,
/* MU register value */
MU_INBOUND_DOORBELL_HANDSHAKE = (1 << 0),
@@ -87,7 +94,7 @@ enum {
MU_STATE_STOP = 5,
MU_STATE_NOCONNECT = 6,
- MU_MAX_DELAY= 120,
+ MU_MAX_DELAY= 50,
MU_HANDSHAKE_SIGNATURE = 0x5555,
MU_HANDSHAKE_SIGNATURE_HALF = 0x5a5a,
MU_HARD_RESET_WAIT = 3,
@@ -135,6 +142,7 @@ enum {
st_yosemite = 2,
st_seq = 3,
st_yel = 4,
+ st_P3 = 5,
PASSTHRU_REQ_TYPE = 0x0001,
PASSTHRU_REQ_NO_WAKEUP = 0x0100,
@@ -339,6 +347,7 @@ struct st_hba {
u16 rq_size;
u16 sts_count;
u8 supports_pm;
+ int msi_lock;
};
struct st_card_info {
@@ -540,11 +549,15 @@ static void stex_controller_info(struct st_hba *hba,
struct st_ccb *ccb)
++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)
@@ -974,15 +987,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 != 0x) {
- /* 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, >reset_work);
- return IRQ_HANDLED;
+ if (hba->cardtype == st_yel) {
+ data = readl(base + YI2H_INT);
+ if (data && data != 0x) {
+ /* 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, >reset_work);
+ return