diff options
Diffstat (limited to 'drivers/ata/ata_generic.c')
| -rw-r--r-- | drivers/ata/ata_generic.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index cc5f7726bde7..6981f7680a00 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | enum { | 35 | enum { |
| 36 | ATA_GEN_CLASS_MATCH = (1 << 0), | 36 | ATA_GEN_CLASS_MATCH = (1 << 0), |
| 37 | ATA_GEN_FORCE_DMA = (1 << 1), | 37 | ATA_GEN_FORCE_DMA = (1 << 1), |
| 38 | ATA_GEN_INTEL_IDER = (1 << 2), | ||
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | /** | 41 | /** |
| @@ -109,6 +110,49 @@ static struct ata_port_operations generic_port_ops = { | |||
| 109 | static int all_generic_ide; /* Set to claim all devices */ | 110 | static int all_generic_ide; /* Set to claim all devices */ |
| 110 | 111 | ||
| 111 | /** | 112 | /** |
| 113 | * is_intel_ider - identify intel IDE-R devices | ||
| 114 | * @dev: PCI device | ||
| 115 | * | ||
| 116 | * Distinguish Intel IDE-R controller devices from other Intel IDE | ||
| 117 | * devices. IDE-R devices have no timing registers and are in | ||
| 118 | * most respects virtual. They should be driven by the ata_generic | ||
| 119 | * driver. | ||
| 120 | * | ||
| 121 | * IDE-R devices have PCI offset 0xF8.L as zero, later Intel ATA has | ||
| 122 | * it non zero. All Intel ATA has 0x40 writable (timing), but it is | ||
| 123 | * not writable on IDE-R devices (this is guaranteed). | ||
| 124 | */ | ||
| 125 | |||
| 126 | static int is_intel_ider(struct pci_dev *dev) | ||
| 127 | { | ||
| 128 | /* For Intel IDE the value at 0xF8 is only zero on IDE-R | ||
| 129 | interfaces */ | ||
| 130 | u32 r; | ||
| 131 | u16 t; | ||
| 132 | |||
| 133 | /* Check the manufacturing ID, it will be zero for IDE-R */ | ||
| 134 | pci_read_config_dword(dev, 0xF8, &r); | ||
| 135 | /* Not IDE-R: punt so that ata_(old)piix gets it */ | ||
| 136 | if (r != 0) | ||
| 137 | return 0; | ||
| 138 | /* 0xF8 will also be zero on some early Intel IDE devices | ||
| 139 | but they will have a sane timing register */ | ||
| 140 | pci_read_config_word(dev, 0x40, &t); | ||
| 141 | if (t != 0) | ||
| 142 | return 0; | ||
| 143 | /* Finally check if the timing register is writable so that | ||
| 144 | we eliminate any early devices hot-docked in a docking | ||
| 145 | station */ | ||
| 146 | pci_write_config_word(dev, 0x40, 1); | ||
| 147 | pci_read_config_word(dev, 0x40, &t); | ||
| 148 | if (t) { | ||
| 149 | pci_write_config_word(dev, 0x40, 0); | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | return 1; | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 112 | * ata_generic_init - attach generic IDE | 156 | * ata_generic_init - attach generic IDE |
| 113 | * @dev: PCI device found | 157 | * @dev: PCI device found |
| 114 | * @id: match entry | 158 | * @id: match entry |
| @@ -134,6 +178,10 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id | |||
| 134 | if ((id->driver_data & ATA_GEN_CLASS_MATCH) && all_generic_ide == 0) | 178 | if ((id->driver_data & ATA_GEN_CLASS_MATCH) && all_generic_ide == 0) |
| 135 | return -ENODEV; | 179 | return -ENODEV; |
| 136 | 180 | ||
| 181 | if (id->driver_data & ATA_GEN_INTEL_IDER) | ||
| 182 | if (!is_intel_ider(dev)) | ||
| 183 | return -ENODEV; | ||
| 184 | |||
| 137 | /* Devices that need care */ | 185 | /* Devices that need care */ |
| 138 | if (dev->vendor == PCI_VENDOR_ID_UMC && | 186 | if (dev->vendor == PCI_VENDOR_ID_UMC && |
| 139 | dev->device == PCI_DEVICE_ID_UMC_UM8886A && | 187 | dev->device == PCI_DEVICE_ID_UMC_UM8886A && |
| @@ -186,7 +234,11 @@ static struct pci_device_id ata_generic[] = { | |||
| 186 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), }, | 234 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), }, |
| 187 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_3), }, | 235 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_3), }, |
| 188 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_5), }, | 236 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_5), }, |
| 189 | #endif | 237 | #endif |
| 238 | /* Intel, IDE class device */ | ||
| 239 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
| 240 | PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, | ||
| 241 | .driver_data = ATA_GEN_INTEL_IDER }, | ||
| 190 | /* Must come last. If you add entries adjust this table appropriately */ | 242 | /* Must come last. If you add entries adjust this table appropriately */ |
| 191 | { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL), | 243 | { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL), |
| 192 | .driver_data = ATA_GEN_CLASS_MATCH }, | 244 | .driver_data = ATA_GEN_CLASS_MATCH }, |
