diff options
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 75dc6988cffd..94b16e0340ae 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/dma-mapping.h> | 24 | #include <linux/dma-mapping.h> |
25 | #include <linux/firewire.h> | 25 | #include <linux/firewire.h> |
26 | #include <linux/firewire-constants.h> | 26 | #include <linux/firewire-constants.h> |
27 | #include <linux/gfp.h> | ||
28 | #include <linux/init.h> | 27 | #include <linux/init.h> |
29 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
30 | #include <linux/io.h> | 29 | #include <linux/io.h> |
@@ -35,6 +34,7 @@ | |||
35 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
36 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
37 | #include <linux/pci_ids.h> | 36 | #include <linux/pci_ids.h> |
37 | #include <linux/slab.h> | ||
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | 40 | ||
@@ -231,6 +231,8 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
231 | 231 | ||
232 | static char ohci_driver_name[] = KBUILD_MODNAME; | 232 | static char ohci_driver_name[] = KBUILD_MODNAME; |
233 | 233 | ||
234 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 | ||
235 | |||
234 | #define QUIRK_CYCLE_TIMER 1 | 236 | #define QUIRK_CYCLE_TIMER 1 |
235 | #define QUIRK_RESET_PACKET 2 | 237 | #define QUIRK_RESET_PACKET 2 |
236 | #define QUIRK_BE_HEADERS 4 | 238 | #define QUIRK_BE_HEADERS 4 |
@@ -239,6 +241,8 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
239 | static const struct { | 241 | static const struct { |
240 | unsigned short vendor, device, flags; | 242 | unsigned short vendor, device, flags; |
241 | } ohci_quirks[] = { | 243 | } ohci_quirks[] = { |
244 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | | ||
245 | QUIRK_RESET_PACKET}, | ||
242 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | 246 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, |
243 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 247 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, |
244 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 248 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, |
@@ -1154,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci, | |||
1154 | struct fw_packet *packet, u32 csr) | 1158 | struct fw_packet *packet, u32 csr) |
1155 | { | 1159 | { |
1156 | struct fw_packet response; | 1160 | struct fw_packet response; |
1157 | int tcode, length, ext_tcode, sel; | 1161 | int tcode, length, ext_tcode, sel, try; |
1158 | __be32 *payload, lock_old; | 1162 | __be32 *payload, lock_old; |
1159 | u32 lock_arg, lock_data; | 1163 | u32 lock_arg, lock_data; |
1160 | 1164 | ||
@@ -1181,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci, | |||
1181 | reg_write(ohci, OHCI1394_CSRCompareData, lock_arg); | 1185 | reg_write(ohci, OHCI1394_CSRCompareData, lock_arg); |
1182 | reg_write(ohci, OHCI1394_CSRControl, sel); | 1186 | reg_write(ohci, OHCI1394_CSRControl, sel); |
1183 | 1187 | ||
1184 | if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) | 1188 | for (try = 0; try < 20; try++) |
1185 | lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData)); | 1189 | if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) { |
1186 | else | 1190 | lock_old = cpu_to_be32(reg_read(ohci, |
1187 | fw_notify("swap not done yet\n"); | 1191 | OHCI1394_CSRData)); |
1192 | fw_fill_response(&response, packet->header, | ||
1193 | RCODE_COMPLETE, | ||
1194 | &lock_old, sizeof(lock_old)); | ||
1195 | goto out; | ||
1196 | } | ||
1197 | |||
1198 | fw_error("swap not done (CSR lock timeout)\n"); | ||
1199 | fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0); | ||
1188 | 1200 | ||
1189 | fw_fill_response(&response, packet->header, | ||
1190 | RCODE_COMPLETE, &lock_old, sizeof(lock_old)); | ||
1191 | out: | 1201 | out: |
1192 | fw_core_handle_response(&ohci->card, &response); | 1202 | fw_core_handle_response(&ohci->card, &response); |
1193 | } | 1203 | } |
1194 | 1204 | ||
1195 | static void handle_local_request(struct context *ctx, struct fw_packet *packet) | 1205 | static void handle_local_request(struct context *ctx, struct fw_packet *packet) |
1196 | { | 1206 | { |
1197 | u64 offset; | 1207 | u64 offset, csr; |
1198 | u32 csr; | ||
1199 | 1208 | ||
1200 | if (ctx == &ctx->ohci->at_request_ctx) { | 1209 | if (ctx == &ctx->ohci->at_request_ctx) { |
1201 | packet->ack = ACK_PENDING; | 1210 | packet->ack = ACK_PENDING; |