aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sn/ioc4.c
diff options
context:
space:
mode:
authorBrent Casavant <bcasavan@sgi.com>2006-06-23 05:05:52 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 10:43:07 -0400
commitf5befceb5cfecba49fdf61f8e0eb4d453200eac9 (patch)
treed44d7b0375408895a686e274a4a336c271184d0a /drivers/sn/ioc4.c
parent862f5f0133f1c8a179dd93adc03d43f8f7e8bac5 (diff)
[PATCH] SGI IOC4: Detect IO card variant
There are three different IO cards which an SGI IOC4 controller may find itself on. One of these variants does not bring out the IDE and serial signals, so we need to disable attaching the corresponding IOC4 subdrivers to such cards. Cleans up message clutter emitted during device probing. Signed-off-by: Brent Casavant <bcasavan@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/sn/ioc4.c')
-rw-r--r--drivers/sn/ioc4.c64
1 files changed, 59 insertions, 5 deletions
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c
index cdeff909403e..8256a97eb508 100644
--- a/drivers/sn/ioc4.c
+++ b/drivers/sn/ioc4.c
@@ -160,9 +160,6 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
160 writel(0, &idd->idd_misc_regs->int_out.raw); 160 writel(0, &idd->idd_misc_regs->int_out.raw);
161 mmiowb(); 161 mmiowb();
162 162
163 printk(KERN_INFO
164 "%s: Calibrating PCI bus speed "
165 "for pci_dev %s ... ", __FUNCTION__, pci_name(idd->idd_pdev));
166 /* Set up square wave */ 163 /* Set up square wave */
167 int_out.raw = 0; 164 int_out.raw = 0;
168 int_out.fields.count = IOC4_CALIBRATE_COUNT; 165 int_out.fields.count = IOC4_CALIBRATE_COUNT;
@@ -206,11 +203,16 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
206 /* Bounds check the result. */ 203 /* Bounds check the result. */
207 if (period > IOC4_CALIBRATE_LOW_LIMIT || 204 if (period > IOC4_CALIBRATE_LOW_LIMIT ||
208 period < IOC4_CALIBRATE_HIGH_LIMIT) { 205 period < IOC4_CALIBRATE_HIGH_LIMIT) {
209 printk("failed. Assuming PCI clock ticks are %d ns.\n", 206 printk(KERN_INFO
207 "IOC4 %s: Clock calibration failed. Assuming"
208 "PCI clock is %d ns.\n",
209 pci_name(idd->idd_pdev),
210 IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); 210 IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
211 period = IOC4_CALIBRATE_DEFAULT; 211 period = IOC4_CALIBRATE_DEFAULT;
212 } else { 212 } else {
213 printk("succeeded. PCI clock ticks are %ld ns.\n", 213 printk(KERN_DEBUG
214 "IOC4 %s: PCI clock is %ld ns.\n",
215 pci_name(idd->idd_pdev),
214 period / IOC4_EXTINT_COUNT_DIVISOR); 216 period / IOC4_EXTINT_COUNT_DIVISOR);
215 } 217 }
216 218
@@ -222,6 +224,51 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
222 idd->count_period = period; 224 idd->count_period = period;
223} 225}
224 226
227/* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT.
228 * Each brings out different combinations of IOC4 signals, thus.
229 * the IOC4 subdrivers need to know to which we're attached.
230 *
231 * We look for the presence of a SCSI (IO9) or SATA (IO10) controller
232 * on the same PCI bus at slot number 3 to differentiate IO9 from IO10.
233 * If neither is present, it's a PCI-RT.
234 */
235static unsigned int
236ioc4_variant(struct ioc4_driver_data *idd)
237{
238 struct pci_dev *pdev = NULL;
239 int found = 0;
240
241 /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */
242 do {
243 pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC,
244 PCI_DEVICE_ID_QLOGIC_ISP12160, pdev);
245 if (pdev &&
246 idd->idd_pdev->bus->number == pdev->bus->number &&
247 3 == PCI_SLOT(pdev->devfn))
248 found = 1;
249 pci_dev_put(pdev);
250 } while (pdev && !found);
251 if (NULL != pdev)
252 return IOC4_VARIANT_IO9;
253
254 /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */
255 pdev = NULL;
256 do {
257 pdev = pci_get_device(PCI_VENDOR_ID_VITESSE,
258 PCI_DEVICE_ID_VITESSE_VSC7174, pdev);
259 if (pdev &&
260 idd->idd_pdev->bus->number == pdev->bus->number &&
261 3 == PCI_SLOT(pdev->devfn))
262 found = 1;
263 pci_dev_put(pdev);
264 } while (pdev && !found);
265 if (NULL != pdev)
266 return IOC4_VARIANT_IO10;
267
268 /* PCI-RT: No SCSI/SATA controller will be present */
269 return IOC4_VARIANT_PCI_RT;
270}
271
225/* Adds a new instance of an IOC4 card */ 272/* Adds a new instance of an IOC4 card */
226static int 273static int
227ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) 274ioc4_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)
286 333
287 /* Failsafe portion of per-IOC4 initialization */ 334 /* Failsafe portion of per-IOC4 initialization */
288 335
336 /* Detect card variant */
337 idd->idd_variant = ioc4_variant(idd);
338 printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev),
339 idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" :
340 idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" :
341 idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown");
342
289 /* Initialize IOC4 */ 343 /* Initialize IOC4 */
290 pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd); 344 pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd);
291 pci_write_config_dword(idd->idd_pdev, PCI_COMMAND, 345 pci_write_config_dword(idd->idd_pdev, PCI_COMMAND,