cdc-ether: divorce initialisation with a filter reset and a generic method
Some devices need their multicast filter reset but others are crashed by that. So the methods need to be separated. Signed-off-by: Oliver Neukum <oneukum@suse.com> Reported-by: "Ridgway, Keith" <kridgway@harris.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
2f9bfd3399
Коммит
7f65b1f5ad
|
@ -310,13 +310,6 @@ skip:
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Some devices don't initialise properly. In particular
|
||||
* the packet filter is not reset. There are devices that
|
||||
* don't do reset all the way. So the packet filter should
|
||||
* be set to a sane initial value.
|
||||
*/
|
||||
usbnet_cdc_update_filter(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
bad_desc:
|
||||
|
@ -325,6 +318,30 @@ bad_desc:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind);
|
||||
|
||||
|
||||
/* like usbnet_generic_cdc_bind() but handles filter initialization
|
||||
* correctly
|
||||
*/
|
||||
int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = usbnet_generic_cdc_bind(dev, intf);
|
||||
if (rv < 0)
|
||||
goto bail_out;
|
||||
|
||||
/* Some devices don't initialise properly. In particular
|
||||
* the packet filter is not reset. There are devices that
|
||||
* don't do reset all the way. So the packet filter should
|
||||
* be set to a sane initial value.
|
||||
*/
|
||||
usbnet_cdc_update_filter(dev);
|
||||
|
||||
bail_out:
|
||||
return rv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_ether_cdc_bind);
|
||||
|
||||
void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
|
||||
{
|
||||
struct cdc_state *info = (void *) &dev->data;
|
||||
|
@ -417,7 +434,7 @@ int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
|
||||
< sizeof(struct cdc_state)));
|
||||
|
||||
status = usbnet_generic_cdc_bind(dev, intf);
|
||||
status = usbnet_ether_cdc_bind(dev, intf);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ struct cdc_state {
|
|||
};
|
||||
|
||||
extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
|
||||
extern int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf);
|
||||
extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *);
|
||||
extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
|
||||
extern void usbnet_cdc_status(struct usbnet *, struct urb *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче