summaryrefslogtreecommitdiff
path: root/wctdm24xxp
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-12-11 17:27:00 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-12-11 17:27:00 +0000
commit2bbac8cb8328db3523aae6f4d9cdd67eb04b4390 (patch)
treed129e5ecbe1c67c11f0cfeeca14f56e2a8c08cde /wctdm24xxp
parentc78bbae434262fe225b6f100ecbff3cc5dc67532 (diff)
coding guidelines cleanup
report results of failure to initialize a VPMADT032 module all the way up the process, so that a card with a failed VPM won't be left in a partially-operational state clean up early exits from wctdm_init_one() to undo all previously completed steps git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3430 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wctdm24xxp')
-rw-r--r--wctdm24xxp/base.c271
1 files changed, 151 insertions, 120 deletions
diff --git a/wctdm24xxp/base.c b/wctdm24xxp/base.c
index 603e5c4..9a7a491 100644
--- a/wctdm24xxp/base.c
+++ b/wctdm24xxp/base.c
@@ -2952,12 +2952,20 @@ static int vpm150m_config_hw(struct wctdm *wc)
}
#endif /* VPM150M_SUPPORT */
-static void wctdm_vpm150m_init(struct wctdm *wc)
+enum vpmadt032_init_result {
+ VPMADT032_SUCCESS,
+ VPMADT032_NOT_FOUND,
+ VPMADT032_FAILED,
+ VPMADT032_DISABLED,
+};
+
+static enum vpmadt032_init_result wctdm_vpm150m_init(struct wctdm *wc)
{
unsigned short i;
struct vpm150m *vpm150m;
unsigned short reg;
unsigned long flags;
+ enum vpmadt032_init_result res = VPMADT032_FAILED;
#ifdef VPM150M_SUPPORT
struct wctdm_firmware fw;
@@ -2976,14 +2984,14 @@ static void wctdm_vpm150m_init(struct wctdm *wc)
if (!vpmsupport) {
printk("VPM: Support Disabled\n");
wc->vpm150m = NULL;
- return;
+ return VPMADT032_DISABLED;
}
vpm150m = kmalloc(sizeof(struct vpm150m), GFP_KERNEL);
if (!vpm150m) {
printk("Unable to allocate VPM150M!\n");
- return;
+ return VPMADT032_FAILED;
}
memset(vpm150m, 0, sizeof(struct vpm150m));
@@ -3017,6 +3025,7 @@ static void wctdm_vpm150m_init(struct wctdm *wc)
if (reg != i) {
if (debug & DEBUG_ECHOCAN)
printk("Failed: Sent %x != %x VPMADT032 Failed HI page test\n", i, reg);
+ res = VPMADT032_NOT_FOUND;
goto failed_exit;
}
}
@@ -3064,7 +3073,7 @@ static void wctdm_vpm150m_init(struct wctdm *wc)
if ((request_firmware(&firmware, vpmadt032_firmware, &wc->dev->dev) != 0) ||
!firmware) {
printk("VPMADT032: firmware %s not available from userspace\n", vpmadt032_firmware);
- return;
+ goto failed_exit;
}
#else
embedded_firmware.data = _binary_vpmadt032_bin_start;
@@ -3117,7 +3126,7 @@ static void wctdm_vpm150m_init(struct wctdm *wc)
goto failed_exit;
}
- return;
+ return VPMADT032_SUCCESS;
#endif /* VPM150M_SUPPORT */
failed_exit:
@@ -3126,7 +3135,7 @@ failed_exit:
spin_unlock_irqrestore(&wc->reglock, flags);
kfree(vpm150m);
- return;
+ return res;
}
static void wctdm_vpm_set_dtmf_threshold(struct wctdm *wc, unsigned int threshold)
@@ -3277,7 +3286,7 @@ static void wctdm_vpm_init(struct wctdm *wc)
#endif
-static void wctdm_locate_modules(struct wctdm *wc)
+static int wctdm_locate_modules(struct wctdm *wc)
{
int x;
unsigned long flags;
@@ -3393,136 +3402,158 @@ retry:
for (x = NUM_CARDS; x < NUM_CARDS + NUM_EC; x++)
wc->modtype[x] = MOD_TYPE_NONE;
spin_unlock_irqrestore(&wc->reglock, flags);
- wctdm_vpm150m_init(wc);
- if (wc->vpm150m) {
+ switch (wctdm_vpm150m_init(wc)) {
+ case VPMADT032_SUCCESS:
printk("VPMADT032: Present and operational (Firmware version %x)\n", wc->vpm150m->version);
wc->ctlreg |= 0x10;
+ break;
+ case VPMADT032_DISABLED:
+ case VPMADT032_NOT_FOUND:
+ /* nothing */
+ break;
+ default:
+ return -1;
}
}
#endif
+
+ return 0;
}
static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int res;
struct wctdm *wc;
struct wctdm_desc *d = (struct wctdm_desc *)ent->driver_data;
int x;
int y;
- if (pci_enable_device(pdev)) {
- res = -EIO;
- } else {
- wc = kmalloc(sizeof(struct wctdm), GFP_KERNEL);
- if (wc) {
- spin_lock(&ifacelock);
- for (x = 0; x < WC_MAX_IFACES; x++)
- if (!ifaces[x]) break;
-
- ifaces[x] = wc;
- spin_unlock(&ifacelock);
-
- memset(wc, 0, sizeof(struct wctdm));
- spin_lock_init(&wc->reglock);
- wc->curcard = -1;
- wc->cards = NUM_CARDS;
- wc->iobase = pci_resource_start(pdev, 0);
- wc->type = d->ports;
- wc->dev = pdev;
- wc->pos = x;
- wc->variety = d->name;
- for (y=0;y<NUM_CARDS;y++)
- wc->flags[y] = d->flags;
- /* Keep track of whether we need to free the region */
- if (request_region(wc->iobase, 0xff, "wctdm24xxp"))
- wc->freeregion = 1;
-
- /* Allocate enough memory for two zt chunks, receive and transmit. Each sample uses
- 32 bits. Allocate an extra set just for control too */
- wc->writechunk = pci_alloc_consistent(pdev, PCI_WINDOW_SIZE, &wc->writedma);
- if (!wc->writechunk) {
- printk("wctdm: Unable to allocate DMA-able memory\n");
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- return -ENOMEM;
- }
+ if (pci_enable_device(pdev))
+ return -EIO;
- wc->readchunk = wc->writechunk + SFRAME_SIZE / 2; /* in doublewords */
- wc->readdma = wc->writedma + SFRAME_SIZE * 2; /* in bytes */
-
- wc->descripchunk = wc->readchunk + SFRAME_SIZE / 2; /* in doublewords */
- wc->descripdma = wc->readdma + SFRAME_SIZE * 2; /* in bytes */
-
- /* Initialize Write/Buffers to all blank data */
- memset((void *)wc->writechunk,0x00, SFRAME_SIZE * 2);
- memset((void *)wc->readchunk, 0x00, SFRAME_SIZE * 2);
-
- init_waitqueue_head(&wc->regq);
-
- if (wctdm_initialize(wc)) {
- printk("%s: Unable to register span with zaptel\n", wc->variety);
- /* Set Reset Low */
- wctdm_stop_dma(wc);
- /* Free Resources */
- free_irq(pdev->irq, wc);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
- kfree(wc);
- return -EIO;
- }
-
- /* Enable bus mastering */
- pci_set_master(pdev);
-
- /* Keep track of which device we are */
- pci_set_drvdata(pdev, wc);
-
- if (request_irq(pdev->irq, wctdm_interrupt, ZAP_IRQ_SHARED, wc->variety, wc)) {
- printk("wctdm24xxp: Unable to request IRQ %d\n", pdev->irq);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
- kfree(wc);
- return -EIO;
- }
-
-
- if (wctdm_hardware_init(wc)) {
- /* Set Reset Low */
- wctdm_stop_dma(wc);
- /* Free Resources */
- free_irq(pdev->irq, wc);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
- zt_unregister(&wc->span);
- kfree(wc);
- return -EIO;
-
- }
+ if (!(wc = kmalloc(sizeof(struct wctdm), GFP_KERNEL)))
+ return -ENOMEM;
-
- /* Enable interrupts */
- wctdm_enable_interrupts(wc);
-
- /* Start DMA */
- wctdm_start_dma(wc);
-
- /* Now track down what modules are installed */
- wctdm_locate_modules(wc);
-
- /* Final initialization */
- wctdm_post_initialize(wc);
-
- printk("Found a Wildcard TDM: %s (%d modules)\n", wc->variety, wc->type);
- res = 0;
- } else
- res = -ENOMEM;
+ spin_lock(&ifacelock);
+ for (x = 0; x < WC_MAX_IFACES; x++)
+ if (!ifaces[x]) break;
+
+ ifaces[x] = wc;
+ spin_unlock(&ifacelock);
+
+ memset(wc, 0, sizeof(struct wctdm));
+ spin_lock_init(&wc->reglock);
+ wc->curcard = -1;
+ wc->cards = NUM_CARDS;
+ wc->iobase = pci_resource_start(pdev, 0);
+ wc->type = d->ports;
+ wc->dev = pdev;
+ wc->pos = x;
+ wc->variety = d->name;
+ for (y=0;y<NUM_CARDS;y++)
+ wc->flags[y] = d->flags;
+ /* Keep track of whether we need to free the region */
+ if (request_region(wc->iobase, 0xff, "wctdm24xxp"))
+ wc->freeregion = 1;
+
+ /* Allocate enough memory for two zt chunks, receive and transmit. Each sample uses
+ 32 bits. Allocate an extra set just for control too */
+ wc->writechunk = pci_alloc_consistent(pdev, PCI_WINDOW_SIZE, &wc->writedma);
+ if (!wc->writechunk) {
+ printk("wctdm: Unable to allocate DMA-able memory\n");
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ return -ENOMEM;
}
- return res;
+
+ wc->readchunk = wc->writechunk + SFRAME_SIZE / 2; /* in doublewords */
+ wc->readdma = wc->writedma + SFRAME_SIZE * 2; /* in bytes */
+
+ wc->descripchunk = wc->readchunk + SFRAME_SIZE / 2; /* in doublewords */
+ wc->descripdma = wc->readdma + SFRAME_SIZE * 2; /* in bytes */
+
+ /* Initialize Write/Buffers to all blank data */
+ memset((void *)wc->writechunk,0x00, SFRAME_SIZE * 2);
+ memset((void *)wc->readchunk, 0x00, SFRAME_SIZE * 2);
+
+ init_waitqueue_head(&wc->regq);
+
+ if (wctdm_initialize(wc)) {
+ printk("%s: Unable to register span with zaptel\n", wc->variety);
+ /* Set Reset Low */
+ wctdm_stop_dma(wc);
+ /* Free Resources */
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ zt_unregister(&wc->span);
+ kfree(wc);
+ return -EIO;
+ }
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
+
+ /* Keep track of which device we are */
+ pci_set_drvdata(pdev, wc);
+
+ if (request_irq(pdev->irq, wctdm_interrupt, ZAP_IRQ_SHARED, wc->variety, wc)) {
+ printk("wctdm24xxp: Unable to request IRQ %d\n", pdev->irq);
+ /* Set Reset Low */
+ wctdm_stop_dma(wc);
+ /* Free Resources */
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ pci_set_drvdata(pdev, NULL);
+ zt_unregister(&wc->span);
+ kfree(wc);
+ return -EIO;
+ }
+
+
+ if (wctdm_hardware_init(wc)) {
+ /* Set Reset Low */
+ wctdm_stop_dma(wc);
+ /* Free Resources */
+ free_irq(pdev->irq, wc);
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ pci_set_drvdata(pdev, NULL);
+ zt_unregister(&wc->span);
+ kfree(wc);
+ return -EIO;
+
+ }
+
+ /* Enable interrupts */
+ wctdm_enable_interrupts(wc);
+
+ /* Start DMA */
+ wctdm_start_dma(wc);
+
+ /* Now track down what modules are installed */
+ if (wctdm_locate_modules(wc)) {
+ wctdm_disable_interrupts(wc);
+ /* Set Reset Low */
+ wctdm_stop_dma(wc);
+ /* Free Resources */
+ free_irq(pdev->irq, wc);
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ pci_set_drvdata(pdev, NULL);
+ zt_unregister(&wc->span);
+ kfree(wc);
+ return -EIO;
+ }
+
+ /* Final initialization */
+ wctdm_post_initialize(wc);
+
+ printk("Found a Wildcard TDM: %s (%d modules)\n", wc->variety, wc->type);
+
+ return 0;
}
static void wctdm_release(struct wctdm *wc)