mtd: jedec_probe: Fix crash in jedec_read_mfr()
[pandora-kernel.git] / drivers / edac / i7300_edac.c
index a76fe83..9afb598 100644 (file)
@@ -215,8 +215,8 @@ static const char *ferr_fat_fbd_name[] = {
        [0]  = "Memory Write error on non-redundant retry or "
               "FBD configuration Write error on retry",
 };
-#define GET_FBD_FAT_IDX(fbderr)        (fbderr & (3 << 28))
-#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
+#define GET_FBD_FAT_IDX(fbderr)        (((fbderr) >> 28) & 3)
+#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22))
 
 #define FERR_NF_FBD    0xa0
 static const char *ferr_nf_fbd_name[] = {
@@ -243,7 +243,7 @@ static const char *ferr_nf_fbd_name[] = {
        [1]  = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
        [0]  = "Uncorrectable Data ECC on Replay",
 };
-#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28))
+#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3)
 #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\
                              (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\
                              (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\
@@ -372,7 +372,7 @@ static const char *get_err_from_table(const char *table[], int size, int pos)
 static void i7300_process_error_global(struct mem_ctl_info *mci)
 {
        struct i7300_pvt *pvt;
-       u32 errnum, value;
+       u32 errnum, error_reg;
        unsigned long errors;
        const char *specific;
        bool is_fatal;
@@ -381,9 +381,9 @@ static void i7300_process_error_global(struct mem_ctl_info *mci)
 
        /* read in the 1st FATAL error register */
        pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
-                             FERR_GLOBAL_HI, &value);
-       if (unlikely(value)) {
-               errors = value;
+                             FERR_GLOBAL_HI, &error_reg);
+       if (unlikely(error_reg)) {
+               errors = error_reg;
                errnum = find_first_bit(&errors,
                                        ARRAY_SIZE(ferr_global_hi_name));
                specific = GET_ERR_FROM_TABLE(ferr_global_hi_name, errnum);
@@ -391,15 +391,15 @@ static void i7300_process_error_global(struct mem_ctl_info *mci)
 
                /* Clear the error bit */
                pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
-                                      FERR_GLOBAL_HI, value);
+                                      FERR_GLOBAL_HI, error_reg);
 
                goto error_global;
        }
 
        pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
-                             FERR_GLOBAL_LO, &value);
-       if (unlikely(value)) {
-               errors = value;
+                             FERR_GLOBAL_LO, &error_reg);
+       if (unlikely(error_reg)) {
+               errors = error_reg;
                errnum = find_first_bit(&errors,
                                        ARRAY_SIZE(ferr_global_lo_name));
                specific = GET_ERR_FROM_TABLE(ferr_global_lo_name, errnum);
@@ -407,7 +407,7 @@ static void i7300_process_error_global(struct mem_ctl_info *mci)
 
                /* Clear the error bit */
                pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
-                                      FERR_GLOBAL_LO, value);
+                                      FERR_GLOBAL_LO, error_reg);
 
                goto error_global;
        }
@@ -427,7 +427,7 @@ error_global:
 static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 {
        struct i7300_pvt *pvt;
-       u32 errnum, value;
+       u32 errnum, value, error_reg;
        u16 val16;
        unsigned branch, channel, bank, rank, cas, ras;
        u32 syndrome;
@@ -440,14 +440,14 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 
        /* read in the 1st FATAL error register */
        pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
-                             FERR_FAT_FBD, &value);
-       if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) {
-               errors = value & FERR_FAT_FBD_ERR_MASK ;
+                             FERR_FAT_FBD, &error_reg);
+       if (unlikely(error_reg & FERR_FAT_FBD_ERR_MASK)) {
+               errors = error_reg & FERR_FAT_FBD_ERR_MASK ;
                errnum = find_first_bit(&errors,
                                        ARRAY_SIZE(ferr_fat_fbd_name));
                specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum);
+               branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0;
 
-               branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
                pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
                                     NRECMEMA, &val16);
                bank = NRECMEMA_BANK(val16);
@@ -455,11 +455,14 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 
                pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
                                NRECMEMB, &value);
-
                is_wr = NRECMEMB_IS_WR(value);
                cas = NRECMEMB_CAS(value);
                ras = NRECMEMB_RAS(value);
 
+               /* Clean the error register */
+               pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
+                               FERR_FAT_FBD, error_reg);
+
                snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
                        "FATAL (Branch=%d DRAM-Bank=%d %s "
                        "RAS=%d CAS=%d Err=0x%lx (%s))",
