[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