diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-02 21:56:31 +0300 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-02 21:56:31 +0300 |
commit | bfa14b42a3bd671f0287b3db42e703e86ef27b48 (patch) | |
tree | ad902a99aa59232832d8e663be8d86a615e24114 /drivers/ide/pci/hpt366.c | |
parent | c413b9b94d9a8e7548cc4b2e04b7df0439ce76fd (diff) | |
download | linux-bfa14b42a3bd671f0287b3db42e703e86ef27b48.tar.xz |
ide: add ->cable_detect method to ide_hwif_t
* Add ->cable_detect method to ide_hwif_t.
* Call the new method in ide_init_port() if:
- the host supports UDMA modes > UDMA2 ('hwif->ultra_mask & 78')
- DMA initialization was successful (if hwif->dma_base is not set
ide_init_port() sets hwif->ultra_mask to zero)
- "idex=ata66" is not used ('hwif->cbl != ATA_CBL_PATA40_SHORT')
* Convert PCI host drivers to use ->cable_detect method.
While at it:
* Factor out cable detection to separate functions (if not already done).
* hpt366.c/it8213.c/slc90e66.c:
- don't check cable type if "idex=ata66" is used
* pdc202xx_new.c:
- add __devinit tag to pdcnew_cable_detect()
* pdc202xx_old.c:
- rename pdc202xx_old_cable_detect() to pdc2026x_old_cable_detect()
- add __devinit tag to pdc2026x_old_cable_detect()
Reviewed-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
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; |