Eagle and ADI 930 usb adsl modem driver
Subsystems (3)
matthieu castet
maintainerPATCH 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
@@ -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
@@ -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
Quoted 6 lines · matthieu castet
Hi,
attached is the driver for USB ADSL modems based on the ADI eagle chipset using the
usb_atminfrastructure.
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
@@ -74,17 +74,17 @@ static int uea_read_proc(char *page, chastatic 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_sofmemcpy (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 *suea_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(struif (!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 uestatic 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);
_
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.
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
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
matthieu castet
maintainerHi 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
matthieu castet
maintainerHi 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
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.c141 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.hlinux-2.6.14/drivers/usb/atm/ueagle-atm.hdrivers/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
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 arequest_firmwarein the probe without any initialisation before. So the problem seems to appear when we do arequest_firmwaretoo early in theusb_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...
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 useget_unalignedfunctions.
Ah, I misread the code.
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.
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
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 arequest_firmwarein the probe without any initialisation before. So the problem seems to appear when we do arequest_firmwaretoo early in theusb_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.
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.
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.
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.
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
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
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.
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.
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 ;)
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
matthieu castet
maintainerHi 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.hlinux-2.6.14/drivers/usb/atm/ueagle-atm.hdrivers/usb/atm/ueagle-atm.h renamed from drivers/usb/atm.old/ueagle-atm.h +0
-0Why 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
matthieu castet
maintainerQuoted 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
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 arequest_firmwarein the probe without any initialisation before. So the problem seems to appear when we do arequest_firmwaretoo early in theusb_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
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
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.
matthieu castet
maintainerHi 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
* disclaimerSo 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.hlinux-2.6.14/drivers/usb/atm/ueagle-atm.h
---linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h1970-01-01
01:00:00.000000000 +0100
+++linux-2.6.14/drivers/usb/atm/ueagle-atm.h2005-10-30
00:25:27.000000000 +0200Why 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
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
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, whenkernel_threadfailed, wherefw_workis 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
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
* disclaimerSo 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_disconnectis scheduled, and calldevice_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_disconnectis 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.hlinux-2.6.14/drivers/usb/atm/ueagle-atm.h
---linux-2.6.14/drivers/usb/atm.old/ueagle-atm.h1970-01-01
01:00:00.000000000 +0100
+++linux-2.6.14/drivers/usb/atm/ueagle-atm.h2005-10-30
00:25:27.000000000 +0200Why 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
matthieu castet
maintainerHi 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
matthieu castet
maintainerHi,
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
@@ -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
@@ -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
matthieu castet
maintainerQuoted 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 thecheck_dsproutine (reported on our mailling list) and kill some unsued code.Signed-off-by Matthieu CASTET <[email protected]>
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 ;