diff options
Diffstat (limited to 'drivers/net/usb/cdc-phonet.c')
| -rw-r--r-- | drivers/net/usb/cdc-phonet.c | 48 | 
1 files changed, 18 insertions, 30 deletions
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 109751bad3b..6358d420e18 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -21,6 +21,7 @@   */  #include <linux/kernel.h> +#include <linux/mm.h>  #include <linux/module.h>  #include <linux/gfp.h>  #include <linux/usb.h> @@ -129,7 +130,7 @@ static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags)  	struct page *page;  	int err; -	page = __netdev_alloc_page(dev, gfp_flags); +	page = __skb_alloc_page(gfp_flags | __GFP_NOMEMALLOC, NULL);  	if (!page)  		return -ENOMEM; @@ -139,7 +140,7 @@ static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags)  	err = usb_submit_urb(req, gfp_flags);  	if (unlikely(err)) {  		dev_dbg(&dev->dev, "RX submit error (%d)\n", err); -		netdev_free_page(dev, page); +		put_page(page);  	}  	return err;  } @@ -163,12 +164,14 @@ static void rx_complete(struct urb *req)  				/* Can't use pskb_pull() on page in IRQ */  				memcpy(skb_put(skb, 1), page_address(page), 1);  				skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, -						page, 1, req->actual_length); +						page, 1, req->actual_length, +						PAGE_SIZE);  				page = NULL;  			}  		} else {  			skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, -					page, 0, req->actual_length); +					page, 0, req->actual_length, +					PAGE_SIZE);  			page = NULL;  		}  		if (req->actual_length < PAGE_SIZE) @@ -207,9 +210,9 @@ static void rx_complete(struct urb *req)  	dev->stats.rx_errors++;  resubmit:  	if (page) -		netdev_free_page(dev, page); +		put_page(page);  	if (req) -		rx_submit(pnd, req, GFP_ATOMIC); +		rx_submit(pnd, req, GFP_ATOMIC | __GFP_COLD);  }  static int usbpn_close(struct net_device *dev); @@ -228,7 +231,8 @@ static int usbpn_open(struct net_device *dev)  	for (i = 0; i < rxq_size; i++) {  		struct urb *req = usb_alloc_urb(0, GFP_KERNEL); -		if (!req || rx_submit(pnd, req, GFP_KERNEL)) { +		if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { +			usb_free_urb(req);  			usbpn_close(dev);  			return -ENOMEM;  		} @@ -324,17 +328,17 @@ MODULE_DEVICE_TABLE(usb, usbpn_ids);  static struct usb_driver usbpn_driver; -int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)  {  	static const char ifname[] = "usbpn%d";  	const struct usb_cdc_union_desc *union_header = NULL; -	const struct usb_cdc_header_desc *phonet_header = NULL;  	const struct usb_host_interface *data_desc;  	struct usb_interface *data_intf;  	struct usb_device *usbdev = interface_to_usbdev(intf);  	struct net_device *dev;  	struct usbpn_dev *pnd;  	u8 *data; +	int phonet = 0;  	int len, err;  	data = intf->altsetting->extra; @@ -355,10 +359,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)  					(struct usb_cdc_union_desc *)data;  				break;  			case 0xAB: -				if (phonet_header || dlen < 5) -					break; -				phonet_header = -					(struct usb_cdc_header_desc *)data; +				phonet = 1;  				break;  			}  		} @@ -366,7 +367,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)  		len -= dlen;  	} -	if (!union_header || !phonet_header) +	if (!union_header || !phonet)  		return -EINVAL;  	data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); @@ -392,10 +393,9 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)  	pnd = netdev_priv(dev);  	SET_NETDEV_DEV(dev, &intf->dev); -	netif_stop_queue(dev);  	pnd->dev = dev; -	pnd->usb = usb_get_dev(usbdev); +	pnd->usb = usbdev;  	pnd->intf = intf;  	pnd->data_intf = data_intf;  	spin_lock_init(&pnd->tx_lock); @@ -441,7 +441,6 @@ out:  static void usbpn_disconnect(struct usb_interface *intf)  {  	struct usbpn_dev *pnd = usb_get_intfdata(intf); -	struct usb_device *usb = pnd->usb;  	if (pnd->disconnected)  		return; @@ -450,7 +449,6 @@ static void usbpn_disconnect(struct usb_interface *intf)  	usb_driver_release_interface(&usbpn_driver,  			(pnd->intf == intf) ? pnd->data_intf : pnd->intf);  	unregister_netdev(pnd->dev); -	usb_put_dev(usb);  }  static struct usb_driver usbpn_driver = { @@ -458,20 +456,10 @@ static struct usb_driver usbpn_driver = {  	.probe =	usbpn_probe,  	.disconnect =	usbpn_disconnect,  	.id_table =	usbpn_ids, +	.disable_hub_initiated_lpm = 1,  }; -static int __init usbpn_init(void) -{ -	return usb_register(&usbpn_driver); -} - -static void __exit usbpn_exit(void) -{ -	usb_deregister(&usbpn_driver); -} - -module_init(usbpn_init); -module_exit(usbpn_exit); +module_usb_driver(usbpn_driver);  MODULE_AUTHOR("Remi Denis-Courmont");  MODULE_DESCRIPTION("USB CDC Phonet host interface");  | 
