Commit e4ec0f23 authored by Jody McIntyre's avatar Jody McIntyre Committed by Linus Torvalds

[PATCH] Fix non-legacy ISO receive regression

Fix non-legacy multichannel ISO receive, broken by Parag Wardukar's
allocation fix.  Multichannel ISO receive still sucks; it should be possible
to use both legacy and non-legacy modes at the same time, but with this
patch, things are no worse than they were in 2.6.11 and allocation is
still done at the correct time.
Signed-off-by: default avatarJody McIntyre <scjody@steamballoon.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dfe547ab
...@@ -539,10 +539,8 @@ static void ohci_initialize(struct ti_ohci *ohci) ...@@ -539,10 +539,8 @@ static void ohci_initialize(struct ti_ohci *ohci)
initialize_dma_trm_ctx(&ohci->at_req_context); initialize_dma_trm_ctx(&ohci->at_req_context);
initialize_dma_trm_ctx(&ohci->at_resp_context); initialize_dma_trm_ctx(&ohci->at_resp_context);
/* Initialize IR Legacy DMA */ /* Initialize IR Legacy DMA channel mask */
ohci->ir_legacy_channels = 0; ohci->ir_legacy_channels = 0;
initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
DBGMSG("ISO receive legacy context activated");
/* /*
* Accept AT requests from all nodes. This probably * Accept AT requests from all nodes. This probably
...@@ -1032,6 +1030,8 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) ...@@ -1032,6 +1030,8 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
case ISO_LISTEN_CHANNEL: case ISO_LISTEN_CHANNEL:
{ {
u64 mask; u64 mask;
struct dma_rcv_ctx *d = &ohci->ir_legacy_context;
int ir_legacy_active;
if (arg<0 || arg>63) { if (arg<0 || arg>63) {
PRINT(KERN_ERR, PRINT(KERN_ERR,
...@@ -1052,9 +1052,37 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) ...@@ -1052,9 +1052,37 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
return -EFAULT; return -EFAULT;
} }
ir_legacy_active = ohci->ir_legacy_channels;
ohci->ISO_channel_usage |= mask; ohci->ISO_channel_usage |= mask;
ohci->ir_legacy_channels |= mask; ohci->ir_legacy_channels |= mask;
spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
if (!ir_legacy_active) {
if (ohci1394_register_iso_tasklet(ohci,
&ohci->ir_legacy_tasklet) < 0) {
PRINT(KERN_ERR, "No IR DMA context available");
return -EBUSY;
}
/* the IR context can be assigned to any DMA context
* by ohci1394_register_iso_tasklet */
d->ctx = ohci->ir_legacy_tasklet.context;
d->ctrlSet = OHCI1394_IsoRcvContextControlSet +
32*d->ctx;
d->ctrlClear = OHCI1394_IsoRcvContextControlClear +
32*d->ctx;
d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
PRINT(KERN_ERR, "IR legacy activated");
}
spin_lock_irqsave(&ohci->IR_channel_lock, flags);
if (arg>31) if (arg>31)
reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet, reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet,
1<<(arg-32)); 1<<(arg-32));
...@@ -1101,6 +1129,12 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) ...@@ -1101,6 +1129,12 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
DBGMSG("Listening disabled on channel %d", arg); DBGMSG("Listening disabled on channel %d", arg);
if (ohci->ir_legacy_channels == 0) {
stop_dma_rcv_ctx(&ohci->ir_legacy_context);
DBGMSG("ISO legacy receive context stopped");
}
break; break;
} }
default: default:
...@@ -1270,8 +1304,10 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso) ...@@ -1270,8 +1304,10 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
OHCI_ISO_RECEIVE, OHCI_ISO_RECEIVE,
ohci_iso_recv_task, (unsigned long) iso); ohci_iso_recv_task, (unsigned long) iso);
if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) {
ret = -EBUSY;
goto err; goto err;
}
recv->task_active = 1; recv->task_active = 1;
...@@ -1896,8 +1932,10 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso) ...@@ -1896,8 +1932,10 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso)
ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT, ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT,
ohci_iso_xmit_task, (unsigned long) iso); ohci_iso_xmit_task, (unsigned long) iso);
if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) {
ret = -EBUSY;
goto err; goto err;
}
xmit->task_active = 1; xmit->task_active = 1;
...@@ -2999,20 +3037,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, ...@@ -2999,20 +3037,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet, ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet,
OHCI_ISO_MULTICHANNEL_RECEIVE, OHCI_ISO_MULTICHANNEL_RECEIVE,
dma_rcv_tasklet, (unsigned long) d); dma_rcv_tasklet, (unsigned long) d);
if (ohci1394_register_iso_tasklet(ohci,
&ohci->ir_legacy_tasklet) < 0) {
PRINT(KERN_ERR, "No IR DMA context available");
free_dma_rcv_ctx(d);
return -EBUSY;
}
/* the IR context can be assigned to any DMA context
* by ohci1394_register_iso_tasklet */
d->ctx = ohci->ir_legacy_tasklet.context;
d->ctrlSet = OHCI1394_IsoRcvContextControlSet + 32*d->ctx;
d->ctrlClear = OHCI1394_IsoRcvContextControlClear + 32*d->ctx;
d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
} else { } else {
d->ctrlSet = context_base + OHCI1394_ContextControlSet; d->ctrlSet = context_base + OHCI1394_ContextControlSet;
d->ctrlClear = context_base + OHCI1394_ContextControlClear; d->ctrlClear = context_base + OHCI1394_ContextControlClear;
...@@ -3413,7 +3437,6 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) ...@@ -3413,7 +3437,6 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
switch (ohci->init_state) { switch (ohci->init_state) {
case OHCI_INIT_DONE: case OHCI_INIT_DONE:
stop_dma_rcv_ctx(&ohci->ir_legacy_context);
hpsb_remove_host(ohci->host); hpsb_remove_host(ohci->host);
/* Clear out BUS Options */ /* Clear out BUS Options */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment