diff options
author | Jody McIntyre <scjody@steamballoon.com> | 2005-04-21 17:09:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-21 17:09:42 -0400 |
commit | e4ec0f23c878f761cf33f3cbb66c66d6c05931ba (patch) | |
tree | 1f80476e6420e8a12a8aa065d5cd106bd0f5b147 /drivers | |
parent | dfe547ab872951949a1a2fcc5cedbedad27a2fe5 (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')
-rw-r--r-- | drivers/ieee1394/ohci1394.c | 63 |
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 */ |