Skip to contentSkip to conversation

Allow built-in firmware to be accessed by request_firmware()

PATCH In review David Woodhouse 14 participants 72 messages May 25, 2008 – Jun 13, 2008

Subsystems (18)
lore
Share & tools
lore
#0 lore raw

v2 cover Allow built-in firmware to be accessed by request_firmware()

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

Signature · 1 line
dwmw2
#1 lore raw

PATCH v2 1/28 libertas: treat firmware data as const

---
 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(-)
drivers/net/wireless/libertas/if_cs.c +1 -1
index 54280e2..d075b44 100644
@@ -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)
drivers/net/wireless/libertas/if_sdio.c +2 -2
index 51f664b..3dd537b 100644
@@ -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);
drivers/net/wireless/libertas/if_usb.c +2 -2
index 8032df7..a25b670 100644
@@ -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 @@ static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
  *         len               image length
  *  @return     0 or -1
  */
-static int check_fwfile_format(uint8_t *data, uint32_t totlen)
+static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
 {
 	uint32_t bincmd, exit;
 	uint32_t blksize, offset, len;
Signature · 1 line
1.5.4.5
Acked-by on v2 1/28
#2 lore raw

Re: [PATCHv2 01/28] libertas: treat firmware data as const

Quoted 6 lines · On Sun, 25 May 2008 11:23:29 +0100 David Woodhouse <[email protected]> wrote:
---
 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(-)
#3 lore raw

PATCH v2 2/28 bluetooth: treat firmware data as const

In reply to David Woodhouse
---
 drivers/bluetooth/bfusb.c   |    3 ++-
 drivers/bluetooth/bt3c_cs.c |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/bluetooth/bfusb.c +2 -1
index b990805..0c211ad 100644
@@ -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;
drivers/bluetooth/bt3c_cs.c +2 -1
index 7703d6e..593b7c5 100644
@@ -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];
Signature · 1 line
1.5.4.5
#5 lore raw

PATCH v2 3/28 cyclades: treat firmware data as const

In reply to David Woodhouse
---
 drivers/char/cyclades.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
drivers/char/cyclades.c +5 -5
index ef73e72..6bff9d8 100644
@@ -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)) {
Signature · 1 line
1.5.4.5
#7 lore raw

PATCH v2 4/28 cx25840: treat firmware data as const

In reply to David Woodhouse
---
 drivers/media/video/cx25840/cx25840-firmware.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)
drivers/media/video/cx25840/cx25840-firmware.c +13 -8
index 620d295..5c08ede 100644
@@ -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);
Signature · 1 line
1.5.4.5
#8 lore raw

Re: [PATCHv2 04/28] cx25840: treat firmware data as const

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

Quoted 67 lines · On Sunday 25 May 2008 12:23:33 David Woodhouse wrote:
---
 drivers/media/video/cx25840/cx25840-firmware.c |   21

+++++++++++++-------- 1 files changed, 13 insertions(+), 8 deletions(-)

(quoted diff) +0 -0

b/drivers/media/video/cx25840/cx25840-firmware.c index 620d295..5c08ede 100644

drivers/media/video/cx25840/cx25840-firmware.c +13 -8
@@ -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);
#9 lore raw

Re: [PATCHv2 04/28] cx25840: treat firmware data as const

Quoted 2 lines · Hans Verkuil

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.

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.

Signature · 1 line
dwmw2
#10 lore raw

Re: [PATCHv2 04/28] cx25840: treat firmware data as const

In reply to Hans Verkuil

Hm, looks like I was also passing the wrong pointer to fw_write(). Here's the new version...

commit 57dc4762554119ffb5c711b2716f47997bc5c181

Author: David Woodhouse <[email protected]>
Date:   Fri May 23 23:58:24 2008 +0100

cx25840: treat firmware data as const

drivers/media/video/cx25840/cx25840-firmware.c +11 -16
index 620d295..8d489a4 100644
@@ -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);
Signature · 1 line
dwmw2
Acked-by
#11 lore raw

Re: [PATCHv2 04/28] cx25840: treat firmware data as const

Quoted 10 lines · On Sunday 25 May 2008 16:56:06 David Woodhouse wrote:

Hm, looks like I was also passing the wrong pointer to fw_write(). Here's the new version...

commit 57dc4762554119ffb5c711b2716f47997bc5c181

Author: David Woodhouse <[email protected]>
Date:   Fri May 23 23:58:24 2008 +0100

cx25840: treat firmware data as const

Looks good. I tested it quickly and it works.

Regards,

Hans

Quoted 63 lines
(quoted diff) +0 -0

b/drivers/media/video/cx25840/cx25840-firmware.c index 620d295..8d489a4 100644

drivers/media/video/cx25840/cx25840-firmware.c +11 -16
@@ -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);
Acked-by
#12 lore raw

Re: [PATCHv2 04/28] cx25840: treat firmware data as const

In reply to David Woodhouse
Quoted 10 lines · David Woodhouse

Hm, looks like I was also passing the wrong pointer to fw_write(). Here's the new version...

commit 57dc4762554119ffb5c711b2716f47997bc5c181

Author: David Woodhouse <[email protected]>
Date:   Fri May 23 23:58:24 2008 +0100

cx25840: treat firmware data as const

Just to be technically correct, this is what I tested successfully with the pvrusb2 driver.

-Mike

Quoted 64 lines
drivers/media/video/cx25840/cx25840-firmware.c +11 -16
index 620d295..8d489a4 100644
@@ -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);
Signature · 3 lines
Mike Isely
isely @ pobox (dot) com
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8
Acked-by
#13 lore raw

Re: [PATCHv2 04/28] cx25840: treat firmware data as const

In reply to Hans Verkuil
Quoted 11 lines · Hans Verkuil

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.

Quoted 4 lines

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.

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.

-Mike

Quoted 75 lines

Regards,

Hans

Quoted 67 lines · On Sunday 25 May 2008 12:23:33 David Woodhouse wrote:
---
 drivers/media/video/cx25840/cx25840-firmware.c |   21

+++++++++++++-------- 1 files changed, 13 insertions(+), 8 deletions(-)

(quoted diff) +0 -0

b/drivers/media/video/cx25840/cx25840-firmware.c index 620d295..5c08ede 100644

drivers/media/video/cx25840/cx25840-firmware.c +13 -8
@@ -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);
Signature · 3 lines
Mike Isely
isely @ pobox (dot) com
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8
#14 lore raw

Re: [PATCHv2 04/28] cx25840: treat firmware data as const

[cx25840-firmware.c]

Looks good to me.

Quoted 1 line · Mike Isely

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.

Separate topic, but maybe the send size should be parameterized, so that the adapter can specify a maximum?

Signature · 5 lines
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
#15 lore raw

PATCH v2 5/28 myri10ge: treat firmware data as const

In reply to David Woodhouse

... which means allocating our own buffer for reading it back.

---
 drivers/net/myri10ge/myri10ge.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)
drivers/net/myri10ge/myri10ge.c +9 -2
index c91b12e..ab7a80b 100644
@@ -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);
Signature · 1 line
1.5.4.5
#16 lore raw

PATCH v2 6/28 vx222: treat firmware data as const

In reply to David Woodhouse
---
 sound/pci/vx222/vx222_ops.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
sound/pci/vx222/vx222_ops.c +1 -1
index b4bfc1a..631f3a6 100644
@@ -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);
Signature · 1 line
1.5.4.5
#17 lore raw

PATCH v2 7/28 riptide: treat firmware data as const

In reply to David Woodhouse
---
 sound/pci/riptide/riptide.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
sound/pci/riptide/riptide.c +5 -5
index 979f7da..6a35962 100644
@@ -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;
 
Signature · 1 line
1.5.4.5
#18 lore raw

PATCH v2 8/28 pcxhr: treat firmware data as const

In reply to David Woodhouse
---
 sound/pci/pcxhr/pcxhr_core.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
sound/pci/pcxhr/pcxhr_core.c +2 -2
index 78aa81f..957e6af 100644
@@ -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);
Signature · 1 line
1.5.4.5
#19 lore raw

PATCH v2 9/28 vx: treat firmware data as const

In reply to David Woodhouse
---
 sound/drivers/vx/vx_core.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
sound/drivers/vx/vx_core.c +2 -2
index 9953886..585af2e 100644
@@ -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);
 
Signature · 1 line
1.5.4.5
#20 lore raw

PATCH v2 10/28 ueagle-atm: treat firmware data as const

In reply to David Woodhouse
---
 drivers/usb/atm/ueagle-atm.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)
drivers/usb/atm/ueagle-atm.c +11 -9
index 5f71ff3..cb01b51 100644
@@ -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 pageoffset;
@@ -986,7 +987,7 @@ static void __uea_load_page_e4(struct uea_softc *sc, u8 pageno, int boot)
 	bi.wReserved = cpu_to_be16(UEA_RESERVED);
 
 	do {
-		u8 *blockoffset;
+		const u8 *blockoffset;
 		unsigned int blocksize;
 
 		blockidx = &p->page_header[blockno];
@@ -1095,7 +1096,7 @@ static inline int wait_cmv_ack(struct uea_softc *sc)
 #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
 
 static int uea_request(struct uea_softc *sc,
-		u16 value, u16 index, u16 size, void *data)
+		u16 value, u16 index, u16 size, const void *data)
 {
 	u8 *xfer_buff;
 	int ret = -ENOMEM;
@@ -1891,7 +1892,8 @@ static int load_XILINX_firmware(struct uea_softc *sc)
 {
 	const struct firmware *fw_entry;
 	int ret, size, u, ln;
-	u8 *pfw, value;
+	const u8 *pfw;
+	u8 value;
 	char *fw_name = FW_DIR "930-fpga.bin";
 
 	uea_enters(INS_TO_USBDEV(sc));
Signature · 1 line
1.5.4.5
#21 lore raw

PATCH v2 11/28 cxacru: treat firmware data as const

In reply to David Woodhouse
---
 drivers/usb/atm/cxacru.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/usb/atm/cxacru.c +1 -1
index 5ea3093..90583d6 100644
@@ -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;
Signature · 1 line
1.5.4.5
#22 lore raw

PATCH v2 12/28 aic94xx: treat firmware data as const

In reply to David Woodhouse
---
 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(-)
drivers/scsi/aic94xx/aic94xx_sds.c +6 -6
index 4446e3d..8630a75 100644
@@ -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) {
drivers/scsi/aic94xx/aic94xx_sds.h +2 -2
index bb9795a..a06dc01 100644
@@ -110,9 +110,9 @@ struct bios_file_header {
 };
 
 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);
 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);
 int asd_chk_write_status(struct asd_ha_struct *asd_ha,
 		u32 sector_addr, u8 erase_flag);
 int asd_check_flash_type(struct asd_ha_struct *asd_ha);
drivers/scsi/aic94xx/aic94xx_seq.c +4 -3
index f4272ac..8f98e33 100644
@@ -46,7 +46,7 @@
 static const struct firmware *sequencer_fw;
 static u16 cseq_vecs[CSEQ_NUM_VECS], lseq_vecs[LSEQ_NUM_VECS], mode2_task,
 	cseq_idle_loop, lseq_idle_loop;
-static u8 *cseq_code, *lseq_code;
+static const u8 *cseq_code, *lseq_code;
 static u32 cseq_code_size, lseq_code_size;
 
 static u16 first_scb_site_no = 0xFFFF;
