diff options
author | Ed Lin <ed.lin@promise.com> | 2009-08-18 15:15:14 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 09:50:41 -0400 |
commit | 69cb48750b02034350bc78d8053647d7464cdde0 (patch) | |
tree | 3dbcf5114ed1d65b1110f5e86c268ce5f2509b9d /drivers/scsi/stex.c | |
parent | 41e05a12c7aae16f0381103af3e5ca791e87ce59 (diff) |
[SCSI] stex: Add reset code for st_yel (v2)
Add reset related code for st_yel.
1. Set the SS_H2I_INT_RESET bit.
2. Wait for the SS_MU_OPERATIONAL flag. This is also part of
normal handshake process so move it to handshake routine.
3. Continue handshake with the firmware.
Signed-off-by: Ed Lin <ed.lin@promise.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r-- | drivers/scsi/stex.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 8d2a95c4e5b5..09fa8861fc58 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -55,6 +55,7 @@ enum { | |||
55 | OIS = 0x30, /* MU_OUTBOUND_INTERRUPT_STATUS */ | 55 | OIS = 0x30, /* MU_OUTBOUND_INTERRUPT_STATUS */ |
56 | OIM = 0x3c, /* MU_OUTBOUND_INTERRUPT_MASK */ | 56 | OIM = 0x3c, /* MU_OUTBOUND_INTERRUPT_MASK */ |
57 | 57 | ||
58 | YIOA_STATUS = 0x00, | ||
58 | YH2I_INT = 0x20, | 59 | YH2I_INT = 0x20, |
59 | YINT_EN = 0x34, | 60 | YINT_EN = 0x34, |
60 | YI2H_INT = 0x9c, | 61 | YI2H_INT = 0x9c, |
@@ -108,6 +109,10 @@ enum { | |||
108 | 109 | ||
109 | SS_HEAD_HANDSHAKE = 0x80, | 110 | SS_HEAD_HANDSHAKE = 0x80, |
110 | 111 | ||
112 | SS_H2I_INT_RESET = 0x100, | ||
113 | |||
114 | SS_MU_OPERATIONAL = 0x80000000, | ||
115 | |||
111 | STEX_CDB_LENGTH = 16, | 116 | STEX_CDB_LENGTH = 16, |
112 | STATUS_VAR_LEN = 128, | 117 | STATUS_VAR_LEN = 128, |
113 | 118 | ||
@@ -884,7 +889,7 @@ static void stex_ss_mu_intr(struct st_hba *hba) | |||
884 | tag = (u16)value; | 889 | tag = (u16)value; |
885 | if (unlikely(tag >= hba->host->can_queue)) { | 890 | if (unlikely(tag >= hba->host->can_queue)) { |
886 | printk(KERN_WARNING DRV_NAME | 891 | printk(KERN_WARNING DRV_NAME |
887 | "(%s): invalid tag\n", pci_name(hba->pdev)); | 892 | "(%s): invalid tag\n", pci_name(hba->pdev)); |
888 | continue; | 893 | continue; |
889 | } | 894 | } |
890 | 895 | ||
@@ -1040,16 +1045,27 @@ static int stex_ss_handshake(struct st_hba *hba) | |||
1040 | void __iomem *base = hba->mmio_base; | 1045 | void __iomem *base = hba->mmio_base; |
1041 | struct st_msg_header *msg_h; | 1046 | struct st_msg_header *msg_h; |
1042 | struct handshake_frame *h; | 1047 | struct handshake_frame *h; |
1043 | __le32 *scratch = hba->scratch; | 1048 | __le32 *scratch; |
1044 | u32 data; | 1049 | u32 data; |
1045 | unsigned long before; | 1050 | unsigned long before; |
1046 | int ret = 0; | 1051 | int ret = 0; |
1047 | 1052 | ||
1048 | h = (struct handshake_frame *)(hba->alloc_rq(hba)); | 1053 | before = jiffies; |
1049 | msg_h = (struct st_msg_header *)h - 1; | 1054 | while ((readl(base + YIOA_STATUS) & SS_MU_OPERATIONAL) == 0) { |
1055 | if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { | ||
1056 | printk(KERN_ERR DRV_NAME | ||
1057 | "(%s): firmware not operational\n", | ||
1058 | pci_name(hba->pdev)); | ||
1059 | return -1; | ||
1060 | } | ||
1061 | msleep(1); | ||
1062 | } | ||
1063 | |||
1064 | msg_h = (struct st_msg_header *)hba->dma_mem; | ||
1050 | msg_h->handle = cpu_to_le64(hba->dma_handle); | 1065 | msg_h->handle = cpu_to_le64(hba->dma_handle); |
1051 | msg_h->flag = SS_HEAD_HANDSHAKE; | 1066 | msg_h->flag = SS_HEAD_HANDSHAKE; |
1052 | 1067 | ||
1068 | h = (struct handshake_frame *)(msg_h + 1); | ||
1053 | h->rb_phy = cpu_to_le64(hba->dma_handle); | 1069 | h->rb_phy = cpu_to_le64(hba->dma_handle); |
1054 | h->req_sz = cpu_to_le16(hba->rq_size); | 1070 | h->req_sz = cpu_to_le16(hba->rq_size); |
1055 | h->req_cnt = cpu_to_le16(hba->rq_count+1); | 1071 | h->req_cnt = cpu_to_le16(hba->rq_count+1); |
@@ -1205,6 +1221,13 @@ static void stex_hard_reset(struct st_hba *hba) | |||
1205 | hba->pdev->saved_config_space[i]); | 1221 | hba->pdev->saved_config_space[i]); |
1206 | } | 1222 | } |
1207 | 1223 | ||
1224 | static void stex_ss_reset(struct st_hba *hba) | ||
1225 | { | ||
1226 | writel(SS_H2I_INT_RESET, hba->mmio_base + YH2I_INT); | ||
1227 | readl(hba->mmio_base + YH2I_INT); | ||
1228 | ssleep(5); | ||
1229 | } | ||
1230 | |||
1208 | static int stex_reset(struct scsi_cmnd *cmd) | 1231 | static int stex_reset(struct scsi_cmnd *cmd) |
1209 | { | 1232 | { |
1210 | struct st_hba *hba; | 1233 | struct st_hba *hba; |
@@ -1221,6 +1244,8 @@ static int stex_reset(struct scsi_cmnd *cmd) | |||
1221 | 1244 | ||
1222 | if (hba->cardtype == st_shasta) | 1245 | if (hba->cardtype == st_shasta) |
1223 | stex_hard_reset(hba); | 1246 | stex_hard_reset(hba); |
1247 | else if (hba->cardtype == st_yel) | ||
1248 | stex_ss_reset(hba); | ||
1224 | 1249 | ||
1225 | if (hba->cardtype != st_yosemite) { | 1250 | if (hba->cardtype != st_yosemite) { |
1226 | if (stex_handshake(hba)) { | 1251 | if (stex_handshake(hba)) { |