Not a linking problem. Rather an issue with not having CONFIG_FW_MODULE set. So there is no firmware loading support from kernel. Even if we compile the module as loadable, we can not modify the files which are required to make it run (e.g. under /etc/... ).jogi10 wrote:here we are again![]()
# insmod /dtv/usb/sda1/acx.ko
insmod: cannot insert `/dtv/usb/sda1/acx.ko': Unknown symbol in module (-1): No such file or directory
seems to be a linking problem
For that reason I added old code for loading firmware in legacy mode. This patch needs to be applied:
Code: Select all
diff -Nur acx.org//acx_func.h acx//acx_func.h
--- acx.org//acx_func.h 2008-02-10 21:06:42.000000000 +0100
+++ acx//acx_func.h 2010-08-03 18:23:32.000000000 +0200
@@ -503,7 +503,11 @@
/***********************************************************************
*/
+#ifdef USE_FW_LOADER_LEGACY
+firmware_image_t *acx_s_read_fw(const char *file, u32 *size);
+#else
firmware_image_t *acx_s_read_fw(struct device *dev, const char *file, u32 *size);
+#endif
int acxpci_s_upload_radio(acx_device_t *adev);
diff -Nur acx.org//acx_struct.h acx//acx_struct.h
--- acx.org//acx_struct.h 2008-02-10 21:06:42.000000000 +0100
+++ acx//acx_struct.h 2010-08-03 17:37:30.000000000 +0200
@@ -1608,6 +1608,17 @@
#include <linux/firmware.h> /* request_firmware() */
#include <linux/pci.h> /* struct pci_device */
+#define USE_FW_LOADER_LEGACY 1
+
+#ifdef USE_FW_LOADER_26
+#include <linux/firmware.h> /* request_firmware() */
+#include <linux/pci.h> /* struct pci_device */
+#endif
+
+#ifdef USE_FW_LOADER_LEGACY
+extern char *firmware_dir;
+#endif
+
/***********************************************************************
*/
diff -Nur acx.org//common.c acx//common.c
--- acx.org//common.c 2008-02-10 21:06:42.000000000 +0100
+++ acx//common.c 2010-08-03 20:24:14.000000000 +0200
@@ -96,6 +96,10 @@
MODULE_AUTHOR("ACX100 Open Source Driver development team");
MODULE_DESCRIPTION("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)");
+#ifdef USE_FW_LOADER_LEGACY
+module_param(firmware_dir, charp, 0);
+MODULE_PARM_DESC(firmware_dir, "Directory to load acx100 firmware files from");
+#endif
/***********************************************************************
*/
@@ -131,7 +135,9 @@
NULL /* needs to remain as last entry */
};
-
+#ifdef USE_FW_LOADER_LEGACY
+char *firmware_dir;
+#endif
/***********************************************************************
** Debugging support
@@ -5480,10 +5486,149 @@
** 0 unable to load file
** pointer to firmware success
*/
+#ifdef USE_FW_LOADER_LEGACY
+static char * const default_firmware_dir = "/dtv/usb/sda1";
+#endif
+
firmware_image_t*
+#ifdef USE_FW_LOADER_LEGACY
+acx_s_read_fw(const char *file, u32 *size)
+#else
acx_s_read_fw(struct device *dev, const char *file, u32 *size)
+#endif
{
firmware_image_t *res;
+
+#ifdef USE_FW_LOADER_LEGACY
+ mm_segment_t orgfs;
+ unsigned long page;
+ char *buffer;
+ struct file *inf;
+ int retval;
+ u32 offset = 0;
+ char *filename;
+
+ res = NULL;
+
+ orgfs = get_fs(); /* store original fs */
+ set_fs(KERNEL_DS);
+
+ /* Read in whole file then check the size */
+ page = __get_free_page(GFP_KERNEL);
+ if (unlikely(0 == page)) {
+ printk("Unable to allocate memory for firmware loading\n");
+ goto fail;
+ }
+
+ filename = kmalloc(PATH_MAX, GFP_KERNEL);
+ if (unlikely(!filename)) {
+ printk("Unable to allocate memory for firmware loading\n");
+ goto fail;
+ }
+ if (!firmware_dir) {
+ firmware_dir = default_firmware_dir;
+ printk("Attention: no firmware directory specified "
+ "via module parameter firmware_dir, using default "
+ "firmware directory %s\n", firmware_dir);
+ }
+ sprintf(filename,"%s/%s", firmware_dir, file);
+ printk("Reading firmware image '%s'\n", filename);
+
+ buffer = (char*)page;
+
+ /* Note that file must be given as absolute path:
+ * a relative path works on first loading,
+ * but any subsequent firmware loading during card
+ * eject/insert will fail, most likely since the first
+ * module loading happens in user space (and thus
+ * filp_open can figure out the absolute path from a
+ * relative path) whereas the card reinsert processing
+ * probably happens in kernel space where you don't have
+ * a current directory to be able to figure out an
+ * absolute path from a relative path... */
+ inf = filp_open(filename, O_RDONLY, 0);
+ kfree(filename);
+ if (OK != IS_ERR(inf)) {
+ const char *err;
+
+ switch(-PTR_ERR(inf)) {
+ case 2: err = "file not found - make sure this EXACT filename is in eXaCtLy this directory!";
+ break;
+ default:
+ err = "unknown error";
+ break;
+ }
+ printk("ERROR %ld trying to open firmware image file '%s': %s\n", -PTR_ERR(inf), file, err);
+ goto fail;
+ }
+
+ if (unlikely((NULL == inf->f_op) || (NULL == inf->f_op->read))) {
+ printk("ERROR: %s does not have a read method\n", file);
+ goto fail_close;
+ }
+
+ offset = 0;
+ do {
+ retval = inf->f_op->read(inf, buffer, PAGE_SIZE, &inf->f_pos);
+
+ if (unlikely(0 > retval)) {
+ printk("ERROR %d reading firmware image file '%s'.\n", -retval, file);
+ if (NULL != res)
+ vfree(res);
+ res = NULL;
+ } else if (0 == retval) {
+ if (0 == offset) {
+ printk("ERROR: firmware image file '%s' is empty.\n", file);
+ }
+ } else if (0 < retval) {
+ /* allocate result buffer here if needed,
+ * since we don't want to waste resources/time
+ * (in case file opening/reading fails)
+ * by doing allocation in front of the loop instead. */
+ if (NULL == res) {
+ *size = 8 + le32_to_cpu(*(u32 *)(4 + buffer));
+
+ res = vmalloc(*size);
+ if (NULL == res) {
+ printk("ERROR: Unable to allocate %u bytes for firmware module loading.\n", *size);
+ goto fail_close;
+ }
+ printk("Allocated %u bytes for firmware module loading.\n", *size);
+ }
+ if ((unlikely(offset + retval > *size)))
+ {
+ printk("ERROR: allocation was less than firmware image size!\n");
+ goto fail_close;
+ }
+ memcpy((u8*)res + offset, buffer, retval);
+ offset += retval;
+ }
+ } while (0 < retval);
+
+fail_close:
+ retval = filp_close(inf, NULL);
+
+ if (unlikely(retval)) {
+ printk("ERROR %d closing %s\n", -retval, file);
+ }
+
+ if (unlikely((NULL != res) && (offset != le32_to_cpu(res->size) + 8))) {
+ printk("Firmware is reporting a different size (0x%08x; 0x%08x was read)\n", le32_to_cpu(res->size) + 8, offset);
+ vfree(res);
+ res = NULL;
+ }
+
+fail:
+ if (page)
+ free_page(page);
+ set_fs(orgfs);
+
+/* ret: */
+ /* checksum will be verified in write_fw, so don't bother here */
+
+ return res;
+
+#else
const struct firmware *fw_entry;
res = NULL;
@@ -5515,6 +5660,7 @@
/* checksum will be verified in write_fw, so don't bother here */
return res;
+#endif
}
diff -Nur acx.org//pci.c acx//pci.c
--- acx.org//pci.c 2008-02-10 21:06:42.000000000 +0100
+++ acx//pci.c 2010-08-03 20:05:44.000000000 +0200
@@ -630,11 +630,19 @@
snprintf(filename, sizeof(filename), "tiacx1%02dc%02X",
IS_ACX111(adev)*11, adev->radio_type);
+#ifdef USE_FW_LOADER_LEGACY
+ fw_image = acx_s_read_fw(filename, &file_size);
+#else
fw_image = acx_s_read_fw(adev->bus_dev, filename, &file_size);
+#endif
if (!fw_image) {
adev->need_radio_fw = 1;
filename[sizeof("tiacx1NN")-1] = '\0';
+#ifdef USE_FW_LOADER_LEGACY
+ fw_image = acx_s_read_fw(filename, &file_size);
+#else
fw_image = acx_s_read_fw(adev->bus_dev, filename, &file_size);
+#endif
if (!fw_image) {
FN_EXIT1(NOT_OK);
return NOT_OK;
@@ -692,7 +700,11 @@
snprintf(filename, sizeof(filename), "tiacx1%02dr%02X",
IS_ACX111(adev)*11,
adev->radio_type);
+#ifdef USE_FW_LOADER_LEGACY
+ radio_image = acx_s_read_fw(filename, &size);
+#else
radio_image = acx_s_read_fw(adev->bus_dev, filename, &size);
+#endif
if (!radio_image) {
printk("acx: can't load radio module '%s'\n", filename);
goto fail;
diff -Nur acx.org//usb.c acx//usb.c
--- acx.org//usb.c 2008-02-10 21:06:42.000000000 +0100
+++ acx//usb.c 2010-08-03 17:53:48.000000000 +0200
@@ -538,7 +538,11 @@
snprintf(filename, sizeof(filename), "tiacx1%02dusbc%02X",
is_tnetw1450 * 11, *radio_type);
+#ifdef USE_FW_LOADER_LEGACY
+ fw_image = acx_s_read_fw(filename, &file_size);
+#else
fw_image = acx_s_read_fw(&usbdev->dev, filename, &file_size);
+#endif
if (!fw_image) {
result = -EIO;
goto end;