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.c130
1 files changed, 114 insertions, 16 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index a487f414960e..4f39dd01936d 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.02 13 * Version : v00.00.02.04
14 * 14 *
15 * Authors: 15 * Authors:
16 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> 16 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
@@ -60,6 +60,12 @@ static struct pci_device_id megasas_pci_table[] = {
60 PCI_ANY_ID, 60 PCI_ANY_ID,
61 }, 61 },
62 { 62 {
63 PCI_VENDOR_ID_LSI_LOGIC,
64 PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP
65 PCI_ANY_ID,
66 PCI_ANY_ID,
67 },
68 {
63 PCI_VENDOR_ID_DELL, 69 PCI_VENDOR_ID_DELL,
64 PCI_DEVICE_ID_DELL_PERC5, // xscale IOP 70 PCI_DEVICE_ID_DELL_PERC5, // xscale IOP
65 PCI_ANY_ID, 71 PCI_ANY_ID,
@@ -199,6 +205,86 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
199*/ 205*/
200 206
201/** 207/**
208* The following functions are defined for ppc (deviceid : 0x60)
209* controllers
210*/
211
212/**
213 * megasas_enable_intr_ppc - Enables interrupts
214 * @regs: MFI register set
215 */
216static inline void
217megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
218{
219 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
220
221 writel(~0x80000004, &(regs)->outbound_intr_mask);
222
223 /* Dummy readl to force pci flush */
224 readl(&regs->outbound_intr_mask);
225}
226
227/**
228 * megasas_read_fw_status_reg_ppc - returns the current FW status value
229 * @regs: MFI register set
230 */
231static u32
232megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
233{
234 return readl(&(regs)->outbound_scratch_pad);
235}
236
237/**
238 * megasas_clear_interrupt_ppc - Check & clear interrupt
239 * @regs: MFI register set
240 */
241static int
242megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
243{
244 u32 status;
245 /*
246 * Check if it is our interrupt
247 */
248 status = readl(&regs->outbound_intr_status);
249
250 if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {
251 return 1;
252 }
253
254 /*
255 * Clear the interrupt by writing back the same value
256 */
257 writel(status, &regs->outbound_doorbell_clear);
258
259 return 0;
260}
261/**
262 * megasas_fire_cmd_ppc - Sends command to the FW
263 * @frame_phys_addr : Physical address of cmd
264 * @frame_count : Number of frames for the command
265 * @regs : MFI register set
266 */
267static inline void
268megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
269{
270 writel((frame_phys_addr | (frame_count<<1))|1,
271 &(regs)->inbound_queue_port);
272}
273
274static struct megasas_instance_template megasas_instance_template_ppc = {
275
276 .fire_cmd = megasas_fire_cmd_ppc,
277 .enable_intr = megasas_enable_intr_ppc,
278 .clear_intr = megasas_clear_intr_ppc,
279 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
280};
281
282/**
283* This is the end of set of functions & definitions
284* specific to ppc (deviceid : 0x60) controllers
285*/
286
287/**
202 * megasas_disable_intr - Disables interrupts 288 * megasas_disable_intr - Disables interrupts
203 * @regs: MFI register set 289 * @regs: MFI register set
204 */ 290 */
@@ -707,6 +793,20 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
707 return 0; 793 return 0;
708} 794}
709 795
796static int megasas_slave_configure(struct scsi_device *sdev)
797{
798 /*
799 * Don't export physical disk devices to the disk driver.
800 *
801 * FIXME: Currently we don't export them to the midlayer at all.
802 * That will be fixed once LSI engineers have audited the
803 * firmware for possible issues.
804 */
805 if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
806 return -ENXIO;
807 return 0;
808}
809
710/** 810/**
711 * megasas_wait_for_outstanding - Wait for all outstanding cmds 811 * megasas_wait_for_outstanding - Wait for all outstanding cmds
712 * @instance: Adapter soft state 812 * @instance: Adapter soft state
@@ -857,6 +957,7 @@ static struct scsi_host_template megasas_template = {
857 .module = THIS_MODULE, 957 .module = THIS_MODULE,
858 .name = "LSI Logic SAS based MegaRAID driver", 958 .name = "LSI Logic SAS based MegaRAID driver",
859 .proc_name = "megaraid_sas", 959 .proc_name = "megaraid_sas",
960 .slave_configure = megasas_slave_configure,
860 .queuecommand = megasas_queue_command, 961 .queuecommand = megasas_queue_command,
861 .eh_device_reset_handler = megasas_reset_device, 962 .eh_device_reset_handler = megasas_reset_device,
862 .eh_bus_reset_handler = megasas_reset_bus_host, 963 .eh_bus_reset_handler = megasas_reset_bus_host,
@@ -985,20 +1086,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
985 break; 1086 break;
986 } 1087 }
987 1088
988 /*
989 * Don't export physical disk devices to mid-layer.
990 */
991 if (!MEGASAS_IS_LOGICAL(cmd->scmd) &&
992 (hdr->cmd_status == MFI_STAT_OK) &&
993 (cmd->scmd->cmnd[0] == INQUIRY)) {
994
995 if (((*(u8 *) cmd->scmd->request_buffer) & 0x1F) ==
996 TYPE_DISK) {
997 cmd->scmd->result = DID_BAD_TARGET << 16;
998 exception = 1;
999 }
1000 }
1001
1002 case MFI_CMD_LD_READ: 1089 case MFI_CMD_LD_READ:
1003 case MFI_CMD_LD_WRITE: 1090 case MFI_CMD_LD_WRITE:
1004 1091
@@ -1607,7 +1694,17 @@ static int megasas_init_mfi(struct megasas_instance *instance)
1607 1694
1608 reg_set = instance->reg_set; 1695 reg_set = instance->reg_set;
1609 1696
1610 instance->instancet = &megasas_instance_template_xscale; 1697 switch(instance->pdev->device)
1698 {
1699 case PCI_DEVICE_ID_LSI_SAS1078R:
1700 instance->instancet = &megasas_instance_template_ppc;
1701 break;
1702 case PCI_DEVICE_ID_LSI_SAS1064R:
1703 case PCI_DEVICE_ID_DELL_PERC5:
1704 default:
1705 instance->instancet = &megasas_instance_template_xscale;
1706 break;
1707 }
1611 1708
1612 /* 1709 /*
1613 * We expect the FW state to be READY 1710 * We expect the FW state to be READY
@@ -1983,6 +2080,7 @@ static int megasas_io_attach(struct megasas_instance *instance)
1983 host->max_channel = MEGASAS_MAX_CHANNELS - 1; 2080 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
1984 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; 2081 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
1985 host->max_lun = MEGASAS_MAX_LUN; 2082 host->max_lun = MEGASAS_MAX_LUN;
2083 host->max_cmd_len = 16;
1986 2084
1987 /* 2085 /*
1988 * Notify the mid-layer about the new controller 2086 * Notify the mid-layer about the new controller