[zaptel-commits] sruffell: branch sruffell/zaptel-1.4-transcoder r4205 - /team/sruffell/zaptel...

SVN commits to the Zaptel project zaptel-commits at lists.digium.com
Tue Apr 29 16:51:10 CDT 2008


Author: sruffell
Date: Tue Apr 29 16:51:10 2008
New Revision: 4205

URL: http://svn.digium.com/view/zaptel?view=rev&rev=4205
Log:
-  Reordered init a little to better recover when there is a problem loading
   the firmware from user space.
-  Fixed typo in dte_send_ack with allocating the ack cmd buffer.
-  Made the timeout message on rx selectable in the debug bit field.

Modified:
    team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c

Modified: team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c
URL: http://svn.digium.com/view/zaptel/team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c?view=diff&rev=4205&r1=4204&r2=4205
==============================================================================
--- team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c (original)
+++ team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c Tue Apr 29 16:51:10 2008
@@ -68,6 +68,7 @@
 #define DTE_DEBUG_CHANNEL_SETUP    (1 << 1)
 #define DTE_DEBUG_RTP_TX           (1 << 2)
 #define DTE_DEBUG_RTP_RX           (1 << 3)
+#define DTE_DEBUG_RX_TIMEOUT	   (1 << 4)
 
 #define DTE_DEBUG(_wc, _dbgmask, _fmt, _args...)                            \
 	if ((debug & _dbgmask) == (_dbgmask)) {                             \
@@ -82,9 +83,6 @@
 #define QUIET_DSP
 
 #define WC_MAX_IFACES 128
-
-#define NUM_CARDS 24
-#define NUM_EC	  4
 
 #if 0
 #define HERE() printk(KERN_DEBUG "HERE: %s:%d\n", __FILE__, __LINE__);
@@ -1195,7 +1193,8 @@
 				cmd = get_ready_cmd(cpvt);
 			} else {
 				/* Timeout... */
-				DTE_PRINTK(wc, INFO, "Timeout while waiting for transcoded packet.\n");
+				DTE_DEBUG(wc, DTE_DEBUG_RX_TIMEOUT, 
+				   "Timeout while waiting for transcoded packet.\n");
 				WARN_ON(!list_empty(&cpvt->rx_queue));
 				return -ENODATA;
 			}
@@ -1335,7 +1334,7 @@
 	struct dte_cmd *cmd;
 	u8 fifo[] = CMD_MSG_ACK(seqno, channel);
 
-	if (!(cmd = alloc_cmd(GFP_ATOMIC, 0))) {
+	if (!(cmd = __alloc_cmd(GFP_ATOMIC, 0))) {
 		WARN_ON(1);
 		return;
 	}
@@ -2411,13 +2410,82 @@
 #endif /* CONFIG_DEBUG_FS */
 
 
+static int initialize_channel_pvt(struct wcdte *wc, encode_t type, struct channel_pvt **cpvt)
+{
+	int chan;
+	*cpvt = kmalloc(sizeof(struct channel_pvt) * wc->numchannels, GFP_KERNEL);
+	if (!(*cpvt)) {
+		return -ENOMEM;
+	}
+	for (chan = 0; chan < wc->numchannels; ++chan) {
+		dte_init_state((*cpvt) + chan, type, chan, wc);
+	}
+	return 0;
+}
+
+static int 
+initialize_transcoder(struct wcdte *wc, unsigned int srcfmts, 
+                      unsigned int dstfmts, struct channel_pvt *pvts, 
+		      struct zt_transcoder **zt)
+{
+	int chan;
+	*zt = zt_transcoder_alloc(wc->numchannels);
+	if (!(*zt)) {
+		return -ENOMEM;
+	}
+	(*zt)->srcfmts = srcfmts;
+	(*zt)->dstfmts = dstfmts;
+	(*zt)->operation = dte_operation;
+	dte_setup_file_operations(&((*zt)->fops));
+	for (chan = 0; chan < wc->numchannels; ++chan) {
+		(*zt)->channels[chan].pvt = &pvts[chan];
+	}
+	return 0;
+}
+
+static int initialize_encoders(struct wcdte *wc, unsigned int complexfmts)
+{
+	int res;
+	if ((res = initialize_channel_pvt(wc, ENCODER, &wc->encoders))) {
+		return res;
+	}
+	if ((res = initialize_transcoder(wc, 
+		 ZT_FORMAT_ULAW | ZT_FORMAT_ALAW,
+		 complexfmts, 
+		 wc->encoders, 
+		 &wc->uencode))) 
+	{
+		return res;
+	}
+	sprintf(wc->uencode->name, "DTE Encoder");
+	return res;
+}
+
+static int initialize_decoders(struct wcdte *wc, unsigned int complexfmts)
+{
+	int res;
+	if ((res = initialize_channel_pvt(wc, DECODER, &wc->decoders))) {
+		return res;
+	}   
+	if ((res = initialize_transcoder(wc, 
+		complexfmts, 
+		ZT_FORMAT_ULAW | ZT_FORMAT_ALAW,
+		wc->decoders, 
+		&wc->udecode))) 
+	{
+		return res;
+	}
+
+	sprintf(wc->udecode->name, "DTE Decoder");
+	return res;
+}
+
 static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	int res, reg;
 	struct wcdte *wc = NULL;
 	struct wcdte_desc *d = (struct wcdte_desc *)ent->driver_data;
-	int chan, x;
-	static int initd_ifaces=0;
+	int x;
 	unsigned char g729_numchannels, g723_numchannels, min_numchannels, dte_firmware_ver, dte_firmware_ver_minor;
 	unsigned int complexfmts;
 
@@ -2431,41 +2499,44 @@
 #endif
 
 	ENTERING();
-	if (!initd_ifaces) {
-		memset((void *)ifaces,0,(sizeof(struct wcdte *))*WC_MAX_IFACES);
-		initd_ifaces=1;
-	}
-	for (x=0;x<WC_MAX_IFACES;x++)
+
+	for (x=0;x<WC_MAX_IFACES;x++) {
 		if (!ifaces[x]) break;
+	}
+
 	if (x >= WC_MAX_IFACES) {
 		printk(KERN_WARNING "%s: Too many interfaces.\n",
 		       THIS_MODULE->name);
 		return -EIO;
 	}
 
-	if (pci_enable_device(pdev)) {
-		res = -EIO;
-		goto error_exit;
-	}
+
+	/* ------------------------------------------------------------------
+	 * Setup the pure software constructs internal to this driver.
+	 * ------------------------------------------------------------------
+	 */
 
 	if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
-		res = -ENOMEM;
-		goto error_exit;
+		return -ENOMEM;
 	}
 
 	ifaces[x] = wc;
 	memset(wc, 0, sizeof(*wc));
 	snprintf(wc->board_name, sizeof(wc->board_name), "tc400b%d", x);
+	wc->iobase           = pci_resource_start(pdev, 0);
+	wc->pdev             = pdev;
+	wc->pos              = x;
+	wc->variety          = d->long_name;
+	wc->last_seqno       = INVALID;
+	wc->seq_num          = 6;
+
+	init_MUTEX(&wc->chansem);
 	spin_lock_init(&wc->reglock);
-	init_MUTEX(&wc->chansem);
-	wc->cards = NUM_CARDS;
-	wc->iobase = pci_resource_start(pdev, 0);
-	wc->pdev = pdev;
-	wc->pos = x;
-	wc->variety = d->long_name;
-
-	wc->last_seqno = INVALID;
-	wc->seq_num = 6;
+	spin_lock_init(&wc->cmd_list_lock);
+	INIT_LIST_HEAD(&wc->cmd_list);
+	INIT_LIST_HEAD(&wc->lost_cmd_list);
+
+	DTE_PRINTK(wc, INFO, "Attached to device at %s.\n", pci_name(wc->pdev));
 
 	/* Keep track of whether we need to free the region */
 	if (!request_region(wc->iobase, 0xff, wc->board_name)) {
@@ -2473,23 +2544,19 @@
 		return -EIO;
 	}
 
-	spin_lock_init(&wc->cmd_list_lock);
-	INIT_LIST_HEAD(&wc->cmd_list);
-	INIT_LIST_HEAD(&wc->lost_cmd_list);
-
 	init_waitqueue_head(&wc->regq);
 
 	if ((res = dte_initialize_descriptor_ring(wc->pdev, &wc->txd,
 		0xe0800000,
 		DMA_TO_DEVICE))) {
-		goto error_exit;
+		goto error_exit_swinit;
 	}
 	if ((res = dte_initialize_descriptor_ring(wc->pdev, &wc->rxd, 0,
 		DMA_FROM_DEVICE))) {
-		goto error_exit;
-	}
-
-#if DEFERRED_PROCESSING == WORKQUEUE
+		goto error_exit_swinit;
+	}
+
+#	if DEFERRED_PROCESSING == WORKQUEUE
 	/* Initialize the work queue */
 	wc->dte_wq = create_singlethread_workqueue(board_name);
 #	if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
@@ -2497,13 +2564,14 @@
 #	else
 	INIT_WORK(&wc->dte_work, dte_wque_run, wc);
 #	endif
-#endif
+#	endif
+
 
 #if defined(HOTPLUG_FIRMWARE)
-	if ((request_firmware(&firmware, tc400m_firmware, &wc->pdev->dev) != 0) ||
+	if ((res = request_firmware(&firmware, tc400m_firmware, &wc->pdev->dev)) ||
 	    !firmware) {
 		DTE_PRINTK(wc, ERR, "Firmware %s not available from userspace.\n", tc400m_firmware);
-		return -EIO;
+		goto error_exit_swinit;
 	}
 #else
 	embedded_firmware.data = _binary_zaptel_fw_tc400m_bin_start;
@@ -2516,8 +2584,6 @@
 	g723_numchannels = firmware->data[2];
 
 	min_numchannels = min(g723_numchannels, g729_numchannels);
-
-	/* Setup Encoders and Decoders */
 
 #if 0 /* Still working on G.723 with new interface. Limit to G.729 for now. */
 	if (!mode || strlen(mode) < 4) {
@@ -2542,89 +2608,54 @@
 	complexfmts = ZT_FORMAT_G729A;
 	wc->numchannels = g729_numchannels;
 #endif
-	
-	wc->uencode = zt_transcoder_alloc(wc->numchannels);
-	wc->udecode = zt_transcoder_alloc(wc->numchannels);
-	wc->encoders = kmalloc(sizeof(struct channel_pvt) * wc->numchannels, GFP_KERNEL);
-	wc->decoders = kmalloc(sizeof(struct channel_pvt) * wc->numchannels, GFP_KERNEL);
-
-	if (!wc->uencode || !wc->udecode || !wc->encoders || !wc->decoders) {
-		if (wc->uencode)
-			zt_transcoder_free(wc->uencode);
-		if (wc->udecode)
-			zt_transcoder_free(wc->udecode);
-		if (wc->encoders)
-			kfree(wc->encoders);
-		if (wc->decoders)
-			kfree(wc->decoders);
-		if (wc) 
-			kfree(wc);
-		return -ENOMEM;
-	}
-	memset(wc->encoders, 0, sizeof(struct channel_pvt) * wc->numchannels);
-	memset(wc->decoders, 0, sizeof(struct channel_pvt) * wc->numchannels);
-
-	sprintf(wc->udecode->name, "DTE Decoder");
-	sprintf(wc->uencode->name, "DTE Encoder");
-
-	wc->udecode->srcfmts = wc->uencode->dstfmts = complexfmts;
-	wc->udecode->dstfmts = wc->uencode->srcfmts = ZT_FORMAT_ULAW | ZT_FORMAT_ALAW;
-
-	dte_setup_file_operations(&wc->udecode->fops);
-	dte_setup_file_operations(&wc->uencode->fops);
-
-	wc->udecode->operation = wc->uencode->operation = dte_operation;
-
-	for (chan=0;chan<wc->numchannels;++chan) {
-		dte_init_state(wc->encoders + chan, ENCODER, chan, wc);
-		wc->encoders[chan].encoder = 1;
-		wc->decoders[chan].encoder = 0;
-		dte_init_state(wc->decoders + chan, DECODER, chan, wc);
-		wc->uencode->channels[chan].pvt = wc->encoders + chan;
-		wc->udecode->channels[chan].pvt = wc->decoders + chan;
-	}
-
-
-	zt_transcoder_register(wc->uencode);
-	zt_transcoder_register(wc->udecode);
+
+	if ((res = initialize_encoders(wc, complexfmts))) {
+		goto error_exit_swinit;
+	}
+	if ((res = initialize_decoders(wc, complexfmts))) {
+		goto error_exit_swinit;
+	}
+
+	/* ------------------------------------------------------------------
+	 * Load the firmware and start the DTE.
+	 * ------------------------------------------------------------------
+	 */
+
+	if ((res = pci_enable_device(pdev))) {
+		DTE_PRINTK(wc, ERR, "Failed to enable device.\n");
+		goto error_exit_swinit;;
+	}
+	pci_set_master(pdev);
+	pci_set_drvdata(pdev, wc);
+	if ((res = request_irq(pdev->irq, wcdte_interrupt, ZAP_IRQ_SHARED, wc->board_name, wc))) {
+		DTE_PRINTK(wc, ERR, "Unable to request IRQ %d\n", pdev->irq);
+		if (firmware != &embedded_firmware) {
+			release_firmware(firmware);
+		}
+		goto error_exit_hwinit;
+	}
+	if ((res = wcdte_hardware_init(wc))) {
+		if (firmware != &embedded_firmware) {
+			release_firmware(firmware);
+		}
+		goto error_exit_hwinit;
+	}
+	wcdte_enable_interrupts(wc);
+	wcdte_start_dma(wc);
+	res = wcdte_boot_processor(wc, firmware);
+	if (firmware != &embedded_firmware) {
+		release_firmware(firmware);
+	}
+	if (res) {
+		goto error_exit_hwinit;
+	}
+	if ((res = wcdte_setup_channels(wc))) {
+		goto error_exit_hwinit;
+	}
 
 	DTE_PRINTK(wc, INFO, "(%s) Transcoder support LOADED " \
 	   "(firm ver = %d.%d)\n", wc->complexname, dte_firmware_ver, 
 	   dte_firmware_ver_minor);
-
-	/* Enable bus mastering */
-	pci_set_master(pdev);
-
-	/* Keep track of which device we are */
-	pci_set_drvdata(pdev, wc);
-
-	if ((res = request_irq(pdev->irq, wcdte_interrupt, ZAP_IRQ_SHARED, wc->board_name, wc))) {
-		DTE_PRINTK(wc, ERR, "Unable to request IRQ %d\n", pdev->irq);
-		goto error_exit;
-	}
-
-
-	if ((res = wcdte_hardware_init(wc))) {
-		goto error_exit;
-	}
-
-	/* Enable Interrupts */
-	wcdte_enable_interrupts(wc);
-
-	/* Start DMA */
-	wcdte_start_dma(wc);
-
-	res = wcdte_boot_processor(wc, firmware);
-
-	if (firmware != &embedded_firmware)
-		release_firmware(firmware);
-
-	if (res) goto error_exit;
-
-	if (wcdte_setup_channels(wc)) {
-		res = -EIO;
-		goto error_exit;
-	}
 
 	reg = wcdte_getctl(wc, 0x00fc);
 	if (debug)
@@ -2639,19 +2670,36 @@
 	}
 	res = 0;
 	wcdte_debugfs_create_board_entry(wc);
+	zt_transcoder_register(wc->uencode);
+	zt_transcoder_register(wc->udecode);
 	LEAVING();
 	return res;
 
-error_exit:
-	if (!wc) return res;
+error_exit_hwinit:
 	wcdte_stop_dma(wc);
-	wcdte_cleanup_descriptor_ring(&wc->txd);
-	wcdte_cleanup_descriptor_ring(&wc->rxd);
 	wcdte_cleanup_command_list(wc);
-	/* Free Resources */
 	free_irq(pdev->irq, wc);
+	pci_set_drvdata(pdev, NULL);
 	release_region(wc->iobase, 0xff);
-	pci_set_drvdata(pdev, NULL);
+error_exit_swinit:
+	if (wc->encoders) {
+		kfree(wc->encoders);
+	}
+	if (wc->decoders) {
+		kfree(wc->decoders);
+	}
+	if (wc->uencode) {
+		zt_transcoder_free(wc->uencode);
+	}
+	if (wc->udecode) {
+		zt_transcoder_free(wc->udecode);
+	}
+	if (wc->txd.desc) {
+		wcdte_cleanup_descriptor_ring(&wc->txd);
+	}
+	if (wc->rxd.desc) {
+		wcdte_cleanup_descriptor_ring(&wc->rxd);
+	}
 	kfree(wc);
 	LEAVING();
  	return res;	
@@ -2764,7 +2812,7 @@
 	id_table: wcdte_pci_tbl,
 };
 
-int ztdte_init(void)
+int __init ztdte_init(void)
 {
 	int res;
 #	if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
@@ -2785,7 +2833,7 @@
 	return 0;
 }
 
-void ztdte_cleanup(void)
+void __exit ztdte_cleanup(void)
 {
 	pci_unregister_driver(&wcdte_driver);
 	wcdte_debugfs_remove_root();




More information about the zaptel-commits mailing list