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>
This commit is contained in:
parent
931c4834c8
commit
0edeefd99f
@ -170,6 +170,8 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
|
|||||||
#define OHCI1394_PCI_HCI_Control 0x40
|
#define OHCI1394_PCI_HCI_Control 0x40
|
||||||
#define SELF_ID_BUF_SIZE 0x800
|
#define SELF_ID_BUF_SIZE 0x800
|
||||||
|
|
||||||
|
#define MAX_STOP_CONTEXT_LOOPS 1000
|
||||||
|
|
||||||
static char ohci_driver_name[] = KBUILD_MODNAME;
|
static char ohci_driver_name[] = KBUILD_MODNAME;
|
||||||
|
|
||||||
static inline void reg_write(const struct fw_ohci *ohci, int offset, u32 data)
|
static 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)
|
|||||||
struct fw_ohci *ohci = ctx->ohci;
|
struct fw_ohci *ohci = ctx->ohci;
|
||||||
struct fw_packet p;
|
struct fw_packet p;
|
||||||
u32 status, length, tcode;
|
u32 status, length, tcode;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* FIXME: We stop and restart the ar context here, what if we
|
||||||
|
* stop while a receive is in progress? Maybe we could just
|
||||||
|
* loop the context back to itself and use it in buffer fill
|
||||||
|
* mode as intended... */
|
||||||
|
reg_write(ctx->ohci, ctx->control_clear, CONTEXT_RUN);
|
||||||
|
|
||||||
/* FIXME: What to do about evt_* errors? */
|
/* FIXME: What to do about evt_* errors? */
|
||||||
length = le16_to_cpu(ctx->descriptor.req_count) -
|
length = le16_to_cpu(ctx->descriptor.req_count) -
|
||||||
@ -287,12 +296,14 @@ static void ar_context_tasklet(unsigned long data)
|
|||||||
dma_sync_single_for_device(ohci->card.device, ctx->descriptor_bus,
|
dma_sync_single_for_device(ohci->card.device, ctx->descriptor_bus,
|
||||||
sizeof ctx->descriptor_bus, DMA_TO_DEVICE);
|
sizeof ctx->descriptor_bus, DMA_TO_DEVICE);
|
||||||
|
|
||||||
/* FIXME: We stop and restart the ar context here, what if we
|
/* Make sure the active bit is 0 before we reprogram the DMA. */
|
||||||
* stop while a receive is in progress? Maybe we could just
|
for (i = 0; i < MAX_STOP_CONTEXT_LOOPS; i++)
|
||||||
* loop the context back to itself and use it in buffer fill
|
if (!(reg_read(ctx->ohci,
|
||||||
* mode as intended... */
|
ctx->control_clear) & CONTEXT_ACTIVE))
|
||||||
|
break;
|
||||||
|
if (i == MAX_STOP_CONTEXT_LOOPS)
|
||||||
|
fw_error("Failed to stop ar context\n");
|
||||||
|
|
||||||
reg_write(ctx->ohci, ctx->control_clear, CONTEXT_RUN);
|
|
||||||
ar_context_run(ctx);
|
ar_context_run(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user