/* 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 */
 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;
        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);
        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)
 {
        .dequeue        = net2280_dequeue,
 
        .set_halt       = net2280_set_halt,
+       .set_wedge      = net2280_set_wedge,
        .fifo_status    = net2280_fifo_status,
        .fifo_flush     = net2280_fifo_flush,
 };
                                goto do_stall;
                        if ((e = get_ep_by_addr (dev, w_index)) == 0)
                                goto do_stall;
-                       clear_halt (e);
+                       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;
                                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);