diff options
author | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-12-11 17:27:00 +0000 |
---|---|---|
committer | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-12-11 17:27:00 +0000 |
commit | 2bbac8cb8328db3523aae6f4d9cdd67eb04b4390 (patch) | |
tree | d129e5ecbe1c67c11f0cfeeca14f56e2a8c08cde /wctdm24xxp | |
parent | c78bbae434262fe225b6f100ecbff3cc5dc67532 (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.c | 271 |
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) |