diff options
Diffstat (limited to 'drivers/net/usb/ipheth.c')
| -rw-r--r-- | drivers/net/usb/ipheth.c | 124 | 
1 files changed, 73 insertions, 51 deletions
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 7d42f9a2c06..76465b117b7 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -45,7 +45,6 @@  #include <linux/kernel.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/slab.h>  #include <linux/module.h>  #include <linux/netdevice.h> @@ -59,12 +58,20 @@  #define USB_PRODUCT_IPHONE_3G   0x1292  #define USB_PRODUCT_IPHONE_3GS  0x1294  #define USB_PRODUCT_IPHONE_4	0x1297 +#define USB_PRODUCT_IPAD 0x129a +#define USB_PRODUCT_IPAD_2	0x12a2 +#define USB_PRODUCT_IPAD_3	0x12a6 +#define USB_PRODUCT_IPAD_MINI    0x12ab +#define USB_PRODUCT_IPHONE_4_VZW 0x129c +#define USB_PRODUCT_IPHONE_4S	0x12a0 +#define USB_PRODUCT_IPHONE_5	0x12a8  #define IPHETH_USBINTF_CLASS    255  #define IPHETH_USBINTF_SUBCLASS 253  #define IPHETH_USBINTF_PROTO    1  #define IPHETH_BUF_SIZE         1516 +#define IPHETH_IP_ALIGN		2	/* padding at front of URB */  #define IPHETH_TX_TIMEOUT       (5 * HZ)  #define IPHETH_INTFNUM          2 @@ -97,6 +104,34 @@ static struct usb_device_id ipheth_table[] = {  		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4,  		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,  		IPHETH_USBINTF_PROTO) }, +	{ USB_DEVICE_AND_INTERFACE_INFO( +		USB_VENDOR_APPLE, USB_PRODUCT_IPAD, +		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, +		IPHETH_USBINTF_PROTO) }, +	{ USB_DEVICE_AND_INTERFACE_INFO( +		USB_VENDOR_APPLE, USB_PRODUCT_IPAD_2, +		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, +		IPHETH_USBINTF_PROTO) }, +	{ USB_DEVICE_AND_INTERFACE_INFO( +		USB_VENDOR_APPLE, USB_PRODUCT_IPAD_3, +		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, +		IPHETH_USBINTF_PROTO) }, +	{ USB_DEVICE_AND_INTERFACE_INFO( +		USB_VENDOR_APPLE, USB_PRODUCT_IPAD_MINI, +		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, +		IPHETH_USBINTF_PROTO) }, +	{ USB_DEVICE_AND_INTERFACE_INFO( +		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, +		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, +		IPHETH_USBINTF_PROTO) }, +	{ USB_DEVICE_AND_INTERFACE_INFO( +		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, +		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, +		IPHETH_USBINTF_PROTO) }, +	{ USB_DEVICE_AND_INTERFACE_INFO( +		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5, +		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, +		IPHETH_USBINTF_PROTO) },  	{ }  };  MODULE_DEVICE_TABLE(usb, ipheth_table); @@ -198,22 +233,27 @@ static void ipheth_rcvbulk_callback(struct urb *urb)  	case 0:  		break;  	default: -		err("%s: urb status: %d", __func__, status); +		dev_err(&dev->intf->dev, "%s: urb status: %d\n", +			__func__, status);  		return;  	} -	len = urb->actual_length; -	buf = urb->transfer_buffer; +	if (urb->actual_length <= IPHETH_IP_ALIGN) { +		dev->net->stats.rx_length_errors++; +		return; +	} +	len = urb->actual_length - IPHETH_IP_ALIGN; +	buf = urb->transfer_buffer + IPHETH_IP_ALIGN; -	skb = dev_alloc_skb(NET_IP_ALIGN + len); +	skb = dev_alloc_skb(len);  	if (!skb) { -		err("%s: dev_alloc_skb: -ENOMEM", __func__); +		dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n", +			__func__);  		dev->net->stats.rx_dropped++;  		return;  	} -	skb_reserve(skb, NET_IP_ALIGN); -	memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN); +	memcpy(skb_put(skb, len), buf, len);  	skb->dev = dev->net;  	skb->protocol = eth_type_trans(skb, dev->net); @@ -237,7 +277,8 @@ static void ipheth_sndbulk_callback(struct urb *urb)  	    status != -ENOENT &&  	    status != -ECONNRESET &&  	    status != -ESHUTDOWN) -		err("%s: urb status: %d", __func__, status); +		dev_err(&dev->intf->dev, "%s: urb status: %d\n", +		__func__, status);  	dev_kfree_skb_irq(dev->tx_skb);  	netif_wake_queue(dev->net); @@ -257,7 +298,8 @@ static int ipheth_carrier_set(struct ipheth_device *dev)  			dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,  			IPHETH_CTRL_TIMEOUT);  	if (retval < 0) { -		err("%s: usb_control_msg: %d", __func__, retval); +		dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n", +			__func__, retval);  		return retval;  	} @@ -294,9 +336,11 @@ static int ipheth_get_macaddr(struct ipheth_device *dev)  				 IPHETH_CTRL_BUF_SIZE,  				 IPHETH_CTRL_TIMEOUT);  	if (retval < 0) { -		err("%s: usb_control_msg: %d", __func__, retval); +		dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n", +			__func__, retval);  	} else if (retval < ETH_ALEN) { -		err("%s: usb_control_msg: short packet: %d bytes", +		dev_err(&dev->intf->dev, +			"%s: usb_control_msg: short packet: %d bytes\n",  			__func__, retval);  		retval = -EINVAL;  	} else { @@ -321,7 +365,8 @@ static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)  	retval = usb_submit_urb(dev->rx_urb, mem_flags);  	if (retval) -		err("%s: usb_submit_urb: %d", __func__, retval); +		dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", +			__func__, retval);  	return retval;  } @@ -382,7 +427,8 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net)  	retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);  	if (retval) { -		err("%s: usb_submit_urb: %d", __func__, retval); +		dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", +			__func__, retval);  		dev->net->stats.tx_errors++;  		dev_kfree_skb_irq(skb);  	} else { @@ -400,33 +446,26 @@ static void ipheth_tx_timeout(struct net_device *net)  {  	struct ipheth_device *dev = netdev_priv(net); -	err("%s: TX timeout", __func__); +	dev_err(&dev->intf->dev, "%s: TX timeout\n", __func__);  	dev->net->stats.tx_errors++;  	usb_unlink_urb(dev->tx_urb);  } -static struct net_device_stats *ipheth_stats(struct net_device *net) -{ -	struct ipheth_device *dev = netdev_priv(net); -	return &dev->net->stats; -} -  static u32 ipheth_ethtool_op_get_link(struct net_device *net)  {  	struct ipheth_device *dev = netdev_priv(net);  	return netif_carrier_ok(dev->net);  } -static struct ethtool_ops ops = { +static const struct ethtool_ops ops = {  	.get_link = ipheth_ethtool_op_get_link  };  static const struct net_device_ops ipheth_netdev_ops = { -	.ndo_open = &ipheth_open, -	.ndo_stop = &ipheth_close, -	.ndo_start_xmit = &ipheth_tx, -	.ndo_tx_timeout = &ipheth_tx_timeout, -	.ndo_get_stats = &ipheth_stats, +	.ndo_open = ipheth_open, +	.ndo_stop = ipheth_close, +	.ndo_start_xmit = ipheth_tx, +	.ndo_tx_timeout = ipheth_tx_timeout,  };  static int ipheth_probe(struct usb_interface *intf, @@ -457,7 +496,7 @@ static int ipheth_probe(struct usb_interface *intf,  	hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);  	if (hintf == NULL) {  		retval = -ENODEV; -		err("Unable to find alternate settings interface"); +		dev_err(&intf->dev, "Unable to find alternate settings interface\n");  		goto err_endpoints;  	} @@ -470,7 +509,7 @@ static int ipheth_probe(struct usb_interface *intf,  	}  	if (!(dev->bulk_in && dev->bulk_out)) {  		retval = -ENODEV; -		err("Unable to find endpoints"); +		dev_err(&intf->dev, "Unable to find endpoints\n");  		goto err_endpoints;  	} @@ -488,18 +527,18 @@ static int ipheth_probe(struct usb_interface *intf,  	retval = ipheth_alloc_urbs(dev);  	if (retval) { -		err("error allocating urbs: %d", retval); +		dev_err(&intf->dev, "error allocating urbs: %d\n", retval);  		goto err_alloc_urbs;  	}  	usb_set_intfdata(intf, dev);  	SET_NETDEV_DEV(netdev, &intf->dev); -	SET_ETHTOOL_OPS(netdev, &ops); +	netdev->ethtool_ops = &ops;  	retval = register_netdev(netdev);  	if (retval) { -		err("error registering netdev: %d", retval); +		dev_err(&intf->dev, "error registering netdev: %d\n", retval);  		retval = -EIO;  		goto err_register_netdev;  	} @@ -539,27 +578,10 @@ static struct usb_driver ipheth_driver = {  	.probe =	ipheth_probe,  	.disconnect =	ipheth_disconnect,  	.id_table =	ipheth_table, +	.disable_hub_initiated_lpm = 1,  }; -static int __init ipheth_init(void) -{ -	int retval; - -	retval = usb_register(&ipheth_driver); -	if (retval) { -		err("usb_register failed: %d", retval); -		return retval; -	} -	return 0; -} - -static void __exit ipheth_exit(void) -{ -	usb_deregister(&ipheth_driver); -} - -module_init(ipheth_init); -module_exit(ipheth_exit); +module_usb_driver(ipheth_driver);  MODULE_AUTHOR("Diego Giagio <diego@giagio.com>");  MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver");  | 
