Second attempt, now in the git tree at git.infradead.org/users/dwmw2/firmware-2.6.git At Alan's suggestion, start by making fw->data const so that we can avoid the extra vmalloc+copy when we find it built-in. Mostly straightforward, but could do with an extra pair of eyes and some testing for the cxusb, myri10ge, cx25840 and or51211 changes. Also switch to using a .S file for the included firmware, which means we can use .incbin instead of including the whole thing in hex form in a C file. And fix up the case where there were no built-in firmware -- dwmw2 --
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
sound/pci/vx222/vx222_ops.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index b4bfc1a..631f3a6 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -359,7 +359,7 @@ static int vx2_load_xilinx_binary(struct vx_core *chip, const struct firmware *x
{
unsigned int i;
unsigned int port;
- unsigned char *image;
+ const unsigned char *image;
/* XILINX reset (wait at least 1 milisecond between reset on and off). */
vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/bluetooth/bfusb.c | 3 ++-
drivers/bluetooth/bt3c_cs.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index b990805..0c211ad 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -566,7 +566,8 @@ static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg
return -ENOIOCTLCMD;
}
-static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, int count)
+static int bfusb_load_firmware(struct bfusb_data *data,
+ const unsigned char *firmware, int count)
{
unsigned char *buf;
int err, pipe, len, size, sent = 0;
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 7703d6e..593b7c5 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -470,7 +470,8 @@ static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long
/* ======================== Card services HCI interaction ======================== */
-static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count)
+static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware,
+ int count)
{
char *ptr = (char *) firmware;
char b[9];
--
1.5.4.5
--
On Sun, 25 May 2008 11:23:31 +0100 Acked-by: Alan Cox <alan@redhat.com> --
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
sound/pci/riptide/riptide.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 979f7da..6a35962 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -682,7 +682,7 @@ static union firmware_version firmware_versions[] = {
},
};
-static u32 atoh(unsigned char *in, unsigned int len)
+static u32 atoh(const unsigned char *in, unsigned int len)
{
u32 sum = 0;
unsigned int mult = 1;
@@ -702,12 +702,12 @@ static u32 atoh(unsigned char *in, unsigned int len)
return sum;
}
-static int senddata(struct cmdif *cif, unsigned char *in, u32 offset)
+static int senddata(struct cmdif *cif, const unsigned char *in, u32 offset)
{
u32 addr;
u32 data;
u32 i;
- unsigned char *p;
+ const unsigned char *p;
i = atoh(&in[1], 2);
addr = offset + atoh(&in[3], 4);
@@ -726,10 +726,10 @@ static int senddata(struct cmdif *cif, unsigned char *in, u32 offset)
return 0;
}
-static int loadfirmware(struct cmdif *cif, unsigned char *img,
+static int loadfirmware(struct cmdif *cif, const unsigned char *img,
unsigned int size)
{
- unsigned char *in;
+ const unsigned char *in;
u32 laddr, saddr, t, val;
int err = 0;
--
1.5.4.5
--
... which means allocating our own buffer for reading it back.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/myri10ge/myri10ge.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index c91b12e..ab7a80b 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -529,6 +529,7 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size)
unsigned crc, reread_crc;
const struct firmware *fw;
struct device *dev = &mgp->pdev->dev;
+ unsigned char *fw_readback;
struct mcp_gen_header *hdr;
size_t hdr_offset;
int status;
@@ -571,9 +572,15 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size)
mb();
readb(mgp->sram);
}
+ fw_readback = vmalloc(fw->size);
+ if (!fw_readback) {
+ status = -ENOMEM;
+ goto abort_with_fw;
+ }
/* corruption checking is good for parity recovery and buggy chipset */
- memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size);
- reread_crc = crc32(~0, fw->data, fw->size);
+ memcpy_fromio(fw_readback, mgp->sram + MYRI10GE_FW_OFFSET, fw->size);
+ reread_crc = crc32(~0, fw_readback, fw->size);
+ vfree(fw_readback);
if (crc != reread_crc) {
dev_err(dev, "CRC failed(fw-len=%u), got 0x%x (expect 0x%x)\n",
(unsigned)fw->size, reread_crc, crc);
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- sound/pci/pcxhr/pcxhr_core.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 78aa81f..957e6af 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -269,7 +269,7 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin unsigned int chipsc; unsigned char data; unsigned char mask; - unsigned char *image; + const unsigned char *image; /* test first xilinx */ chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC); @@ -316,7 +316,7 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp) int err; unsigned int i; unsigned int len; - unsigned char *data; + const unsigned char *data; unsigned char dummy; /* check the length of boot image */ snd_assert(dsp->size > 0, return -EINVAL); -- 1.5.4.5 --
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/wireless/zd1201.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index d5c0c66..78baa0f 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -49,7 +49,7 @@ MODULE_DEVICE_TABLE(usb, zd1201_table);
static int zd1201_fw_upload(struct usb_device *dev, int apfw)
{
const struct firmware *fw_entry;
- char *data;
+ const char *data;
unsigned long len;
int err;
unsigned char ret;
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/usb/atm/ueagle-atm.c | 20 +++++++++++---------
1 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 5f71ff3..cb01b51 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -579,7 +579,7 @@ MODULE_PARM_DESC(annex,
* uea_send_modem_cmd - Send a command for pre-firmware devices.
*/
static int uea_send_modem_cmd(struct usb_device *usb,
- u16 addr, u16 size, u8 * buff)
+ u16 addr, u16 size, const u8 *buff)
{
int ret = -ENOMEM;
u8 *xfer_buff;
@@ -604,7 +604,8 @@ static int uea_send_modem_cmd(struct usb_device *usb,
static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context)
{
struct usb_device *usb = context;
- u8 *pfw, value;
+ const u8 *pfw;
+ u8 value;
u32 crc = 0;
int ret, size;
@@ -720,7 +721,7 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
/*
* Make sure that the DSP code provided is safe to use.
*/
-static int check_dsp_e1(u8 *dsp, unsigned int len)
+static int check_dsp_e1(const u8 *dsp, unsigned int len)
{
u8 pagecount, blockcount;
u16 blocksize;
@@ -771,7 +772,7 @@ static int check_dsp_e1(u8 *dsp, unsigned int len)
return 0;
}
-static int check_dsp_e4(u8 *dsp, int len)
+static int check_dsp_e4(const u8 *dsp, int len)
{
int i;
struct l1_code *p = (struct l1_code *) dsp;
@@ -819,7 +820,7 @@ static int check_dsp_e4(u8 *dsp, int len)
/*
* send data to the idma pipe
* */
-static int uea_idma_write(struct uea_softc *sc, void *data, u32 size)
+static int uea_idma_write(struct uea_softc *sc, const void *data, u32 size)
{
int ret = -ENOMEM;
u8 *xfer_buff;
@@ -903,7 +904,7 @@ static void uea_load_page_e1(struct work_struct *work)
u16 ovl = sc->ovl;
struct block_info_e1 bi;
- u8 *p;
+ const u8 *p;
u8 pagecount, blockcount;
u16 blockaddr, blocksize;
u32 ...Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/scsi/aic94xx/aic94xx_sds.c | 12 ++++++------
drivers/scsi/aic94xx/aic94xx_sds.h | 4 ++--
drivers/scsi/aic94xx/aic94xx_seq.c | 7 ++++---
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index 4446e3d..8630a75 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -1093,9 +1093,9 @@ out:
* @bytes_to_verify: total bytes to verify
*/
int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_verify)
+ const void *src, u32 dest_offset, u32 bytes_to_verify)
{
- u8 *src_buf;
+ const u8 *src_buf;
u8 flash_char;
int err;
u32 nv_offset, reg, i;
@@ -1105,7 +1105,7 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
err = FLASH_OK;
nv_offset = dest_offset;
- src_buf = (u8 *)src;
+ src_buf = (const u8 *)src;
for (i = 0; i < bytes_to_verify; i++) {
flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i);
if (flash_char != src_buf[i]) {
@@ -1124,9 +1124,9 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
* @bytes_to_write: total bytes to write
*/
int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
- void *src, u32 dest_offset, u32 bytes_to_write)
+ const void *src, u32 dest_offset, u32 bytes_to_write)
{
- u8 *src_buf;
+ const u8 *src_buf;
u32 nv_offset, reg, i;
int err;
@@ -1153,7 +1153,7 @@ int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
return err;
}
- src_buf = (u8 *)src;
+ src_buf = (const u8 *)src;
for (i = 0; i < bytes_to_write; i++) {
/* Setup program command sequence */
switch (asd_ha->hw_prof.flash.method) {
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.h b/drivers/scsi/aic94xx/aic94xx_sds.h
index bb9795a..a06dc01 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.h
+++ b/drivers/scsi/aic94xx/aic94xx_sds.h
@@ -110,9 +110,9 @@ struct ...Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/wireless/atmel.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 438e63e..d1acef7 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -560,7 +560,7 @@ static const struct {
static void build_wpa_mib(struct atmel_private *priv);
static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static void atmel_copy_to_card(struct net_device *dev, u16 dest,
- unsigned char *src, u16 len);
+ const unsigned char *src, u16 len);
static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
u16 src, u16 len);
static void atmel_set_gcr(struct net_device *dev, u16 mask);
@@ -3853,7 +3853,7 @@ static int reset_atmel_card(struct net_device *dev)
if (priv->card_type == CARD_TYPE_EEPROM) {
/* copy in firmware if needed */
const struct firmware *fw_entry = NULL;
- unsigned char *fw;
+ const unsigned char *fw;
int len = priv->firmware_length;
if (!(fw = priv->firmware)) {
if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
@@ -4120,7 +4120,7 @@ static void atmel_writeAR(struct net_device *dev, u16 data)
}
static void atmel_copy_to_card(struct net_device *dev, u16 dest,
- unsigned char *src, u16 len)
+ const unsigned char *src, u16 len)
{
int i;
atmel_writeAR(dev, dest);
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/media/dvb/dvb-usb/gp8psk.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
index 9a942af..85836da 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -86,7 +86,8 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
{
int ret;
const struct firmware *fw = NULL;
- u8 *ptr, *buf;
+ const u8 *ptr;
+ u8 *buf;
if ((ret = request_firmware(&fw, bcm4500_firmware,
&d->udev->dev)) != 0) {
err("did not find the bcm4500 firmware file. (%s) "
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/media/common/tuners/tuner-xc2028.c | 2 +-
drivers/media/common/tuners/xc5000.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 9e9003c..0a6e26a 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -255,7 +255,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
{
struct xc2028_data *priv = fe->tuner_priv;
const struct firmware *fw = NULL;
- unsigned char *p, *endp;
+ const unsigned char *p, *endp;
int rc = 0;
int n, n_array;
char name[33];
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index ceae6db..d21a5a7 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -277,7 +277,7 @@ static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData)
return result;
}
-static int xc_load_i2c_sequence(struct dvb_frontend *fe, u8 i2c_sequence[])
+static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
{
struct xc5000_priv *priv = fe->tuner_priv;
--
1.5.4.5
--
...which means allocating our own copy when we want to modify it.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/media/dvb/dvb-usb/cxusb.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 720fcd1..94bb482 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -24,6 +24,7 @@
* see Documentation/dvb/README.dvb-usb for more information
*/
#include <media/tuner.h>
+#include <linux/vmalloc.h>
#include "cxusb.h"
@@ -700,12 +701,26 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
- fw->data[idoff + 2] =
+ struct firmware new_fw;
+ u8 *new_fw_data = vmalloc(fw->size);
+ int ret;
+
+ if (!new_fw_data)
+ return -ENOMEM;
+
+ memcpy(new_fw_data, fw->data, fw->size);
+ new_fw.size = fw->size;
+ new_fw.data = fw->data;
+
+ new_fw_data[idoff + 2] =
le16_to_cpu(udev->descriptor.idProduct) + 1;
- fw->data[idoff + 3] =
+ new_fw_data[idoff + 3] =
le16_to_cpu(udev->descriptor.idProduct) >> 8;
- return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2);
+ ret = usb_cypress_load_firmware(udev, &new_fw,
+ CYPRESS_FX2);
+ vfree(new_fw_data);
+ return ret;
}
}
--
1.5.4.5
--
David, It's broken... Please see fix, below: The unmodified firmware was being uploaded to the device, instead of the patched firmware :-( After making this additional one-line change, the patch works fine. Please feel free to fold this into your own patch. Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> --- linux/drivers/media/dvb/dvb-usb/cxusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -710,7 +710,7 @@ memcpy(new_fw_data, fw->data, fw->size); new_fw.size = fw->size; - new_fw.data = fw->data; + new_fw.data = new_fw_data; new_fw_data[idoff + 2] = le16_to_cpu(udev->descriptor.idProduct) + 1; --
commit e6983a70abb3e6d7a0d711176c89113c81f2ead6
Author: David Woodhouse <dwmw2@infradead.org>
Date: Sat May 24 00:12:42 2008 +0100
cxusb: treat firmware data as const
...which means allocating our own copy when we want to modify it.
(stupid thinko fixed by mkrufky)
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 720fcd1..0286156 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -24,6 +24,7 @@
* see Documentation/dvb/README.dvb-usb for more information
*/
#include <media/tuner.h>
+#include <linux/vmalloc.h>
#include "cxusb.h"
@@ -700,12 +701,26 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
- fw->data[idoff + 2] =
+ struct firmware new_fw;
+ u8 *new_fw_data = vmalloc(fw->size);
+ int ret;
+
+ if (!new_fw_data)
+ return -ENOMEM;
+
+ memcpy(new_fw_data, fw->data, fw->size);
+ new_fw.size = fw->size;
+ new_fw.data = new_fw_data;
+
+ new_fw_data[idoff + 2] =
le16_to_cpu(udev->descriptor.idProduct) + 1;
- fw->data[idoff + 3] =
+ new_fw_data[idoff + 3] =
le16_to_cpu(udev->descriptor.idProduct) >> 8;
- return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2);
+ ret = usb_cypress_load_firmware(udev, &new_fw,
+ CYPRESS_FX2);
+ vfree(new_fw_data);
+ return ret;
}
}
--
dwmw2
--
This allows arbitrary firmware files to be included in the static kernel where the firmware loader can find them without requiring userspace to be alive. Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- Makefile | 2 +- drivers/base/Kconfig | 12 ++++++++++ firmware/Makefile | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletions(-) create mode 100644 firmware/Makefile diff --git a/Makefile b/Makefile index 20b3235..ac2ab7e 100644 --- a/Makefile +++ b/Makefile @@ -450,7 +450,7 @@ scripts: scripts_basic include/config/auto.conf # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ -drivers-y := drivers/ sound/ +drivers-y := drivers/ sound/ firmware/ net-y := net/ libs-y := lib/ core-y := usr/ diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index d7da109..b856fe8 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -34,6 +34,18 @@ config FW_LOADER require userspace firmware loading support, but a module built outside the kernel tree does. +config BUILTIN_FIRMWARE + string "Firmware blobs to build into the kernel binary" + depends on FW_LOADER + help + This option allows firmware to be built into the kernel, for the + cases where the user either cannot or doesn't want to provide it from + userspace at runtime (for example, when the firmware in question is + required for accessing the boot device, and the user doesn't want to + use an initrd). Multiple files should be separated with spaces, and + the required files should exist under the firmware/ directory in + the source tree. + config DEBUG_DRIVER bool "Driver Core verbose debug messages" depends on DEBUG_KERNEL diff --git a/firmware/Makefile b/firmware/Makefile new file mode 100644 index 0000000..4243c5a --- /dev/null +++ b/firmware/Makefile @@ -0,0 +1,58 @@ +# +# kbuild file for firmware/ +# + +firmware-y := + +firmware_bins := $(subst ...
Feedback/patches from Johannes Berg -- sort $(firmware_dirs) to prevent
make from complaining about duplicates, and don't unconditionally depend
on include/config/64bit.h. Also fix O= compilation again by including
$(srctree) in the filename passed to .incbin in the .S files.
I also fixed up the dependencies for the object files built from
binaries -- the .S file doesn't need to depend on the binary, but the .o
does.
Still don't have the behaviour we want from clean/mrproper, but I think
we need Sam's help with that.
commit bb71d4c53b14456ec591eb579923566f9c3302ed
Author: David Woodhouse <dwmw2@infradead.org>
Date: Fri May 23 13:58:12 2008 +0100
firmware: Add CONFIG_BUILTIN_FIRMWARE option
This allows arbitrary firmware files to be included in the static kernel
where the firmware loader can find them without requiring userspace to
be alive.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
diff --git a/Makefile b/Makefile
index 20b3235..ac2ab7e 100644
--- a/Makefile
+++ b/Makefile
@@ -450,7 +450,7 @@ scripts: scripts_basic include/config/auto.conf
# Objects we will link into vmlinux / subdirs we need to visit
init-y := init/
-drivers-y := drivers/ sound/
+drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index d7da109..b856fe8 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -34,6 +34,18 @@ config FW_LOADER
require userspace firmware loading support, but a module built outside
the kernel tree does.
+config BUILTIN_FIRMWARE
+ string "Firmware blobs to build into the kernel binary"
+ depends on FW_LOADER
+ help
+ This option allows firmware to be built into the kernel, for the
+ cases where the user either cannot or doesn't want to provide it from
+ userspace at runtime (for example, when the firmware in question is
+ required for accessing the boot device, and the user doesn't want to
+ ...I worked it out -- we don't include .config when we make clean, although it was trying to remove the .S files corresponding to all the configured firmwares, there were effectively none of those. Fixed thus: -targets := $(firmware_objs) $(patsubst $(obj)/%,%, $(firmware_srcs)) +targets := $(patsubst $(obj)/%,%, $(wildcard $(shell find $(obj) -name \*.S))) -- dwmw2 --
More feedback... Andrew wanted the help text to be a little more...
well, helpful. And Johannes wanted to add a CONFIG_BUILTIN_FIRMWARE_DIR
option, which lets you just point it at /lib/firmware or somewhere else
outside the kernel tree. And we fixed up a bunch of other details, like
the dependencies on directories, and the fact that the .S file doesn't
actually need to change when the binary blob does.
I even made the Makefile fit in 80 characters. It's going to make your
brain hurt either way -- but that's normal for kernel Makefiles.
commit 4311743f8ef92ab462c06a9dd2ff8e0d735b3dae
Author: David Woodhouse <dwmw2@infradead.org>
Date: Fri May 23 13:58:12 2008 +0100
firmware: Add CONFIG_BUILTIN_FIRMWARE option
This allows arbitrary firmware files to be included in the static kernel
where the firmware loader can find them without requiring userspace to
be alive.
(Updated and CONFIG_BUILTIN_FIRMWARE_DIR added with lots of help from
Johannes Berg).
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
diff --git a/Makefile b/Makefile
index 20b3235..ac2ab7e 100644
--- a/Makefile
+++ b/Makefile
@@ -450,7 +450,7 @@ scripts: scripts_basic include/config/auto.conf
# Objects we will link into vmlinux / subdirs we need to visit
init-y := init/
-drivers-y := drivers/ sound/
+drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index d7da109..f204ae7 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -34,6 +34,39 @@ config FW_LOADER
require userspace firmware loading support, but a module built outside
the kernel tree does.
+config BUILTIN_FIRMWARE
+ string "Firmware blobs to build into the kernel binary"
+ depends on FW_LOADER
+ help
+ This option allows firmware to be built into the kernel, for the
+ cases where the user either cannot or ...This installs all the in-kernel-tree firmware into $(INSTALL_FW_PATH), which defaults to $(objtree)/usr/lib/firmware and is intended end up in /lib/firmware for udev to find the files. This, in conjunction with the builtin-firmware support, makes it simple for drivers with associated firmware to move over to request_firmware() and give the user a choice of whether to have it built in to the kernel image or loaded separately from userspace. As with kernel header installation for userspace, it intentionally pays no attention to configuration variables -- it installs _all_ available firmware blobs, unconditionally. Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- Makefile | 9 +++++++++ scripts/Makefile.fwinst | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 0 deletions(-) create mode 100644 scripts/Makefile.fwinst diff --git a/Makefile b/Makefile index ac2ab7e..3521afe 100644 --- a/Makefile +++ b/Makefile @@ -995,6 +995,15 @@ depend dep: @echo '*** Warning: make $@ is unnecessary now.' # --------------------------------------------------------------------------- +# Firmware install +INSTALL_FW_PATH=$(objtree)/usr/lib/firmware +export INSTALL_FW_PATH + +PHONY += firmware_install +firmware_install: FORCE + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install + +# --------------------------------------------------------------------------- # Kernel headers INSTALL_HDR_PATH=$(objtree)/usr export INSTALL_HDR_PATH diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst new file mode 100644 index 0000000..bde4073 --- /dev/null +++ b/scripts/Makefile.fwinst @@ -0,0 +1,26 @@ +# ========================================================================== +# Installing firmware +# +# We don't include the .config, so all firmware files are in $(fw-shipped-) +# rather than in $(fw-shipped-y) or $(fw-shipped-n). +# ...
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
firmware/Makefile | 2 +-
.../korg1212-firmware.h => firmware/korg/k1212.c | 5 ++++-
sound/pci/korg1212/korg1212.c | 18 ------------------
3 files changed, 5 insertions(+), 20 deletions(-)
rename sound/pci/korg1212/korg1212-firmware.h => firmware/korg/k1212.c (99%)
diff --git a/firmware/Makefile b/firmware/Makefile
index 4243c5a..bcae927 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -2,7 +2,7 @@
# kbuild file for firmware/
#
-firmware-y :=
+firmware-$(CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL) += korg/k1212
firmware_bins := $(subst ",,$(CONFIG_BUILTIN_FIRMWARE))
firmware_srcs := $(patsubst %,$(obj)/%.S, $(firmware_bins))
diff --git a/sound/pci/korg1212/korg1212-firmware.h b/firmware/korg/k1212.c
similarity index 99%
rename from sound/pci/korg1212/korg1212-firmware.h
rename to firmware/korg/k1212.c
index f6f5b91..1ed3ebb 100644
--- a/sound/pci/korg1212/korg1212-firmware.h
+++ b/firmware/korg/k1212.c
@@ -1,4 +1,5 @@
-static char dspCode [] = {
+#include <linux/firmware.h>
+static const char dspCode [] = {
0x01,0xff,0x18,0xff,0xf5,0xff,0xcf,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
0x26,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
@@ -985,3 +986,5 @@ static char dspCode [] = {
0x00,0xff,0x40,0xff,0xff,0xff,0xc4,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff };
+
+DECLARE_BUILTIN_FIRMWARE("korg/k1212.dsp", dspCode);
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index f4c85b5..4a44c0f 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -260,14 +260,6 @@ enum MonitorModeSelector {
#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for ...On Sun, 25 May 2008 11:23:58 +0100 Acked-by: Alan Cox <alan@redhat.com> for the rest of the series too --
any chance to make it get into 2.6.26? before this i need to keep two copies klibc with fw (qla24xxx) in initramfs. one for 32 bit and one for 64 bit. YH --
Well, it's supposedly too late, but it's dead simple and shouldn't have much chance of breaking anything, so I suppose as long as we don't include the korg1212 patch and the rest of the similar patches which we're still working on, that's not such an insane request. As long as the one or two drivers I mentioned get tested, that is. -- dwmw2 --
Some drivers have their own hacks to bypass the kernel's firmware loader
and build their firmware into the kernel; this renders those unnecessary.
Other drivers don't use the firmware loader at all, because they always
want the firmware to be available. This allows them to start using the
firmware loader.
A third set of drivers already use the firmware loader, but can't be
used without help from userspace, which sometimes requires an initrd.
This allows them to work in a static kernel.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/base/firmware_class.c | 33 +++++++++++++++++++++++++++++++--
include/asm-generic/vmlinux.lds.h | 7 +++++++
include/linux/firmware.h | 21 +++++++++++++++++++++
3 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 264b3a2..c09f060 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -49,6 +49,14 @@ struct firmware_priv {
struct timer_list timeout;
};
+#ifdef CONFIG_FW_LOADER
+extern struct builtin_fw __start_builtin_fw[];
+extern struct builtin_fw __end_builtin_fw[];
+#else /* Module case. Avoid ifdefs later; it'll all optimise out */
+static struct builtin_fw *__start_builtin_fw = NULL;
+static struct builtin_fw *__end_builtin_fw = NULL;
+#endif
+
static void
fw_load_abort(struct firmware_priv *fw_priv)
{
@@ -391,13 +399,12 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
struct device *f_dev;
struct firmware_priv *fw_priv;
struct firmware *firmware;
+ struct builtin_fw *builtin;
int retval;
if (!firmware_p)
return -EINVAL;
- printk(KERN_INFO "firmware: requesting %s\n", name);
-
*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
if (!firmware) {
printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
@@ -406,6 +413,20 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
goto out;
...Hmm, linux/module.h does this too, perhaps some enthusiast can implement __concat() and use it everywhere. Cheers, Rusty. --
Took me a while to find that... in moduleparam.h :) Yeah, it probably makes sense to split it out, and probably add a 'uniquify' macro which properly appends __COUNTER__ to some string; PCI fixup declarations could do with that too. I'll probably just add them to stringify.h -- I don't think they each justify separate files of their own. It's all just CPP magic. Although I was actually going to drop DECLARE_BUILTIN_FIRMWARE. I'm not doing that from C code at all any more -- it's all in asm. At this point, it only really serves as documentation for that one patch in the series (and yes, it's scary that such a construct really does give people more of a clue what's going on). -- dwmw2 --
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/char/cyclades.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index ef73e72..6bff9d8 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -4668,7 +4668,7 @@ static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
return 0;
}
-static inline void __devinit cyz_fpga_copy(void __iomem *fpga, u8 *data,
+static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
unsigned int size)
{
for (; size > 0; size--) {
@@ -4701,10 +4701,10 @@ static int __devinit __cyz_load_fw(const struct firmware *fw,
const char *name, const u32 mailbox, void __iomem *base,
void __iomem *fpga)
{
- void *ptr = fw->data;
- struct zfile_header *h = ptr;
- struct zfile_config *c, *cs;
- struct zfile_block *b, *bs;
+ const void *ptr = fw->data;
+ const struct zfile_header *h = ptr;
+ const struct zfile_config *c, *cs;
+ const struct zfile_block *b, *bs;
unsigned int a, tmp, len = fw->size;
#define BAD_FW KERN_ERR "Bad firmware: "
if (len < sizeof(*h)) {
--
1.5.4.5
--
On Sun, 25 May 2008 11:23:32 +0100 Acked-by: Alan Cox <alan@redhat.com> --
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/wireless/p54/p54usb.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 98ddbb3..6728254 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -375,7 +375,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
const struct firmware *fw_entry = NULL;
int err, alen;
u8 carry = 0;
- u8 *buf, *tmp, *data;
+ u8 *buf, *tmp;
+ const u8 *data;
unsigned int left, remains, block_size;
struct x2_header *hdr;
unsigned long timeout;
@@ -522,7 +523,7 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
void *buf;
__le32 reg;
unsigned int remains, offset;
- u8 *data;
+ const u8 *data;
buf = kmalloc(512, GFP_KERNEL);
if (!buf) {
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/irda/irda-usb.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 6f50ed7..18b471c 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1024,7 +1024,7 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self)
* Upload firmware code to SigmaTel 421X IRDA-USB dongle
*/
static int stir421x_fw_upload(struct irda_usb_cb *self,
- unsigned char *patch,
+ const unsigned char *patch,
const unsigned int patch_len)
{
int ret = -ENOMEM;
@@ -1073,11 +1073,11 @@ static int stir421x_fw_upload(struct irda_usb_cb *self,
*/
static int stir421x_patch_device(struct irda_usb_cb *self)
{
- unsigned int i;
- int ret;
- char stir421x_fw_name[11];
- const struct firmware *fw;
- unsigned char *fw_version_ptr; /* pointer to version string */
+ unsigned int i;
+ int ret;
+ char stir421x_fw_name[11];
+ const struct firmware *fw;
+ const unsigned char *fw_version_ptr; /* pointer to version string */
unsigned long fw_version = 0;
/*
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/media/video/bt8xx/bttv-cards.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index f20a01c..f93f1ad 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3767,7 +3767,8 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
#define BTTV_ALT_DCLK 0x100000
#define BTTV_ALT_NCONFIG 0x800000
-static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
+static int __devinit pvr_altera_load(struct bttv *btv, const u8 *micro,
+ u32 microlen)
{
u32 n;
u8 bits;
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
sound/drivers/vx/vx_core.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 9953886..585af2e 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -453,7 +453,7 @@ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
vx_outb(chip, TXM, 0);
vx_outb(chip, TXL, 0);
} else {
- unsigned char *image = boot->data + i;
+ const unsigned char *image = boot->data + i;
if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
return -EIO;
@@ -671,7 +671,7 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
unsigned int i;
int err;
unsigned int csum = 0;
- unsigned char *image, *cptr;
+ const unsigned char *image, *cptr;
snd_assert(dsp->size % 3 == 0, return -EINVAL);
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/media/dvb/ttusb-dec/ttusb_dec.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 42eee04..8af88f1 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1275,7 +1275,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
u8 b1[] = { 0x61 };
u8 *b;
char idstring[21];
- u8 *firmware = NULL;
+ const u8 *firmware = NULL;
size_t firmware_size = 0;
u16 firmware_csum = 0;
u16 firmware_csum_ns;
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/wireless/libertas/if_cs.c | 2 +-
drivers/net/wireless/libertas/if_sdio.c | 4 ++--
drivers/net/wireless/libertas/if_usb.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 54280e2..d075b44 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -122,7 +122,7 @@ static inline void if_cs_write16(struct if_cs_card *card, uint reg, u16 val)
static inline void if_cs_write16_rep(
struct if_cs_card *card,
uint reg,
- void *buf,
+ const void *buf,
unsigned long count)
{
if (debug_output)
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 51f664b..3dd537b 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -392,7 +392,7 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
unsigned long timeout;
u8 *chunk_buffer;
u32 chunk_size;
- u8 *firmware;
+ const u8 *firmware;
size_t size;
lbs_deb_enter(LBS_DEB_SDIO);
@@ -508,7 +508,7 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
unsigned long timeout;
u8 *chunk_buffer;
u32 chunk_size;
- u8 *firmware;
+ const u8 *firmware;
size_t size, req_size;
lbs_deb_enter(LBS_DEB_SDIO);
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 8032df7..a25b670 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -293,7 +293,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
{
struct fwdata *fwdata = cardp->ep_out_buf;
- uint8_t *firmware = cardp->fw->data;
+ const uint8_t *firmware = cardp->fw->data;
/* If we got a CRC failure on the last block, back
up and retry it */
@@ -746,7 +746,7 @@ ...On Sun, 25 May 2008 11:23:29 +0100 Acked-by: Alan Cox <alan@redhat.com> --
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/media/video/cx25840/cx25840-firmware.c | 21 +++++++++++++--------
1 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 620d295..5c08ede 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -79,7 +79,7 @@ static int check_fw_load(struct i2c_client *client, int size)
return 0;
}
-static int fw_write(struct i2c_client *client, u8 *data, int size)
+static int fw_write(struct i2c_client *client, const u8 *data, int size)
{
if (i2c_master_send(client, data, size) < size) {
v4l_err(client, "firmware load i2c failure\n");
@@ -93,7 +93,8 @@ int cx25840_loadfw(struct i2c_client *client)
{
struct cx25840_state *state = i2c_get_clientdata(client);
const struct firmware *fw = NULL;
- u8 buffer[4], *ptr;
+ u8 buffer[FWSEND];
+ const u8 *ptr;
int size, retval;
if (state->is_cx23885)
@@ -108,6 +109,8 @@ int cx25840_loadfw(struct i2c_client *client)
buffer[0] = 0x08;
buffer[1] = 0x02;
+
+ /* Do we really need to do the first two bytes first? */
buffer[2] = fw->data[0];
buffer[3] = fw->data[1];
retval = fw_write(client, buffer, 4);
@@ -118,19 +121,21 @@ int cx25840_loadfw(struct i2c_client *client)
}
size = fw->size - 2;
- ptr = fw->data;
+ ptr = fw->data + 2;
while (size > 0) {
- ptr[0] = 0x08;
- ptr[1] = 0x02;
- retval = fw_write(client, ptr, min(FWSEND, size + 2));
+ int len = min(FWSEND - 2, size);
+
+ memcpy(buffer + 2, ptr, len);
+
+ retval = fw_write(client, ptr, len + 2);
if (retval < 0) {
release_firmware(fw);
return retval;
}
- size -= FWSEND - 2;
- ptr += FWSEND - 2;
+ size -= len;
+ ptr += len;
}
end_fw_load(client);
--
1.5.4.5
--
Hi David, There is no need to do the first two bytes first. As far as I can tell it was done to avoid having to allocate a local buffer. The initial version of this code was writing much larger blocks at a time to the i2c bus, so having to setup a large buffer on the stack was undesirable. The pvrusb driver requires a much smaller buffer (FWSEND), but the code was never changed. Now, however, the initial four-byte write is just in the way and can be removed in favor of always writing FWSEND-sized blocks of data. I've CC-ed Mike Isely, the pvrusb2 maintainer, just in case there is an outlandish restriction I'm not aware of on that USB device requiring the firmware load to be done this way. Regards, Hans --
Thanks. I suspected as much, but wanted to err on the side of caution since I can't test it. I'll change it in the next iteration. -- dwmw2 --
Hm, looks like I was also passing the wrong pointer to fw_write().
Here's the new version...
commit 57dc4762554119ffb5c711b2716f47997bc5c181
Author: David Woodhouse <dwmw2@infradead.org>
Date: Fri May 23 23:58:24 2008 +0100
cx25840: treat firmware data as const
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 620d295..8d489a4 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -79,7 +79,7 @@ static int check_fw_load(struct i2c_client *client, int size)
return 0;
}
-static int fw_write(struct i2c_client *client, u8 *data, int size)
+static int fw_write(struct i2c_client *client, const u8 *data, int size)
{
if (i2c_master_send(client, data, size) < size) {
v4l_err(client, "firmware load i2c failure\n");
@@ -93,7 +93,8 @@ int cx25840_loadfw(struct i2c_client *client)
{
struct cx25840_state *state = i2c_get_clientdata(client);
const struct firmware *fw = NULL;
- u8 buffer[4], *ptr;
+ u8 buffer[FWSEND];
+ const u8 *ptr;
int size, retval;
if (state->is_cx23885)
@@ -108,29 +109,23 @@ int cx25840_loadfw(struct i2c_client *client)
buffer[0] = 0x08;
buffer[1] = 0x02;
- buffer[2] = fw->data[0];
- buffer[3] = fw->data[1];
- retval = fw_write(client, buffer, 4);
- if (retval < 0) {
- release_firmware(fw);
- return retval;
- }
-
- size = fw->size - 2;
+ size = fw->size;
ptr = fw->data;
while (size > 0) {
- ptr[0] = 0x08;
- ptr[1] = 0x02;
- retval = fw_write(client, ptr, min(FWSEND, size + 2));
+ int len = min(FWSEND - 2, size);
+
+ memcpy(buffer + 2, ptr, len);
+
+ retval = fw_write(client, buffer, len + 2);
if (retval < 0) {
release_firmware(fw);
return retval;
}
- size -= FWSEND - 2;
- ptr += FWSEND - 2;
+ size -= len;
+ ptr += len;
}
end_fw_load(client);
--
dwmw2
--
Looks good. I tested it quickly and it works. Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Regards, --
Just to be technically correct, this is what I tested successfully with the pvrusb2 driver. Acked-By: Mike Isely <isely@pobox.com> -- Mike Isely isely @ pobox (dot) com PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8 --
The pvrusb2 driver's FWSEND limit is an artifact of the hardware and cannot be changed. HOWEVER, in the standalone driver (not in the kernel) I have a hack implemented that can monitor and intercept such I2C operations and break them into smaller I2C transactions. I implemented this to allow the standalone driver to function correctly on some older kernels where FWSEND is too large. I can enable that hack for the kernel driver and thus lift the limit. But without it, FWSEND absolutely has to be small enough that the entire transaction (including a few bytes of transport overhead) can fit within a 64 byte URB. I see that this change allocates a local buffer on the stack (sized by FWSEND). Though the buffer is small (48 bytes, see above paragraph), it is controlled by a macro and thus leaves open the possibility that it could be accidentally increased to a point where the stack gets overflowed. Seems like not a good idea, but either way it should not affect the pvrusb2 driver. Acked-By: Mike Isely <isely@pobox.com> -- Mike Isely isely @ pobox (dot) com PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8 --
[cx25840-firmware.c] Looks good to me. Acked-By: Tyler Trafford <ttrafford@gmail.com> Separate topic, but maybe the send size should be parameterized, so that the adapter can specify a maximum? -- Tyler Trafford A sect or party is an elegant incognito devised to save a man from the vexation of thinking. -- Ralph Waldo Emerson, Journals, 1831 --
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/cxgb3/common.h | 5 +++--
drivers/net/cxgb3/t3_hw.c | 7 ++++---
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 579bee4..8e8ebd7 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -686,8 +686,9 @@ int t3_seeprom_write(struct adapter *adapter, u32 addr, __le32 data);
int t3_seeprom_wp(struct adapter *adapter, int enable);
int t3_get_tp_version(struct adapter *adapter, u32 *vers);
int t3_check_tpsram_version(struct adapter *adapter, int *must_load);
-int t3_check_tpsram(struct adapter *adapter, u8 *tp_ram, unsigned int size);
-int t3_set_proto_sram(struct adapter *adap, u8 *data);
+int t3_check_tpsram(struct adapter *adapter, const u8 *tp_ram,
+ unsigned int size);
+int t3_set_proto_sram(struct adapter *adap, const u8 *data);
int t3_read_flash(struct adapter *adapter, unsigned int addr,
unsigned int nwords, u32 *data, int byte_oriented);
int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size);
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index d405a93..47d5178 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -923,7 +923,8 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load)
* Checks if an adapter's tp sram is compatible with the driver.
* Returns 0 if the versions are compatible, a negative error otherwise.
*/
-int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size)
+int t3_check_tpsram(struct adapter *adapter, const u8 *tp_sram,
+ unsigned int size)
{
u32 csum;
unsigned int i;
@@ -2875,10 +2876,10 @@ static void ulp_config(struct adapter *adap, const struct tp_params *p)
*
* Write the contents of the protocol SRAM.
*/
-int t3_set_proto_sram(struct adapter *adap, u8 *data)
+int t3_set_proto_sram(struct adapter *adap, const u8 *data)
{
int ...In preparation for supporting firmware files linked into the static
kernel, make fw->data const to ensure that users aren't modifying it (so
that we can pass a pointer to the original in-kernel copy, rather than
having to copy it).
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/base/firmware_class.c | 2 +-
include/linux/firmware.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 9fd4a85..264b3a2 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -257,7 +257,7 @@ firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr,
if (retval)
goto out;
- memcpy(fw->data + offset, buffer, count);
+ memcpy((u8 *)fw->data + offset, buffer, count);
fw->size = max_t(size_t, offset + count, fw->size);
retval = count;
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index 4d10c73..5e73f3f 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -8,7 +8,7 @@
struct firmware {
size_t size;
- u8 *data;
+ const u8 *data;
};
struct device;
--
1.5.4.5
--
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/media/dvb/frontends/bcm3510.c | 5 +++--
drivers/media/dvb/frontends/nxt200x.c | 3 ++-
drivers/media/dvb/frontends/or51211.c | 4 ++--
drivers/media/dvb/frontends/sp8870.c | 2 +-
drivers/media/dvb/frontends/sp887x.c | 2 +-
drivers/media/dvb/frontends/tda10048.c | 2 +-
drivers/media/dvb/frontends/tda1004x.c | 2 +-
7 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index d268e65..cf5e576 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -590,7 +590,8 @@ static void bcm3510_release(struct dvb_frontend* fe)
*/
#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
-static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, u8 *b, u16 len)
+static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
+ u16 len)
{
int ret = 0,i;
bcm3510_register_value vH, vL,vD;
@@ -614,7 +615,7 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
struct bcm3510_state* st = fe->demodulator_priv;
const struct firmware *fw;
u16 addr,len;
- u8 *b;
+ const u8 *b;
int ret,i;
deb_info("requesting firmware\n");
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index 23d0228..af29835 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -93,7 +93,8 @@ static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
return 0;
}
-static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len)
+static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
+ const u8 *buf, u8 len)
{
u8 buf2 [len+1];
int err;
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 7eaa476..6afe12a 100644
--- ...Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/net/wireless/rt2x00/rt2x00.h | 4 ++--
drivers/net/wireless/rt2x00/rt2x00pci.h | 2 +-
drivers/net/wireless/rt2x00/rt61pci.c | 4 ++--
drivers/net/wireless/rt2x00/rt73usb.c | 6 +++---
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 57bdc15..79eabaa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -506,8 +506,8 @@ struct rt2x00lib_ops {
*/
int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev);
- u16 (*get_firmware_crc) (void *data, const size_t len);
- int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data,
+ u16 (*get_firmware_crc) (const void *data, const size_t len);
+ int (*load_firmware) (struct rt2x00_dev *rt2x00dev, const void *data,
const size_t len);
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 9d1cdb9..b41967e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -82,7 +82,7 @@ static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
static inline void
rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned long offset,
- void *value, const u16 length)
+ const void *value, const u16 length)
{
memcpy_toio(rt2x00dev->csr.base + offset, value, length);
}
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 14bc7b2..bb78de5 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -915,7 +915,7 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
return fw_name;
}
-static u16 rt61pci_get_firmware_crc(void *data, const size_t len)
+static u16 rt61pci_get_firmware_crc(const void ...Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
drivers/usb/atm/cxacru.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 5ea3093..90583d6 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -820,7 +820,7 @@ reschedule:
}
static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw,
- u8 code1, u8 code2, u32 addr, u8 *data, int size)
+ u8 code1, u8 code2, u32 addr, const u8 *data, int size)
{
int ret;
u8 *buf;
--
1.5.4.5
--
The maestro3 driver is byte-swapping its firmware to be host-endian in
advance, when it doesn't seem to be necessary -- we could just use
le16_to_cpu() as we load it.
Doing that means that we need to switch the in-tree firmware to be
little-endian too.
Take the least intrusive way of doing this, which is to switch the
existing snd_m3_convert_from_le() function to convert _to_ little-endian
instead, and use it on the in-tree firmware instead of the loaded
firmware. It's a bit suboptimal but doesn't matter much right now
because we're about to remove the special cases for the in-tree version
anyway.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
sound/pci/maestro3.c | 27 +++++++++++++--------------
1 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index a536c59..cbb08d9 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2240,18 +2240,16 @@ static const struct firmware assp_minisrc = {
.size = sizeof assp_minisrc_image
};
-#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */
-
#ifdef __LITTLE_ENDIAN
-static inline void snd_m3_convert_from_le(const struct firmware *fw) { }
+static inline void snd_m3_convert_to_le(const struct firmware *fw) { }
#else
-static void snd_m3_convert_from_le(const struct firmware *fw)
+static void snd_m3_convert_to_le(const struct firmware *fw)
{
int i;
u16 *data = (u16 *)fw->data;
for (i = 0; i < fw->size / 2; ++i)
- le16_to_cpus(&data[i]);
+ cpu_to_le16s(&data[i]);
}
#endif
@@ -2271,7 +2269,7 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = {
static void snd_m3_assp_init(struct snd_m3 *chip)
{
unsigned int i;
- u16 *data;
+ const u16 *data;
/* zero kernel data */
for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
@@ -2289,10 +2287,11 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
KDATA_DMA_XFER0);
/* write kernel into code memory.. */
- data = (u16 ...>From d4f7e79e7e1cf8c3bace102c30496bf47684ab82 Mon Sep 17 00:00:00 2001 From: David Woodhouse <dwmw2@infradead.org> Date: Thu, 29 May 2008 13:32:28 +0300 Subject: [PATCH] firmware: convert maestro3 driver to use firmware loader exclusively Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- firmware/Makefile | 2 + firmware/ess/maestro3_assp_kernel.fw.ihex | 120 ++++++++++++++++++++ firmware/ess/maestro3_assp_minisrc.fw.ihex | 51 +++++++++ sound/pci/Kconfig | 2 +- sound/pci/maestro3.c | 169 ---------------------------- 5 files changed, 174 insertions(+), 170 deletions(-) create mode 100644 firmware/ess/maestro3_assp_kernel.fw.ihex create mode 100644 firmware/ess/maestro3_assp_minisrc.fw.ihex diff --git a/firmware/Makefile b/firmware/Makefile index ba845ba..4b4a57b 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -9,6 +9,8 @@ fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) fw-external-y := $(subst ",,$(CONFIG_BUILTIN_FIRMWARE)) fw-shipped-$(CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL) += korg/k1212.dsp +fw-shipped-$(CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL) += \ + ess/maestro3_assp_kernel.fw ess/maestro3_assp_minisrc.fw firmware-y := $(fw-external-y) $(fw-shipped-y) firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y)))) diff --git a/firmware/ess/maestro3_assp_kernel.fw.ihex b/firmware/ess/maestro3_assp_kernel.fw.ihex new file mode 100644 index 0000000..7624ecd --- /dev/null +++ b/firmware/ess/maestro3_assp_kernel.fw.ihex @@ -0,0 +1,120 ...
Standardise both in-kernel and loaded firmware to be stored as
little-endian instead of host-endian.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---
As with the maestro3 version, take the least intrusive solution since
it's not going to be there for long.
sound/pci/ymfpci/ymfpci_main.c | 59 +++++++++++++++++++++++-----------------
1 files changed, 34 insertions(+), 25 deletions(-)
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 29b3056..6298b29 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/control.h>
@@ -2009,11 +2010,34 @@ static struct firmware snd_ymfpci_controller_1e_microcode = {
.size = YDSXG_CTRLLENGTH,
.data = (u8 *)CntrlInst1E,
};
+
+#ifdef __BIG_ENDIAN
+static int microcode_swapped;
+static DEFINE_MUTEX(microcode_swap);
+
+static void snd_ymfpci_convert_to_le(const struct firmware *fw)
+{
+ int i;
+ u32 *data = (u32 *)fw->data;
+
+ for (i = 0; i < fw->size / 4; ++i)
+ cpu_to_le32s(&data[i]);
+}
#endif
-#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
{
+#ifdef __BIG_ENDIAN
+ mutex_lock(&microcode_swap);
+ if (!microcode_swapped) {
+ snd_ymfpci_convert_to_le(&snd_ymfpci_dsp_microcode);
+ snd_ymfpci_convert_to_le(&snd_ymfpci_controller_1e_microcode);
+ snd_ymfpci_convert_to_le(&snd_ymfpci_controller_microcode);
+ microcode_swapped = 1;
+ }
+ mutex_unlock(&microcode_swap);
+#endif
+
chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
@@ -2029,19 +2053,6 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
#else /* use fw_loader */
-#ifdef __LITTLE_ENDIAN
-static inline void ...Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- firmware/Makefile | 2 + firmware/yamaha/ds1_ctrl.fw.ihex | 769 ++++++++++++++++++ firmware/yamaha/ds1_dsp.fw.ihex | 9 + firmware/yamaha/ds1e_ctrl.fw.ihex | 769 ++++++++++++++++++ sound/pci/ymfpci/ymfpci_image.h | 1565 ------------------------------------- sound/pci/ymfpci/ymfpci_main.c | 63 -- 6 files changed, 1549 insertions(+), 1628 deletions(-) create mode 100644 firmware/yamaha/ds1_ctrl.fw.ihex create mode 100644 firmware/yamaha/ds1_dsp.fw.ihex create mode 100644 firmware/yamaha/ds1e_ctrl.fw.ihex delete mode 100644 sound/pci/ymfpci/ymfpci_image.h diff --git a/firmware/Makefile b/firmware/Makefile index 4b4a57b..c70d18c 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -11,6 +11,8 @@ fw-external-y := $(subst ",,$(CONFIG_BUILTIN_FIRMWARE)) fw-shipped-$(CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL) += \ ess/maestro3_assp_kernel.fw ess/maestro3_assp_minisrc.fw +fw-shipped-$(CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL) += yamaha/ds1_ctrl.fw \ + yamaha/ds1_dsp.fw yamaha/ds1e_ctrl.fw firmware-y := $(fw-external-y) $(fw-shipped-y) firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y)))) diff --git a/firmware/yamaha/ds1_ctrl.fw.ihex b/firmware/yamaha/ds1_ctrl.fw.ihex new file mode 100644 index 0000000..aa9b1d7 --- /dev/null +++ b/firmware/yamaha/ds1_ctrl.fw.ihex @@ -0,0 +1,769 ...
Subject: [PATCH] smctr: use request_firmware() Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- Trying hard not to actually look too hard at it while I'm there... drivers/net/tokenring/Kconfig | 8 + drivers/net/tokenring/smctr.c | 54 ++- drivers/net/tokenring/smctr.h | 2 - drivers/net/tokenring/smctr_firmware.h | 978 -------------------------------- firmware/Makefile | 1 + firmware/tr_smctr.bin.ihex | 477 ++++++++++++++++ 6 files changed, 519 insertions(+), 1001 deletions(-) delete mode 100644 drivers/net/tokenring/smctr_firmware.h create mode 100644 firmware/tr_smctr.bin.ihex diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig index e6b2e06..5aa5be1 100644 --- a/drivers/net/tokenring/Kconfig +++ b/drivers/net/tokenring/Kconfig @@ -182,4 +182,12 @@ config SMCTR To compile this driver as a module, choose M here: the module will be called smctr. +config SMCTR_FIRMWARE + bool "SMC ISA/MCA adapter firmware" + depends on SMCTR + ---help--- + Build firmware for SMCTR into the kernel instead of obtaining it + through udev. Say 'N'. + + endif # TR diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 5f1c507..d36b9fc 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -48,6 +48,7 @@ #include <linux/skbuff.h> #include <linux/trdevice.h> #include <linux/bitops.h> +#include <linux/firmware.h> #include <asm/system.h> #include <asm/io.h> @@ -59,7 +60,6 @@ #endif #include "smctr.h" /* Our Stuff */ -#include "smctr_firmware.h" /* SMC adapter firmware */ static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n"; static const char cardname[] = "smctr"; @@ -103,7 +103,8 @@ static int smctr_clear_trc_reset(int ioaddr); static int smctr_close(struct net_device *dev); /* D */ -static int ...
thanks a lot, please add a printk for users: printk(KERN_ERR "smctr: Can't load firmware file tr_smctr.bin\n") -- maks --
I think you get that kind of failure report from udev anyway, don't you? You certainly get the 'trying to load...' from the kernel. -- dwmw2 --
Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- drivers/net/usb/Kconfig | 8 + drivers/net/usb/kaweth.c | 38 ++- drivers/net/usb/kawethfw.h | 557 ----------------------------- firmware/Makefile | 3 + firmware/kaweth/new_code.bin.ihex | 206 +++++++++++ firmware/kaweth/new_code_fix.bin.ihex | 40 ++ firmware/kaweth/trigger_code.bin.ihex | 13 + firmware/kaweth/trigger_code_fix.bin.ihex | 3 + 8 files changed, 296 insertions(+), 572 deletions(-) delete mode 100644 drivers/net/usb/kawethfw.h create mode 100644 firmware/kaweth/new_code.bin.ihex create mode 100644 firmware/kaweth/new_code_fix.bin.ihex create mode 100644 firmware/kaweth/trigger_code.bin.ihex create mode 100644 firmware/kaweth/trigger_code_fix.bin.ihex diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 0604f3f..c692510 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -66,6 +66,14 @@ config USB_KAWETH To compile this driver as a module, choose M here: the module will be called kaweth. +config USB_KAWETH_FIRMWARE + bool "Include firmware for USB KLSI KL5USB101-based ethernet devices" + depends on USB_KAWETH + ---help--- + This includes firmware for the "kaweth" devices in the kernel + image directly, so that it doesn't need to be provided by + the firmware loader. Say 'N'. + config USB_PEGASUS tristate "USB Pegasus/Pegasus-II based ethernet device support" select MII diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 0dcfc03..bcc43b4 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -57,13 +57,12 @@ #include <linux/ethtool.h> #include <linux/dma-mapping.h> #include <linux/wait.h> +#include <linux/firmware.h> #include <asm/uaccess.h> #include <asm/byteorder.h> #undef DEBUG -#include "kawethfw.h" - #define KAWETH_MTU 1514 #define KAWETH_BUF_SIZE 1664 #define ...
We don't put hirarchy policy into drivers. Regards Oliver
Not a strictly accurate observation; we've been doing so for some time. -- dwmw2 --
we tried to not put that policy into the drivers and I was looking over this, but in the meantime driver slipped past me and made it in. We should not do this at all and if people wanna have this, then they should solve this within udev. Regards Marcel --
Then you arrived at the party a year too late. The format name/firmware is commonly used all over the kernel. How that maps to a file or directory is indeed a matter for udev, but there is already a heirarchical namespace and pretending otherwise won't help. Alan --
If that is supposed to be constructed from the driver/file pair, it is a good idea, but would argue against hardcoding it in the source. Regards Oliver --
It's not. It could be named dwmw2-rulez-new-fix or dwmw2/rulez/new/fix or anything else, it's just a key, a string, an identifier. Any pathnames or relationship with driver names you're seeing there are just a figment of your imagination ;-) / 2 -- Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/ Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org} FSFLA Board Member ¡Sé Libre! => http://www.fsfla.org/ Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org} --
I was not late to the party. I was the first one using request_firmware() and always keeping an eye on drivers using it and making sure using it correctly. However drivers sneaked in without that I realized it. Mainly because I don't have that hardware and reviewing every single driver obviously never happened. I repeatedly said that no hierarchical namespace should be used (and this was a couple of years ago) and now since some developers misuse it, it makes it right. Don't think so. Regards Marcel --
Nothing in the documentation says that it can't have a heirarchical name, so naturally lots of people did it. They didn't sneak in - they improved on the interface and evolved it. They did it in a way that didn't upset anything else (which is why you didn't notice). It means by consensus the developer community decided that a heirarchical namespace was useful. And that is the party you've arrived late for. Alan --
Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- drivers/media/dvb/ttusb-budget/Kconfig | 9 + drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 14 +- .../media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h | 1644 -------------------- firmware/Makefile | 1 + firmware/ttusb-budget-dspbootcode.bin.ihex | 820 ++++++++++ 5 files changed, 840 insertions(+), 1648 deletions(-) delete mode 100644 drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h create mode 100644 firmware/ttusb-budget-dspbootcode.bin.ihex diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index f546bcc..7e6b141 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig @@ -1,5 +1,6 @@ config DVB_TTUSB_BUDGET tristate "Technotrend/Hauppauge Nova-USB devices" + select FW_LOADER depends on DVB_CORE && USB && I2C select DVB_CX22700 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE @@ -16,3 +17,11 @@ config DVB_TTUSB_BUDGET an external software decoder to watch TV. Say Y if you own such a device and want to use it. + +config DVB_TTUSB_BUDGET_FIRMWARE + bool "Firmware for Technotrend/Hauppauge Nova-USB devices" + depends on DVB_TTUSB_BUDGET + help + Include DSP bootcode for the device within the kernel image, + instead of having it provided from userspace by the firmware + loader. Say 'N'. diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 732ce4d..cef90c6 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -19,6 +19,7 @@ #include <linux/errno.h> #include <linux/jiffies.h> #include <linux/mutex.h> +#include <linux/firmware.h> #include "dvb_frontend.h" #include "dmxdev.h" @@ -285,13 +286,17 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int ...
On Thu, 29 May 2008 20:49:04 +0300 Acked-by: Mauro Carvalho Chehab <mchehab@infradead.org> Cheers, Mauro --
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 3df8a66..4a28d91 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -105,6 +105,8 @@
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/firmware.h>
+#include <linux/ihex.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
@@ -1339,13 +1341,13 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
port->tty = NULL;
}
-
/* download the firmware to a pre-renumeration device */
static int keyspan_fake_startup (struct usb_serial *serial)
{
int response;
- const struct ezusb_hex_record *record;
+ const struct ihex_binrec *record;
char *fw_name;
+ const struct firmware *fw;
dbg("Keyspan startup version %04x product %04x",
le16_to_cpu(serial->dev->descriptor.bcdDevice),
@@ -1359,72 +1361,60 @@ static int keyspan_fake_startup (struct usb_serial *serial)
/* Select firmware image on the basis of idProduct */
switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
case keyspan_usa28_pre_product_id:
- record = &keyspan_usa28_firmware[0];
- fw_name = "USA28";
+ fw_name = "keyspan/usa28.fw";
break;
case keyspan_usa28x_pre_product_id:
- record = &keyspan_usa28x_firmware[0];
- fw_name = "USA28X";
+ fw_name = "keyspan/usa28x.fw";
break;
case keyspan_usa28xa_pre_product_id:
- record = &keyspan_usa28xa_firmware[0];
- fw_name = "USA28XA";
+ fw_name = "keyspan/usa28xa.fw";
break;
case keyspan_usa28xb_pre_product_id:
- record = &keyspan_usa28xb_firmware[0];
- fw_name = "USA28XB";
+ fw_name = "keyspan/usa28xb.fw";
break;
case keyspan_usa19_pre_product_id:
- record = &keyspan_usa19_firmware[0];
- fw_name = "USA19";
+ fw_name = "keyspan/usa19.fw";
break;
case keyspan_usa19qi_pre_product_id:
- record = &keyspan_usa19qi_firmware[0];
- fw_name = ...On Fri, 30 May 2008 14:45:33 +0300 David Woodhouse <dwmw2@infradead.org> wrote: [...] ACK Seems reasonable to me, though I wouldn't claim to be particularly authoritative on such matters these days :) Cheers, Hugh --
Signed-off-by: David Woodhouse <dwmw2@infradead.org> --- drivers/usb/serial/Kconfig | 17 ++++ drivers/usb/serial/keyspan_pda.c | 51 ++++++------ drivers/usb/serial/keyspan_pda_fw.h | 99 ----------------------- drivers/usb/serial/xircom_pgs_fw.h | 103 ------------------------ firmware/Makefile | 2 + firmware/keyspan_pda/keyspan_pda.fw.ihex | 121 ++++++++++++++++++++++++++++ firmware/keyspan_pda/xircom_pgs.fw.ihex | 127 ++++++++++++++++++++++++++++++ 7 files changed, 291 insertions(+), 229 deletions(-) delete mode 100644 drivers/usb/serial/keyspan_pda_fw.h delete mode 100644 drivers/usb/serial/xircom_pgs_fw.h create mode 100644 firmware/keyspan_pda/keyspan_pda.fw.ihex create mode 100644 firmware/keyspan_pda/xircom_pgs.fw.ihex diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 31f9cc3..c354203 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -279,6 +279,7 @@ config USB_SERIAL_IUU config USB_SERIAL_KEYSPAN_PDA tristate "USB Keyspan PDA Single Port Serial Driver" + select FW_LOADER select USB_EZUSB help Say Y here if you want to use a Keyspan PDA single port USB to @@ -288,6 +289,13 @@ config USB_SERIAL_KEYSPAN_PDA To compile this driver as a module, choose M here: the module will be called keyspan_pda. +config USB_SERIAL_KEYSPAN_PDA_FIRMWARE + bool "Include Keyspan PDA firmware in kernel" + help + This option allows you to build the required firmware for the + Keyspan PDA serial port into the kernel. Say 'N' and let it + get loaded by udev instead. + config USB_SERIAL_KEYSPAN tristate "USB Keyspan USA-xxx Serial Driver" select FW_LOADER @@ -538,6 +546,7 @@ config USB_SERIAL_CYBERJACK config USB_SERIAL_XIRCOM tristate "USB Xircom / Entregra Single Port Serial Driver" + select FW_LOADER select USB_EZUSB help Say Y here if you want to use a Xircom or Entregra single port USB to @@ -547,6 ...
