Compare commits

...

5 Commits

Author SHA1 Message Date
Shaun Ruffell
1ab5723b85 wcte43x: Remove 'dcxo' debug attribute.
Removes another bit of debugging instrumentation that I let slip through.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2013-11-20 09:39:12 -06:00
Shaun Ruffell
cbad5a7ae1 wcte43x: Do not grab reglock in handle_transmit/handle_receive.
If the driver is loaded with vpmsupport=0, then it was possible to create a
deadlock situation since the call into __dahdi_ec_chunk might then try to grab
the channel lock while already holding the reglock.

The purpose of grabbing reglock in the DMA routines was to protect the channel
array, which can be changed when linemode is changing. So instead, we'll
completely mask off that interrupt line from all CPUs when potentially changing
the channel array.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2013-11-20 09:33:07 -06:00
Shaun RuffellL
b3c6320374 wcaxx: Remove some left over debugging trace statements.
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2013-11-17 02:36:29 -06:00
Shaun Ruffell
69a716af1a wcxb: Update the firmware meta block during flash update.
The meta block contains specific version and checksum information and allows the
test tools to validate the image in the flash.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2013-11-16 16:03:19 -06:00
Shaun Ruffell
eed2e4e00b wcaxx: Update A4B firmware to version 0b0017
Resolves some sporadic issues with invalid underruns.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
2013-11-16 16:02:00 -06:00
4 changed files with 42 additions and 88 deletions

View File

@@ -37,7 +37,7 @@ TE435_VERSION:=d0017
A8A_VERSION:=1d0017
A8B_VERSION:=1d0017
A4A_VERSION:=a0017
A4B_VERSION:=a0017
A4B_VERSION:=b0017
FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases

View File

