[svn-commits] wendell: linux/trunk r6262 - /linux/trunk/drivers/dahdi/voicebus.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Mar 26 13:33:29 CDT 2009


Author: wendell
Date: Thu Mar 26 13:33:28 2009
New Revision: 6262

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6262
Log:
Fixes DAHDI-214 crash on driver unload. Affects wcte12xp and wctdm24xxp modules.

Modified:
    linux/trunk/drivers/dahdi/voicebus.c

Modified: linux/trunk/drivers/dahdi/voicebus.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/voicebus.c?view=diff&rev=6262&r1=6261&r2=6262
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus.c (original)
+++ linux/trunk/drivers/dahdi/voicebus.c Thu Mar 26 13:33:28 2009
@@ -222,6 +222,7 @@
 #define RX_UNDERRUN			2
 #define IN_DEFERRED_PROCESSING		3
 #define STOP				4
+#define STOPPED				8
 
 #if VOICEBUS_DEFERRED == WORKQUEUE
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
@@ -413,7 +414,7 @@
 {
 	u32 reg;
 	reg = vb_getctl(vb, SR_CSR5);
-	reg = (reg >> 17)&0x38;
+	reg = (reg >> 17) & 0x38;
 	return (0 == reg) ? 1 : 0;
 }
 
@@ -621,6 +622,14 @@
 
 	vb_setctl(vb, 0x0000, pci_access);
 
+	return 0;
+}
+
+static int
+vb_initialize_interface(struct voicebus *vb)
+{
+	u32 reg;
+
 	vb_cleanup_descriptors(vb, &vb->txd);
 	vb_cleanup_descriptors(vb, &vb->rxd);
 
@@ -645,7 +654,6 @@
 	vb_setsdi(vb, 0x00, 0x0100);
 	vb_setsdi(vb, 0x16, 0x2100);
 	reg = vb_getctl(vb, 0x00fc);
-
 
 	/*
 	 * The calls to setsdi above toggle the reset line of the CPLD.  Wait
@@ -720,7 +728,7 @@
 	unsigned int head = dl->head;
 	assert_in_vb_deferred(vb);
 	d = vb_descriptor(dl, head);
-	if (!OWNED(d)) {
+	if (d->buffer1 && !OWNED(d)) {
 		dma_unmap_single(&vb->pdev->dev, d->buffer1,
 			vb->framesize, dl->direction);
 		vbb = dl->pending[head];
@@ -877,6 +885,9 @@
 		return -EBUSY;
 
 	ret = vb_reset_interface(vb);
+	if (ret)
+		return ret;
+	ret = vb_initialize_interface(vb);
 	if (ret)
 		return ret;
 
@@ -917,6 +928,7 @@
 
 	VBLOCK(vb);
 	clear_bit(STOP, &vb->flags);
+	clear_bit(STOPPED, &vb->flags);
 #if VOICEBUS_DEFERRED == TIMER
 	vb->timer.expires = jiffies + HZ/1000;
 	add_timer(&vb->timer);
@@ -1002,18 +1014,24 @@
 	INIT_COMPLETION(vb->stopped_completion);
 	set_bit(STOP, &vb->flags);
 	vb_clear_start_transmit_bit(vb);
+	vb_clear_start_receive_bit(vb);
 	if (vb_wait_for_completion_timeout(&vb->stopped_completion, HZ)) {
-#if VOICEBUS_DEFERRED == TIMER
-		del_timer_sync(&vb->timer);
-#else
-		vb_disable_interrupts(vb);
-#endif
 		assert(vb_is_stopped(vb));
-		clear_bit(STOP, &vb->flags);
 	} else {
 		VB_PRINTK(vb, WARNING, "Timeout while waiting for board to "\
 			"stop.\n");
-	}
+
+
+		vb_clear_start_transmit_bit(vb);
+		vb_clear_start_receive_bit(vb);
+		set_bit(STOPPED, &vb->flags);
+		vb_disable_interrupts(vb);
+	}
+
+#if VOICEBUS_DEFERRED == TIMER
+	del_timer_sync(&vb->timer);
+#endif
+
 	return 0;
 }
 
@@ -1114,11 +1132,14 @@
 #ifdef DBG
 	static int count;
 #endif
+#if 0
 	int stopping = test_bit(STOP, &vb->flags);
+#endif
 	int underrun = test_bit(TX_UNDERRUN, &vb->flags);
 
 
 	start_vb_deferred(vb);
+#if 0
 	if (unlikely(stopping)) {
 
 		while ((vbb = vb_get_completed_txb(vb)))
@@ -1130,7 +1151,7 @@
 		stop_vb_deferred(vb);
 		return;
 	}
-
+#endif
 	if (unlikely(underrun)) {
 		/* When we've underrun our FIFO, for some reason we're not
 		 * able to keep enough transmit descriptors pending.  This can
@@ -1232,15 +1253,15 @@
 
 		if (int_status & TX_STOPPED_INTERRUPT) {
 			assert(test_bit(STOP, &vb->flags));
-			vb_clear_start_receive_bit(vb);
-			__vb_setctl(vb, SR_CSR5, DEFAULT_INTERRUPTS);
 			__vb_disable_interrupts(vb);
 			complete(&vb->stopped_completion);
 		}
 		if (int_status & RX_STOPPED_INTERRUPT) {
 			assert(test_bit(STOP, &vb->flags));
-			if (vb_is_stopped(vb))
+			if (vb_is_stopped(vb)) {
+				__vb_disable_interrupts(vb);
 				complete(&vb->stopped_completion);
+			}
 		}
 
 		/* Clear the interrupt(s) */
@@ -1264,7 +1285,7 @@
 #else
 	vb_isr(0, vb);
 #endif
-	if (!vb_is_stopped(vb)) {
+	if (!test_bit(STOPPED, &vb->flags)) {
 		vb->timer.expires = start + HZ/1000;
 		add_timer(&vb->timer);
 	}




More information about the svn-commits mailing list