diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-21 11:58:01 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:36:55 -0500 |
commit | 4a635593f447443459fb92a482b5cc6d1dd15199 (patch) | |
tree | a3821827971de21daa1dd56f760064f8d3ead604 /drivers/firewire | |
parent | ecb1cf9c446ad7e8248160fe6797cd9bed817f24 (diff) |
firewire: ohci: use an ID table for quirks detection
We don't have a lot of quirks to take into account (especially since
dual-buffer IR is out of the picture), but still, a table-based approach
is more organized than a series of if () clauses.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/ohci.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 39ddb620cad5..3dc2e8529a42 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -169,10 +169,7 @@ struct fw_ohci { | |||
169 | int node_id; | 169 | int node_id; |
170 | int generation; | 170 | int generation; |
171 | int request_generation; /* for timestamping incoming requests */ | 171 | int request_generation; /* for timestamping incoming requests */ |
172 | 172 | unsigned quirks; | |
173 | bool old_uninorth; | ||
174 | bool bus_reset_packet_quirk; | ||
175 | bool iso_cycle_timer_quirk; | ||
176 | 173 | ||
177 | /* | 174 | /* |
178 | * Spinlock for accessing fw_ohci data. Never call out of | 175 | * Spinlock for accessing fw_ohci data. Never call out of |
@@ -234,6 +231,21 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
234 | 231 | ||
235 | static char ohci_driver_name[] = KBUILD_MODNAME; | 232 | static char ohci_driver_name[] = KBUILD_MODNAME; |
236 | 233 | ||
234 | #define QUIRK_CYCLE_TIMER 1 | ||
235 | #define QUIRK_RESET_PACKET 2 | ||
236 | #define QUIRK_BE_HEADERS 4 | ||
237 | |||
238 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | ||
239 | static const struct { | ||
240 | unsigned short vendor, device, flags; | ||
241 | } ohci_quirks[] = { | ||
242 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | ||
243 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
244 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
245 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
246 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, | ||
247 | }; | ||
248 | |||
237 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG | 249 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG |
238 | 250 | ||
239 | #define OHCI_PARAM_DEBUG_AT_AR 1 | 251 | #define OHCI_PARAM_DEBUG_AT_AR 1 |
@@ -507,7 +519,7 @@ static void ar_context_release(struct ar_context *ctx) | |||
507 | 519 | ||
508 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | 520 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) |
509 | #define cond_le32_to_cpu(v) \ | 521 | #define cond_le32_to_cpu(v) \ |
510 | (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v)) | 522 | (ohci->quirks & QUIRK_BE_HEADERS ? (__force __u32)(v) : le32_to_cpu(v)) |
511 | #else | 523 | #else |
512 | #define cond_le32_to_cpu(v) le32_to_cpu(v) | 524 | #define cond_le32_to_cpu(v) le32_to_cpu(v) |
513 | #endif | 525 | #endif |
@@ -588,7 +600,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
588 | * at a slightly incorrect time (in bus_reset_tasklet). | 600 | * at a slightly incorrect time (in bus_reset_tasklet). |
589 | */ | 601 | */ |
590 | if (evt == OHCI1394_evt_bus_reset) { | 602 | if (evt == OHCI1394_evt_bus_reset) { |
591 | if (!ohci->bus_reset_packet_quirk) | 603 | if (!(ohci->quirks & QUIRK_RESET_PACKET)) |
592 | ohci->request_generation = (p.header[2] >> 16) & 0xff; | 604 | ohci->request_generation = (p.header[2] >> 16) & 0xff; |
593 | } else if (ctx == &ohci->ar_request_ctx) { | 605 | } else if (ctx == &ohci->ar_request_ctx) { |
594 | fw_core_handle_request(&ohci->card, &p); | 606 | fw_core_handle_request(&ohci->card, &p); |
@@ -1312,7 +1324,7 @@ static void bus_reset_tasklet(unsigned long data) | |||
1312 | context_stop(&ohci->at_response_ctx); | 1324 | context_stop(&ohci->at_response_ctx); |
1313 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); | 1325 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); |
1314 | 1326 | ||
1315 | if (ohci->bus_reset_packet_quirk) | 1327 | if (ohci->quirks & QUIRK_RESET_PACKET) |
1316 | ohci->request_generation = generation; | 1328 | ohci->request_generation = generation; |
1317 | 1329 | ||
1318 | /* | 1330 | /* |
@@ -1806,7 +1818,7 @@ static u32 ohci_get_cycle_time(struct fw_card *card) | |||
1806 | 1818 | ||
1807 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1819 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
1808 | 1820 | ||
1809 | if (ohci->iso_cycle_timer_quirk) { | 1821 | if (ohci->quirks & QUIRK_CYCLE_TIMER) { |
1810 | i = 0; | 1822 | i = 0; |
1811 | c1 = c2; | 1823 | c1 = c2; |
1812 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1824 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
@@ -2308,7 +2320,7 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2308 | struct fw_ohci *ohci; | 2320 | struct fw_ohci *ohci; |
2309 | u32 bus_options, max_receive, link_speed, version; | 2321 | u32 bus_options, max_receive, link_speed, version; |
2310 | u64 guid; | 2322 | u64 guid; |
2311 | int err; | 2323 | int i, err; |
2312 | size_t size; | 2324 | size_t size; |
2313 | 2325 | ||
2314 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); | 2326 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); |
@@ -2351,15 +2363,13 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2351 | 2363 | ||
2352 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | 2364 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; |
2353 | 2365 | ||
2354 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | 2366 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) |
2355 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | 2367 | if (ohci_quirks[i].vendor == dev->vendor && |
2356 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | 2368 | (ohci_quirks[i].device == dev->device || |
2357 | #endif | 2369 | ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { |
2358 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | 2370 | ohci->quirks = ohci_quirks[i].flags; |
2359 | 2371 | break; | |
2360 | ohci->iso_cycle_timer_quirk = dev->vendor == PCI_VENDOR_ID_AL || | 2372 | } |
2361 | dev->vendor == PCI_VENDOR_ID_NEC || | ||
2362 | dev->vendor == PCI_VENDOR_ID_VIA; | ||
2363 | 2373 | ||
2364 | ar_context_init(&ohci->ar_request_ctx, ohci, | 2374 | ar_context_init(&ohci->ar_request_ctx, ohci, |
2365 | OHCI1394_AsReqRcvContextControlSet); | 2375 | OHCI1394_AsReqRcvContextControlSet); |