@@ -476,21 +479,17 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 
        /* read in the 1st NON-FATAL error register */
        pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
-                             FERR_NF_FBD, &value);
-       if (unlikely(value & FERR_NF_FBD_ERR_MASK)) {
-               errors = value & FERR_NF_FBD_ERR_MASK;
+                             FERR_NF_FBD, &error_reg);
+       if (unlikely(error_reg & FERR_NF_FBD_ERR_MASK)) {
+               errors = error_reg & FERR_NF_FBD_ERR_MASK;
                errnum = find_first_bit(&errors,
                                        ARRAY_SIZE(ferr_nf_fbd_name));
                specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
-
-               /* Clear the error bit */
-               pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
-                                      FERR_GLOBAL_LO, value);
+               branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0;
 
                pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
                        REDMEMA, &syndrome);
 
-               branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
                pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
                                     RECMEMA, &val16);
                bank = RECMEMA_BANK(val16);
@@ -498,18 +497,20 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 
                pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
                                RECMEMB, &value);
-
                is_wr = RECMEMB_IS_WR(value);
                cas = RECMEMB_CAS(value);
                ras = RECMEMB_RAS(value);
 
                pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
                                     REDMEMB, &value);
-
                channel = (branch << 1);
                if (IS_SECOND_CH(value))
                        channel++;
 
+               /* Clear the error bit */
+               pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
+                               FERR_NF_FBD, error_reg);
+
                /* Form out message */
                snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
                        "Corrected error (Branch=%d, Channel %d), "
@@ -802,6 +803,7 @@ static int i7300_init_csrows(struct mem_ctl_info *mci)
        }
 
        /* Get the set of MTR[0-7] regs by each branch */
+       nr_pages = 0;
        for (slot = 0; slot < MAX_SLOTS; slot++) {
                int where = mtr_regs[slot];
                for (branch = 0; branch < MAX_BRANCHES; branch++) {
@@ -961,33 +963,35 @@ static int __devinit i7300_get_devices(struct mem_ctl_info *mci)
 
        /* Attempt to 'get' the MCH register we want */
        pdev = NULL;
-       while (!pvt->pci_dev_16_1_fsb_addr_map ||
-              !pvt->pci_dev_16_2_fsb_err_regs) {
-               pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
-                                     PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, pdev);
-               if (!pdev) {
-                       /* End of list, leave */
-                       i7300_printk(KERN_ERR,
-                               "'system address,Process Bus' "
-                               "device not found:"
-                               "vendor 0x%x device 0x%x ERR funcs "
-                               "(broken BIOS?)\n",
-                               PCI_VENDOR_ID_INTEL,
-                               PCI_DEVICE_ID_INTEL_I7300_MCH_ERR);
-                       goto error;
-               }
-
+       while ((pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
+                                     PCI_DEVICE_ID_INTEL_I7300_MCH_ERR,
+                                     pdev))) {
                /* Store device 16 funcs 1 and 2 */
                switch (PCI_FUNC(pdev->devfn)) {
                case 1:
-                       pvt->pci_dev_16_1_fsb_addr_map = pdev;
+                       if (!pvt->pci_dev_16_1_fsb_addr_map)
+                               pvt->pci_dev_16_1_fsb_addr_map =
+                                                       pci_dev_get(pdev);
                        break;
                case 2:
-                       pvt->pci_dev_16_2_fsb_err_regs = pdev;
+                       if (!pvt->pci_dev_16_2_fsb_err_regs)
+                               pvt->pci_dev_16_2_fsb_err_regs =
+                                                       pci_dev_get(pdev);
                        break;
                }
        }
 
+       if (!pvt->pci_dev_16_1_fsb_addr_map ||
+           !pvt->pci_dev_16_2_fsb_err_regs) {
+               /* At least one device was not found */
+               i7300_printk(KERN_ERR,
+                       "'system address,Process Bus' device not found:"
+                       "vendor 0x%x device 0x%x ERR funcs (broken BIOS?)\n",
+                       PCI_VENDOR_ID_INTEL,
+                       PCI_DEVICE_ID_INTEL_I7300_MCH_ERR);
+               goto error;
+       }
+
        debugf1("System Address, processor bus- PCI Bus ID: %s  %x:%x\n",
                pci_name(pvt->pci_dev_16_0_fsb_ctlr),
                pvt->pci_dev_16_0_fsb_ctlr->vendor,