diff options
Diffstat (limited to 'drivers/ide/pci/hpt366.c')
-rw-r--r-- | drivers/ide/pci/hpt366.c | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 5623cad569da..7a8c8c7a8b96 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1279,12 +1279,55 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha return dev->irq; } +static u8 __devinit hpt3xx_cable_detect(ide_hwif_t *hwif) +{ + struct pci_dev *dev = to_pci_dev(hwif->dev); + struct hpt_info *info = pci_get_drvdata(dev); + u8 chip_type = info->chip_type; + u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02; + + /* + * The HPT37x uses the CBLID pins as outputs for MA15/MA16 + * address lines to access an external EEPROM. To read valid + * cable detect state the pins must be enabled as inputs. + */ + if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) { + /* + * HPT374 PCI function 1 + * - set bit 15 of reg 0x52 to enable TCBLID as input + * - set bit 15 of reg 0x56 to enable FCBLID as input + */ + u8 mcr_addr = hwif->select_data + 2; + u16 mcr; + + pci_read_config_word(dev, mcr_addr, &mcr); + pci_write_config_word(dev, mcr_addr, (mcr | 0x8000)); + /* now read cable id register */ + pci_read_config_byte(dev, 0x5a, &scr1); + pci_write_config_word(dev, mcr_addr, mcr); + } else if (chip_type >= HPT370) { + /* + * HPT370/372 and 374 pcifn 0 + * - clear bit 0 of reg 0x5b to enable P/SCBLID as inputs + */ + u8 scr2 = 0; + + pci_read_config_byte(dev, 0x5b, &scr2); + pci_write_config_byte(dev, 0x5b, (scr2 & ~1)); + /* now read cable id register */ + pci_read_config_byte(dev, 0x5a, &scr1); + pci_write_config_byte(dev, 0x5b, scr2); + } else + pci_read_config_byte(dev, 0x5a, &scr1); + + return (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; +} + static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); struct hpt_info *info = pci_get_drvdata(dev); int serialize = HPT_SERIALIZE_IO; - u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02; u8 chip_type = info->chip_type; u8 new_mcr, old_mcr = 0; @@ -1301,6 +1344,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) hwif->udma_filter = &hpt3xx_udma_filter; hwif->mdma_filter = &hpt3xx_mdma_filter; + hwif->cable_detect = hpt3xx_cable_detect; + /* * HPT3xxN chips have some complications: * @@ -1346,43 +1391,6 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) if (hwif->dma_base == 0) return; - /* - * The HPT37x uses the CBLID pins as outputs for MA15/MA16 - * address lines to access an external EEPROM. To read valid - * cable detect state the pins must be enabled as inputs. - */ - if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) { - /* - * HPT374 PCI function 1 - * - set bit 15 of reg 0x52 to enable TCBLID as input - * - set bit 15 of reg 0x56 to enable FCBLID as input - */ - u8 mcr_addr = hwif->select_data + 2; - u16 mcr; - - pci_read_config_word (dev, mcr_addr, &mcr); - pci_write_config_word(dev, mcr_addr, (mcr | 0x8000)); - /* now read cable id register */ - pci_read_config_byte (dev, 0x5a, &scr1); - pci_write_config_word(dev, mcr_addr, mcr); - } else if (chip_type >= HPT370) { - /* - * HPT370/372 and 374 pcifn 0 - * - clear bit 0 of reg 0x5b to enable P/SCBLID as inputs - */ - u8 scr2 = 0; - - pci_read_config_byte (dev, 0x5b, &scr2); - pci_write_config_byte(dev, 0x5b, (scr2 & ~1)); - /* now read cable id register */ - pci_read_config_byte (dev, 0x5a, &scr1); - pci_write_config_byte(dev, 0x5b, scr2); - } else - pci_read_config_byte (dev, 0x5a, &scr1); - - if (hwif->cbl != ATA_CBL_PATA40_SHORT) - hwif->cbl = (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; - if (chip_type >= HPT374) { hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; hwif->ide_dma_end = &hpt374_ide_dma_end; |