summaryrefslogtreecommitdiff
path: root/drivers/ide/pci/hpt366.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/pci/hpt366.c')
-rw-r--r--drivers/ide/pci/hpt366.c84
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;