aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-ohci.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-01-26 00:38:49 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-03-09 16:02:49 -0500
commit0edeefd99fd31f74432aba5860f6ebcbde874dbf (patch)
tree45b6411584a198947c7d37a7c78bbf85346ac927 /drivers/firewire/fw-ohci.c
parent931c4834c8d1e1bf0dcc256b89449a01711f970d (diff)
firewire: Make sure we wait for DMA to stop before we reprogram it.
Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-ohci.c')
-rw-r--r--drivers/firewire/fw-ohci.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 58bc85dd7917..29285f209dcf 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -170,6 +170,8 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
170#define OHCI1394_PCI_HCI_Control 0x40 170#define OHCI1394_PCI_HCI_Control 0x40
171#define SELF_ID_BUF_SIZE 0x800 171#define SELF_ID_BUF_SIZE 0x800
172 172
173#define MAX_STOP_CONTEXT_LOOPS 1000
174
173static char ohci_driver_name[] = KBUILD_MODNAME; 175static char ohci_driver_name[] = KBUILD_MODNAME;
174 176
175static inline void reg_write(const struct fw_ohci *ohci, int offset, u32 data) 177static inline void reg_write(const struct fw_ohci *ohci, int offset, u32 data)
@@ -224,6 +226,13 @@ static void ar_context_tasklet(unsigned long data)
224 struct fw_ohci *ohci = ctx->ohci; 226 struct fw_ohci *ohci = ctx->ohci;
225 struct fw_packet p; 227 struct fw_packet p;
226 u32 status, length, tcode; 228 u32 status, length, tcode;
229 int i;
230
231 /* FIXME: We stop and restart the ar context here, what if we
232 * stop while a receive is in progress? Maybe we could just
233 * loop the context back to itself and use it in buffer fill
234 * mode as intended... */
235 reg_write(ctx->ohci, ctx->control_clear, CONTEXT_RUN);
227 236
228 /* FIXME: What to do about evt_* errors? */ 237 /* FIXME: What to do about evt_* errors? */
229 length = le16_to_cpu(ctx->descriptor.req_count) - 238 length = le16_to_cpu(ctx->descriptor.req_count) -
@@ -287,12 +296,14 @@ static void ar_context_tasklet(unsigned long data)
287 dma_sync_single_for_device(ohci->card.device, ctx->descriptor_bus, 296 dma_sync_single_for_device(ohci->card.device, ctx->descriptor_bus,
288 sizeof ctx->descriptor_bus, DMA_TO_DEVICE); 297 sizeof ctx->descriptor_bus, DMA_TO_DEVICE);
289 298
290 /* FIXME: We stop and restart the ar context here, what if we 299 /* Make sure the active bit is 0 before we reprogram the DMA. */
291 * stop while a receive is in progress? Maybe we could just 300 for (i = 0; i < MAX_STOP_CONTEXT_LOOPS; i++)
292 * loop the context back to itself and use it in buffer fill 301 if (!(reg_read(ctx->ohci,
293 * mode as intended... */ 302 ctx->control_clear) & CONTEXT_ACTIVE))
303 break;
304 if (i == MAX_STOP_CONTEXT_LOOPS)
305 fw_error("Failed to stop ar context\n");
294 306
295 reg_write(ctx->ohci, ctx->control_clear, CONTEXT_RUN);
296 ar_context_run(ctx); 307 ar_context_run(ctx);
297} 308}
298 309