@@ -1155,9 +1155,6 @@ static int wcaxx_proslic_verify_indirect_regs(struct wcaxx *wc,
if (j < 0) {
dev_notice(&wc->xb.pdev->dev,
"Failed to read indirect register %d\n", i);
#ifdef CONFIG_TRACING
tracing_off();
#endif
return -1;
}
initial = indirect_regs[i].initial;
@@ -1179,14 +1176,8 @@ static int wcaxx_proslic_verify_indirect_regs(struct wcaxx *wc,
} else {
dev_notice(&wc->xb.pdev->dev,
" !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");
#ifdef CONFIG_TRACING
tracing_off();
#endif
return -1;
}
#ifdef CONFIG_TRACING
tracing_off();
#endif
return 0;
}
@@ -2077,9 +2068,6 @@ wcaxx_proslic_insane(struct wcaxx *wc, struct wcaxx_module *const mod)
/* let's be really sure this is an FXS before we continue */
reg1 = wcaxx_getreg(wc, mod, 1);
#ifdef CONFIG_TRACING
trace_printk("reg1 = %02x blah=%02x\n", reg1, blah);
#endif
if ((0x80 != (blah & 0xf0)) || (0x88 != reg1)) {
if (debug & DEBUG_CARD) {
dev_info(&wc->xb.pdev->dev,
@@ -2503,13 +2491,6 @@ wcaxx_init_voicedaa(struct wcaxx *wc, struct wcaxx_module *mod,
unsigned long flags;
unsigned long newjiffies;
#ifdef CONFIG_TRACING
tracing_on();
#endif
#ifdef CONFIG_TRACING
trace_printk("Starting %s\n", __func__);
#endif
/* Send a short write to the device in order to reset the SPI state
* machine. It may be out of sync since the driver was probing for an
* FXS device on that chip select. */
@@ -2519,15 +2500,8 @@ wcaxx_init_voicedaa(struct wcaxx *wc, struct wcaxx_module *mod,
mod->type = FXO;
spin_unlock_irqrestore(&wc->reglock, flags);
if (!sane && wcaxx_voicedaa_insane(wc, mod)) {
#ifdef CONFIG_TRACING
trace_printk("wcaxx_voicedaa_insane failed\n");
#endif
#ifdef CONFIG_TRACING
tracing_off();
#endif
if (!sane && wcaxx_voicedaa_insane(wc, mod))
return -2;
}
/* Software reset */
wcaxx_setreg(wc, mod, 1, 0x80);
@@ -2582,9 +2556,6 @@ wcaxx_init_voicedaa(struct wcaxx *wc, struct wcaxx_module *mod,
if (!(wcaxx_getreg(wc, mod, 11) & 0xf0)) {
dev_notice(&wc->xb.pdev->dev, "VoiceDAA did not bring up ISO link properly!\n");
#ifdef CONFIG_TRACING
tracing_off();
#endif
return -1;
}
@@ -2626,9 +2597,6 @@ wcaxx_init_voicedaa(struct wcaxx *wc, struct wcaxx_module *mod,
-(wcaxx_getreg(wc, mod, 41) - 16) :
wcaxx_getreg(wc, mod, 41));
}
#ifdef CONFIG_TRACING
tracing_off();
#endif
return 0;
}
@@ -3915,7 +3883,7 @@ static int wcaxx_check_firmware(struct wcaxx *wc)
u32 firmware_version;
const bool force_firmware = false;
const unsigned int A4A_VERSION = 0x0a0017;
const unsigned int A4B_VERSION = 0x0a0017;
const unsigned int A4B_VERSION = 0x0b0017;
const unsigned int A8A_VERSION = 0x1d0017;
const unsigned int A8B_VERSION = 0x1d0017;
@@ -4459,10 +4427,6 @@ static int __init wcaxx_init(void)
int res;
int x;
#ifdef CONFIG_TRACING
tracing_off();
#endif
for (x = 0; x < ARRAY_SIZE(fxo_modes); x++) {
if (!strcmp(fxo_modes[x].name, opermode))
break;

View File

@@ -1276,31 +1276,6 @@ static ssize_t t43x_timing_master_show(struct device *dev,
static DEVICE_ATTR(timing_master, 0400, t43x_timing_master_show, NULL);
static ssize_t
dcxo_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct t43x *wc = dev_get_drvdata(dev);
return sprintf(buf, "0x%08x\n", ioread32be(wc->xb.membase + 0x2008));
}
static ssize_t
dcxo_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
struct t43x *wc = dev_get_drvdata(dev);
u32 dcxo_setting;
ret = sscanf(buf, "%x", &dcxo_setting);
iowrite32be(dcxo_setting, wc->xb.membase + 0x2008);
ioread32be(wc->xb.membase + 0x2008);
iowrite32be(dcxo_setting, wc->xb.membase + 0x2008);
ioread32be(wc->xb.membase + 0x2008);
return count;
}
static DEVICE_ATTR(dcxo, 0644, dcxo_show, dcxo_store);
static void create_sysfs_files(struct t43x *wc)
{
int ret;
@@ -1310,19 +1285,11 @@ static void create_sysfs_files(struct t43x *wc)
dev_info(&wc->xb.pdev->dev,
"Failed to create device attributes.\n");
}
dev_warn(&wc->xb.pdev->dev, "WARNING: Creating dcxo file. Do not release like this.\n");
ret = device_create_file(&wc->xb.pdev->dev, &dev_attr_dcxo);
if (ret) {
dev_info(&wc->xb.pdev->dev,
"Failed to create DCXO device attributes.\n");
}
}
static void remove_sysfs_files(struct t43x *wc)
{
device_remove_file(&wc->xb.pdev->dev, &dev_attr_timing_master);
device_remove_file(&wc->xb.pdev->dev, &dev_attr_dcxo);
}
static inline void __t43x_update_timing(struct t43x *wc)
@@ -2454,10 +2421,9 @@ t43x_init_one_span(struct t43x *wc, struct t43x_span *ts, enum linemode type)
goto error_exit;
}
/* Stop the interrupt handler so that we may swap the channel array. */
disable_irq(wc->xb.pdev->irq);
/* Because the interrupt handler is running, we need to atomically
* swap the channel arrays. */
spin_lock_irqsave(&wc->reglock, flags);
for (x = 0; x < ARRAY_SIZE(ts->chans); x++) {
kfree(ts->chans[x]);
@@ -2997,7 +2963,6 @@ static void t43x_handle_receive(struct wcxb *xb, void *vfp)
if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &ts->span.flags))
continue;
spin_lock(&wc->reglock);
for (j = 0; j < DAHDI_CHUNKSIZE; j++) {
for (i = 0; i < ts->span.channels; i++) {
ts->chans[i]->readchunk[j] =
@@ -3012,7 +2977,6 @@ static void t43x_handle_receive(struct wcxb *xb, void *vfp)
c->writechunk);
}
}
spin_unlock(&wc->reglock);
_dahdi_receive(&ts->span);
}
@@ -3034,12 +2998,10 @@ static void t43x_handle_transmit(struct wcxb *xb, void *vfp)
_dahdi_transmit(&ts->span);
spin_lock(&wc->reglock);
for (j = 0; j < DAHDI_CHUNKSIZE; j++)
for (i = 0; i < ts->span.channels; i++)
frame[j*WCXB_DMA_CHAN_SIZE+(s+1+i*4)] =
ts->chans[i]->writechunk[j];
spin_unlock(&wc->reglock);
}
}

