Hi guys! It's my first experience, and util now I acquired a null pointer dereference, which kicks my kernel off! :) This is the patch ... I know for sure I'm doing something horrible! I'm a newbie !! XD diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4709fa3..725d892 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -52,7 +52,7 @@ #include <linux/usb/usbnet.h> #include <linux/usb/cdc.h> #include <linux/usb/cdc_ncm.h> - +#include <linux/usb/cdc-wdm.h> #define DRIVER_VERSION "14-Mar-2012" #if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) @@ -62,12 +62,41 @@ static bool prefer_mbim; #endif module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions"); - +atomic_t pmcount; static void cdc_ncm_txpath_bh(unsigned long param); static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx); static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); static struct usb_driver cdc_ncm_driver; +static int cdc_mbim_manage_power(struct usbnet *dev, int on) +{ + int rv = 0; + + + if ((on && atomic_add_return(1, &pmcount) == 1) || (!on && atomic_dec_and_test(&pmcount))) { + /* need autopm_get/put here to ensure the usbcore sees the new value */ + rv = usb_autopm_get_interface(dev->intf); + if (rv < 0) + goto err; + dev->intf->needs_remote_wakeup = on; + usb_autopm_put_interface(dev->intf); + } +err: + return rv; +} + +static int cdc_mbim_wdm_manage_power(struct usb_interface *intf, int status) +{ + struct usbnet *dev = usb_get_intfdata(intf); + + /* can be called while disconnecting */ + if (!dev) + return 0; + + return cdc_mbim_manage_power(dev, status); +} + + static void cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) { @@ -355,6 +384,7 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = { int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting) { struct cdc_ncm_ctx *ctx; + struct usb_driver *subdriver; struct usb_driver *driver; u8 *buf; int len; @@ -507,6 +537,20 @@ advance: dev->rx_urb_size = ctx->rx_max; ctx->tx_speed = ctx->rx_speed = 0; + + usb_driver_release_interface(driver, ctx->control); + if (ctx->control == NULL){ + printk("ctx->control is NULL!\n"); + return -ENODEV; + } + if (&dev->status->desc == NULL){ + printk("ctx->control is NULL!\n"); + return -ENODEV; + } + subdriver = usb_cdc_wdm_register(ctx->control, + &dev->status->desc, + le16_to_cpu(ctx->mbim_desc->wMaxControlMessage), + cdc_mbim_wdm_manage_power); return 0; error2: @@ -603,13 +647,14 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) /* NCM data altsetting is always 1 */ ret = cdc_ncm_bind_common(dev, intf, 1); + /* * We should get an event when network connection is "connected" or * "disconnected". Set network connection in "disconnected" state * (carrier is OFF) during attach, so the IP network stack does not * start IPv6 negotiation and more. - */ + */ netif_carrier_off(dev->net); return ret; } thank you for your help! -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html