Skip to contentSkip to conversation

Eagle and ADI 930 usb adsl modem driver

PATCH In review matthieu castet 9 participants 34 messages Oct 29, 2005 – Nov 7, 2005

Subsystems (3)
lore
Share & tools
lore

matthieu castet

author maintainer
#0 lore raw

PATCH 1/1 Eagle and ADI 930 usb adsl modem driver

Hi,

attached is the driver for USB ADSL modems based on the ADI eagle chipset using the usb_atm infrastructure.

The managing part was taken from bsd ueagle driver, other parts were written from scratch.

The driver uses the in-kernel firmware loader :
- to load a first usb firmware when the modem is in pre-firmware state
- to load the dsp firmware that are swapped in host memory.
- to load CMV (configuration and management variables) when the modem boot. (We can't use options or sysfs for this as there many possible values. See
https://mail.gna.org/public/eagleusb-dev/2005-04/msg00031.html for a description of some)
- to load fpga code for 930 chipset.

The device had 4 endpoints :
* 2 for data (use by usbatm). The incoming
endpoint could be iso or bulk. The modem seems buggy and produce lot's of atm errors when using it in bulk mode for speed > 3Mbps, so iso endpoint is need for speed > 3Mbps. At the moment iso endpoint need a patched usbatm library and for this reason is not included in this patch.

* One bulk endpoint for uploading dsp firmware

* One irq endpoint that notices the driver
- if we need to upload a page of the dsp firmware
- an ack for read or write CMV and the value (for the read case).

If order to make the driver cleaner, we design synchronous (read|write)_cmv :
-send a synchronous control message to the modem -wait for an ack or a timeout
-return the value if needed.

In order to run these synchronous usb messages we need a kernel thread.

Please comment and consider for inclusion.

The driver has been tested with sagem fast 800 modems with different eagle chipset revision and with ADI 930 since April 2005.

Thanks.

Matthieu

drivers/usb/atm/Kconfig renamed from drivers/usb/atm.old/Kconfig +13 -0
diff -rNu -x '*.ko*' -x '*.mod*' -x '*.o*' linux-2.6.14/drivers/usb/atm.old/Kconfig linux-2.6.14/drivers/usb/atm/Kconfig
@@ -44,6 +44,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cxacru.
 
+config USB_UEAGLEATM
+	tristate "ADI 930 and eagle USB DSL modem"
+	depends on USB_ATM
+	select FW_LOADER
+	help
+	  Say Y here if you have an ADSL USB modem based on the ADI 930
+	  or eagle chipset. In order to use your modem you will need to
+	  install firmwares and CMV (Command Management Variables); see
+	  <https://gna.org/projects/ueagleatm/> for details.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ueagle-atm.
+	  
 config USB_XUSBATM
 	tristate "Other USB DSL modem support"
 	depends on USB_ATM
drivers/usb/atm/Makefile renamed from drivers/usb/atm.old/Makefile +1 -0
diff -rNu -x '*.ko*' -x '*.mod*' -x '*.o*' linux-2.6.14/drivers/usb/atm.old/Makefile linux-2.6.14/drivers/usb/atm/Makefile
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_USB_CXACRU)	+= cxacru.o
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= speedtch.o
+obj-$(CONFIG_USB_UEAGLEATM)	+= ueagle-atm.o
 obj-$(CONFIG_USB_ATM)		+= usbatm.o
 obj-$(CONFIG_USB_XUSBATM)	+= xusbatm.o
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +1607 -0

1,607 lines not on this page · raw message

drivers/usb/atm/ueagle-atm.h renamed from drivers/usb/atm.old/ueagle-atm.h +353 -0

353 lines not on this page · raw message

#1 lore raw
Quoted 6 lines · matthieu castet

Hi,

attached is the driver for USB ADSL modems based on the ADI eagle chipset using the usb_atm infrastructure.

Dunno much about USB drivers, but..

Review

Quoted 12 lines
(quoted diff) +12 -0
+/*
+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

egad. Is there no better way?

Review

Quoted 8 lines

...

(quoted diff) +7 -0
+static int request_cmvs(struct uea_softc *sc,
+		 struct uea_cmvs **cmvs, const struct firmware **fw)
+{
+	int ret, size;
+	u8 *data;
+	char *file;
+	char cmv_name[256] = FW_DIR;

That's rather a lot of stack. Can this be made static, of kmalloced?

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+	*cmvs = (struct uea_cmvs *)(data + 1);

That's a bit rude - asking the compiler to perform a structure copy from an odd address. memcpy() would be saner.

Review

Quoted 4 lines

...

(quoted diff) +3 -0
+static int uea_kthread(void *data)
+{
+	struct uea_softc *sc = (struct uea_softc *)data;

Unneeded cast.

Review

Quoted 6 lines

...

(quoted diff) +5 -0
+/**
+ * uea_read_proc : /proc information
+ */
+static int uea_read_proc(char *page, 
+		char **start, off_t off, int count, int *eof, void *data)

People get shouted at for adding /proc handlers. Greg may have thoughts...

General: the patch adds tons of trailing whitespace. I stripped that off the patch I added to -mm.

Trivial fixups:

 drivers/usb/atm/ueagle-atm.c |   31 ++++++++++++++-----------------
 1 files changed, 14 insertions(+), 17 deletions(-)
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm/ueagle-atm.c~eagle-and-adi-930-usb-adsl-modem-driver-tidies +14 -17
diff -puN drivers/usb/atm/ueagle-atm.c~eagle-and-adi-930-usb-adsl-modem-driver-tidies drivers/usb/atm/ueagle-atm.c
@@ -74,17 +74,17 @@ static int uea_read_proc(char *page, cha
 
 static struct usb_driver uea_driver;
 static struct proc_dir_entry *uea_procdir;
-DECLARE_MUTEX(uea_semaphore);
+static DECLARE_MUTEX(uea_semaphore);
 static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};
 
 /*
  * User supplied debug level
  */
-static unsigned int debug = 0;
+static unsigned int debug;
 
-static int modem_index = 0;
-static int sync_wait[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 0 };
-static char *cmv_file[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = NULL };
+static int modem_index;
+static int sync_wait[NB_MODEM];
+static char *cmv_file[NB_MODEM];
 
 module_param(debug, uint, 0644);
 MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
@@ -314,15 +314,13 @@ static int uea_idma_write(struct uea_sof
 
 	memcpy(xfer_buff, data, size);
 
-	ret =
-	    usb_bulk_msg(sc->usb_dev,
+	ret = usb_bulk_msg(sc->usb_dev,
 			 usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE),
 			 xfer_buff, size, &bytes_read, BULK_TIMEOUT);
 
 	kfree(xfer_buff);
-	if (ret < 0) {
+	if (ret < 0)
 		return ret;
-	}
 	if (size != bytes_read) {
 		uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size,
 		       bytes_read);
@@ -873,7 +871,7 @@ out:
 
 static int uea_kthread(void *data)
 {
-	struct uea_softc *sc = (struct uea_softc *)data;
+	struct uea_softc *sc = data;
 	int ret = -EAGAIN;
 
 	uea_enters(INS_TO_USBDEV(sc));
@@ -1135,7 +1133,7 @@ static void uea_stop(struct uea_softc *s
 	/* stop any pending boot process */
 	flush_scheduled_work();
 
-     	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
+	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
 
 	usb_kill_urb(sc->urb_int);
 	kfree(sc->urb_int->transfer_buffer);
@@ -1146,7 +1144,6 @@ static void uea_stop(struct uea_softc *s
 	uea_leaves(INS_TO_USBDEV(sc));
 }
 
-
 /* syfs interface */
 static struct uea_softc *dev_to_uea(struct device *dev)
 {
@@ -1161,7 +1158,7 @@ static struct uea_softc *dev_to_uea(stru
 	if (!usbatm)
 		return NULL;
 
-	return (struct uea_softc *)usbatm->driver_data;
+	return usbatm->driver_data;
 }
 
 /* we need to use semaphore until sysfs and removable devices is fixed
@@ -1247,14 +1244,14 @@ static int uea_getesi(struct uea_softc *
 /* ATM stuff */
 static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
 {
-	struct uea_softc *sc = (struct uea_softc *)usbatm->driver_data;
+	struct uea_softc *sc = usbatm->driver_data;
 
 	return uea_getesi(sc, atm_dev->esi);
 }
 
 static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf)
 {
-	struct uea_softc *sc = (struct uea_softc *)usbatm->driver_data;
+	struct uea_softc *sc = usbatm->driver_data;
 
 	wait_event(sc->sync_q, IS_OPERATIONAL(sc));
 
@@ -1340,7 +1337,7 @@ static int uea_bind(struct usbatm_data *
 			return ret;
 	}
 
-	sc = kcalloc(1, sizeof(struct uea_softc), GFP_KERNEL);
+	sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL);
 	if (!sc) {
 		uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n");
 		return -ENOMEM;
@@ -1382,7 +1379,7 @@ static void destroy_fs_entries(struct ue
 
 static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
 {
-	struct uea_softc *sc = (struct uea_softc *)usbatm->driver_data;
+	struct uea_softc *sc = usbatm->driver_data;
 
 	destroy_fs_entries(sc, intf);
 	uea_stop(sc);

_

#2 lore raw

Hi Andrew,

Quoted 6 lines
Quoted 6 lines
(quoted diff) +6 -0
+/*
+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+{
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

egad. Is there no better way?

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem holding the firmware is mounted; I guess the delay usually gives the filesystem enough time to be mounted. I'm told that the correct solution is to stick the firmware in an initramfs as well. That's a
pity: it would be nice if users could just dump the firmware in an appropriate directory and have everything work [*]. As it is, they also have to regenerate an initramfs.

Ciao,

Duncan.

[*] For legal reasons, users usually have to download and install the firmware themselves. For the speedtouch modems I don't know of any distribution which comes with the firmware preinstalled.

#3 lore raw
Quoted 6 lines · Duncan Sands

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem holding the firmware is mounted; I guess the delay usually gives the filesystem enough time to be mounted. I'm told that the correct solution is to stick the firmware in an initramfs as well.

Why can't we request the firmware again when the device is first used, if it wasn't present when the driver was first loaded?

Signature · 1 line
dwmw2
#4 lore raw
Quoted 2 lines · David Woodhouse

Why can't we request the firmware again when the device is first used, if it wasn't present when the driver was first loaded?

For a start, because currently there is no device to use until the firmware has been loaded.

If people really think that this is a problem which needs to be solved then maybe a better solution would be to extend the $DEVPATH/loading to allow loading the firmware at any time, even asyncronously after the timeout.

Signature · 2 lines
ciao,
Marco
author maintainer
#10 lore raw
In reply to Duncan Sands

Hi Duncan,

Quoted 6 lines · Duncan Sands

Hi Andrew,

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem

No, it wasn't the problem, even when loading with insmod/modprobe the timeout occurs on some configurations. For example on http://atm.eagle-usb.org/wakka.php?wiki=TestUEagleAtmBaud123, you could see the 'firmware ueagle-atm/eagleIII.fw is not available' error.

It is only happen for pre-firmware modem (uea_load_firmware) ie where we just do a request_firmware in the probe without any initialisation before. So the problem seems to appear when we do a request_firmware too early in the usb_probe.

Matthieu

author maintainer
#14 lore raw
In reply to Andrew Morton

Hi Andrew,

thanks for the review.

Quoted 16 lines · Andrew Morton

Review

Quoted 8 lines · matthieu castet

...

(quoted diff) +7 -0
+static int request_cmvs(struct uea_softc *sc,
+		 struct uea_cmvs **cmvs, const struct firmware **fw)
+{
+	int ret, size;
+	u8 *data;
+	char *file;
+	char cmv_name[256] = FW_DIR;

That's rather a lot of stack. Can this be made static, of kmalloced?

I think we'll made it static.

Quoted 7 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+	*cmvs = (struct uea_cmvs *)(data + 1);

That's a bit rude - asking the compiler to perform a structure copy from an odd address. memcpy() would be saner.

Could you elaborate a bit more ?
I don't see where there is a copy.
*cmvs is a pointer to the structure, not the structure. And when we parse the structure, we use get_unaligned functions.

Quoted 10 lines

Review

Quoted 6 lines

...

(quoted diff) +5 -0
+/**
+ * uea_read_proc : /proc information
+ */
+static int uea_read_proc(char *page, 
+		char **start, off_t off, int count, int *eof, void *data)

People get shouted at for adding /proc handlers. Greg may have thoughts...

Ok, we may be convert some values to sysfs. It would be nice if usbatm allow us to export some common value (margin, ...).

Matthieu

#17 lore raw
In reply to matthieu castet
Quoted 1 line · matthieu castet

Please comment and consider for inclusion.

I need a "Signed-off-by:" line in order to be able to add it. Care to redo things based on the comments you have had and resend it with this line?

Quoted 10 lines

+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:

<snip> You don't need the whole GPL 2 copy here, just put the first paragraph you have before this one in.

Quoted 1 line

+#define EAGLEUSBVERSION "ueagle-svn $Id: ueagle.c 141 2005-09-03 20:12:24Z matc $"

We don't use $Id within the kernel tree, please remove this.

drivers/usb/atm/ueagle-atm.c line 73

Quoted 2 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +2 -0
+static int uea_read_proc(char *page, char **start, off_t off, int count,
+			int *eof, void *data);

No new proc files will be added for drivers, please use sysfs instead (with only one file per value.)

drivers/usb/atm/ueagle-atm.c line 114

Quoted 12 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +12 -0
+/*
+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Quoted 3 lines

+/* we need to use semaphore until sysfs and removable devices is fixed
+ * the problem is explained on http://marc.theaimsgroup.com/?t=112006484100003
+ */

This is the proper fix, why do you think it should be fixed in the driver core?

drivers/usb/atm/ueagle-atm.c line 1521

Quoted 2 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +2 -0
+#define UEA_DEVICE(vid, pid, info) \
+	{USB_DEVICE((vid), (pid)), .driver_info = (info)}

Why create a macro for such a simple thing? That's not needed.

drivers/usb/atm/ueagle-atm.h

Quoted 3 lines

diff -rNu -x '*.ko*' -x '*.mod*' -x '*.o*' linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h linux-2.6.14/drivers/usb/atm/ueagle-atm.h

drivers/usb/atm/ueagle-atm.h renamed from drivers/usb/atm.old/ueagle-atm.h +0 -0

Why do you need a header file for a single .c file?

Quoted 1 line

+#define PACKED __attribute__ ((packed))

No, spell it out please.

drivers/usb/atm/ueagle-atm.h line 276

Quoted 10 lines
drivers/usb/atm/ueagle-atm.h renamed from drivers/usb/atm.old/ueagle-atm.h +10 -0
+/* structure describing a block within a DSP page */
+typedef struct {
+	__le16 wHdr;
+#define UEA_BIHDR 0xabcd
+	__le16 wAddress;
+	__le16 wSize;
+	__le16 wOvlOffset;
+	__le16 wOvl;		/* overlay */
+	__le16 wLast;
+} PACKED block_info_t;

Do not create new typedefs. Please get rid of all of them.

thanks,

greg k-h

#11 lore raw
In reply to matthieu castet
Quoted 16 lines · matthieu castet

Hi Duncan,

Quoted 6 lines · Duncan Sands

Hi Andrew,

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem

No, it wasn't the problem, even when loading with insmod/modprobe the timeout occurs on some configurations. For example on
http://atm.eagle-usb.org/wakka.php?wiki=TestUEagleAtmBaud123, you could see the 'firmware ueagle-atm/eagleIII.fw is not available' error.

Quoted 5 lines

It is only happen for pre-firmware modem (uea_load_firmware) ie where we just do a request_firmware in the probe without any initialisation before. So the problem seems to appear when we do a request_firmware too early in the usb_probe.

Can you please work out exactly what's happening and come up with a more solid solution than msleep(1)?

Because other drivers may hit this problem (whatever it is) and fixes in core kernel might be needed. If we just work around stuff, core kernel remains unfixed...

#15 lore raw
In reply to matthieu castet
Quoted 8 lines · matthieu castet
Quoted 8 lines

Review

Quoted 3 lines
(quoted diff) +2 -0
+
+	*cmvs = (struct uea_cmvs *)(data + 1);

That's a bit rude - asking the compiler to perform a structure copy from an odd address. memcpy() would be saner.

Quoted 6 lines

Could you elaborate a bit more ?
I don't see where there is a copy.
*cmvs is a pointer to the structure, not the structure. And when we parse the structure, we use get_unaligned functions.

Ah, I misread the code.

#5 lore raw
In reply to David Woodhouse

Hi David,

Quoted 10 lines · David Woodhouse
Quoted 6 lines · Duncan Sands

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem holding the firmware is mounted; I guess the delay usually gives the filesystem enough time to be mounted. I'm told that the correct solution is to stick the firmware in an initramfs as well.

Why can't we request the firmware again when the device is first used, if it wasn't present when the driver was first loaded?

we could do this for the speedtouch - in fact we used to do this: when someone tried to open a connection, we loaded the firmware if it hadn't been loaded yet. The problem is with other modems, like the connexant access runner, for which you can't get all the info needed to create an ATM device before the firmware is loaded (the MAC address for example).

Ciao,

D.

#6 lore raw
Quoted 6 lines · Duncan Sands

we could do this for the speedtouch - in fact we used to do this: when someone tried to open a connection, we loaded the firmware if it hadn't been loaded yet. The problem is with other modems, like the connexant access runner, for which you can't get all the info needed to create an ATM device before the firmware is loaded (the MAC address for example).

Don't we also have Ethernet devices like that -- where the MAC address doesn't get set until you bring the device up?

Can we get away with changing the MAC address later? Or is there other stuff we need earlier?

Signature · 1 line
dwmw2
#13 lore raw
In reply to matthieu castet
Quoted 9 lines
Quoted 3 lines

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem

No, it wasn't the problem, even when loading with insmod/modprobe the timeout occurs on some configurations. For example on
http://atm.eagle-usb.org/wakka.php?wiki=TestUEagleAtmBaud123, you could see the 'firmware ueagle-atm/eagleIII.fw is not available' error.

Quoted 4 lines

It is only happen for pre-firmware modem (uea_load_firmware) ie where we just do a request_firmware in the probe without any initialisation before. So the problem seems to appear when we do a request_firmware too early in the usb_probe.

That sounds pretty strange. Maybe when probe is called the driver model device (sysfs) is not completely setup, in any case not enough to support firmware loading?

Ciao,

Duncan.

#16 lore raw
In reply to matthieu castet
Quoted 4 lines
Quoted 2 lines

People get shouted at for adding /proc handlers. Greg may have thoughts...

Ok, we may be convert some values to sysfs. It would be nice if usbatm allow us to export some common value (margin, ...).

Yes it would be nice. Patches welcome :)

D.

#18 lore raw
In reply to Greg KH
Quoted 6 lines
Quoted 6 lines

+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */

drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +3 -0
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
Quoted 8 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 5 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +5 -0
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Hi Greg, it looks like you understand what the problem is here. Could you please explain to us lesser mortals ;)

Thanks,

Duncan.

#7 lore raw
In reply to David Woodhouse
Quoted 8 lines · David Woodhouse
Quoted 6 lines · Duncan Sands

we could do this for the speedtouch - in fact we used to do this: when someone tried to open a connection, we loaded the firmware if it hadn't been loaded yet. The problem is with other modems, like the connexant access runner, for which you can't get all the info needed to create an ATM device before the firmware is loaded (the MAC address for example).

Quoted 5 lines

Don't we also have Ethernet devices like that -- where the MAC address doesn't get set until you bring the device up?

Can we get away with changing the MAC address later? Or is there other stuff we need earlier?

Hi David, it's only the MAC address. I didn't check carefully, but I'm pretty sure that in general the MAC address is the only device dependant info needed to setup an ATM device. But isn't changing the MAC address later a horrible hack that is sure to break stuff?

Duncan.

#19 lore raw
In reply to Duncan Sands
Quoted 15 lines · Duncan Sands
Quoted 6 lines
Quoted 6 lines

+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */

drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +3 -0
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
Quoted 8 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 5 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +5 -0
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Quoted 2 lines

Hi Greg, it looks like you understand what the problem is here. Could you please explain to us lesser mortals ;)

If you use the async mode, there is no timeout. When userspace gets around to giving you the firmware, then you continue on with the rest of your device initialization (don't block the usb probe function though.)

Everyone should switch to that interface, then we would not have any timeout issues anymore...

thanks,

greg k-h

#20 lore raw

Am Mittwoch, 2. November 2005 09:03 schrieb Greg KH:

Quoted 16 lines · Duncan Sands
Quoted 15 lines
Quoted 14 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 11 lines

+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */

drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +8 -0
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Quoted 6 lines
Quoted 2 lines

Hi Greg, it looks like you understand what the problem is here. Could you please explain to us lesser mortals ;)

If you use the async mode, there is no timeout. When userspace gets around to giving you the firmware, then you continue on with the rest of your device initialization (don't block the usb probe function though.)

How would you handle errors in setting up the device?
A driver cannot reject a device after probe, yet you need to handle errors appearing only after the firmware is in the device.

Regards
Oliver

#21 lore raw
Quoted 20 lines · Oliver Neukum

Am Mittwoch, 2. November 2005 09:03 schrieb Greg KH:

Quoted 19 lines · Duncan Sands
Quoted 17 lines
Quoted 6 lines
Quoted 6 lines

+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */

drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +3 -0
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
Quoted 8 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 5 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +5 -0
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Hi Greg, it looks like you understand what the problem is here. Could you please explain to us lesser mortals ;)

Quoted 7 lines
Quoted 3 lines

If you use the async mode, there is no timeout. When userspace gets around to giving you the firmware, then you continue on with the rest of your device initialization (don't block the usb probe function though.)

How would you handle errors in setting up the device?
A driver cannot reject a device after probe, yet you need to handle errors appearing only after the firmware is in the device.

Isn't that the case anyway with the sync version? After all, sync loading of firmware from the probe method is unacceptable, since it can block khubd for a long time (also, if the firmware lives on a USB device that gets disconnected just as probe for the device that loads firmware is called, or some variation of this theme, couldn't horrible blockage happen?).

Ciao,

D.

#8 lore raw
In reply to David Woodhouse
Quoted 10 lines · David Woodhouse
Quoted 6 lines · Duncan Sands

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem holding the firmware is mounted; I guess the delay usually gives the filesystem enough time to be mounted. I'm told that the correct solution is to stick the firmware in an initramfs as well.

Why can't we request the firmware again when the device is first used, if it wasn't present when the driver was first loaded?

Because the firmware loading can take long, and apps may legitimately give up opening the device after a timeout.

Besides, it doesn't look logical. An uninitialized device is not particularly useful for anything but initialization. You don't create, say, a network device for your ethernet card until you're finished with its PCI setup, do you?

I think the async firmware loading can do the job nicely, in a generic manner. BTW the usbatm drivers do it already (wasn't it you who implemented it? :), long before request_firmware_nowait() was available. So it's only a matter of tools adjusting, which seems to be going on.

Roman.

#9 lore raw

Hi Roman, glad to see you're still alive!

Quoted 20 lines · Roman Kagan
Quoted 10 lines · David Woodhouse
Quoted 6 lines · Duncan Sands

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem holding the firmware is mounted; I guess the delay usually gives the filesystem enough time to be mounted. I'm told that the correct solution is to stick the firmware in an initramfs as well.

Why can't we request the firmware again when the device is first used, if it wasn't present when the driver was first loaded?

Because the firmware loading can take long, and apps may legitimately give up opening the device after a timeout.

Besides, it doesn't look logical. An uninitialized device is not particularly useful for anything but initialization. You don't create, say, a network device for your ethernet card until you're finished with its PCI setup, do you?

Quoted 4 lines

I think the async firmware loading can do the job nicely, in a generic manner. BTW the usbatm drivers do it already (wasn't it you who implemented it? :), long before request_firmware_nowait() was available. So it's only a matter of tools adjusting, which seems to be going on.

I can't help feeling that it is wrong to add ad-hoc code to drivers (such
as: if the firmware wasn't there, try to load it again later) in an attempt to work around what is, in the end, a userspace configuration problem. The fact that configuring userspace correctly seems to be tricky is sad, but not the driver's problem.

I don't mind using request_firmware_nowait by the way. The lack of a timeout is no problem as long as we make it possible for the user to shoot the firmware loading down by sending a signal.

Ciao,

Duncan.

PS: On the other hand, users are feeling the pain, which means I get to feel their pain, which tempts me to hack in a workaround ;)

#24 lore raw
In reply to Greg KH
Quoted 6 lines · Greg KH
Quoted 3 lines

+/* we need to use semaphore until sysfs and removable devices is fixed
+ * the problem is explained on http://marc.theaimsgroup.com/?t=112006484100003
+ */

This is the proper fix, why do you think it should be fixed in the driver core?

I missed the earlier discussion about this when it appeared on lkml.

This is no doubt a widespread problem, and it should be brought to many people's attention. Greg, can you think of any good way to make this more visible? Maybe a short piece in Linux Journal combined with a more eye-catching $SUBJECT in lkml?

Maybe this could be combined with a brief discussion of the open-remove race as well (and the use of BKL to help resolve it).

Alan Stern

author maintainer
#25 lore raw
In reply to Greg KH

Hi Greg,

thanks for your review.

Quoted 10 lines · Greg KH
Quoted 1 line · matthieu castet

Please comment and consider for inclusion.

I need a "Signed-off-by:" line in order to be able to add it. Care to redo things based on the comments you have had and resend it with this line?

no problem ;)

Quoted 12 lines
Quoted 10 lines

+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:

Quoted 3 lines

<snip> You don't need the whole GPL 2 copy here, just put the first paragraph you have before this one in.

The paragraph you quote is the BSD licence, and point 1 is :
Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer

So could I remove it ?

Quoted 8 lines
Quoted 8 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +8 -0
+/*
+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
+	if (request_firmware(fw, name, dev) == 0)
Quoted 10 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 4 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +4 -0
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Thanks, but does userspace will retry if it fails the first time ?
The device needs the firmware quickly and after 3-5 seconds without it, it goes berserk.

Quoted 8 lines
Quoted 3 lines

+/* we need to use semaphore until sysfs and removable devices is fixed
+ * the problem is explained on http://marc.theaimsgroup.com/?t=112006484100003
+ */

This is the proper fix, why do you think it should be fixed in the driver core?

I don't remember, but aren't any possible race in sysfs code ?
In the read, after the up, the usb_disconnect is scheduled, and call device_remove_file. Is that ok for the sysfs code to be still in the read code ? An other case : a process open a file, and start a read. Before the down , the usb_disconnect is scheduled and the module is removed. What will do the read, run code from the removed code ?

Quoted 8 lines

drivers/usb/atm/ueagle-atm.h

Quoted 4 lines

diff -rNu -x '*.ko*' -x '*.mod*' -x '*.o*' linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h linux-2.6.14/drivers/usb/atm/ueagle-atm.h

drivers/usb/atm/ueagle-atm.h renamed from drivers/usb/atm.old/ueagle-atm.h +0 -0

Why do you need a header file for a single .c file?

I think it makes things cleaner. I even like the bsd style where there is an header for reg (hardware values) and an other for val (driver structures).

Quoted 6 lines
Quoted 1 line

+#define PACKED __attribute__ ((packed))

No, spell it out please.

Quoted 13 lines

drivers/usb/atm/ueagle-atm.h line 276

Quoted 10 lines
drivers/usb/atm/ueagle-atm.h renamed from drivers/usb/atm.old/ueagle-atm.h +10 -0
+/* structure describing a block within a DSP page */
+typedef struct {
+	__le16 wHdr;
+#define UEA_BIHDR 0xabcd
+	__le16 wAddress;
+	__le16 wSize;
+	__le16 wOvlOffset;
+	__le16 wOvl;		/* overlay */
+	__le16 wLast;
+} PACKED block_info_t;

Do not create new typedefs. Please get rid of all of them.

It comes from bsd driver, it will be cleaned.

thanks,

Matthieu

author maintainer
#26 lore raw
Quoted 20 lines · matthieu castet

Hi Greg,

Quoted 9 lines
Quoted 9 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +9 -0
+/*
+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */
+static int sleepy_request_firmware(const struct firmware **fw, 
+        const char *name, struct device *dev)
+{
+    if (request_firmware(fw, name, dev) == 0)
+        return 0;
Quoted 10 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 3 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +3 -0
+    msleep(1000);
+    return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Quoted 3 lines

Thanks, but does userspace will retry if it fails the first time ?
The device needs the firmware quickly and after 3-5 seconds without it, it goes berserk.

In request_firmware_nowait, when kernel_thread failed, where fw_work is freed ? Aren't there a memleack ?

Matthieu

#12 lore raw
In reply to Andrew Morton
Quoted 17 lines · Andrew Morton
Quoted 16 lines · matthieu castet

Hi Duncan,

Quoted 6 lines · Duncan Sands

Hi Andrew,

this code looks like a 'orrible hack to work around a common problem with USB modem's of this type: if the modem is plugged in while the system boots, the driver may look for firmware before the filesystem

No, it wasn't the problem, even when loading with insmod/modprobe the timeout occurs on some configurations. For example on
http://atm.eagle-usb.org/wakka.php?wiki=TestUEagleAtmBaud123, you could see the 'firmware ueagle-atm/eagleIII.fw is not available' error.

Quoted 8 lines
Quoted 5 lines

It is only happen for pre-firmware modem (uea_load_firmware) ie where we just do a request_firmware in the probe without any initialisation before. So the problem seems to appear when we do a request_firmware too early in the usb_probe.

Can you please work out exactly what's happening and come up with a more solid solution than msleep(1)?

The fix is to use the async firmware interface, no sleeping or timeouts needed.

thanks,

greg k-h

#23 lore raw
In reply to Oliver Neukum
Quoted 20 lines · Oliver Neukum

Am Mittwoch, 2. November 2005 09:03 schrieb Greg KH:

Quoted 19 lines · Duncan Sands
Quoted 17 lines
Quoted 6 lines
Quoted 6 lines

+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */

drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +3 -0
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
Quoted 8 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 5 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +5 -0
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Hi Greg, it looks like you understand what the problem is here. Could you please explain to us lesser mortals ;)

Quoted 7 lines
Quoted 3 lines

If you use the async mode, there is no timeout. When userspace gets around to giving you the firmware, then you continue on with the rest of your device initialization (don't block the usb probe function though.)

How would you handle errors in setting up the device?
A driver cannot reject a device after probe, yet you need to handle errors appearing only after the firmware is in the device.

Yes, you can disconnect from a device after you accept it. And you _know_ you want this device anyway, as it is of the type you handle. If something bad happens, it's ok to still have the device "claimed" as what else would you be able to do with it? :)

thanks,

greg k-h

#22 lore raw
In reply to Duncan Sands
Quoted 25 lines · Duncan Sands
Quoted 24 lines · Oliver Neukum

Am Mittwoch, 2. November 2005 09:03 schrieb Greg KH:

Quoted 22 lines · Duncan Sands
Quoted 15 lines
Quoted 6 lines
Quoted 6 lines

+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */

drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +3 -0
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
Quoted 8 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 5 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +5 -0
+	if (request_firmware(fw, name, dev) == 0)
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Quoted 2 lines

Hi Greg, it looks like you understand what the problem is here. Could you please explain to us lesser mortals ;)

If you use the async mode, there is no timeout. When userspace gets around to giving you the firmware, then you continue on with the rest of your device initialization (don't block the usb probe function though.)

Quoted 5 lines
Quoted 3 lines

How would you handle errors in setting up the device?
A driver cannot reject a device after probe, yet you need to handle errors appearing only after the firmware is in the device.

Isn't that the case anyway with the sync version?

Yes.

Quoted 5 lines

After all, sync loading of firmware from the probe method is unacceptable, since it can block khubd for a long time (also, if the firmware lives on a USB device that gets disconnected just as probe for the device that loads firmware is called, or some variation of this theme, couldn't horrible blockage happen?).

Yes it could. That's why you should use the async version :)

One of these days I'll start multi-threading the device probe stuff, and it will not be that big of a deal...[1]

thanks,

greg k-h

[1] Yes, I know the usb core and drivers will not expect this, and work will be needed to get this working properly.

author maintainer
#28 lore raw
In reply to matthieu castet

Hi Greg,

Quoted 35 lines · matthieu castet
Quoted 13 lines
Quoted 10 lines

+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:

Quoted 3 lines

<snip> You don't need the whole GPL 2 copy here, just put the first paragraph you have before this one in.

The paragraph you quote is the BSD licence, and point 1 is :
Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer

So could I remove it ?

Quoted 11 lines
Quoted 6 lines

diff -rNu -x '*.ko*' -x '*.mod*' -x '*.o*' linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h linux-2.6.14/drivers/usb/atm/ueagle-atm.h
--- linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h 1970-01-01
01:00:00.000000000 +0100
+++ linux-2.6.14/drivers/usb/atm/ueagle-atm.h 2005-10-30
00:25:27.000000000 +0200

Why do you need a header file for a single .c file?

Quoted 2 lines

I think it makes things cleaner. I even like the bsd style where there is an header for reg (hardware values) and an other for val (driver structures).

We patched our driver with the comments sent, but we still don't know what to do with this 2 points :
- For the license stuff, all the dual bsd/gpl drivers I saw in the kernel tree have the complete bsd header.
- For the header file I prefer a separate header file, but if Linux policy is to merge header and source file, that's fine.

Regards,

Matthieu

#29 lore raw
Quoted 2 lines · matthieu castet

- For the license stuff, all the dual bsd/gpl drivers I saw in the kernel tree have the complete bsd header.

That's fine.

Quoted 2 lines

- For the header file I prefer a separate header file, but if Linux policy is to merge header and source file, that's fine.

It's ok, as long as it is local, and it is what you want to do. I don't have a strong feeling toward it.

thanks,

greg k-h

#27 lore raw
In reply to matthieu castet
Quoted 21 lines · matthieu castet
Quoted 20 lines · matthieu castet

Hi Greg,

Quoted 19 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 12 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +12 -0
+/*
+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */
+static int sleepy_request_firmware(const struct firmware **fw, 
+        const char *name, struct device *dev)
+{
+    if (request_firmware(fw, name, dev) == 0)
+        return 0;
+    msleep(1000);
+    return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Quoted 7 lines
Quoted 4 lines

Thanks, but does userspace will retry if it fails the first time ? The device needs the firmware quickly and after 3-5 seconds without it, it goes berserk.

In request_firmware_nowait, when kernel_thread failed, where fw_work is freed ?
Aren't there a memleack ?

I really do not know, as I have not looked at that code. If you see problems in it, please feel free to fix it up, as there is no living maintainer for it anymore :(

thanks,

greg k-h

#30 lore raw
In reply to matthieu castet
Quoted 31 lines · matthieu castet

Hi Greg,

thanks for your review.

Quoted 10 lines · Greg KH
Quoted 1 line · matthieu castet

Please comment and consider for inclusion.

I need a "Signed-off-by:" line in order to be able to add it. Care to redo things based on the comments you have had and resend it with this line?

no problem ;)

Quoted 12 lines
Quoted 10 lines

+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:

Quoted 3 lines

<snip> You don't need the whole GPL 2 copy here, just put the first paragraph you have before this one in.

Quoted 6 lines

The paragraph you quote is the BSD licence, and point 1 is :
Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer

So could I remove it ?

Ugh, you are right, I missed that this was BSD also, sorry. It's fine.

Quoted 18 lines
Quoted 8 lines
Quoted 8 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +8 -0
+/*
+ * sometime hotplug don't have time to give the firmware the
+ * first time, retry it.
+ */
+static int sleepy_request_firmware(const struct firmware **fw, 
+		const char *name, struct device *dev)
+{
+	if (request_firmware(fw, name, dev) == 0)
Quoted 10 lines

drivers/usb/atm/ueagle-atm.c line 114

Quoted 4 lines
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +4 -0
+		return 0;
+	msleep(1000);
+	return request_firmware(fw, name, dev);
+}

No, use the async firmware download mode instead of this. That will solve all of your problems.

Quoted 3 lines

Thanks, but does userspace will retry if it fails the first time ? The device needs the firmware quickly and after 3-5 seconds without it, it goes berserk.

That sounds like a pretty broken device :)

I don't know, have your own timer that disconnects it after X seconds if you haven't gotten the firmware yet? Don't rely on userspace getting around to you real quickly, as we have seen lots of problems with drivers relying on that timeout.

Quoted 6 lines
Quoted 6 lines
Quoted 4 lines

+/* we need to use semaphore until sysfs and removable devices is fixed
+ * the problem is explained on
http://marc.theaimsgroup.com/?t=112006484100003
+ */

Quoted 7 lines
Quoted 3 lines

This is the proper fix, why do you think it should be fixed in the driver core?

I don't remember, but aren't any possible race in sysfs code ? In the read, after the up, the usb_disconnect is scheduled, and call device_remove_file. Is that ok for the sysfs code to be still in the read code ?

Depends on what that code does.

Quoted 3 lines

An other case : a process open a file, and start a read. Before the down , the usb_disconnect is scheduled and the module is removed. What will do the read, run code from the removed code ?

Again, depends on how your code is structured, and what you are referencing in that read code.

Quoted 11 lines
Quoted 11 lines
Quoted 7 lines

diff -rNu -x '*.ko*' -x '*.mod*' -x '*.o*'
linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h
linux-2.6.14/drivers/usb/atm/ueagle-atm.h
--- linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h 1970-01-01
01:00:00.000000000 +0100
+++ linux-2.6.14/drivers/usb/atm/ueagle-atm.h 2005-10-30
00:25:27.000000000 +0200

Why do you need a header file for a single .c file?

Quoted 3 lines

I think it makes things cleaner. I even like the bsd style where there is an header for reg (hardware values) and an other for val (driver structures).

This isn't BSD :)

thanks,

greg k-h

author maintainer
#31 lore raw

Hi Greg,

Quoted 5 lines · Greg KH
Quoted 2 lines

Thanks, but does userspace will retry if it fails the first time ?
The device needs the firmware quickly and after 3-5 seconds without it, it goes berserk.

That sounds like a pretty broken device :)

If it was only that (don't work in bulk mode with down rate > 3Mbps ; empty iso urb report errors, ...)...

Quoted 4 lines

This isn't BSD :)

It's ok, as long as it is local, and it is what you want to do. I don't have a strong feeling toward it.

I finally merge them like other usbatm driver did.

The corrected version is ready, I will wait some time in order others developers could do final checking. I will send it this evening or tomorrow.

Thanks

Matthieu

author maintainer
#32 lore raw
In reply to Greg KH

Hi,

here the corrected version of ueagle-atm.

The comments of Adrew Morton and Greg KH have been applied.
We also fix a bug in the check_dsp routine (reported on our mailling list) and kill some unsued code.

drivers/usb/atm/Kconfig renamed from drivers/usb/atm.old/Kconfig +13 -0
diff -ruN -x '*.o*' -x '*.mod*' -x '*.ko*' linux-2.6.14/drivers/usb/atm.old/Kconfig linux-2.6.14/drivers/usb/atm/Kconfig
@@ -44,6 +44,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cxacru.
 
+config USB_UEAGLEATM
+	tristate "ADI 930 and eagle USB DSL modem"
+	depends on USB_ATM
+	select FW_LOADER
+	help
+	  Say Y here if you have an ADSL USB modem based on the ADI 930
+	  or eagle chipset. In order to use your modem you will need to
+	  install firmwares and CMV (Command Management Variables); see
+	  <https://gna.org/projects/ueagleatm/> for details.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ueagle-atm.
+	  
 config USB_XUSBATM
 	tristate "Other USB DSL modem support"
 	depends on USB_ATM
drivers/usb/atm/Makefile renamed from drivers/usb/atm.old/Makefile +1 -0
diff -ruN -x '*.o*' -x '*.mod*' -x '*.ko*' linux-2.6.14/drivers/usb/atm.old/Makefile linux-2.6.14/drivers/usb/atm/Makefile
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_USB_CXACRU)	+= cxacru.o
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= speedtch.o
+obj-$(CONFIG_USB_UEAGLEATM)	+= ueagle-atm.o
 obj-$(CONFIG_USB_ATM)		+= usbatm.o
 obj-$(CONFIG_USB_XUSBATM)	+= xusbatm.o
drivers/usb/atm/ueagle-atm.c renamed from drivers/usb/atm.old/ueagle-atm.c +1813 -0

1,813 lines not on this page · raw message

author maintainer
#33 lore raw
Quoted 10 lines · matthieu castet

Hi,

here the corrected version of ueagle-atm.

The comments of Adrew Morton and Greg KH have been applied.
We also fix a bug in the check_dsp routine (reported on our mailling list) and kill some unsued code.

Could you add this fix ?

More care on loading firmware, take into account fw->size can't be zero.

thanks

Matthieu

drivers/usb/atm/ueagle-atm.c +18 -10
@@ -426,14 +426,14 @@
 
 	pfw = fw_entry->data;
 	size = fw_entry->size;
+	if (size < 4)
+		goto err_fw_corrupted;
 
 	crc = FW_GET_LONG(pfw);
 	pfw += 4;
 	size -= 4;
-	if (crc32_be(0, pfw, size) != crc) {
-		uea_err(usb, "firmware is corrupted\n");
-		goto err;
-	}
+	if (crc32_be(0, pfw, size) != crc)
+		goto err_fw_corrupted;
 
 	/*
 	 * Start to upload formware : send reset
@@ -446,9 +446,14 @@
 		goto err;
 	}
 
-	while (size > 0) {
+	while (size > 3) {
 		u8 len = FW_GET_BYTE(pfw);
 		u16 add = FW_GET_WORD(pfw + 1);
+
+		size -= len + 3;
+		if (size < 0)
+			goto err_fw_corrupted;
+
 		ret = uea_send_modem_cmd(usb, add, len, pfw + 3);
 		if (ret < 0) {
 			uea_err(usb, "uploading firmware data failed "
@@ -456,9 +461,11 @@
 			goto err;
 		}
 		pfw += len + 3;
-		size -= len + 3;
 	}
 
+	if (size != 0)
+		goto err_fw_corrupted;
+
 	/*
 	 * Tell the modem we finish : de-assert reset
 	 */
@@ -469,6 +476,11 @@
 	else
 		uea_info(usb, "firmware uploaded\n");
 
+	uea_leaves(usb);
+	return;
+
+err_fw_corrupted:
+	uea_err(usb, "firmware is corrupted\n");
 err:
 	uea_leaves(usb);
 }
@@ -522,10 +534,6 @@
 	u32 pageoffset;
 	unsigned int i, j, p, pp;
 
-	/* enough space for pagecount? */
-	if (len < 1)
-		return 1;
-
 	pagecount = FW_GET_BYTE(dsp);
 	p = 1;