All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wolfgang Grandegger <wg@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] eth: remove usb-ethernet devices before re-enumerating them
Date: Tue, 10 Jan 2012 07:49:30 +0100	[thread overview]
Message-ID: <4F0BDF7A.3050703@denx.de> (raw)
In-Reply-To: <CAP_ceTzLJJRJ+cYeKq2ArPWX_XC6L8FjsnHyGrORs2Gn+NrXGg@mail.gmail.com>

On 01/09/2012 10:08 PM, Vincent Palatin wrote:
> On Mon, Jan 9, 2012 at 12:57, Marek Vasut <marek.vasut@gmail.com> wrote:
>>> Fix the crash when running several times usb_init() with a USB ethernet
>>> device plugged.
>>>
>>> Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
>>> Tested-by: Wolfgang Grandegger <wg@denx.de>
>>> ---
>>>  drivers/usb/eth/usb_ether.c |    7 +++++--
>>>  include/net.h               |    1 +
>>>  net/eth.c                   |   29 +++++++++++++++++++++++++++++
>>>  3 files changed, 35 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c
>>> index 6565ea5..73a0790 100644
>>> --- a/drivers/usb/eth/usb_ether.c
>>> +++ b/drivers/usb/eth/usb_ether.c
>>> @@ -127,8 +127,11 @@ int usb_host_eth_scan(int mode)
>>>
>>>       old_async = usb_disable_asynch(1); /* asynch transfer not allowed */
>>>
>>> -     for (i = 0; i < USB_MAX_ETH_DEV; i++)
>>> -             memset(&usb_eth[i], 0, sizeof(usb_eth[i]));
>>> +     /* unregister a previously detected device */
>>> +     for (i = 0; i < usb_max_eth_dev; i++)
>>> +             eth_unregister(&usb_eth[i].eth_dev);
>>> +
>>> +     memset(usb_eth, 0, sizeof(usb_eth));
>>>
>>>       for (i = 0; prob_dev[i].probe; i++) {
>>>               if (prob_dev[i].before_probe)
>>> diff --git a/include/net.h b/include/net.h
>>> index e4d42c2..1707a7f 100644
>>> --- a/include/net.h
>>> +++ b/include/net.h
>>> @@ -96,6 +96,7 @@ struct eth_device {
>>>
>>>  extern int eth_initialize(bd_t *bis);        /* Initialize network subsystem
>> */
>>>  extern int eth_register(struct eth_device* dev);/* Register network device
>>> */ +extern int eth_unregister(struct eth_device *dev);/* Remove network
>>> device */ extern void eth_try_another(int first_restart);     /* Change the
>>> device */ extern void eth_set_current(void);          /* set nterface to
>> ethcur
>>> var */ extern struct eth_device *eth_get_dev(void);   /* get the current
>>> device MAC */ diff --git a/net/eth.c b/net/eth.c
>>> index b4b9b43..3fb5fb6 100644
>>> --- a/net/eth.c
>>> +++ b/net/eth.c
>>> @@ -224,6 +224,35 @@ int eth_register(struct eth_device *dev)
>>>       return 0;
>>>  }
>>>
>>> +int eth_unregister(struct eth_device *dev)
>>> +{
>>> +     struct eth_device *cur;
>>> +
>>> +     /* No device */
>>> +     if (!eth_devices)
>>> +             return -1;
>>> +
>>> +     for (cur = eth_devices; cur->next != eth_devices && cur->next != dev;
>>> +          cur = cur->next)
>>> +             ;
>>> +
>>> +     /* Device not found */
>>> +     if (cur->next != dev)
>>> +             return -1;
>>> +
>>> +     cur->next = dev->next;
>>> +
>>> +     if (eth_devices == dev)
>>> +             eth_devices = dev->next == eth_devices ? NULL : dev->next;
>>> +
>>> +     if (eth_current == dev) {
>>> +             eth_current = eth_devices;
>>> +             eth_current_changed();
>>> +     }
>>> +
>>> +     return 0;
>>> +}
>>> +
>>>  int eth_initialize(bd_t *bis)
>>>  {
>>>       int num_devices = 0;
>>
>> Looks sane. On what hardware did this happen (just for the record)?
> 
> I got it on x86 and ARM (tegra2) platforms (both with an EHCI controller).
> I did most of my testing with ASIX-based USB-ethernet dongle, but the
> issue seems pretty generic.

It happens with *any* hardware calling eth_register() more than once
because "struct eth_device *dev*" is memset 0 before calling
eth_register() resulting in an endless loop when scanning the devices.

Viele Gr??e,

Wolfgang

  reply	other threads:[~2012-01-10  6:49 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-09 18:32 [U-Boot] [PATCH] eth: remove usb-ethernet devices before re-enumerating them Vincent Palatin
2012-01-09 20:57 ` Marek Vasut
2012-01-09 21:08   ` Vincent Palatin
2012-01-10  6:49     ` Wolfgang Grandegger [this message]
2012-01-10 10:54       ` Marek Vasut
2012-01-15 19:41 ` Remy Bohmer
2012-02-26 23:10 ` Marek Vasut
2012-03-08  7:03   ` Simon Glass
2012-03-08 14:14     ` Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F0BDF7A.3050703@denx.de \
    --to=wg@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.