Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1992

kernel-2.6.18-238.el5.src.rpm

From: Jonathan Lim <jolim@redhat.com>
Date: Fri, 18 Apr 2008 18:32:52 -0400
Subject: [misc] ioc4: fixes - pci_put_dev, printks, mem resource
Message-id: 20080418223252.GA6658@sgi-desktop.boston.redhat.com
O-Subject: [RHEL5.3 PATCH] BZ 442424: Various fixes for IOC4 driver
Bugzilla: 442424
RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com>

The RHEL5.2 IOC4 driver is missing several fixes compared to the current top
of tree.  The ones involving pci_put_dev() could panic the machine during
device probing if left unfixed.

The patch has been tested on ia64 and is upstream:

  http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.24.y.git;a=blob;f=drivers/misc/ioc4.c;hb=90d8dabf74179e6615bd4688a118e12ec29ab7aa

Following is the diff against the 2.6.18-87.el5 kernel source:

diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c
index 8562821..70608aa 100644
--- a/drivers/sn/ioc4.c
+++ b/drivers/sn/ioc4.c
@@ -210,10 +210,12 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
 		       IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
 		period = IOC4_CALIBRATE_DEFAULT;
 	} else {
+		u64 ns = period;
+
+		do_div(ns, IOC4_EXTINT_COUNT_DIVISOR);
 		printk(KERN_DEBUG
-		       "IOC4 %s: PCI clock is %ld ns.\n",
-		       pci_name(idd->idd_pdev),
-		       period / IOC4_EXTINT_COUNT_DIVISOR);
+		       "IOC4 %s: PCI clock is %llu ns.\n",
+		       pci_name(idd->idd_pdev), (unsigned long long)ns);
 	}
 
 	/* Remember results.  We store the extint clock period rather
@@ -246,10 +248,11 @@ ioc4_variant(struct ioc4_driver_data *idd)
 		    idd->idd_pdev->bus->number == pdev->bus->number &&
 		    3 == PCI_SLOT(pdev->devfn))
 			found = 1;
-		pci_dev_put(pdev);
 	} while (pdev && !found);
-	if (NULL != pdev)
+	if (NULL != pdev) {
+		pci_dev_put(pdev);
 		return IOC4_VARIANT_IO9;
+	}
 
 	/* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */
 	pdev = NULL;
@@ -260,10 +263,11 @@ ioc4_variant(struct ioc4_driver_data *idd)
 		    idd->idd_pdev->bus->number == pdev->bus->number &&
 		    3 == PCI_SLOT(pdev->devfn))
 			found = 1;
-		pci_dev_put(pdev);
 	} while (pdev && !found);
-	if (NULL != pdev)
+	if (NULL != pdev) {
+		pci_dev_put(pdev);
 		return IOC4_VARIANT_IO10;
+	}
 
 	/* PCI-RT: No SCSI/SATA controller will be present */
 	return IOC4_VARIANT_PCI_RT;
@@ -311,7 +315,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
 		ret = -ENODEV;
 		goto out_pci;
 	}
-	if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
+	if (!request_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
 			    "ioc4_misc")) {
 		printk(KERN_WARNING
 		       "%s: Unable to request IOC4 misc region "
@@ -381,7 +385,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
 	return 0;
 
 out_misc_region:
-	release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+	release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
 out_pci:
 	kfree(idd);
 out_idd:
@@ -420,7 +424,7 @@ ioc4_remove(struct pci_dev *pdev)
 		       "Device removal may be incomplete.\n",
 		       __FUNCTION__, pci_name(idd->idd_pdev));
 	}
-	release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+	release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
 
 	/* Disable IOC4 and relinquish */
 	pci_disable_device(pdev);