aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */