[Linux1394-cvslog] rev 716 - trunk
Brought to you by:
aeb,
bencollins
From: SVN U. <ano...@li...> - 2002-12-22 14:51:12
|
Author: anonymous Date: 2002-12-20 03:12:30 -0500 (Fri, 20 Dec 2002) New Revision: 716 Modified: trunk/ohci1394.c Log: couple of minor ohci1394 ISO DMA improvements Modified: trunk/ohci1394.c ============================================================================== --- trunk/ohci1394.c (original) +++ trunk/ohci1394.c 2002-12-22 09:50:39.000000000 -0500 @@ -1104,7 +1104,10 @@ static void ohci_iso_recv_stop(struct hpsb_iso *iso) { struct ohci_iso_recv *recv = iso->hostdata; - + + /* disable interrupts */ + reg_write(recv->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << recv->task.context); + /* halt DMA */ ohci1394_stop_context(recv->ohci, recv->ContextControlClear, NULL); } @@ -1114,12 +1117,7 @@ struct ohci_iso_recv *recv = iso->hostdata; if(recv->task_active) { - /* halt DMA */ - ohci1394_stop_context(recv->ohci, recv->ContextControlClear, NULL); - - /* disable interrupts */ - reg_write(recv->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << recv->task.context); - + ohci_iso_recv_stop(iso); ohci1394_unregister_iso_tasklet(recv->ohci, &recv->task); recv->task_active = 0; } @@ -1230,14 +1228,18 @@ } reg_write(recv->ohci, recv->ContextMatch, contextMatch); - + /* address of first descriptor block */ command = dma_prog_region_offset_to_bus(&recv->prog, recv->pkt_dma * sizeof(struct dma_cmd)); command |= 1; /* Z=1 */ - + reg_write(recv->ohci, recv->CommandPtr, command); + + /* enable interrupts */ + reg_write(recv->ohci, OHCI1394_IsoRecvIntMaskSet, 1 << recv->task.context); + wmb(); - + /* run */ reg_write(recv->ohci, recv->ContextControlSet, 0x8000); @@ -1446,11 +1448,6 @@ xmit->ContextControlClear = OHCI1394_IsoXmitContextControlClear + 16 * ctx; xmit->CommandPtr = OHCI1394_IsoXmitCommandPtr + 16 * ctx; - reg_write(xmit->ohci, xmit->ContextControlClear, 0xFFFFFFFF); - - /* enable interrupts */ - reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskSet, 1 << ctx); - return 0; err: @@ -1461,7 +1458,17 @@ static void ohci_iso_xmit_stop(struct hpsb_iso *iso) { struct ohci_iso_xmit *xmit = iso->hostdata; - ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL); + + /* disable interrupts */ + reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << xmit->task.context); + + /* halt DMA */ + if(ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) { + /* XXX the DMA context will lock up if you try to send too much data! */ + PRINT(KERN_ERR, xmit->ohci->id, + "you probably exceeded the OHCI card's bandwidth limit - " + "reload the module and reduce xmit bandwidth"); + } } static void ohci_iso_xmit_shutdown(struct hpsb_iso *iso) @@ -1469,12 +1476,7 @@ struct ohci_iso_xmit *xmit = iso->hostdata; if(xmit->task_active) { - /* halt DMA */ - ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL); - - /* disable interrupts */ - reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << xmit->task.context); - + ohci_iso_xmit_stop(iso); ohci1394_unregister_iso_tasklet(xmit->ohci, &xmit->task); xmit->task_active = 0; } @@ -1544,7 +1546,7 @@ } } -static void ohci_iso_xmit_queue_one(struct hpsb_iso *iso) +static int ohci_iso_xmit_queue_one(struct hpsb_iso *iso) { struct ohci_iso_xmit *xmit = iso->hostdata; struct hpsb_iso_packet_info *info; @@ -1625,13 +1627,19 @@ /* increment cursors */ iso->first_packet = (iso->first_packet+1) % iso->buf_packets; atomic_inc(&iso->n_dma_packets); + + return 0; } -static void ohci_iso_xmit_queue(struct hpsb_iso *iso, int n_packets) +static int ohci_iso_xmit_queue(struct hpsb_iso *iso, int n_packets) { - int i; - for(i = 0; i < n_packets; i++) - ohci_iso_xmit_queue_one(iso); + int i, ret; + for(i = 0; i < n_packets; i++) { + ret = ohci_iso_xmit_queue_one(iso); + if(ret) + return ret; + } + return 0; } static int ohci_iso_xmit_start(struct hpsb_iso *iso, int cycle) @@ -1662,13 +1670,16 @@ reg_write(xmit->ohci, xmit->ContextControlSet, 0x80000000 | (start << 16)); } + /* enable interrupts */ + reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskSet, 1 << xmit->task.context); + /* run */ reg_write(xmit->ohci, xmit->ContextControlSet, 0x8000); mb(); - + /* wait 100 usec to give the card time to go active */ udelay(100); - + /* check the RUN bit */ if(!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) { PRINT(KERN_ERR, xmit->ohci->id, "Error starting IT DMA (ContextControl 0x%08x)\n", @@ -1691,8 +1702,7 @@ ohci_iso_xmit_stop(iso); return 0; case XMIT_QUEUE: - ohci_iso_xmit_queue(iso, arg); - return 0; + return ohci_iso_xmit_queue(iso, arg); case XMIT_SHUTDOWN: ohci_iso_xmit_shutdown(iso); return 0; |