View File

@@ -761,6 +761,12 @@ int wcxb_start(struct wcxb *xb)
return 0;
}
struct wcxb_meta_block {
__le32 chksum;
__le32 version;
__le32 size;
} __packed;
struct wcxb_firm_header {
u8 header[6];
__le32 chksum;
@@ -786,32 +792,54 @@ static int wcxb_update_firmware(struct wcxb *xb, const struct firmware *fw,
const char *filename)
{
u32 tdm_control;
int offset = 0x200000;
const u8 *data, *end;
static const int APPLICATION_ADDRESS = 0x200000;
static const int META_BLOCK_OFFSET = 0x170000;
static const int ERASE_BLOCK_SIZE = 0x010000;
static const int END_OFFSET = APPLICATION_ADDRESS + META_BLOCK_OFFSET +
ERASE_BLOCK_SIZE;
struct wcxb_spi_master *flash_spi_master;
struct wcxb_spi_device *flash_spi_device;
struct wcxb_meta_block meta;
int offset;
struct wcxb_firm_header *head = (struct wcxb_firm_header *)(fw->data);
if (fw->size > (META_BLOCK_OFFSET + sizeof(*head))) {
dev_err(&xb->pdev->dev,
"Firmware is too large to fit in available space.\n");
return -EINVAL;
}
meta.size = cpu_to_le32(fw->size);
meta.version = head->version;
meta.chksum = head->chksum;
flash_spi_master = wcxb_spi_master_create(&xb->pdev->dev,
xb->membase + FLASH_SPI_BASE,
false);
flash_spi_device = wcxb_spi_device_create(flash_spi_master, 0);
dev_info(&xb->pdev->dev,
"Uploading %s. This can take up to 30 seconds.\n", filename);
data = &fw->data[sizeof(struct wcxb_firm_header)];
end = &fw->data[fw->size];
while (data < end) {
/* First erase all the blocks in the application area. */
offset = APPLICATION_ADDRESS;
while (offset < END_OFFSET) {
wcxb_flash_sector_erase(flash_spi_device, offset);
data += 0x10000;
offset += 0x10000;
offset += ERASE_BLOCK_SIZE;
}
data = &fw->data[sizeof(struct wcxb_firm_header)];
offset = 0x200000;
/* Then write the new firmware file. */
wcxb_flash_write(flash_spi_device, APPLICATION_ADDRESS,
&fw->data[sizeof(struct wcxb_firm_header)],
fw->size - sizeof(struct wcxb_firm_header));
wcxb_flash_write(flash_spi_device, offset, data, end-data);
/* Finally, update the meta block. */
wcxb_flash_write(flash_spi_device,
APPLICATION_ADDRESS + META_BLOCK_OFFSET,
&meta, sizeof(meta));
/* Reset fpga after loading firmware */
dev_info(&xb->pdev->dev, "Firmware load complete. Reseting device.\n");