aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/ide/pci/sgiioc4.c6
-rw-r--r--drivers/serial/ioc4_serial.c9
-rw-r--r--drivers/sn/ioc4.c64
-rw-r--r--include/linux/ioc4.h5
4 files changed, 79 insertions, 5 deletions
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 27c9eb989a9a..e125032bb403 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -723,6 +723,12 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
723int 723int
724ioc4_ide_attach_one(struct ioc4_driver_data *idd) 724ioc4_ide_attach_one(struct ioc4_driver_data *idd)
725{ 725{
726 /* PCI-RT does not bring out IDE connection.
727 * Do not attach to this particular IOC4.
728 */
729 if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
730 return 0;
731
726 return pci_init_sgiioc4(idd->idd_pdev, 732 return pci_init_sgiioc4(idd->idd_pdev,
727 &sgiioc4_chipsets[idd->idd_pci_id->driver_data]); 733 &sgiioc4_chipsets[idd->idd_pci_id->driver_data]);
728} 734}
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index c620209d7b9a..717e47bbd784 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -2646,7 +2646,10 @@ static int ioc4_serial_remove_one(struct ioc4_driver_data *idd)
2646 struct ioc4_port *port; 2646 struct ioc4_port *port;
2647 struct ioc4_soft *soft; 2647 struct ioc4_soft *soft;
2648 2648
2649 /* If serial driver did not attach, don't try to detach */
2649 control = idd->idd_serial_data; 2650 control = idd->idd_serial_data;
2651 if (!control)
2652 return 0;
2650 2653
2651 for (port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; port_num++) { 2654 for (port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; port_num++) {
2652 for (port_type = UART_PORT_MIN; 2655 for (port_type = UART_PORT_MIN;
@@ -2778,6 +2781,12 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
2778 DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev, 2781 DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev,
2779 idd->idd_pci_id)); 2782 idd->idd_pci_id));
2780 2783
2784 /* PCI-RT does not bring out serial connections.
2785 * Do not attach to this particular IOC4.
2786 */
2787 if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
2788 return 0;
2789
2781 /* request serial registers */ 2790 /* request serial registers */
2782 tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET; 2791 tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET;
2783 2792
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,
diff --git a/include/linux/ioc4.h b/include/linux/ioc4.h
index 3dd18b785ebd..de73a3289cc2 100644
--- a/include/linux/ioc4.h
+++ b/include/linux/ioc4.h
@@ -147,6 +147,10 @@ struct ioc4_misc_regs {
147#define IOC4_GPCR_EDGE_6 0x40 147#define IOC4_GPCR_EDGE_6 0x40
148#define IOC4_GPCR_EDGE_7 0x80 148#define IOC4_GPCR_EDGE_7 0x80
149 149
150#define IOC4_VARIANT_IO9 0x0900
151#define IOC4_VARIANT_PCI_RT 0x0901
152#define IOC4_VARIANT_IO10 0x1000
153
150/* One of these per IOC4 */ 154/* One of these per IOC4 */
151struct ioc4_driver_data { 155struct ioc4_driver_data {
152 struct list_head idd_list; 156 struct list_head idd_list;
@@ -156,6 +160,7 @@ struct ioc4_driver_data {
156 struct __iomem ioc4_misc_regs *idd_misc_regs; 160 struct __iomem ioc4_misc_regs *idd_misc_regs;
157 unsigned long count_period; 161 unsigned long count_period;
158 void *idd_serial_data; 162 void *idd_serial_data;
163 unsigned int idd_variant;
159}; 164};
160 165
161/* One per submodule */ 166/* One per submodule */