aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid/megaraid_sas.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas.c')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c133
1 files changed, 94 insertions, 39 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 2fb53af8de2a..a487f414960e 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -10,7 +10,7 @@
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 * 11 *
12 * FILE : megaraid_sas.c 12 * FILE : megaraid_sas.c
13 * Version : v00.00.02.01 13 * Version : v00.00.02.02
14 * 14 *
15 * Authors: 15 * Authors:
16 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> 16 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
@@ -55,13 +55,13 @@ static struct pci_device_id megasas_pci_table[] = {
55 55
56 { 56 {
57 PCI_VENDOR_ID_LSI_LOGIC, 57 PCI_VENDOR_ID_LSI_LOGIC,
58 PCI_DEVICE_ID_LSI_SAS1064R, 58 PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP
59 PCI_ANY_ID, 59 PCI_ANY_ID,
60 PCI_ANY_ID, 60 PCI_ANY_ID,
61 }, 61 },
62 { 62 {
63 PCI_VENDOR_ID_DELL, 63 PCI_VENDOR_ID_DELL,
64 PCI_DEVICE_ID_DELL_PERC5, 64 PCI_DEVICE_ID_DELL_PERC5, // xscale IOP
65 PCI_ANY_ID, 65 PCI_ANY_ID,
66 PCI_ANY_ID, 66 PCI_ANY_ID,
67 }, 67 },
@@ -119,12 +119,18 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
119 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); 119 spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
120} 120}
121 121
122
123/**
124* The following functions are defined for xscale
125* (deviceid : 1064R, PERC5) controllers
126*/
127
122/** 128/**
123 * megasas_enable_intr - Enables interrupts 129 * megasas_enable_intr_xscale - Enables interrupts
124 * @regs: MFI register set 130 * @regs: MFI register set
125 */ 131 */
126static inline void 132static inline void
127megasas_enable_intr(struct megasas_register_set __iomem * regs) 133megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
128{ 134{
129 writel(1, &(regs)->outbound_intr_mask); 135 writel(1, &(regs)->outbound_intr_mask);
130 136
@@ -133,13 +139,73 @@ megasas_enable_intr(struct megasas_register_set __iomem * regs)
133} 139}
134 140
135/** 141/**
142 * megasas_read_fw_status_reg_xscale - returns the current FW status value
143 * @regs: MFI register set
144 */
145static u32
146megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
147{
148 return readl(&(regs)->outbound_msg_0);
149}
150/**
151 * megasas_clear_interrupt_xscale - Check & clear interrupt
152 * @regs: MFI register set
153 */
154static int
155megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
156{
157 u32 status;
158 /*
159 * Check if it is our interrupt
160 */
161 status = readl(&regs->outbound_intr_status);
162
163 if (!(status & MFI_OB_INTR_STATUS_MASK)) {
164 return 1;
165 }
166
167 /*
168 * Clear the interrupt by writing back the same value
169 */
170 writel(status, &regs->outbound_intr_status);
171
172 return 0;
173}
174
175/**
176 * megasas_fire_cmd_xscale - Sends command to the FW
177 * @frame_phys_addr : Physical address of cmd
178 * @frame_count : Number of frames for the command
179 * @regs : MFI register set
180 */
181static inline void
182megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
183{
184 writel((frame_phys_addr >> 3)|(frame_count),
185 &(regs)->inbound_queue_port);
186}
187
188static struct megasas_instance_template megasas_instance_template_xscale = {
189
190 .fire_cmd = megasas_fire_cmd_xscale,
191 .enable_intr = megasas_enable_intr_xscale,
192 .clear_intr = megasas_clear_intr_xscale,
193 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
194};
195
196/**
197* This is the end of set of functions & definitions specific
198* to xscale (deviceid : 1064R, PERC5) controllers
199*/
200
201/**
136 * megasas_disable_intr - Disables interrupts 202 * megasas_disable_intr - Disables interrupts
137 * @regs: MFI register set 203 * @regs: MFI register set
138 */ 204 */
139static inline void 205static inline void
140megasas_disable_intr(struct megasas_register_set __iomem * regs) 206megasas_disable_intr(struct megasas_register_set __iomem * regs)
141{ 207{
142 u32 mask = readl(&regs->outbound_intr_mask) & (~0x00000001); 208 u32 mask = 0x1f;
143 writel(mask, &regs->outbound_intr_mask); 209 writel(mask, &regs->outbound_intr_mask);
144 210
145 /* Dummy readl to force pci flush */ 211 /* Dummy readl to force pci flush */
@@ -167,8 +233,7 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
167 /* 233 /*
168 * Issue the frame using inbound queue port 234 * Issue the frame using inbound queue port
169 */ 235 */
170 writel(cmd->frame_phys_addr >> 3, 236 instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
171 &instance->reg_set->inbound_queue_port);
172 237
173 /* 238 /*
174 * Wait for cmd_status to change 239 * Wait for cmd_status to change
@@ -198,8 +263,7 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
198{ 263{
199 cmd->cmd_status = ENODATA; 264 cmd->cmd_status = ENODATA;
200 265
201 writel(cmd->frame_phys_addr >> 3, 266 instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
202 &instance->reg_set->inbound_queue_port);
203 267
204 wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA)); 268 wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA));
205 269
@@ -242,8 +306,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
242 cmd->sync_cmd = 1; 306 cmd->sync_cmd = 1;
243 cmd->cmd_status = 0xFF; 307 cmd->cmd_status = 0xFF;
244 308
245 writel(cmd->frame_phys_addr >> 3, 309 instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
246 &instance->reg_set->inbound_queue_port);
247 310
248 /* 311 /*
249 * Wait for this cmd to complete 312 * Wait for this cmd to complete
@@ -633,8 +696,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
633 instance->fw_outstanding++; 696 instance->fw_outstanding++;
634 spin_unlock_irqrestore(&instance->instance_lock, flags); 697 spin_unlock_irqrestore(&instance->instance_lock, flags);
635 698
636 writel(((cmd->frame_phys_addr >> 3) | (cmd->frame_count - 1)), 699 instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
637 &instance->reg_set->inbound_queue_port);
638 700
639 return 0; 701 return 0;
640 702
@@ -1045,7 +1107,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
1045static int 1107static int
1046megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) 1108megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
1047{ 1109{
1048 u32 status;
1049 u32 producer; 1110 u32 producer;
1050 u32 consumer; 1111 u32 consumer;
1051 u32 context; 1112 u32 context;
@@ -1053,17 +1114,10 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
1053 1114
1054 /* 1115 /*
1055 * Check if it is our interrupt 1116 * Check if it is our interrupt
1117 * Clear the interrupt
1056 */ 1118 */
1057 status = readl(&instance->reg_set->outbound_intr_status); 1119 if(instance->instancet->clear_intr(instance->reg_set))
1058
1059 if (!(status & MFI_OB_INTR_STATUS_MASK)) {
1060 return IRQ_NONE; 1120 return IRQ_NONE;
1061 }
1062
1063 /*
1064 * Clear the interrupt by writing back the same value
1065 */
1066 writel(status, &instance->reg_set->outbound_intr_status);
1067 1121
1068 producer = *instance->producer; 1122 producer = *instance->producer;
1069 consumer = *instance->consumer; 1123 consumer = *instance->consumer;
@@ -1097,7 +1151,7 @@ static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs)
1097 1151
1098/** 1152/**
1099 * megasas_transition_to_ready - Move the FW to READY state 1153 * megasas_transition_to_ready - Move the FW to READY state
1100 * @reg_set: MFI register set 1154 * @instance: Adapter soft state
1101 * 1155 *
1102 * During the initialization, FW passes can potentially be in any one of 1156 * During the initialization, FW passes can potentially be in any one of
1103 * several possible states. If the FW in operational, waiting-for-handshake 1157 * several possible states. If the FW in operational, waiting-for-handshake
@@ -1105,14 +1159,14 @@ static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs)
1105 * has to wait for the ready state. 1159 * has to wait for the ready state.
1106 */ 1160 */
1107static int 1161static int
1108megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set) 1162megasas_transition_to_ready(struct megasas_instance* instance)
1109{ 1163{
1110 int i; 1164 int i;
1111 u8 max_wait; 1165 u8 max_wait;
1112 u32 fw_state; 1166 u32 fw_state;
1113 u32 cur_state; 1167 u32 cur_state;
1114 1168
1115 fw_state = readl(&reg_set->outbound_msg_0) & MFI_STATE_MASK; 1169 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
1116 1170
1117 while (fw_state != MFI_STATE_READY) { 1171 while (fw_state != MFI_STATE_READY) {
1118 1172
@@ -1130,7 +1184,7 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
1130 * Set the CLR bit in inbound doorbell 1184 * Set the CLR bit in inbound doorbell
1131 */ 1185 */
1132 writel(MFI_INIT_CLEAR_HANDSHAKE, 1186 writel(MFI_INIT_CLEAR_HANDSHAKE,
1133 &reg_set->inbound_doorbell); 1187 &instance->reg_set->inbound_doorbell);
1134 1188
1135 max_wait = 2; 1189 max_wait = 2;
1136 cur_state = MFI_STATE_WAIT_HANDSHAKE; 1190 cur_state = MFI_STATE_WAIT_HANDSHAKE;
@@ -1140,8 +1194,8 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
1140 /* 1194 /*
1141 * Bring it to READY state; assuming max wait 2 secs 1195 * Bring it to READY state; assuming max wait 2 secs
1142 */ 1196 */
1143 megasas_disable_intr(reg_set); 1197 megasas_disable_intr(instance->reg_set);
1144 writel(MFI_INIT_READY, &reg_set->inbound_doorbell); 1198 writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell);
1145 1199
1146 max_wait = 10; 1200 max_wait = 10;
1147 cur_state = MFI_STATE_OPERATIONAL; 1201 cur_state = MFI_STATE_OPERATIONAL;
@@ -1190,8 +1244,8 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
1190 * The cur_state should not last for more than max_wait secs 1244 * The cur_state should not last for more than max_wait secs
1191 */ 1245 */
1192 for (i = 0; i < (max_wait * 1000); i++) { 1246 for (i = 0; i < (max_wait * 1000); i++) {
1193 fw_state = MFI_STATE_MASK & 1247 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
1194 readl(&reg_set->outbound_msg_0); 1248 MFI_STATE_MASK ;
1195 1249
1196 if (fw_state == cur_state) { 1250 if (fw_state == cur_state) {
1197 msleep(1); 1251 msleep(1);
@@ -1553,18 +1607,20 @@ static int megasas_init_mfi(struct megasas_instance *instance)
1553 1607
1554 reg_set = instance->reg_set; 1608 reg_set = instance->reg_set;
1555 1609
1610 instance->instancet = &megasas_instance_template_xscale;
1611
1556 /* 1612 /*
1557 * We expect the FW state to be READY 1613 * We expect the FW state to be READY
1558 */ 1614 */
1559 if (megasas_transition_to_ready(instance->reg_set)) 1615 if (megasas_transition_to_ready(instance))
1560 goto fail_ready_state; 1616 goto fail_ready_state;
1561 1617
1562 /* 1618 /*
1563 * Get various operational parameters from status register 1619 * Get various operational parameters from status register
1564 */ 1620 */
1565 instance->max_fw_cmds = readl(&reg_set->outbound_msg_0) & 0x00FFFF; 1621 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
1566 instance->max_num_sge = (readl(&reg_set->outbound_msg_0) & 0xFF0000) >> 1622 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
1567 0x10; 1623 0x10;
1568 /* 1624 /*
1569 * Create a pool of commands 1625 * Create a pool of commands
1570 */ 1626 */
@@ -1873,8 +1929,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
1873 /* 1929 /*
1874 * Issue the aen registration frame 1930 * Issue the aen registration frame
1875 */ 1931 */
1876 writel(cmd->frame_phys_addr >> 3, 1932 instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
1877 &instance->reg_set->inbound_queue_port);
1878 1933
1879 return 0; 1934 return 0;
1880} 1935}
@@ -2063,7 +2118,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2063 goto fail_irq; 2118 goto fail_irq;
2064 } 2119 }
2065 2120
2066 megasas_enable_intr(instance->reg_set); 2121 instance->instancet->enable_intr(instance->reg_set);
2067 2122
2068 /* 2123 /*
2069 * Store instance in PCI softstate 2124 * Store instance in PCI softstate