diff options
-rw-r--r-- | drivers/ide/pci/sgiioc4.c | 6 | ||||
-rw-r--r-- | drivers/serial/ioc4_serial.c | 9 | ||||
-rw-r--r-- | drivers/sn/ioc4.c | 64 | ||||
-rw-r--r-- | include/linux/ioc4.h | 5 |
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 = { | |||
723 | int | 723 | int |
724 | ioc4_ide_attach_one(struct ioc4_driver_data *idd) | 724 | ioc4_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 | */ | ||
235 | static unsigned int | ||
236 | ioc4_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 */ |
226 | static int | 273 | static int |
227 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | 274 | 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) | |||
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 */ |
151 | struct ioc4_driver_data { | 155 | struct 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 */ |