@@ -1235,7 +1235,8 @@ int asd_release_firmware(void)
 static int asd_request_firmware(struct asd_ha_struct *asd_ha)
 {
 	int err, i;
-	struct sequencer_file_header header, *hdr_ptr;
+	struct sequencer_file_header header;
+	const struct sequencer_file_header *hdr_ptr;
 	u32 csum = 0;
 	u16 *ptr_cseq_vecs, *ptr_lseq_vecs;
 
@@ -1249,7 +1250,7 @@ static int asd_request_firmware(struct asd_ha_struct *asd_ha)
 	if (err)
 		return err;
 
-	hdr_ptr = (struct sequencer_file_header *)sequencer_fw->data;
+	hdr_ptr = (const struct sequencer_file_header *)sequencer_fw->data;
 
 	header.csum = le32_to_cpu(hdr_ptr->csum);
 	header.major = le32_to_cpu(hdr_ptr->major);
Signature · 1 line
1.5.4.5
#23 lore raw

PATCH v2 13/28 zd1201: treat firmware data as const

In reply to David Woodhouse
---
 drivers/net/wireless/zd1201.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/zd1201.c +1 -1
index d5c0c66..78baa0f 100644
@@ -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;
Signature · 1 line
1.5.4.5
#24 lore raw

PATCH v2 14/28 rt2x00: treat firmware data as const

In reply to David Woodhouse
---
 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(-)
drivers/net/wireless/rt2x00/rt2x00.h +2 -2
index 57bdc15..79eabaa 100644
@@ -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);
 
 	/*
drivers/net/wireless/rt2x00/rt2x00pci.h +1 -1
index 9d1cdb9..b41967e 100644
@@ -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);
 }
drivers/net/wireless/rt2x00/rt61pci.c +2 -2
index 14bc7b2..bb78de5 100644
@@ -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 *data, const size_t len)
 {
 	u16 crc;
 
@@ -932,7 +932,7 @@ static u16 rt61pci_get_firmware_crc(void *data, const size_t len)
 	return crc;
 }
 
-static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
+static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
 				 const size_t len)
 {
 	int i;
drivers/net/wireless/rt2x00/rt73usb.c +3 -3
index da19a3a..36c2f17 100644
@@ -850,7 +850,7 @@ static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
 	return FIRMWARE_RT2571;
 }
 
-static u16 rt73usb_get_firmware_crc(void *data, const size_t len)
+static u16 rt73usb_get_firmware_crc(const void *data, const size_t len)
 {
 	u16 crc;
 
@@ -867,13 +867,13 @@ static u16 rt73usb_get_firmware_crc(void *data, const size_t len)
 	return crc;
 }
 
-static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
+static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
 				 const size_t len)
 {
 	unsigned int i;
 	int status;
 	u32 reg;
-	char *ptr = data;
+	const char *ptr = data;
 	char *cache;
 	int buflen;
 	int timeout;
Signature · 1 line
1.5.4.5
#25 lore raw

PATCH v2 15/28 p54: treat firmware data as const

In reply to David Woodhouse
---
 drivers/net/wireless/p54/p54usb.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/net/wireless/p54/p54usb.c +3 -2
index 98ddbb3..6728254 100644
@@ -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) {
Signature · 1 line
1.5.4.5
#26 lore raw

PATCH v2 16/28 atmel: treat firmware data as const

In reply to David Woodhouse
---
 drivers/net/wireless/atmel.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/atmel.c +3 -3
index 438e63e..d1acef7 100644
@@ -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);
Signature · 1 line
1.5.4.5
#27 lore raw

PATCH v2 17/28 irda-usb: treat firmware data as const

In reply to David Woodhouse
---
 drivers/net/irda/irda-usb.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)
drivers/net/irda/irda-usb.c +6 -6
index 6f50ed7..18b471c 100644
@@ -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;
 
         /*
Signature · 1 line
1.5.4.5
#28 lore raw

PATCH v2 18/28 cxgb3: treat firmware data as const

In reply to David Woodhouse
---
 drivers/net/cxgb3/common.h |    5 +++--
 drivers/net/cxgb3/t3_hw.c  |    7 ++++---
 2 files changed, 7 insertions(+), 5 deletions(-)
drivers/net/cxgb3/common.h +3 -2
index 579bee4..8e8ebd7 100644
@@ -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);
drivers/net/cxgb3/t3_hw.c +4 -3
index d405a93..47d5178 100644
@@ -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 i;
-	__be32 *buf = (__be32 *)data;
+	const __be32 *buf = (const __be32 *)data;
 
 	for (i = 0; i < PROTO_SRAM_LINES; i++) {
 		t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, be32_to_cpu(*buf++));
Signature · 1 line
1.5.4.5
#29 lore raw

PATCH v2 19/28 bt8xx: treat firmware data as const

In reply to David Woodhouse
---
 drivers/media/video/bt8xx/bttv-cards.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/media/video/bt8xx/bttv-cards.c +2 -1
index f20a01c..f93f1ad 100644
@@ -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;
Signature · 1 line
1.5.4.5
#30 lore raw

PATCH v2 20/28 ttusb-dec: treat firmware data as const

In reply to David Woodhouse
---
 drivers/media/dvb/ttusb-dec/ttusb_dec.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/media/dvb/ttusb-dec/ttusb_dec.c +1 -1
index 42eee04..8af88f1 100644
@@ -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;
Signature · 1 line
1.5.4.5
#31 lore raw

PATCH v2 21/28 dvb frontends: treat firmware data as const

In reply to David Woodhouse
---
 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(-)
drivers/media/dvb/frontends/bcm3510.c +3 -2
index d268e65..cf5e576 100644
@@ -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");
drivers/media/dvb/frontends/nxt200x.c +2 -1
index 23d0228..af29835 100644
@@ -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;
drivers/media/dvb/frontends/or51211.c +2 -2
index 7eaa476..6afe12a 100644
@@ -69,7 +69,7 @@ struct or51211_state {
 	u32 current_frequency;
 };
 
-static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf,
+static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf,
 			   int len)
 {
 	int err;
@@ -77,7 +77,7 @@ static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf,
 	msg.addr	= reg;
 	msg.flags	= 0;
 	msg.len		= len;
-	msg.buf		= buf;
+	msg.buf		= (u8 *)buf;
 
 	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
 		printk(KERN_WARNING "or51211: i2c_writebytes error "
drivers/media/dvb/frontends/sp8870.c +1 -1
index aa78aa1..1c9a9b4 100644
@@ -98,7 +98,7 @@ static int sp8870_readreg (struct sp8870_state* state, u16 reg)
 static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
 {
 	struct i2c_msg msg;
-	char *fw_buf = fw->data;
+	const char *fw_buf = fw->data;
 	int fw_pos;
 	u8 tx_buf[255];
 	int tx_len;
drivers/media/dvb/frontends/sp887x.c +1 -1
index 49f5587..4543609 100644
@@ -140,7 +140,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware
 	u8 buf [BLOCKSIZE+2];
 	int i;
 	int fw_size = fw->size;
-	unsigned char *mem = fw->data;
+	const unsigned char *mem = fw->data;
 
 	dprintk("%s\n", __func__);
 
drivers/media/dvb/frontends/tda10048.c +1 -1
index 090fb7d..0ab8d86 100644
@@ -233,7 +233,7 @@ static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
 }
 
 static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg,
-	u8 *data, u16 len)
+				 const u8 *data, u16 len)
 {
 	int ret = -EREMOTEIO;
 	struct i2c_msg msg;
drivers/media/dvb/frontends/tda1004x.c +1 -1
index 4997384..ff6b427 100644
@@ -317,7 +317,7 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state,
 }
 
 static int tda1004x_do_upload(struct tda1004x_state *state,
-			      unsigned char *mem, unsigned int len,
+			      const unsigned char *mem, unsigned int len,
 			      u8 dspCodeCounterReg, u8 dspCodeInReg)
 {
 	u8 buf[65];
Signature · 1 line
1.5.4.5
#32 lore raw

PATCH v2 22/28 cxusb: treat firmware data as const

In reply to David Woodhouse

...which means allocating our own copy when we want to modify it.

---
 drivers/media/dvb/dvb-usb/cxusb.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)
drivers/media/dvb/dvb-usb/cxusb.c +18 -3
index 720fcd1..94bb482 100644
@@ -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;
 		}
 	}
 
Signature · 1 line
1.5.4.5
#33 lore raw

Re: [PATCHv2 22/28] cxusb: treat firmware data as const

David,

It's broken... Please see fix, below:

Quoted 40 lines · David Woodhouse

...which means allocating our own copy when we want to modify it.

---
 drivers/media/dvb/dvb-usb/cxusb.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)
drivers/media/dvb/dvb-usb/cxusb.c +14 -2
index 720fcd1..94bb482 100644
@@ -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] =

drivers/media/dvb/dvb-usb/cxusb.c static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, · line 726

Quoted 10 lines
drivers/media/dvb/dvb-usb/cxusb.c +4 -1
 				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;
 		}
 	}
 

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.

---
 linux/drivers/media/dvb/dvb-usb/cxusb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/dvb/dvb-usb/cxusb.c +1 -1
@@ -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;
#34 lore raw

Re: [PATCHv2 22/28] cxusb: treat firmware data as const

Quoted 2 lines · Michael Krufky

The unmodified firmware was being uploaded to the device, instead of the patched firmware :-(

Heh. Stupid dwmw2. Thanks.

Signature · 1 line
dwmw2
#35 lore raw

Re: [PATCHv2 22/28] cxusb: treat firmware data as const

In reply to Michael Krufky
Quoted 1 line · Michael Krufky

It's broken... Please see fix, below:

commit e6983a70abb3e6d7a0d711176c89113c81f2ead6

Author: David Woodhouse <[email protected]>
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)

drivers/media/dvb/dvb-usb/cxusb.c +18 -3
index 720fcd1..0286156 100644
@@ -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;
 		}
 	}
 
Signature · 1 line
dwmw2
#36 lore raw

PATCH v2 23/28 gp8psk: treat firmware data as const

In reply to David Woodhouse
---
 drivers/media/dvb/dvb-usb/gp8psk.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/media/dvb/dvb-usb/gp8psk.c +2 -1
index 9a942af..85836da 100644
@@ -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) "
Signature · 1 line
1.5.4.5
#37 lore raw

PATCH v2 24/28 tuners: treat firmware data as const

In reply to David Woodhouse
---
 drivers/media/common/tuners/tuner-xc2028.c |    2 +-
 drivers/media/common/tuners/xc5000.c       |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/media/common/tuners/tuner-xc2028.c +1 -1
index 9e9003c..0a6e26a 100644
@@ -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];
drivers/media/common/tuners/xc5000.c +1 -1
index ceae6db..d21a5a7 100644
@@ -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;
 
Signature · 1 line
1.5.4.5
#38 lore raw

PATCH v2 25/28 firmware: make fw->data const

In reply to David Woodhouse

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).

---
 drivers/base/firmware_class.c |    2 +-
 include/linux/firmware.h      |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/base/firmware_class.c +1 -1
index 9fd4a85..264b3a2 100644
@@ -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;
include/linux/firmware.h +1 -1
index 4d10c73..5e73f3f 100644
@@ -8,7 +8,7 @@
 
 struct firmware {
 	size_t size;
-	u8 *data;
+	const u8 *data;
 };
 
 struct device;
Signature · 1 line
1.5.4.5
#39 lore raw

PATCH v2 26/28 firmware: allow firmware files to be built into kernel image

In reply to David Woodhouse

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.

---
 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(-)
drivers/base/firmware_class.c +31 -2
index 264b3a2..c09f060 100644
@@ -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;
 	}
 
+	for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
+	     builtin++) {
+		if (strcmp(name, builtin->name))
+			continue;
+		printk(KERN_INFO "firmware: using built-in firmware %s\n",
+		       name);
+		firmware->size = builtin->size;
+		firmware->data = builtin->data;
+		return 0;
+	}
+
+	if (uevent)
+		printk(KERN_INFO "firmware: requesting %s\n", name);
+
 	retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
 	if (retval)
 		goto error_kfree_fw;
@@ -473,8 +494,16 @@ request_firmware(const struct firmware **firmware_p, const char *name,
 void
 release_firmware(const struct firmware *fw)
 {
+	struct builtin_fw *builtin;
+
 	if (fw) {
+		for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
+		     builtin++) {
+			if (fw->data == builtin->data)
+				goto free_fw;
+		}
 		vfree(fw->data);
+	free_fw:
 		kfree(fw);
 	}
 }
include/asm-generic/vmlinux.lds.h +7 -0
index f054778..8d71a40 100644
@@ -86,6 +86,13 @@
 		VMLINUX_SYMBOL(__end_pci_fixups_resume) = .;		\
 	}								\
 									\
+	/* Built-in firmware blobs */					\
+	.builtin_fw        : AT(ADDR(.builtin_fw) - LOAD_OFFSET) {	\
+		VMLINUX_SYMBOL(__start_builtin_fw) = .;			\
+		*(.builtin_fw)						\
+		VMLINUX_SYMBOL(__end_builtin_fw) = .;			\
+	}								\
+									\
 	/* RapidIO route ops */						\
 	.rio_route        : AT(ADDR(.rio_route) - LOAD_OFFSET) {	\
 		VMLINUX_SYMBOL(__start_rio_route_ops) = .;		\
include/linux/firmware.h +21 -0
index 5e73f3f..279eaad 100644
@@ -1,7 +1,10 @@
 #ifndef _LINUX_FIRMWARE_H
 #define _LINUX_FIRMWARE_H
+
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/compiler.h>
+
 #define FIRMWARE_NAME_MAX 30 
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
@@ -13,6 +16,24 @@ struct firmware {
 
 struct device;
 
+struct builtin_fw {
+	char *name;
+	void *data;
+	unsigned long size;
+};
+
+/* We have to play tricks here much like stringify() to get the
+   __COUNTER__ macro to be expanded as we want it */
+#define __fw_concat1(x,y) x##y
+#define __fw_concat(x,y) __fw_concat1(x,y)
+
+#define DECLARE_BUILTIN_FIRMWARE(name, blob)				     \
+	DECLARE_BUILTIN_FIRMWARE_SIZE(name, &(blob), sizeof(blob))
+
+#define DECLARE_BUILTIN_FIRMWARE_SIZE(name, blob, size)			     \
+	static const struct builtin_fw __fw_concat(__builtin_fw,__COUNTER__) \
+	__used __section(.builtin_fw) = { name, blob, size }
+
 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 int request_firmware(const struct firmware **fw, const char *name,
 		     struct device *device);
Signature · 1 line
1.5.4.5
#40 lore raw

Re: [PATCHv2 26/28] firmware: allow firmware files to be built into kernel image

Quoted 127 lines · On Sunday 25 May 2008 20:23:56 David Woodhouse wrote:

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.

---
 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(-)
drivers/base/firmware_class.c +23 -2
index 264b3a2..c09f060 100644
@@ -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;
 	}
 
+	for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
+	     builtin++) {
+		if (strcmp(name, builtin->name))
+			continue;
+		printk(KERN_INFO "firmware: using built-in firmware %s\n",
+		       name);
+		firmware->size = builtin->size;
+		firmware->data = builtin->data;
+		return 0;
+	}
+
+	if (uevent)
+		printk(KERN_INFO "firmware: requesting %s\n", name);
+
 	retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
 	if (retval)
 		goto error_kfree_fw;
@@ -473,8 +494,16 @@ request_firmware(const struct firmware **firmware_p,

const char *name, void
release_firmware(const struct firmware *fw)
{

drivers/base/firmware_class.c +8 -0
+	struct builtin_fw *builtin;
+
 	if (fw) {
+		for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
+		     builtin++) {
+			if (fw->data == builtin->data)
+				goto free_fw;
+		}
 		vfree(fw->data);
+	free_fw:
 		kfree(fw);
 	}
 }
(quoted diff) +0 -0

b/include/asm-generic/vmlinux.lds.h index f054778..8d71a40 100644

include/asm-generic/vmlinux.lds.h +7 -0
@@ -86,6 +86,13 @@
 		VMLINUX_SYMBOL(__end_pci_fixups_resume) = .;		\
 	}								\
 									\
+	/* Built-in firmware blobs */					\
+	.builtin_fw        : AT(ADDR(.builtin_fw) - LOAD_OFFSET) {	\
+		VMLINUX_SYMBOL(__start_builtin_fw) = .;			\
+		*(.builtin_fw)						\
+		VMLINUX_SYMBOL(__end_builtin_fw) = .;			\
+	}								\
+									\
 	/* RapidIO route ops */						\
 	.rio_route        : AT(ADDR(.rio_route) - LOAD_OFFSET) {	\
 		VMLINUX_SYMBOL(__start_rio_route_ops) = .;		\
include/linux/firmware.h +3 -0
index 5e73f3f..279eaad 100644
@@ -1,7 +1,10 @@
 #ifndef _LINUX_FIRMWARE_H
 #define _LINUX_FIRMWARE_H
+
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/compiler.h>
+
 #define FIRMWARE_NAME_MAX 30
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
@@ -13,6 +16,24 @@ struct firmware {
 
 struct device;
 

include/linux/firmware.h struct firmware { · line 28

Quoted 10 lines
include/linux/firmware.h +10 -0
+struct builtin_fw {
+	char *name;
+	void *data;
+	unsigned long size;
+};
+
+/* We have to play tricks here much like stringify() to get the
+   __COUNTER__ macro to be expanded as we want it */
+#define __fw_concat1(x,y) x##y
+#define __fw_concat(x,y) __fw_concat1(x,y)

Hmm, linux/module.h does this too, perhaps some enthusiast can implement __concat() and use it everywhere.

Cheers,
Rusty.

#41 lore raw

Re: [PATCHv2 26/28] firmware: allow firmware files to be built into kernel image

Quoted 8 lines · Rusty Russell

include/linux/firmware.h struct firmware { · line 28

Quoted 5 lines
include/linux/firmware.h +4 -0
+/* We have to play tricks here much like stringify() to get the
+   __COUNTER__ macro to be expanded as we want it */
+#define __fw_concat1(x,y) x##y
+#define __fw_concat(x,y) __fw_concat1(x,y)

Hmm, linux/module.h does this too, perhaps some enthusiast can implement __concat() and use it everywhere.

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).

Signature · 1 line
dwmw2
#42 lore raw

PATCH v2 27/28 firmware: Add CONFIG_BUILTIN_FIRMWARE option

In reply to David Woodhouse

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.

---
 Makefile             |    2 +-
 drivers/base/Kconfig |   12 ++++++++++
 firmware/Makefile    |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+), 1 deletions(-)
 create mode 100644 firmware/Makefile
Makefile +1 -1
index 20b3235..ac2ab7e 100644
@@ -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/
drivers/base/Kconfig +12 -0
index d7da109..b856fe8 100644
@@ -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
firmware/Makefile new file +58 -0

58 lines not on this page · raw message

Signature · 1 line
1.5.4.5
#43 lore raw

PATCH v3 27/28 firmware: Add CONFIG_BUILTIN_FIRMWARE option

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 <[email protected]>
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.

Makefile +1 -1
index 20b3235..ac2ab7e 100644
@@ -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/
drivers/base/Kconfig +12 -0
index d7da109..b856fe8 100644
@@ -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
firmware/Makefile new file +70 -0

70 lines not on this page · raw message

Signature · 1 line
dwmw2
#44 lore raw

Re: [PATCHv3 27/28] firmware: Add CONFIG_BUILTIN_FIRMWARE option

Quoted 2 lines · David Woodhouse

Still don't have the behaviour we want from clean/mrproper, but I think we need Sam's help with that.

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)))

Signature · 1 line
dwmw2
#45 lore raw

Re: [PATCHv4 27/28] firmware: Add CONFIG_BUILTIN_FIRMWARE option

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 <[email protected]>
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).

Makefile +1 -1
index 20b3235..ac2ab7e 100644
@@ -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/
drivers/base/Kconfig +33 -0
index d7da109..f204ae7 100644
@@ -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 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).
+
+	  This option is a string, and takes the (space-separated) names of the
+	  firmware files -- the same names which appear in MODULE_FIRMWARE()
+	  and request_firmware() in the source. These files should exist under
+	  the directory specified by the BUILTIN_FIRMWARE_DIR option, which is
+	  by default the firmware/ subdirectory of the kernel source tree.
+
+	  So, for example, you might set CONFIG_BUILTIN_FIRMWARE="usb8388.bin",
+	  copy the usb8388.bin file into the firmware/ directory, and build the
+	  kernel. Then any request_firmware("usb8388.bin") will be
+	  satisfied internally without needing to call out to userspace.
+
+config BUILTIN_FIRMWARE_DIR
+	string "Firmware blobs root directory"
+	depends on BUILTIN_FIRMWARE != ""
+	default "firmware"
+	help
+	  This option controls the directory in which the kernel build system
+	  looks for the firmware files listed in the BUILTIN_FIRMWARE option.
+	  The default is the firmware/ directory in the kernel source tree,
+	  but by changing this option you can point it elsewhere, such as
+	  the /lib/firmware/ directory or another separate directory
+	  containing firmware files.
+
 config DEBUG_DRIVER
 	bool "Driver Core verbose debug messages"
 	depends on DEBUG_KERNEL
firmware/Makefile new file +86 -0

86 lines not on this page · raw message

Signature · 1 line
dwmw2
#46 lore raw

[PATCH 29/28] firmware: Add 'firmware_install' make target

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.

---
 Makefile                |    9 +++++++++
 scripts/Makefile.fwinst |   26 ++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 0 deletions(-)
 create mode 100644 scripts/Makefile.fwinst
Makefile +9 -0
index ac2ab7e..3521afe 100644
@@ -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
scripts/Makefile.fwinst new file +26 -0
new file mode 100644
index 0000000..bde4073
@@ -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).
+# ==========================================================================
+
+INSTALL := install
+
+include scripts/Kbuild.include 
+include $(srctree)/$(obj)/Makefile
+
+installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-))
+installed-fw-dirs := $(dir $(installed-fw))
+
+quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)
+      cmd_install = $(INSTALL) -m0644 $< $@
+
+$(installed-fw-dirs):
+	$(call cmd,mkdir)
+
+$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %)/	
+	$(call cmd,install)
+
+.PHONY: __fw_install
+__fw_install: $(installed-fw)
Signature · 5 lines
1.5.4.5


-- 
dwmw2
#47 lore raw

PATCH v2 28/28 firmware: convert korg1212 driver to use firmware loader exclusively

In reply to David Woodhouse
---
 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%)
firmware/Makefile +1 -1
index 4243c5a..bcae927 100644
@@ -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))
firmware/korg/k1212.c renamed from sound/pci/korg1212/korg1212-firmware.h +4 -1
similarity index 99%
rename from sound/pci/korg1212/korg1212-firmware.h
rename to firmware/korg/k1212.c
index f6f5b91..1ed3ebb 100644
@@ -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);
sound/pci/korg1212/korg1212.c +0 -18
index f4c85b5..4a44c0f 100644
@@ -260,14 +260,6 @@ enum MonitorModeSelector {
 #define COMMAND_ACK_DELAY   13         // number of RTC ticks to wait for an acknowledgement
                                        //    from the card after sending a command.
 
-#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
-#include "korg1212-firmware.h"
-static const struct firmware static_dsp_code = {
-	.data = (u8 *)dspCode,
-	.size = sizeof dspCode
-};
-#endif
-
 enum ClockSourceIndex {
    K1212_CLKIDX_AdatAt44_1K = 0,    // selects source as ADAT at 44.1 kHz
    K1212_CLKIDX_AdatAt48K,          // selects source as ADAT at 48 kHz
@@ -412,9 +404,7 @@ struct snd_korg1212 {
 MODULE_DESCRIPTION("korg1212");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
-#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
 MODULE_FIRMWARE("korg/k1212.dsp");
-#endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	   /* ID for this card */
@@ -2348,9 +2338,6 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
         korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
 		offsetof(struct KorgSharedBuffer, AdatTimeCode);
 
-#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
-	dsp_code = &static_dsp_code;
-#else
 	err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
 	if (err < 0) {
 		release_firmware(dsp_code);
@@ -2358,15 +2345,12 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
 		snd_korg1212_free(korg1212);
 		return err;
 	}
-#endif
 
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				dsp_code->size, &korg1212->dma_dsp) < 0) {
 		snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
                 snd_korg1212_free(korg1212);
-#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
 		release_firmware(dsp_code);
-#endif
                 return -ENOMEM;
         }
 
@@ -2376,9 +2360,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
 
 	memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
 
-#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
 	release_firmware(dsp_code);
-#endif
 
 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
 
Signature · 1 line
1.5.4.5
#49 lore raw

Re: [PATCHv2 28/28] firmware: convert korg1212 driver to use firmware loader exclusively

Quoted 7 lines · Alan Cox
Quoted 1 line · On Sun, 25 May 2008 11:23:58 +0100 David Woodhouse <[email protected]> wrote:

--

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

#50 lore raw

Re: [PATCHv2 28/28] firmware: convert korg1212 driver to use firmware loader exclusively

Quoted 4 lines · Yinghai Lu

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.

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.

Signature · 1 line
dwmw2
#51 lore raw

PATCH v2 1/1 maestro3: treat firmware data as const

In reply to David Woodhouse

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.

---
 sound/pci/maestro3.c |   27 +++++++++++++--------------
 1 files changed, 13 insertions(+), 14 deletions(-)
sound/pci/maestro3.c +13 -14
index a536c59..cbb08d9 100644
@@ -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 *)chip->assp_kernel_image->data;
+	data = (const u16 *)chip->assp_kernel_image->data;
 	for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) {
 		snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 
-				  REV_B_CODE_MEMORY_BEGIN + i, data[i]);
+				  REV_B_CODE_MEMORY_BEGIN + i,
+				  le16_to_cpu(data[i]));
 	}
 
 	/*
@@ -2301,10 +2300,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
 	 * drop it there.  It seems that the minisrc doesn't
 	 * need vectors, so we won't bother with them..
 	 */
-	data = (u16 *)chip->assp_minisrc_image->data;
+	data = (const u16 *)chip->assp_minisrc_image->data;
 	for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) {
 		snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 
-				  0x400 + i, data[i]);
+				  0x400 + i, le16_to_cpu(data[i]));
 	}
 
 	/*
@@ -2743,26 +2742,26 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
 
 #ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
 	chip->assp_kernel_image = &assp_kernel;
+	snd_m3_convert_to_le(chip->assp_kernel_image);
 #else
 	err = request_firmware(&chip->assp_kernel_image,
 			       "ess/maestro3_assp_kernel.fw", &pci->dev);
 	if (err < 0) {
 		snd_m3_free(chip);
 		return err;
-	} else
-		snd_m3_convert_from_le(chip->assp_kernel_image);
+	}
 #endif
 
 #ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
 	chip->assp_minisrc_image = &assp_minisrc;
+	snd_m3_convert_to_le(chip->assp_minisrc_image);
 #else
 	err = request_firmware(&chip->assp_minisrc_image,
 			       "ess/maestro3_assp_minisrc.fw", &pci->dev);
 	if (err < 0) {
 		snd_m3_free(chip);
 		return err;
-	} else
-		snd_m3_convert_from_le(chip->assp_minisrc_image);
+	}
 #endif
 
 	if ((err = pci_request_regions(pci, card->driver)) < 0) {
Signature · 5 lines
1.5.4.5


-- 
dwmw2
#52 lore raw

[PATCHv2 30/28] firmware: convert maestro3 driver to use firmware loader exclusively

Quoted 1 line

From d4f7e79e7e1cf8c3bace102c30496bf47684ab82 Mon Sep 17 00:00:00 2001

From: David Woodhouse <[email protected]>
Date: Thu, 29 May 2008 13:32:28 +0300
Subject: [PATCH] firmware: convert maestro3 driver to use firmware loader exclusively

---
 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
firmware/Makefile +2 -0
index ba845ba..4b4a57b 100644
@@ -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))))
firmware/ess/maestro3_assp_kernel.fw.ihex new file +120 -0

120 lines not on this page · raw message

firmware/ess/maestro3_assp_minisrc.fw.ihex new file +51 -0

51 lines not on this page · raw message

sound/pci/Kconfig +1 -1
index a969d95..83c00ae 100644
@@ -754,7 +754,7 @@ config SND_KORG1212_FIRMWARE_IN_KERNEL
 config SND_MAESTRO3
 	tristate "ESS Allegro/Maestro3"
 	depends on SND
-	select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL
+	select FW_LOADER
 	select SND_AC97_CODEC
 	help
 	  Say Y here to include support for soundcards based on ESS Maestro 3
sound/pci/maestro3.c +0 -169

210 lines not on this page · raw message

Signature · 5 lines
1.5.4.5


-- 
dwmw2
#53 lore raw

PATCH 1/1 ymfpci: treat firmware data as const

In reply to David Woodhouse

Standardise both in-kernel and loaded firmware to be stored as little-endian instead of host-endian.

---
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(-)
sound/pci/ymfpci/ymfpci_main.c +34 -25
index 29b3056..6298b29 100644
@@ -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 snd_ymfpci_convert_from_le(const struct firmware *fw) { }
-#else
-static void snd_ymfpci_convert_from_le(const struct firmware *fw)
-{
-	int i;
-	u32 *data = (u32 *)fw->data;
-
-	for (i = 0; i < fw->size / 4; ++i)
-		le32_to_cpus(&data[i]);
-}
-#endif
-
 static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
 {
 	int err, is_1e;
@@ -2050,9 +2061,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
 	err = request_firmware(&chip->dsp_microcode, "yamaha/ds1_dsp.fw",
 			       &chip->pci->dev);
 	if (err >= 0) {
-		if (chip->dsp_microcode->size == YDSXG_DSPLENGTH)
-			snd_ymfpci_convert_from_le(chip->dsp_microcode);
-		else {
+		if (chip->dsp_microcode->size != YDSXG_DSPLENGTH) {
 			snd_printk(KERN_ERR "DSP microcode has wrong size\n");
 			err = -EINVAL;
 		}
@@ -2067,9 +2076,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
 	err = request_firmware(&chip->controller_microcode, name,
 			       &chip->pci->dev);
 	if (err >= 0) {
-		if (chip->controller_microcode->size == YDSXG_CTRLLENGTH)
-			snd_ymfpci_convert_from_le(chip->controller_microcode);
-		else {
+		if (chip->controller_microcode->size != YDSXG_CTRLLENGTH) {
 			snd_printk(KERN_ERR "controller microcode"
 				   " has wrong size\n");
 			err = -EINVAL;
@@ -2090,7 +2097,7 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
 {
 	int i;
 	u16 ctrl;
-	u32 *inst;
+	const __le32 *inst;
 
 	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
 	snd_ymfpci_disable_dsp(chip);
@@ -2105,14 +2112,16 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
 	snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
 
 	/* setup DSP instruction code */
-	inst = (u32 *)chip->dsp_microcode->data;
+	inst = (const __le32 *)chip->dsp_microcode->data;
 	for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
-		snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), inst[i]);
+		snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2),
+				  le32_to_cpu(inst[i]));
 
 	/* setup control instruction code */
-	inst = (u32 *)chip->controller_microcode->data;
+	inst = (const __le32 *)chip->controller_microcode->data;
 	for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
-		snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]);
+		snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2),
+				  le32_to_cpu(inst[i]));
 
 	snd_ymfpci_enable_dsp(chip);
 }
Signature · 5 lines
1.5.4.5


-- 
dwmw2
#54 lore raw

PATCH 1/1 firmware: convert ymfpci driver to use firmware loader exclusively

---
 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
firmware/Makefile +2 -0
index 4b4a57b..c70d18c 100644
@@ -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))))
firmware/yamaha/ds1_ctrl.fw.ihex new file +769 -0

769 lines not on this page · raw message

firmware/yamaha/ds1_dsp.fw.ihex new file +9 -0
new file mode 100644
index 0000000..acb0ba4
@@ -0,0 +1,9 @@
+:1000000081000000A40100000A0000002F00000091
+:1000100053020800170380017B4000003F8400006A
+:100020003C4801003C9401003CD805003C1C000009
+:100030007BC000003F0C05003C5021010000000087
+:1000400000000000000000000000000000000000B0
+:1000500000000000000000000000000000000000A0
+:100060000000000000000000000000000000000090
+:100070000000000000000000000000000000000080
+:00000001FF
firmware/yamaha/ds1e_ctrl.fw.ihex new file +769 -0

769 lines not on this page · raw message

sound/pci/ymfpci/ymfpci_image.h deleted +0 -1565

1,445 lines not on this page · raw message

sound/pci/ymfpci/ymfpci_main.c +0 -63

63 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 5 lines
1.5.4.5


-- 
dwmw2

Part of the diff is not shown here. View the raw message.

#55 lore raw

PATCH 1/1 smctr: use request_firmware()

In reply to David Woodhouse

Subject: [PATCH] smctr: use request_firmware()

---
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
drivers/net/tokenring/Kconfig +8 -0
index e6b2e06..5aa5be1 100644
@@ -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
drivers/net/tokenring/smctr.c +33 -21

133 lines not on this page · raw message

drivers/net/tokenring/smctr.h +0 -2
index 88dfa2e..52df7dd 100644
@@ -1042,8 +1042,6 @@ typedef struct net_local {
         __u16            functional_address[2];
         __u16            bitwise_group_address[2];
 
-	const __u8       *ptr_ucode;
-
 	__u8		cleanup;
 
 	struct sk_buff_head SendSkbQueue;
drivers/net/tokenring/smctr_firmware.h deleted +0 -978

978 lines not on this page · raw message

firmware/Makefile +1 -0
index c70d18c..2f55795 100644
@@ -13,6 +13,7 @@ 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
+fw-shipped-$(CONFIG_SMCTR_FIRMWARE) += tr_smctr.bin
 
 firmware-y    := $(fw-external-y) $(fw-shipped-y)
 firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y))))
firmware/tr_smctr.bin.ihex new file +477 -0

477 lines not on this page · raw message

Signature · 5 lines
1.5.4.5


-- 
dwmw2
#56 lore raw

Re: [PATCH] smctr: use request_firmware()

drivers/net/tokenring/smctr.c static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) · line 2973

Quoted 2 lines
drivers/net/tokenring/smctr.c +2 -0
+       if (request_firmware(&fw, "tr_smctr.bin", &dev->dev))
+               return (UCODE_NOT_PRESENT);

thanks a lot, please add a printk for users:
printk(KERN_ERR "smctr: Can't load firmware file tr_smctr.bin\n")

Signature · 1 line
maks
#57 lore raw

Re: [PATCH] smctr: use request_firmware()

Quoted 3 lines · maximilian attems

thanks a lot, please add a printk for users:
printk(KERN_ERR "smctr: Can't load firmware file tr_smctr.bin\n")

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.

Signature · 1 line
dwmw2
#58 lore raw

PATCH 1/1 kaweth: use request_firmware()

In reply to David Woodhouse
---
 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
drivers/net/usb/Kconfig +8 -0
index 0604f3f..c692510 100644
@@ -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
drivers/net/usb/kaweth.c +23 -15
index 0dcfc03..bcc43b4 100644
@@ -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 KAWETH_TX_TIMEOUT		(5 * HZ)
@@ -108,6 +107,10 @@
 MODULE_AUTHOR("Michael Zappe <[email protected]>, Stephane Alnet <[email protected]>, Brad Hards <[email protected]> and Oliver Neukum <[email protected]>");
 MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("kaweth/new_code.bin");
+MODULE_FIRMWARE("kaweth/new_code_fix.bin");
+MODULE_FIRMWARE("kaweth/trigger_code.bin");
+MODULE_FIRMWARE("kaweth/trigger_code_fix.bin");
 
 static const char driver_name[] = "kaweth";
 
