diff options
Diffstat (limited to 'drivers/net/usb/lan78xx.c')
| -rw-r--r-- | drivers/net/usb/lan78xx.c | 113 | 
1 files changed, 31 insertions, 82 deletions
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index eccbf4cd7149..442507f25aad 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -377,10 +377,6 @@ struct lan78xx_net {  	struct tasklet_struct	bh;  	struct delayed_work	wq; -	struct usb_host_endpoint *ep_blkin; -	struct usb_host_endpoint *ep_blkout; -	struct usb_host_endpoint *ep_intr; -  	int			msg_enable;  	struct urb		*urb_intr; @@ -2860,78 +2856,12 @@ lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net)  	return NETDEV_TX_OK;  } -static int -lan78xx_get_endpoints(struct lan78xx_net *dev, struct usb_interface *intf) -{ -	int tmp; -	struct usb_host_interface *alt = NULL; -	struct usb_host_endpoint *in = NULL, *out = NULL; -	struct usb_host_endpoint *status = NULL; - -	for (tmp = 0; tmp < intf->num_altsetting; tmp++) { -		unsigned ep; - -		in = NULL; -		out = NULL; -		status = NULL; -		alt = intf->altsetting + tmp; - -		for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { -			struct usb_host_endpoint *e; -			int intr = 0; - -			e = alt->endpoint + ep; -			switch (e->desc.bmAttributes) { -			case USB_ENDPOINT_XFER_INT: -				if (!usb_endpoint_dir_in(&e->desc)) -					continue; -				intr = 1; -				/* FALLTHROUGH */ -			case USB_ENDPOINT_XFER_BULK: -				break; -			default: -				continue; -			} -			if (usb_endpoint_dir_in(&e->desc)) { -				if (!intr && !in) -					in = e; -				else if (intr && !status) -					status = e; -			} else { -				if (!out) -					out = e; -			} -		} -		if (in && out) -			break; -	} -	if (!alt || !in || !out) -		return -EINVAL; - -	dev->pipe_in = usb_rcvbulkpipe(dev->udev, -				       in->desc.bEndpointAddress & -				       USB_ENDPOINT_NUMBER_MASK); -	dev->pipe_out = usb_sndbulkpipe(dev->udev, -					out->desc.bEndpointAddress & -					USB_ENDPOINT_NUMBER_MASK); -	dev->ep_intr = status; - -	return 0; -} -  static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)  {  	struct lan78xx_priv *pdata = NULL;  	int ret;  	int i; -	ret = lan78xx_get_endpoints(dev, intf); -	if (ret) { -		netdev_warn(dev->net, "lan78xx_get_endpoints failed: %d\n", -			    ret); -		return ret; -	} -  	dev->data[0] = (unsigned long)kzalloc(sizeof(*pdata), GFP_KERNEL);  	pdata = (struct lan78xx_priv *)(dev->data[0]); @@ -3700,6 +3630,7 @@ static void lan78xx_stat_monitor(struct timer_list *t)  static int lan78xx_probe(struct usb_interface *intf,  			 const struct usb_device_id *id)  { +	struct usb_host_endpoint *ep_blkin, *ep_blkout, *ep_intr;  	struct lan78xx_net *dev;  	struct net_device *netdev;  	struct usb_device *udev; @@ -3748,6 +3679,34 @@ static int lan78xx_probe(struct usb_interface *intf,  	mutex_init(&dev->stats.access_lock); +	if (intf->cur_altsetting->desc.bNumEndpoints < 3) { +		ret = -ENODEV; +		goto out2; +	} + +	dev->pipe_in = usb_rcvbulkpipe(udev, BULK_IN_PIPE); +	ep_blkin = usb_pipe_endpoint(udev, dev->pipe_in); +	if (!ep_blkin || !usb_endpoint_is_bulk_in(&ep_blkin->desc)) { +		ret = -ENODEV; +		goto out2; +	} + +	dev->pipe_out = usb_sndbulkpipe(udev, BULK_OUT_PIPE); +	ep_blkout = usb_pipe_endpoint(udev, dev->pipe_out); +	if (!ep_blkout || !usb_endpoint_is_bulk_out(&ep_blkout->desc)) { +		ret = -ENODEV; +		goto out2; +	} + +	ep_intr = &intf->cur_altsetting->endpoint[2]; +	if (!usb_endpoint_is_int_in(&ep_intr->desc)) { +		ret = -ENODEV; +		goto out2; +	} + +	dev->pipe_intr = usb_rcvintpipe(dev->udev, +					usb_endpoint_num(&ep_intr->desc)); +  	ret = lan78xx_bind(dev, intf);  	if (ret < 0)  		goto out2; @@ -3759,18 +3718,7 @@ static int lan78xx_probe(struct usb_interface *intf,  	netdev->max_mtu = MAX_SINGLE_PACKET_SIZE;  	netif_set_gso_max_size(netdev, MAX_SINGLE_PACKET_SIZE - MAX_HEADER); -	dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0; -	dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1; -	dev->ep_intr = (intf->cur_altsetting)->endpoint + 2; - -	dev->pipe_in = usb_rcvbulkpipe(udev, BULK_IN_PIPE); -	dev->pipe_out = usb_sndbulkpipe(udev, BULK_OUT_PIPE); - -	dev->pipe_intr = usb_rcvintpipe(dev->udev, -					dev->ep_intr->desc.bEndpointAddress & -					USB_ENDPOINT_NUMBER_MASK); -	period = dev->ep_intr->desc.bInterval; - +	period = ep_intr->desc.bInterval;  	maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0);  	buf = kmalloc(maxp, GFP_KERNEL);  	if (buf) { @@ -3783,6 +3731,7 @@ static int lan78xx_probe(struct usb_interface *intf,  			usb_fill_int_urb(dev->urb_intr, dev->udev,  					 dev->pipe_intr, buf, maxp,  					 intr_complete, dev, period); +			dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;  		}  	}  | 
