Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8066134f authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: gadget: net2280: implement set_wedge



This patch (as1132) implements the set_wedge() method for net2280.
This method is necessary for strict USBCV compliance in
g_file_storage.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
CC: David Brownell <david-b@pacbell.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 851a526d
Loading
Loading
Loading
Loading
+34 −6
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)

	/* ep_reset() has already been called */
	ep->stopped = 0;
	ep->wedged = 0;
	ep->out_overflow = 0;

	/* set speed-dependent max packet; may kick in high bandwidth */
@@ -1218,7 +1219,7 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
static int net2280_fifo_status (struct usb_ep *_ep);

static int
net2280_set_halt (struct usb_ep *_ep, int value)
net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
{
	struct net2280_ep	*ep;
	unsigned long		flags;
@@ -1239,16 +1240,21 @@ net2280_set_halt (struct usb_ep *_ep, int value)
	else if (ep->is_in && value && net2280_fifo_status (_ep) != 0)
		retval = -EAGAIN;
	else {
		VDEBUG (ep->dev, "%s %s halt\n", _ep->name,
				value ? "set" : "clear");
		VDEBUG (ep->dev, "%s %s %s\n", _ep->name,
				value ? "set" : "clear",
				wedged ? "wedge" : "halt");
		/* set/clear, then synch memory views with the device */
		if (value) {
			if (ep->num == 0)
				ep->dev->protocol_stall = 1;
			else
				set_halt (ep);
		} else
			if (wedged)
				ep->wedged = 1;
		} else {
			clear_halt (ep);
			ep->wedged = 0;
		}
		(void) readl (&ep->regs->ep_rsp);
	}
	spin_unlock_irqrestore (&ep->dev->lock, flags);
@@ -1256,6 +1262,20 @@ net2280_set_halt (struct usb_ep *_ep, int value)
	return retval;
}

static int
net2280_set_halt(struct usb_ep *_ep, int value)
{
	return net2280_set_halt_and_wedge(_ep, value, 0);
}

static int
net2280_set_wedge(struct usb_ep *_ep)
{
	if (!_ep || _ep->name == ep0name)
		return -EINVAL;
	return net2280_set_halt_and_wedge(_ep, 1, 1);
}

static int
net2280_fifo_status (struct usb_ep *_ep)
{
@@ -1302,6 +1322,7 @@ static const struct usb_ep_ops net2280_ep_ops = {
	.dequeue	= net2280_dequeue,

	.set_halt	= net2280_set_halt,
	.set_wedge	= net2280_set_wedge,
	.fifo_status	= net2280_fifo_status,
	.fifo_flush	= net2280_fifo_flush,
};
@@ -2410,9 +2431,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
				goto do_stall;
			if ((e = get_ep_by_addr (dev, w_index)) == 0)
				goto do_stall;
			if (e->wedged) {
				VDEBUG(dev, "%s wedged, halt not cleared\n",
						ep->ep.name);
			} else {
				VDEBUG(dev, "%s clear halt\n", ep->ep.name);
				clear_halt(e);
			}
			allow_status (ep);
			VDEBUG (dev, "%s clear halt\n", ep->ep.name);
			goto next_endpoints;
			}
			break;
@@ -2427,6 +2453,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
				goto do_stall;
			if ((e = get_ep_by_addr (dev, w_index)) == 0)
				goto do_stall;
			if (e->ep.name == ep0name)
				goto do_stall;
			set_halt (e);
			allow_status (ep);
			VDEBUG (dev, "%s set halt\n", ep->ep.name);
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ struct net2280_ep {
						in_fifo_validate : 1,
						out_overflow : 1,
						stopped : 1,
						wedged : 1,
						is_in : 1,
						is_iso : 1,
						responded : 1;