[SCSI] megaraid_sas: support for 1078 type controller added
authorSumant Patro <sumantp@lsil.com>
Fri, 3 Feb 2006 23:34:35 +0000 (15:34 -0800)
committer <jejb@mulgrave.il.steeleye.com> <>
Sat, 4 Feb 2006 22:38:41 +0000 (16:38 -0600)
This patch adds support for 1078 type controller (device id : 0x60).

Signed-off-by: Sumant Patro <Sumant.Patro@lsil.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Documentation/scsi/ChangeLog.megaraid_sas
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h

index 9e8085b..2dafa63 100644 (file)
@@ -1,3 +1,14 @@
+1 Release Date    : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.02.04
+3 Older Version   : 00.00.02.04 
+
+i.     Support for 1078 type (ppc IOP) controller, device id : 0x60 added.
+       During initialization, depending on the device id, the template members 
+       are initialized with function pointers specific to the ppc or 
+       xscale controllers.  
+
+               -Sumant Patro <Sumant.Patro@lsil.com>
+               
 1 Release Date    : Fri Feb 03 14:16:25 PST 2006 - Sumant Patro 
                                                        <Sumant.Patro@lsil.com>
 2 Current Version : 00.00.02.04
index 0b73824..7de267e 100644 (file)
@@ -60,6 +60,12 @@ static struct pci_device_id megasas_pci_table[] = {
         PCI_ANY_ID,
         },
        {
+        PCI_VENDOR_ID_LSI_LOGIC,
+        PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP
+        PCI_ANY_ID,
+        PCI_ANY_ID,
+       },
+       {
         PCI_VENDOR_ID_DELL,
         PCI_DEVICE_ID_DELL_PERC5, // xscale IOP
         PCI_ANY_ID,
@@ -199,6 +205,86 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
 */
 
 /**
+*      The following functions are defined for ppc (deviceid : 0x60) 
+*      controllers
+*/
+
+/**
+ * megasas_enable_intr_ppc -   Enables interrupts
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
+{
+       writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
+    
+       writel(~0x80000004, &(regs)->outbound_intr_mask);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_ppc - returns the current FW status value
+ * @regs:                      MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
+{
+       return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_ppc -       Check & clear interrupt
+ * @regs:                              MFI register set
+ */
+static int 
+megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
+{
+       u32 status;
+       /*
+        * Check if it is our interrupt
+        */
+       status = readl(&regs->outbound_intr_status);
+
+       if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {
+               return 1;
+       }
+
+       /*
+        * Clear the interrupt by writing back the same value
+        */
+       writel(status, &regs->outbound_doorbell_clear);
+
+       return 0;
+}
+/**
+ * megasas_fire_cmd_ppc -      Sends command to the FW
+ * @frame_phys_addr :          Physical address of cmd
+ * @frame_count :              Number of frames for the command
+ * @regs :                     MFI register set
+ */
+static inline void 
+megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
+{
+       writel((frame_phys_addr | (frame_count<<1))|1, 
+                       &(regs)->inbound_queue_port);
+}
+
+static struct megasas_instance_template megasas_instance_template_ppc = {
+       
+       .fire_cmd = megasas_fire_cmd_ppc,
+       .enable_intr = megasas_enable_intr_ppc,
+       .clear_intr = megasas_clear_intr_ppc,
+       .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
+};
+
+/**
+*      This is the end of set of functions & definitions
+*      specific to ppc (deviceid : 0x60) controllers
+*/
+
+/**
  * megasas_disable_intr -      Disables interrupts
  * @regs:                      MFI register set
  */
@@ -1607,7 +1693,17 @@ static int megasas_init_mfi(struct megasas_instance *instance)
 
        reg_set = instance->reg_set;
 
-       instance->instancet = &megasas_instance_template_xscale;
+       switch(instance->pdev->device)
+       {
+               case PCI_DEVICE_ID_LSI_SAS1078R:        
+                       instance->instancet = &megasas_instance_template_ppc;
+                       break;
+               case PCI_DEVICE_ID_LSI_SAS1064R:
+               case PCI_DEVICE_ID_DELL_PERC5:
+               default:
+                       instance->instancet = &megasas_instance_template_xscale;
+                       break;
+       }
 
        /*
         * We expect the FW state to be READY
index 917326f..89639f0 100644 (file)
@@ -20,7 +20,7 @@
  */
 #define MEGASAS_VERSION                                "00.00.02.04"
 #define MEGASAS_RELDATE                                "Feb 03, 2006"
-#define MEGASAS_EXT_VERSION                    "Fri Feb 03 14:16:25 PST 2006"
+#define MEGASAS_EXT_VERSION                    "Fri Feb 03 14:31:44 PST 2006"
 /*
  * =====================================
  * MegaRAID SAS MFI firmware definitions
@@ -553,31 +553,46 @@ struct megasas_ctrl_info {
 #define MFI_OB_INTR_STATUS_MASK                        0x00000002
 #define MFI_POLL_TIMEOUT_SECS                  10
 
+#define MFI_REPLY_1078_MESSAGE_INTERRUPT       0x80000000
+#define PCI_DEVICE_ID_LSI_SAS1078R             0x00000060
 struct megasas_register_set {
+       u32     reserved_0[4];                  /*0000h*/
 
-       u32 reserved_0[4];      /*0000h */
+       u32     inbound_msg_0;                  /*0010h*/
+       u32     inbound_msg_1;                  /*0014h*/
+       u32     outbound_msg_0;                 /*0018h*/
+       u32     outbound_msg_1;                 /*001Ch*/
 
-       u32 inbound_msg_0;      /*0010h */
-       u32 inbound_msg_1;      /*0014h */
-       u32 outbound_msg_0;     /*0018h */
-       u32 outbound_msg_1;     /*001Ch */
+       u32     inbound_doorbell;               /*0020h*/
+       u32     inbound_intr_status;            /*0024h*/
+       u32     inbound_intr_mask;              /*0028h*/
 
-       u32 inbound_doorbell;   /*0020h */
-       u32 inbound_intr_status;        /*0024h */
-       u32 inbound_intr_mask;  /*0028h */
+       u32     outbound_doorbell;              /*002Ch*/
+       u32     outbound_intr_status;           /*0030h*/
+       u32     outbound_intr_mask;             /*0034h*/
 
-       u32 outbound_doorbell;  /*002Ch */
-       u32 outbound_intr_status;       /*0030h */
-       u32 outbound_intr_mask; /*0034h */
+       u32     reserved_1[2];                  /*0038h*/
 
-       u32 reserved_1[2];      /*0038h */
+       u32     inbound_queue_port;             /*0040h*/
+       u32     outbound_queue_port;            /*0044h*/
 
-       u32 inbound_queue_port; /*0040h */
-       u32 outbound_queue_port;        /*0044h */
+       u32     reserved_2[22];                 /*0048h*/
 
-       u32 reserved_2;         /*004Ch */
+       u32     outbound_doorbell_clear;        /*00A0h*/
 
-       u32 index_registers[1004];      /*0050h */
+       u32     reserved_3[3];                  /*00A4h*/
+
+       u32     outbound_scratch_pad ;          /*00B0h*/
+
+       u32     reserved_4[3];                  /*00B4h*/
+
+       u32     inbound_low_queue_port ;        /*00C0h*/
+
+       u32     inbound_high_queue_port ;       /*00C4h*/
+
+       u32     reserved_5;                     /*00C8h*/
+       u32     index_registers[820];           /*00CCh*/
 
 } __attribute__ ((packed));