[dahdi-commits] dahdi/linux.git branch "master" updated.
SVN commits to the DAHDI project
dahdi-commits at lists.digium.com
Fri Jan 24 15:55:17 CST 2014
branch "master" has been updated
via 3efa9d8cd1f65f1cf524a041cf68a87df44c1080 (commit)
from 4cd09feb54c97148e8792a393396f3fc31744372 (commit)
Summary of changes:
drivers/dahdi/wcaxx-base.c | 2 +-
drivers/dahdi/wcte13xp-base.c | 35 +++++++++++++--------
drivers/dahdi/wcte43x-base.c | 2 +-
drivers/dahdi/wcxb.c | 68 +++++++++++++++++++++++++++++++++--------
drivers/dahdi/wcxb.h | 10 +++++-
5 files changed, 90 insertions(+), 27 deletions(-)
- Log -----------------------------------------------------------------
commit 3efa9d8cd1f65f1cf524a041cf68a87df44c1080
Author: Russ Meyerriecks <rmeyerriecks at digium.com>
Date: Wed Dec 11 16:46:36 2013 -0600
wcte13xp: wcxb: Add delayed reset firmware feature
Allow certain older firmwares to delay the hard reset until a full power cycle.
This way we can "preload" newer firmware images, without requiring the user to
physically power off/on their machine.
Signed-off-by: Russ Meyerriecks <rmeyerriecks at digium.com>
Acked-by: Shaun Ruffell <sruffell at digium.com>
diff --git a/drivers/dahdi/wcaxx-base.c b/drivers/dahdi/wcaxx-base.c
index c17f1bc..d90f014 100644
--- a/drivers/dahdi/wcaxx-base.c
+++ b/drivers/dahdi/wcaxx-base.c
@@ -3909,7 +3909,7 @@ static int wcaxx_check_firmware(struct wcaxx *wc)
}
return wcxb_check_firmware(&wc->xb, firmware_version,
- filename, force_firmware);
+ filename, force_firmware, WCXB_RESET_NOW);
}
static void wcaxx_check_sethook(struct wcaxx *wc, struct wcaxx_module *mod)
diff --git a/drivers/dahdi/wcte13xp-base.c b/drivers/dahdi/wcte13xp-base.c
index 726a63c..5c61309 100644
--- a/drivers/dahdi/wcte13xp-base.c
+++ b/drivers/dahdi/wcte13xp-base.c
@@ -2431,6 +2431,26 @@ error_exit:
return serial;
}
+static int te13xp_check_firmware(struct t13x *wc)
+{
+ const char *filename;
+ enum wcxb_reset_option reset;
+
+ if (is_pcie(wc))
+ filename = TE133_FW_FILENAME;
+ else
+ filename = TE134_FW_FILENAME;
+
+ /* Specific firmware requires power cycle to properly reset */
+ if (0x6f0017 == wcxb_get_firmware_version(&wc->xb))
+ reset = WCXB_RESET_LATER;
+ else
+ reset = WCXB_RESET_NOW;
+
+ return wcxb_check_firmware(&wc->xb, TE13X_FW_VERSION, filename,
+ force_firmware, reset);
+}
+
static int __devinit te13xp_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -2513,18 +2533,9 @@ static int __devinit te13xp_init_one(struct pci_dev *pdev,
if (res)
goto fail_exit;
- /* Check for field updatable firmware */
- if (is_pcie(wc)) {
- res = wcxb_check_firmware(&wc->xb, TE13X_FW_VERSION,
- TE133_FW_FILENAME, force_firmware);
- if (res)
- goto fail_exit;
- } else {
- res = wcxb_check_firmware(&wc->xb, TE13X_FW_VERSION,
- TE134_FW_FILENAME, force_firmware);
- if (res)
- goto fail_exit;
- }
+ res = te13xp_check_firmware(wc);
+ if (res)
+ goto fail_exit;
wc->ddev->hardware_id = t13x_read_serial(wc);
if (!wc->ddev->hardware_id) {
diff --git a/drivers/dahdi/wcte43x-base.c b/drivers/dahdi/wcte43x-base.c
index af7b787..a285fa2 100644
--- a/drivers/dahdi/wcte43x-base.c
+++ b/drivers/dahdi/wcte43x-base.c
@@ -3357,7 +3357,7 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
/* Check for field updatable firmware */
res = wcxb_check_firmware(&wc->xb, TE435_VERSION,
- TE435_FW_FILENAME, force_firmware);
+ TE435_FW_FILENAME, force_firmware, WCXB_RESET_NOW);
if (res)
goto fail_exit;
diff --git a/drivers/dahdi/wcxb.c b/drivers/dahdi/wcxb.c
index 5ae5325..3373723 100644
--- a/drivers/dahdi/wcxb.c
+++ b/drivers/dahdi/wcxb.c
@@ -792,7 +792,7 @@ struct wcxb_firm_header {
__le32 version;
} __packed;
-static u32 wcxb_get_firmware_version(struct wcxb *xb)
+u32 wcxb_get_firmware_version(struct wcxb *xb)
{
u32 version = 0;
@@ -807,7 +807,8 @@ static u32 wcxb_get_firmware_version(struct wcxb *xb)
}
static int wcxb_update_firmware(struct wcxb *xb, const struct firmware *fw,
- const char *filename)
+ const char *filename,
+ enum wcxb_reset_option reset)
{
u32 tdm_control;
static const int APPLICATION_ADDRESS = 0x200000;
@@ -859,14 +860,20 @@ static int wcxb_update_firmware(struct wcxb *xb, const struct firmware *fw,
APPLICATION_ADDRESS + META_BLOCK_OFFSET,
&meta, sizeof(meta));
- /* Reset fpga after loading firmware */
- dev_info(&xb->pdev->dev, "Firmware load complete. Reseting device.\n");
- tdm_control = ioread32be(xb->membase + TDM_CONTROL);
+ if (WCXB_RESET_NOW == reset) {
+ /* Reset fpga after loading firmware */
+ dev_info(&xb->pdev->dev,
+ "Firmware load complete. Reseting device.\n");
+ tdm_control = ioread32be(xb->membase + TDM_CONTROL);
- wcxb_hard_reset(xb);
+ wcxb_hard_reset(xb);
- iowrite32be(0, xb->membase + 0x04);
- iowrite32be(tdm_control, xb->membase + TDM_CONTROL);
+ iowrite32be(0, xb->membase + 0x04);
+ iowrite32be(tdm_control, xb->membase + TDM_CONTROL);
+ } else {
+ dev_info(&xb->pdev->dev,
+ "Delaying reset. Firmware load requires a power cycle\n");
+ }
wcxb_spi_device_destroy(flash_spi_device);
wcxb_spi_master_destroy(flash_spi_master);
@@ -874,10 +881,16 @@ static int wcxb_update_firmware(struct wcxb *xb, const struct firmware *fw,
}
int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
- const char *firmware_filename, bool force_firmware)
+ const char *firmware_filename, bool force_firmware,
+ enum wcxb_reset_option reset)
{
const struct firmware *fw;
const struct wcxb_firm_header *header;
+ static const int APPLICATION_ADDRESS = 0x200000;
+ static const int META_BLOCK_OFFSET = 0x170000;
+ struct wcxb_spi_master *flash_spi_master;
+ struct wcxb_spi_device *flash_spi_device;
+ struct wcxb_meta_block meta;
int res = 0;
u32 crc;
u32 version = 0;
@@ -896,6 +909,27 @@ int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
return 0;
}
+ /* Check meta firmware version for a not-booted application image */
+ 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);
+ res = wcxb_flash_read(flash_spi_device,
+ APPLICATION_ADDRESS + META_BLOCK_OFFSET,
+ &meta, sizeof(meta));
+ if (res) {
+ dev_info(&xb->pdev->dev, "Unable to read flash\n");
+ return -EIO;
+ }
+
+ if ((meta.version == cpu_to_le32(expected_version))
+ && !force_firmware) {
+ dev_info(&xb->pdev->dev,
+ "Detected previous firmware updated to current version %x, but not running. You likely need to power cycle your system.\n",
+ expected_version);
+ return 0;
+ }
+
if (force_firmware) {
dev_info(&xb->pdev->dev,
"force_firmware module parameter is set. Forcing firmware load, regardless of version\n");
@@ -938,12 +972,22 @@ int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
dev_info(&xb->pdev->dev, "Found %s (version: %x) Preparing for flash\n",
firmware_filename, header->version);
- res = wcxb_update_firmware(xb, fw, firmware_filename);
+ res = wcxb_update_firmware(xb, fw, firmware_filename, reset);
version = wcxb_get_firmware_version(xb);
- dev_info(&xb->pdev->dev, "Reset into firmware version: %x\n", version);
+ if (WCXB_RESET_NOW == reset) {
+ dev_info(&xb->pdev->dev,
+ "Reset into firmware version: %x\n", version);
+ } else {
+ dev_info(&xb->pdev->dev,
+ "Running firmware version: %x\n", version);
+ dev_info(&xb->pdev->dev,
+ "Loaded firmware version: %x (Will load after next power cycle)\n",
+ header->version);
+ }
- if ((expected_version != version) && !force_firmware) {
+ if ((WCXB_RESET_NOW == reset) && (expected_version != version)
+ && !force_firmware) {
/* On the off chance that the interface is in a state where it
* cannot boot into the updated firmware image, power cycling
* the card can recover. A simple "reset" of the computer is not
diff --git a/drivers/dahdi/wcxb.h b/drivers/dahdi/wcxb.h
index 268e6c2..af7828b 100644
--- a/drivers/dahdi/wcxb.h
+++ b/drivers/dahdi/wcxb.h
@@ -105,9 +105,17 @@ static inline void wcxb_disable_timing_header_driver(struct wcxb *xb)
xb->flags.drive_timing_cable = 0;
}
+enum wcxb_reset_option {
+ WCXB_RESET_NOW,
+ WCXB_RESET_LATER
+};
+
+extern u32 wcxb_get_firmware_version(struct wcxb *xb);
extern int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
const char *firmware_filename,
- bool force_firmware);
+ bool force_firmware,
+ enum wcxb_reset_option reset);
+
extern void wcxb_stop_dma(struct wcxb *xb);
extern void wcxb_disable_interrupts(struct wcxb *xb);
-----------------------------------------------------------------------
--
dahdi/linux.git
More information about the dahdi-commits
mailing list