aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/ohci1394.c
diff options
context:
space:
mode:
authorJody McIntyre <scjody@steamballoon.com>2005-04-21 17:09:42 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-21 17:09:42 -0400
commite4ec0f23c878f761cf33f3cbb66c66d6c05931ba (patch)
tree1f80476e6420e8a12a8aa065d5cd106bd0f5b147 /drivers/ieee1394/ohci1394.c
parentdfe547ab872951949a1a2fcc5cedbedad27a2fe5 (diff)
[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: Jody McIntyre <scjody@steamballoon.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/ieee1394/ohci1394.c')
-rw-r--r--drivers/ieee1394/ohci1394.c63
1 files changed, 43 insertions, 20 deletions
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 72830e6fde45..6cb0b586c297 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -539,10 +539,8 @@ static void ohci_initialize(struct ti_ohci *ohci)
539 initialize_dma_trm_ctx(&ohci->at_req_context); 539 initialize_dma_trm_ctx(&ohci->at_req_context);
540 initialize_dma_trm_ctx(&ohci->at_resp_context); 540 initialize_dma_trm_ctx(&ohci->at_resp_context);
541 541
542 /* Initialize IR Legacy DMA */ 542 /* Initialize IR Legacy DMA channel mask */
543 ohci->ir_legacy_channels = 0; 543 ohci->ir_legacy_channels = 0;
544 initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
545 DBGMSG("ISO receive legacy context activated");
546 544
547 /* 545 /*
548 * Accept AT requests from all nodes. This probably 546 * 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 case ISO_LISTEN_CHANNEL: 1030 case ISO_LISTEN_CHANNEL:
1033 { 1031 {
1034 u64 mask; 1032 u64 mask;
1033 struct dma_rcv_ctx *d = &ohci->ir_legacy_context;
1034 int ir_legacy_active;
1035 1035
1036 if (arg<0 || arg>63) { 1036 if (arg<0 || arg>63) {
1037 PRINT(KERN_ERR, 1037 PRINT(KERN_ERR,
@@ -1052,9 +1052,37 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
1052 return -EFAULT; 1052 return -EFAULT;
1053 } 1053 }
1054 1054
1055 ir_legacy_active = ohci->ir_legacy_channels;
1056
1055 ohci->ISO_channel_usage |= mask; 1057 ohci->ISO_channel_usage |= mask;
1056 ohci->ir_legacy_channels |= mask; 1058 ohci->ir_legacy_channels |= mask;
1057 1059
1060 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
1061
1062 if (!ir_legacy_active) {
1063 if (ohci1394_register_iso_tasklet(ohci,
1064 &ohci->ir_legacy_tasklet) < 0) {
1065 PRINT(KERN_ERR, "No IR DMA context available");
1066 return -EBUSY;
1067 }
1068
1069 /* the IR context can be assigned to any DMA context
1070 * by ohci1394_register_iso_tasklet */
1071 d->ctx = ohci->ir_legacy_tasklet.context;
1072 d->ctrlSet = OHCI1394_IsoRcvContextControlSet +
1073 32*d->ctx;
1074 d->ctrlClear = OHCI1394_IsoRcvContextControlClear +
1075 32*d->ctx;
1076 d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
1077 d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
1078
1079 initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
1080
1081 PRINT(KERN_ERR, "IR legacy activated");
1082 }
1083
1084 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
1085
1058 if (arg>31) 1086 if (arg>31)
1059 reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet, 1087 reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet,
1060 1<<(arg-32)); 1088 1<<(arg-32));
@@ -1101,6 +1129,12 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
1101 1129
1102 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); 1130 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
1103 DBGMSG("Listening disabled on channel %d", arg); 1131 DBGMSG("Listening disabled on channel %d", arg);
1132
1133 if (ohci->ir_legacy_channels == 0) {
1134 stop_dma_rcv_ctx(&ohci->ir_legacy_context);
1135 DBGMSG("ISO legacy receive context stopped");
1136 }
1137
1104 break; 1138 break;
1105 } 1139 }
1106 default: 1140 default:
@@ -1270,8 +1304,10 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
1270 OHCI_ISO_RECEIVE, 1304 OHCI_ISO_RECEIVE,
1271 ohci_iso_recv_task, (unsigned long) iso); 1305 ohci_iso_recv_task, (unsigned long) iso);
1272 1306
1273 if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) 1307 if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) {
1308 ret = -EBUSY;
1274 goto err; 1309 goto err;
1310 }
1275 1311
1276 recv->task_active = 1; 1312 recv->task_active = 1;
1277 1313
@@ -1896,8 +1932,10 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso)
1896 ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT, 1932 ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT,
1897 ohci_iso_xmit_task, (unsigned long) iso); 1933 ohci_iso_xmit_task, (unsigned long) iso);
1898 1934
1899 if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) 1935 if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) {
1936 ret = -EBUSY;
1900 goto err; 1937 goto err;
1938 }
1901 1939
1902 xmit->task_active = 1; 1940 xmit->task_active = 1;
1903 1941
@@ -2999,20 +3037,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
2999 ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet, 3037 ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet,
3000 OHCI_ISO_MULTICHANNEL_RECEIVE, 3038 OHCI_ISO_MULTICHANNEL_RECEIVE,
3001 dma_rcv_tasklet, (unsigned long) d); 3039 dma_rcv_tasklet, (unsigned long) d);
3002 if (ohci1394_register_iso_tasklet(ohci,
3003 &ohci->ir_legacy_tasklet) < 0) {
3004 PRINT(KERN_ERR, "No IR DMA context available");
3005 free_dma_rcv_ctx(d);
3006 return -EBUSY;
3007 }
3008
3009 /* the IR context can be assigned to any DMA context
3010 * by ohci1394_register_iso_tasklet */
3011 d->ctx = ohci->ir_legacy_tasklet.context;
3012 d->ctrlSet = OHCI1394_IsoRcvContextControlSet + 32*d->ctx;
3013 d->ctrlClear = OHCI1394_IsoRcvContextControlClear + 32*d->ctx;
3014 d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
3015 d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
3016 } else { 3040 } else {
3017 d->ctrlSet = context_base + OHCI1394_ContextControlSet; 3041 d->ctrlSet = context_base + OHCI1394_ContextControlSet;
3018 d->ctrlClear = context_base + OHCI1394_ContextControlClear; 3042 d->ctrlClear = context_base + OHCI1394_ContextControlClear;
@@ -3413,7 +3437,6 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
3413 3437
3414 switch (ohci->init_state) { 3438 switch (ohci->init_state) {
3415 case OHCI_INIT_DONE: 3439 case OHCI_INIT_DONE:
3416 stop_dma_rcv_ctx(&ohci->ir_legacy_context);
3417 hpsb_remove_host(ohci->host); 3440 hpsb_remove_host(ohci->host);
3418 3441
3419 /* Clear out BUS Options */ 3442 /* Clear out BUS Options */