diff options
author | Alan Cox <alan@linux.intel.com> | 2010-09-28 08:19:38 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-10-21 20:21:05 -0400 |
commit | 60039a5295b3d82a48fe132c699987d2e1408675 (patch) | |
tree | 38009cc6be6c876dfa0cd1752bd4c82b7d5d0e96 /drivers/ata/ata_generic.c | |
parent | b34e90429ce8a23546b6b927d4e151df4c113644 (diff) |
ata: Intel IDE-R support
Intel IDE-R devices are part of the Intel AMT management setup. They don't
have any special configuration registers or settings so the ata_generic
driver will support them fully.
Rather than add a huge table of IDs for each chipset and keep sending in
new ones this patch autodetects them.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
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 }, |