@@ -385,17 +388,26 @@ static int kaweth_set_receive_filter(struct kaweth_device *kaweth,
  *     kaweth_download_firmware
  ****************************************************************/
 static int kaweth_download_firmware(struct kaweth_device *kaweth,
-				    __u8 *data,
-				    __u16 data_len,
+				    const char *fwname,
 				    __u8 interrupt,
 				    __u8 type)
 {
-	if(data_len > KAWETH_FIRMWARE_BUF_SIZE)	{
-		err("Firmware too big: %d", data_len);
+	const struct firmware *fw;
+	int data_len;
+	int ret;
+
+	ret = request_firmware(&fw, fwname, &kaweth->dev->dev);
+	if (ret)
+		return ret;
+
+	if (fw->size > KAWETH_FIRMWARE_BUF_SIZE)	{
+		err("Firmware too big: %d", fw->size);
 		return -ENOSPC;
 	}
+	data_len = fw->size;
+	memcpy(kaweth->firmware_buf, fw->data, fw->size);
 
-	memcpy(kaweth->firmware_buf, data, data_len);
+	release_firmware(fw);
 
 	kaweth->firmware_buf[2] = (data_len & 0xFF) - 7;
 	kaweth->firmware_buf[3] = data_len >> 8;
@@ -1009,8 +1021,7 @@ static int kaweth_probe(
 		info("Downloading firmware...");
 		kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
 		if ((result = kaweth_download_firmware(kaweth,
-						      kaweth_new_code,
-						      len_kaweth_new_code,
+						      "kaweth/new_code.bin",
 						      100,
 						      2)) < 0) {
 			err("Error downloading firmware (%d)", result);
@@ -1018,8 +1029,7 @@ static int kaweth_probe(
 		}
 
 		if ((result = kaweth_download_firmware(kaweth,
-						      kaweth_new_code_fix,
-						      len_kaweth_new_code_fix,
+						      "kaweth/new_code_fix.bin",
 						      100,
 						      3)) < 0) {
 			err("Error downloading firmware fix (%d)", result);
@@ -1027,8 +1037,7 @@ static int kaweth_probe(
 		}
 
 		if ((result = kaweth_download_firmware(kaweth,
-						      kaweth_trigger_code,
-						      len_kaweth_trigger_code,
+						      "kaweth/trigger_code.bin",
 						      126,
 						      2)) < 0) {
 			err("Error downloading trigger code (%d)", result);
@@ -1037,8 +1046,7 @@ static int kaweth_probe(
 		}
 
 		if ((result = kaweth_download_firmware(kaweth,
-						      kaweth_trigger_code_fix,
-						      len_kaweth_trigger_code_fix,
+						      "kaweth/trigger_code_fix.bin",
 						      126,
 						      3)) < 0) {
 			err("Error downloading trigger code fix (%d)", result);
drivers/net/usb/kawethfw.h deleted +0 -557

557 lines not on this page · raw message

firmware/Makefile +3 -0
index 2f55795..f5c50d6 100644
@@ -14,6 +14,9 @@ fw-shipped-$(CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL) += \
 fw-shipped-$(CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL) += yamaha/ds1_ctrl.fw \
 		yamaha/ds1_dsp.fw yamaha/ds1e_ctrl.fw
 fw-shipped-$(CONFIG_SMCTR_FIRMWARE) += tr_smctr.bin
+fw-shipped-$(CONFIG_USB_KAWETH_FIRMWARE) += kaweth/new_code.bin \
+		kaweth/new_code_fix.bin kaweth/trigger_code.bin \
+		kaweth/trigger_code_fix.bin
 
 firmware-y    := $(fw-external-y) $(fw-shipped-y)
 firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y))))
firmware/kaweth/new_code.bin.ihex new file +206 -0

206 lines not on this page · raw message

firmware/kaweth/new_code_fix.bin.ihex new file +40 -0
new file mode 100644
index 0000000..fb35d3d
@@ -0,0 +1,40 @@
+:10000000B6C3AABBCCDD0200080028002C003400D7
+:100010003C0040004800540058005E006400680046
+:100020006E006C00720076007C00800086008A0002
+:100030009000940098009E00A600AA00B000B400B2
+:10004000B800C000C600CA00D000D400D800E0004C
+:10005000DE00E800F000FC0004010A0118012201A2
+:1000600028013A013E017E0198019C01A201AC01E8
+:10007000B201BA01C001C801D001D601F401FC01EE
+:10008000080216021A0222022A022E023E0244022C
+:100090004A025002640262026C02720286028C0200
+:1000A00090029E02BC02D002D802DC02E002E8020A
+:1000B000E602F402FE0204030C0328037C0390030F
+:1000C00094039C03A203C003D003D403EE03FA03FA
+:1000D000FE032E0432043C0440044E0476047C04E7
+:1000E00084048A048E04A604B004B804BE04D204B6
+:1000F000DC04EE0410051A0524052A05360534052E
+:100100003C05420564056A056E058605220626063D
+:100110002C06300642064A064E06560654065A0675
+:1001200060066606E806EE06F406160726072C07A4
+:10013000320736073A073E07520756075A07640741
+:1001400076077A07800784078A079E07A207DA07DF
+:10015000DE07E207E607EA07EE07F207F6070E08F2
+:10016000160818081A081C081E0820082208240867
+:10017000260828082A082C082E0832083A084608BB
+:100180004E0854085E0878087E08820886088C08A5
+:10019000900898089E08A408AA08B008AE08B408F9
+:1001A000BE08C408C208CA08C808D408E408E80899
+:1001B000F608140912091A092009260924092A092E
+:1001C0003E094C0956097009740978097E097C09B1
+:1001D000820998099C09A009A609B809DC09E8095F
+:1001E000EC09FC09120A180A1E0A420A460A4E0ABB
+:1001F000540A5A0A5E0A680A6E0A720A780A760A6D
+:100200007C0A800A840A940AA40AB80ABE0ABC0AB4
+:10021000C20AC80AC60ACC0AD00AD40AD80ADC0A1A
+:10022000E00AF20AF60AFA0A140B1A0B200B1E0B4C
+:10023000260B2E0B2C0B360B3C0B420B400B4A0BA8
+:10024000AA0BB00BB60BC00BC80BDA0BE80BEC0B10
+:10025000FA0B4A0C540C620C660C960C9A0CA00C0F
+:0E026000A60CA40CAC0CB20CB00CC00C000030
+:00000001FF
firmware/kaweth/trigger_code.bin.ihex new file +13 -0
new file mode 100644
index 0000000..c3e1658
@@ -0,0 +1,13 @@
+:10000000B6C3AABBCCDDC807A000F0075E0006009F
+:10001000F0070A000800F00900000200E7073600B8
+:100020000000F00700000400E70750C310C0F0090B
+:100030000EC00000E78701000EC097CFD70900C0AF
+:100040001702C807A000E71750C310C030D804003B
+:10005000305C08000400B0C00600C805E70500C019
+:10006000C0DF97CF49AFC007000060AF4AAF000CB8
+:100070000C0040D2001C0C0040D230000800F007F9
+:1000800000000400F0078600060067CF270C02007E
+:100090000000270C00000EC049AF64AFC00700008D
+:1000A0004BAF4AAF5ACF0000000000000000000034
+:0600B000940005000000B1
+:00000001FF
firmware/kaweth/trigger_code_fix.bin.ihex new file +3 -0
new file mode 100644
index 0000000..7712f73
@@ -0,0 +1,3 @@
+:10000000B6C3AABBCCDD0200060018003E0080008B
+:060010009800AA000000A8
+:00000001FF
Signature · 5 lines
1.5.4.5


-- 
dwmw2
#59 lore raw

Re: [PATCH] kaweth: use request_firmware()

Am Donnerstag, 29. Mai 2008 16:20:41 schrieb David Woodhouse:>                 if ((result = kaweth_download_firmware(kaweth,> -                                                     kaweth_trigger_code_fix,> -                                                     len_kaweth_trigger_code_fix,> +                                                     "kaweth/trigger_code_fix.bin", We don't put hirarchy policy into drivers.
Regards Oliver
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

#60 lore raw

Re: [PATCH] kaweth: use request_firmware()

Quoted 7 lines · Oliver Neukum

Am Donnerstag, 29. Mai 2008 16:20:41 schrieb David Woodhouse:

drivers/net/usb/kaweth.c static int kaweth_probe( · line 1049

Quoted 4 lines

if ((result = kaweth_download_firmware(kaweth,

drivers/net/usb/kaweth.c +1 -2
-                                                     kaweth_trigger_code_fix,
-                                                     len_kaweth_trigger_code_fix,
+                                                     "kaweth/trigger_code_fix.bin",

We don't put hirarchy policy into drivers.

Not a strictly accurate observation; we've been doing so for some time.

Signature · 1 line
dwmw2
maintainer
#61 lore raw

Re: [PATCH] kaweth: use request_firmware()

Hi David,

Quoted 11 lines
Quoted 9 lines
Quoted 7 lines

if ((result = kaweth_download_firmware(kaweth,
-
kaweth_trigger_code_fix,
-
len_kaweth_trigger_code_fix,
+ "kaweth/
trigger_code_fix.bin",

We don't put hirarchy policy into drivers.

Not a strictly accurate observation; we've been doing so for some time.

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

#62 lore raw

Re: [PATCH] kaweth: use request_firmware()

Quoted 4 lines

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.

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

#63 lore raw

Re: [PATCH] kaweth: use request_firmware()

Am Freitag, 30. Mai 2008 17:48:42 schrieb Alan Cox:

Quoted 9 lines
Quoted 4 lines

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.

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.

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

#64 lore raw

Re: [PATCH] kaweth: use request_firmware()

Quoted 2 lines · Oliver Neukum

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.

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

Signature · 4 lines
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}
maintainer
#65 lore raw

Re: [PATCH] kaweth: use request_firmware()

In reply to Alan Cox

Hi Alan,

Quoted 9 lines
Quoted 4 lines

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.

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.

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

#66 lore raw

Re: [PATCH] kaweth: use request_firmware()

Quoted 5 lines

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.

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).

No sneaking involved.

Quoted 3 lines

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.

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

#67 lore raw

PATCH 1/1 ttusb-budget: use request_firmware()

In reply to David Woodhouse
---
 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
drivers/media/dvb/ttusb-budget/Kconfig +9 -0
index f546bcc..7e6b141 100644
@@ -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'.
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +10 -4
index 732ce4d..cef90c6 100644
@@ -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 num
 	return i;
 }
 
-#include "dvb-ttusb-dspbootcode.h"
-
 static int ttusb_boot_dsp(struct ttusb *ttusb)
 {
+	const struct firmware *fw;
 	int i, err;
 	u8 b[40];
 
+	err = request_firmware(&fw, "ttusb-budget-dspbootcode.bin",
+			       &ttusb->dev->dev);
+	if (err)
+		return err;
+
 	/* BootBlock */
 	b[0] = 0xaa;
 	b[2] = 0x13;
@@ -299,8 +304,8 @@ static int ttusb_boot_dsp(struct ttusb *ttusb)
 
 	/* upload dsp code in 32 byte steps (36 didn't work for me ...) */
 	/* 32 is max packet size, no messages should be splitted. */
-	for (i = 0; i < sizeof(dsp_bootcode); i += 28) {
-		memcpy(&b[4], &dsp_bootcode[i], 28);
+	for (i = 0; i < fw->size; i += 28) {
+		memcpy(&b[4], &fw->data[i], 28);
 
 		b[1] = ++ttusb->c;
 
@@ -1820,3 +1825,4 @@ module_exit(ttusb_exit);
 MODULE_AUTHOR("Holger Waechtler <[email protected]>");
 MODULE_DESCRIPTION("TTUSB DVB Driver");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("ttusb-budget-dspbootcode.bin");
drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h deleted +0 -1644

1,644 lines not on this page · raw message

firmware/Makefile +1 -0
index 2f6a6e2..30b6ef4 100644
@@ -17,6 +17,7 @@ fw-shipped-$(CONFIG_SMCTR_FIRMWARE) += tr_smctr.bin
 fw-shipped-$(CONFIG_USB_KAWETH_FIRMWARE) += kaweth/new_code.bin \
 		kaweth/new_code_fix.bin kaweth/trigger_code.bin \
 		kaweth/trigger_code_fix.bin
+fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET_FIRMWARE) += ttusb-budget-dspbootcode.bin
 
 firmware-y    := $(fw-external-y) $(fw-shipped-y)
 firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y))))
firmware/ttusb-budget-dspbootcode.bin.ihex new file +820 -0

820 lines not on this page · raw message

Signature · 5 lines
1.5.4.5


-- 
dwmw2
#69 lore raw

PATCH 1/1 keyspan: use request_firmware()

In reply to David Woodhouse
drivers/usb/serial/keyspan.c +42 -36
index 3df8a66..4a28d91 100644
@@ -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 = "USA19QI";
+		fw_name = "keyspan/usa19qi.fw";
 		break;
 			     
 	case keyspan_mpr_pre_product_id:
-		record = &keyspan_mpr_firmware[0];
-		fw_name = "MPR";
+		fw_name = "keyspan/mpr.fw";
 		break;
 
 	case keyspan_usa19qw_pre_product_id:
-		record = &keyspan_usa19qw_firmware[0];
-		fw_name = "USA19QI";
+		fw_name = "keyspan/usa19qw.fw";
 		break;
 			     
 	case keyspan_usa18x_pre_product_id:
-		record = &keyspan_usa18x_firmware[0];
-		fw_name = "USA18X";
+		fw_name = "keyspan/usa18x.fw";
 		break;
 			     
 	case keyspan_usa19w_pre_product_id:
-		record = &keyspan_usa19w_firmware[0];
-		fw_name = "USA19W";
+		fw_name = "keyspan/usa19w.fw";
 		break;
 		
 	case keyspan_usa49w_pre_product_id:
-		record = &keyspan_usa49w_firmware[0];
-		fw_name = "USA49W";
+		fw_name = "keyspan/usa49w.fw";
 		break;
 
 	case keyspan_usa49wlc_pre_product_id:
-		record = &keyspan_usa49wlc_firmware[0];
-		fw_name = "USA49WLC";
+		fw_name = "keyspan/usa49wlc.fw";
 		break;
 
 	default:
-		record = NULL;
-		fw_name = "Unknown";
-		break;
+		dev_err(&serial->dev->dev, "Unknown product ID (%04x)\n",
+			le16_to_cpu(serial->dev->descriptor.idProduct));
+		return 1;
 	}
 
-	if (record == NULL) {
+	if (request_firmware(&fw, fw_name, &serial->dev->dev)) {
 		dev_err(&serial->dev->dev, "Required keyspan firmware image (%s) unavailable.\n", fw_name);
 		return(1);
 	}
@@ -1434,19 +1424,22 @@ static int keyspan_fake_startup (struct usb_serial *serial)
 		/* download the firmware image */
 	response = ezusb_set_reset(serial, 1);
 
-	while(record->address != 0xffff) {
-		response = ezusb_writememory(serial, record->address,
+	record = (const struct ihex_binrec *)fw->data;
+
+	while (record) {
+		response = ezusb_writememory(serial, be32_to_cpu(record->addr),
 					     (unsigned char *)record->data,
-					     record->data_size, 0xa0);
+					     record->len, 0xa0);
 		if (response < 0) {
 			dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan"
 				"firmware (%d %04X %p %d)\n",
-				response, 
-				record->address, record->data, record->data_size);
+				response, be32_to_cpu(record->addr), 
+				record->data, record->len);
 			break;
 		}
-		record++;
+		record = ihex_next_binrec(record);
 	}
+	release_firmware(fw);
 		/* bring device out of reset. Renumeration will occur in a
 		   moment and the new device will bind to the real driver */
 	response = ezusb_set_reset(serial, 0);
@@ -2756,6 +2749,19 @@ MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_LICENSE("GPL");
 
+MODULE_FIRMWARE("keyspan/usa28.fw");
+MODULE_FIRMWARE("keyspan/usa28x.fw");
+MODULE_FIRMWARE("keyspan/usa28xa.fw");
+MODULE_FIRMWARE("keyspan/usa28xb.fw");
+MODULE_FIRMWARE("keyspan/usa19.fw");
+MODULE_FIRMWARE("keyspan/usa19qi.fw");
+MODULE_FIRMWARE("keyspan/mpr.fw");
+MODULE_FIRMWARE("keyspan/usa19qw.fw");
+MODULE_FIRMWARE("keyspan/usa18x.fw");
+MODULE_FIRMWARE("keyspan/usa19w.fw");
+MODULE_FIRMWARE("keyspan/usa49w.fw");
+MODULE_FIRMWARE("keyspan/usa49wlc.fw");
+
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
drivers/usb/serial/keyspan.h +0 -84

90 lines not on this page · raw message

firmware/Makefile +12 -0
index 30b6ef4..eb3b992 100644
@@ -18,6 +18,18 @@ fw-shipped-$(CONFIG_USB_KAWETH_FIRMWARE) += kaweth/new_code.bin \
 		kaweth/new_code_fix.bin kaweth/trigger_code.bin \
 		kaweth/trigger_code_fix.bin
 fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET_FIRMWARE) += ttusb-budget-dspbootcode.bin
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_MPR) += keyspan/mpr.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA18X) += keyspan/usa18x.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19) += keyspan/usa19.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QI) += keyspan/usa19qi.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QW) += keyspan/usa19qw.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19W) += keyspan/usa19w.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28) += keyspan/usa28.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XA) += keyspan/usa28xa.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XB) += keyspan/usa28xb.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28X) += keyspan/usa28x.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49W) += keyspan/usa49w.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49WLC) += keyspan/usa49wlc.fw
 
 firmware-y    := $(fw-external-y) $(fw-shipped-y)
 firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y))))
