diff options
Diffstat (limited to 'drivers/sn/ioc4.c')
-rw-r--r-- | drivers/sn/ioc4.c | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index cdeff909403..8256a97eb50 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c @@ -160,9 +160,6 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) writel(0, &idd->idd_misc_regs->int_out.raw); mmiowb(); - printk(KERN_INFO - "%s: Calibrating PCI bus speed " - "for pci_dev %s ... ", __FUNCTION__, pci_name(idd->idd_pdev)); /* Set up square wave */ int_out.raw = 0; int_out.fields.count = IOC4_CALIBRATE_COUNT; @@ -206,11 +203,16 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) /* Bounds check the result. */ if (period > IOC4_CALIBRATE_LOW_LIMIT || period < IOC4_CALIBRATE_HIGH_LIMIT) { - printk("failed. Assuming PCI clock ticks are %d ns.\n", + printk(KERN_INFO + "IOC4 %s: Clock calibration failed. Assuming" + "PCI clock is %d ns.\n", + pci_name(idd->idd_pdev), IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); period = IOC4_CALIBRATE_DEFAULT; } else { - printk("succeeded. PCI clock ticks are %ld ns.\n", + printk(KERN_DEBUG + "IOC4 %s: PCI clock is %ld ns.\n", + pci_name(idd->idd_pdev), period / IOC4_EXTINT_COUNT_DIVISOR); } @@ -222,6 +224,51 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) idd->count_period = period; } +/* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT. + * Each brings out different combinations of IOC4 signals, thus. + * the IOC4 subdrivers need to know to which we're attached. + * + * We look for the presence of a SCSI (IO9) or SATA (IO10) controller + * on the same PCI bus at slot number 3 to differentiate IO9 from IO10. + * If neither is present, it's a PCI-RT. + */ +static unsigned int +ioc4_variant(struct ioc4_driver_data *idd) +{ + struct pci_dev *pdev = NULL; + int found = 0; + + /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */ + do { + pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC, + PCI_DEVICE_ID_QLOGIC_ISP12160, pdev); + if (pdev && + 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) + return IOC4_VARIANT_IO9; + + /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */ + pdev = NULL; + do { + pdev = pci_get_device(PCI_VENDOR_ID_VITESSE, + PCI_DEVICE_ID_VITESSE_VSC7174, pdev); + if (pdev && + 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) + return IOC4_VARIANT_IO10; + + /* PCI-RT: No SCSI/SATA controller will be present */ + return IOC4_VARIANT_PCI_RT; +} + /* Adds a new instance of an IOC4 card */ static int ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) @@ -286,6 +333,13 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) /* Failsafe portion of per-IOC4 initialization */ + /* Detect card variant */ + idd->idd_variant = ioc4_variant(idd); + printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev), + idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" : + idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" : + idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown"); + /* Initialize IOC4 */ pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd); pci_write_config_dword(idd->idd_pdev, PCI_COMMAND, |