From 8b55e255fe5c5539d5550d0ebf2624e44275b6ae Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Mon, 2 Apr 2012 14:05:17 +0000 Subject: wctdm24xxp, wcte12xp: Allow VPMOCT032 firmware to be compiled into driver. Enables the driver to update firmware on systems that do not have the firmware loader configured / enabled (Linux config option CONFIG_FW_LOADER). Compiling the firmware into the driver increase the memory footprint by around ~440K. Internal-Issue-ID: DAHDI-963 Reported-and-Tested-by: Guenther Kelleter Signed-off-by: Shaun Ruffell Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10618 git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10620 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/firmware/Makefile | 6 +++++ drivers/dahdi/voicebus/Kbuild | 14 ++++++++++- drivers/dahdi/voicebus/vpmoct.c | 52 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/drivers/dahdi/firmware/Makefile b/drivers/dahdi/firmware/Makefile index 5b1bd4b..e9ba388 100644 --- a/drivers/dahdi/firmware/Makefile +++ b/drivers/dahdi/firmware/Makefile @@ -58,6 +58,7 @@ OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128.o) OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-256=dahdi-fw-oct6114-256.o) OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-TC400M=dahdi-fw-tc400m.o) OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-HX8=dahdi-fw-hx8.o) +OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-VPMOCT032=dahdi-fw-vpmoct032.o) # Force usage of wget, for now DOWNLOAD=wget @@ -220,3 +221,8 @@ dahdi-fw-oct6114-256.o: dahdi-fw-oct6114-256-$(OCT6114_256_VERSION).tar.gz dahdi dahdi-fw-tc400m.o: dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz dahdi-fw-tc400m.bin make_firmware_object @echo Making firmware object file for dahdi-fw-tc400m.bin ./make_firmware_object dahdi-fw-tc400m.bin $@ + +# Build object file of a VPMOCT032 firmware image for linking +dahdi-fw-vpmoct032.o: dahdi-fw-vpmoct032-$(VPMOCT032_VERSION).tar.gz dahdi-fw-vpmoct032.bin make_firmware_object + @echo Making firmware object file for dahdi-fw-vpmoct032.bin + ./make_firmware_object dahdi-fw-vpmoct032.bin $@ diff --git a/drivers/dahdi/voicebus/Kbuild b/drivers/dahdi/voicebus/Kbuild index b8b23ff..6266653 100644 --- a/drivers/dahdi/voicebus/Kbuild +++ b/drivers/dahdi/voicebus/Kbuild @@ -2,4 +2,16 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += dahdi_voicebus.o dahdi_voicebus-objs := voicebus.o GpakCust.o GpakApi.o voicebus_net.o vpmoct.o -EXTRA_CFLAGS := -I$(src)/.. -Wno-undef +FIRM_DIR := ../firmware + +ifneq ($(HOTPLUG_FIRMWARE),yes) +dahdi_voicebus-objs += $(FIRM_DIR)/dahdi-fw-vpmoct032.o +else + EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE +endif + +EXTRA_CFLAGS += -I$(src)/.. -Wno-undef + +$(obj)/$(FIRM_DIR)/dahdi-fw-vpmoct032.o: $(obj)/voicebus.o + $(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-vpmoct032.o + diff --git a/drivers/dahdi/voicebus/vpmoct.c b/drivers/dahdi/voicebus/vpmoct.c index 3280e69..1cb2193 100644 --- a/drivers/dahdi/voicebus/vpmoct.c +++ b/drivers/dahdi/voicebus/vpmoct.c @@ -443,6 +443,47 @@ static void vpmoct_set_defaults(struct vpmoct *vpm) vpmoct_write_dword(vpm, 0x30, 0); } +static const char *const FIRMWARE_NAME = "dahdi-fw-vpmoct032.bin"; +#if defined(HOTPLUG_FIRMWARE) +static int +vpmoct_request_firmware(const struct firmware **fw, struct device *dev) +{ + return request_firmware(fw, FIRMWARE_NAME, dev); +} + +static void vpmoct_release_firmware(const struct firmware *fw) +{ + release_firmware(fw); +} +#else +static int +vpmoct_request_firmware(const struct firmware **fw_p, struct device *dev) +{ + struct firmware *fw; + extern void _binary_dahdi_fw_vpmoct032_bin_size; + extern u8 _binary_dahdi_fw_vpmoct032_bin_start[]; + + *fw_p = fw = kzalloc(sizeof(*fw), GFP_KERNEL); + if (!fw) + return -ENOMEM; + + fw->data = _binary_dahdi_fw_vpmoct032_bin_start; + /* Yes... this is weird. objcopy gives us a symbol containing + the size of the firmware, not a pointer a variable containing the + size. The only way we can get the value of the symbol is to take + its address, so we define it as a pointer and then cast that value + to the proper type. */ + fw->size = (size_t) &_binary_dahdi_fw_vpmoct032_bin_size; + + return 0; +} + +static void vpmoct_release_firmware(const struct firmware *fw) +{ + kfree(fw); +} +#endif + /** * vpmoct_load_flash - Check the current flash version and possibly load. * @vpm: The VPMOCT032 module to check / load. @@ -463,10 +504,9 @@ static void vpmoct_load_flash(struct work_struct *data) const struct firmware *fw; const struct vpmoct_header *header; char serial[VPMOCT_SERIAL_SIZE+1]; - const char *const FIRMWARE_NAME = "dahdi-fw-vpmoct032.bin"; int i; - res = request_firmware(&fw, FIRMWARE_NAME, vpm->dev); + res = vpmoct_request_firmware(&fw, vpm->dev); if (res) { dev_warn(vpm->dev, "vpmoct: Failed to load firmware from userspace! %d\n", @@ -505,7 +545,7 @@ static void vpmoct_load_flash(struct work_struct *data) FIRMWARE_NAME); /* Just use the old version of the fimware. */ - release_firmware(fw); + vpmoct_release_firmware(fw); vpmoct_set_defaults(vpm); vpmoct_load_complete(work, true); return; @@ -514,7 +554,7 @@ static void vpmoct_load_flash(struct work_struct *data) if (vpm->minor == header->minor && vpm->major == header->major) { /* Proper version is running */ - release_firmware(fw); + vpmoct_release_firmware(fw); vpmoct_set_defaults(vpm); vpmoct_load_complete(work, true); return; @@ -548,14 +588,14 @@ static void vpmoct_load_flash(struct work_struct *data) if (vpmoct_check_firmware_crc(vpm, fw->size-VPMOCT_FIRM_HEADER_LEN*2, header->major, header->minor)) goto error; - release_firmware(fw); + vpmoct_release_firmware(fw); vpmoct_set_defaults(vpm); vpmoct_load_complete(work, true); return; error: dev_info(vpm->dev, "Unable to load firmware\n"); - release_firmware(fw); + vpmoct_release_firmware(fw); /* TODO: Should we disable module if the firmware doesn't load? */ vpmoct_load_complete(work, false); return; -- cgit v1.2.3