include/linux/ihex.h new file +28 -0
new file mode 100644
index 0000000..902222f
@@ -0,0 +1,28 @@
+/*
+ * Compact binary representation of ihex records. Some devices need their
+ * firmware loaded in strange orders rather than a single big blob, but 
+ * actually parsing ihex-as-text within the kernel seems silly. Thus,...
+ */
+
+#ifndef __LINUX_IHEX_H__
+#define __LINUX_IHEX_H__
+
+#include <linux/types.h>
+
+struct ihex_binrec {
+	__be32 addr;
+	uint8_t len;
+	uint8_t data[0];
+} __attribute__((aligned(4)));
+
+/* Find the next record, taking into account the 4-byte alignment */
+static inline const struct ihex_binrec *
+ihex_next_binrec(const struct ihex_binrec *rec)
+{
+	int next = ((rec->len + 4) & ~3) - 1;
+	rec = (void *)&rec->data[next];
+
+	return rec->len ? rec : NULL;
+}
+
+#endif /* __LINUX_IHEX_H__ */
Signature · 1 line
dwmw2
#70 lore raw

Re: [PATCH] keyspan: use request_firmware()

On Fri, 30 May 2008 14:45:33 +0300
David Woodhouse <[email protected]> wrote:

[...]

ACK

Seems reasonable to me, though I wouldn't claim to be particularly authoritative on such matters these days :)

Cheers,
Hugh

#71 lore raw

PATCH 1/1 keyspan_pda: use request_firmware()

In reply to David Woodhouse
---
 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
drivers/usb/serial/Kconfig +17 -0
index 31f9cc3..c354203 100644
@@ -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 +556,14 @@ config USB_SERIAL_XIRCOM
 	  To compile this driver as a module, choose M here: the
 	  module will be called keyspan_pda.
 
+config USB_SERIAL_XIRCOM_FIRMWARE
+	bool "Include Xircom / Entregra firmware in kernel"
+	help
+	  This option allows you to build the required firmware for the
+	  Xircom / Entregra serial port into the kernel. Say 'N' and let
+	  it get loaded by udev instead.
+
+
 config USB_SERIAL_OPTION
 	tristate "USB driver for GSM and CDMA modems"
 	help
drivers/usb/serial/keyspan_pda.c +24 -27

94 lines not on this page · raw message

drivers/usb/serial/keyspan_pda_fw.h deleted +0 -99

99 lines not on this page · raw message

drivers/usb/serial/xircom_pgs_fw.h deleted +0 -103

103 lines not on this page · raw message

firmware/Makefile +2 -0
index eb3b992..94e4dd1 100644
@@ -30,6 +30,8 @@ fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XB) += keyspan/usa28xb.fw
 fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28X) += keyspan/usa28x.fw
 fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49W) += keyspan/usa49w.fw
 fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49WLC) += keyspan/usa49wlc.fw
+fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA_FIRMWARE) += keyspan_pda/keyspan_pda.fw
+fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM_FIRMWARE) += keyspan_pda/xircom_pgs.fw
 
 firmware-y    := $(fw-external-y) $(fw-shipped-y)
 firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y))))
firmware/keyspan_pda/keyspan_pda.fw.ihex new file +121 -0

121 lines not on this page · raw message

firmware/keyspan_pda/xircom_pgs.fw.ihex new file +127 -0

127 lines not on this page · raw message

Signature · 5 lines
1.5.4.5


-- 
dwmw2