> Nice work.  I've applied all 15 of these patches, but now
> drivers/usb/host/sl811-hcd.c and drivers/usb/gadget/dummy_hcd.c have
> build errors. 

Here's the sl811-hcd patch; compile-tested only,
that system doesn't have a 2.6.11 port yet.  ;)

- Dave

SL811 changes getting rid of the "hcd_dev" support, using
usb_host_endpoint to hold the QH.  This also eliminates the
"sl811h_req" data type.  Compile-tested only!

Signed-off-by: David Brownell <[EMAIL PROTECTED]>

--- 1.2/drivers/usb/host/sl811-hcd.c	2004-12-09 12:40:35 -08:00
+++ edited/drivers/usb/host/sl811-hcd.c	2004-12-15 19:56:06 -08:00
@@ -67,7 +67,7 @@
 MODULE_DESCRIPTION("SL811HS USB Host Controller Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION	"06 Dec 2004"
+#define DRIVER_VERSION	"15 Dec 2004"
 
 
 #ifndef DEBUG
@@ -314,7 +314,6 @@
 static struct sl811h_ep	*start(struct sl811 *sl811, u8 bank)
 {
 	struct sl811h_ep	*ep;
-	struct sl811h_req	*req;
 	struct urb		*urb;
 	int			fclock;
 	u8			control;
@@ -348,13 +347,12 @@
 					struct sl811h_ep, schedule);
 	}
 
-	if (unlikely(list_empty(&ep->queue))) {
+	if (unlikely(list_empty(&ep->hep->urb_list))) {
 		DBG("empty %p queue?\n", ep);
 		return NULL;
 	}
 
-	req = container_of(ep->queue.next, struct sl811h_req, queue);
-	urb = req->urb;
+	urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);
 	control = ep->defctrl;
 
 	/* if this frame doesn't have enough time left to transfer this
@@ -432,17 +430,12 @@
 static void finish_request(
 	struct sl811		*sl811,
 	struct sl811h_ep	*ep,
-	struct sl811h_req	*req,
+	struct urb		*urb,
 	struct pt_regs		*regs,
 	int			status
 ) __releases(sl811->lock) __acquires(sl811->lock)
 {
 	unsigned		i;
-	struct urb		*urb = req->urb;
-
-	list_del(&req->queue);
-	kfree(req);
-	urb->hcpriv = NULL;
 
 	if (usb_pipecontrol(urb->pipe))
 		ep->nextpid = USB_PID_SETUP;
@@ -457,7 +450,7 @@
 	spin_lock(&sl811->lock);
 
 	/* leave active endpoints in the schedule */
-	if (!list_empty(&ep->queue))
+	if (!list_empty(&ep->hep->urb_list))
 		return;
 
 	/* async deschedule? */
@@ -496,7 +489,6 @@
 done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs)
 {
 	u8			status;
-	struct sl811h_req	*req;
 	struct urb		*urb;
 	int			urbstat = -EINPROGRESS;
 
@@ -505,8 +497,7 @@
 
 	status = sl811_read(sl811, bank + SL11H_PKTSTATREG);
 
-	req = container_of(ep->queue.next, struct sl811h_req, queue);
-	urb = req->urb;
+	urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);
 
 	/* we can safely ignore NAKs */
 	if (status & SL11H_STATMASK_NAK) {
@@ -577,7 +568,7 @@
 					urb->status = urbstat;
 				spin_unlock(&urb->lock);
 
-				req = NULL;
+				urb = NULL;
 				ep->nextpid = USB_PID_ACK;
 			}
 			break;
@@ -618,9 +609,8 @@
 				bank, status, ep, urbstat);
 	}
 
-	if ((urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)
-			&& req)
-		finish_request(sl811, ep, req, regs, urbstat);
+	if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS))
+		finish_request(sl811, ep, urb, regs, urbstat);
 }
 
 static inline u8 checkdone(struct sl811 *sl811)
@@ -643,7 +633,7 @@
 		ctl = sl811_read(sl811, SL811_EP_B(SL11H_HOSTCTLREG));
 		if (ctl & SL11H_HCTLMASK_ARM)
 			sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
-		DBG("%s DONE_B: ctrl %02x sts %02x\n", ctl,
+		DBG("%s DONE_B: ctrl %02x sts %02x\n",
 			(ctl & SL11H_HCTLMASK_ARM) ? "timeout" : "lost",
 			ctl,
 			sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
@@ -732,8 +722,8 @@
 		if (sl811->active_a) {
 			sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0);
 			finish_request(sl811, sl811->active_a,
-				container_of(sl811->active_a->queue.next,
-					struct sl811h_req, queue),
+				container_of(sl811->active_a->hep->urb_list.next,
+					struct urb, urb_list),
 				NULL, -ESHUTDOWN);
 			sl811->active_a = NULL;
 		}
@@ -741,8 +731,8 @@
 		if (sl811->active_b) {
 			sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
 			finish_request(sl811, sl811->active_b,
-				container_of(sl811->active_b->queue.next,
-					struct sl811h_req, queue),
+				container_of(sl811->active_b->hep->urb_list.next,
+					struct urb, urb_list),
 				NULL, -ESHUTDOWN);
 			sl811->active_b = NULL;
 		}
@@ -816,19 +806,18 @@
 /*-------------------------------------------------------------------------*/
 
 static int sl811h_urb_enqueue(
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	int		mem_flags
+	struct usb_hcd		*hcd,
+	struct usb_host_endpoint *hep,
+	struct urb		*urb,
+	int			mem_flags
 ) {
 	struct sl811		*sl811 = hcd_to_sl811(hcd);
 	struct usb_device	*udev = urb->dev;
-	struct hcd_dev		*hdev = (struct hcd_dev *) udev->hcpriv;
 	unsigned int		pipe = urb->pipe;
 	int			is_out = !usb_pipein(pipe);
 	int			type = usb_pipetype(pipe);
 	int			epnum = usb_pipeendpoint(pipe);
 	struct sl811h_ep	*ep = NULL;
-	struct sl811h_req	*req;
 	unsigned long		flags;
 	int			i;
 	int			retval = 0;
@@ -838,16 +827,8 @@
 		return -ENOSPC;
 #endif
 
-	/* avoid all allocations within spinlocks: request or endpoint */
-	urb->hcpriv = req = kmalloc(sizeof *req, mem_flags);
-	if (!req)
-		return -ENOMEM;
-	req->urb = urb;
-
-	i = epnum << 1;
-	if (i && is_out)
-		i |= 1;
-	if (!hdev->ep[i])
+	/* avoid all allocations within spinlocks */
+	if (!hep->hcpriv)
 		ep = kcalloc(1, sizeof *ep, mem_flags);
 
 	spin_lock_irqsave(&sl811->lock, flags);
@@ -859,15 +840,14 @@
 		goto fail;
 	}
 
-	if (hdev->ep[i]) {
+	if (hep->hcpriv) {
 		kfree(ep);
-		ep = hdev->ep[i];
+		ep = hep->hcpriv;
 	} else if (!ep) {
 		retval = -ENOMEM;
 		goto fail;
 
 	} else {
-		INIT_LIST_HEAD(&ep->queue);
 		INIT_LIST_HEAD(&ep->schedule);
 		ep->udev = usb_get_dev(udev);
 		ep->epnum = epnum;
@@ -911,7 +891,7 @@
 			break;
 		}
 
-		hdev->ep[i] = ep;
+		hep->hcpriv = ep;
 	}
 
 	/* maybe put endpoint into schedule */
@@ -966,47 +946,38 @@
 	spin_lock(&urb->lock);
 	if (urb->status != -EINPROGRESS) {
 		spin_unlock(&urb->lock);
-		finish_request(sl811, ep, req, NULL, 0);
-		req = NULL;
+		finish_request(sl811, ep, urb, NULL, 0);
 		retval = 0;
 		goto fail;
 	}
-	list_add_tail(&req->queue, &ep->queue);
+	urb->hcpriv = hep;
 	spin_unlock(&urb->lock);
 
 	start_transfer(sl811);
 	sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable);
 fail:
 	spin_unlock_irqrestore(&sl811->lock, flags);
-	if (retval)
-		kfree(req);
 	return retval;
 }
 
 static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
 {
 	struct sl811		*sl811 = hcd_to_sl811(hcd);
-	struct usb_device	*udev = urb->dev;
-	struct hcd_dev		*hdev = (struct hcd_dev *) udev->hcpriv;
-	unsigned int		pipe = urb->pipe;
-	int			is_out = !usb_pipein(pipe);
+	struct usb_host_endpoint *hep = urb->hcpriv;
 	unsigned long		flags;
-	unsigned		i;
 	struct sl811h_ep	*ep;
-	struct sl811h_req	*req = urb->hcpriv;
 	int			retval = 0;
 
-	i = usb_pipeendpoint(pipe) << 1;
-	if (i && is_out)
-		i |= 1;
+	if (!hep)
+		return -EINVAL;
 
 	spin_lock_irqsave(&sl811->lock, flags);
-	ep = hdev->ep[i];
+	ep = hep->hcpriv;
 	if (ep) {
 		/* finish right away if this urb can't be active ...
 		 * note that some drivers wrongly expect delays
 		 */
-		if (ep->queue.next != &req->queue) {
+		if (ep->hep->urb_list.next != &urb->urb_list) {
 			/* not front of queue?  never active */
 
 		/* for active transfers, we expect an IRQ */
@@ -1022,7 +993,7 @@
 						0);
 				sl811->active_a = NULL;
 			} else
-				req = NULL;
+				urb = NULL;
 #ifdef	USE_B
 		} else if (sl811->active_b == ep) {
 			if (time_before_eq(sl811->jiffies_a, jiffies)) {
@@ -1036,14 +1007,14 @@
 						0);
 				sl811->active_b = NULL;
 			} else
-				req = NULL;
+				urb = NULL;
 #endif
 		} else {
 			/* front of queue for inactive endpoint */
 		}
 
-		if (req)
-			finish_request(sl811, ep, req, NULL, 0);
+		if (urb)
+			finish_request(sl811, ep, urb, NULL, 0);
 		else
 			VDBG("dequeue, urb %p active %s; wait4irq\n", urb,
 				(sl811->active_a == ep) ? "A" : "B");
@@ -1054,33 +1025,22 @@
 }
 
 static void
-sl811h_endpoint_disable(struct usb_hcd *hcd, struct hcd_dev *hdev, int epnum)
+sl811h_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
 {
-	struct sl811		*sl811 = hcd_to_sl811(hcd);
-	struct sl811h_ep	*ep;
-	unsigned long		flags;
-	int			i;
-
-	i = (epnum & 0xf) << 1;
-	if (epnum && !(epnum & USB_DIR_IN))
-		i |= 1;
-
-	spin_lock_irqsave(&sl811->lock, flags);
-	ep = hdev->ep[i];
-	hdev->ep[i] = NULL;
-	spin_unlock_irqrestore(&sl811->lock, flags);
+	struct sl811h_ep	*ep = hep->hcpriv;
 
-	if (ep) {
-		/* assume we'd just wait for the irq */
-		if (!list_empty(&ep->queue))
-			msleep(3);
-		if (!list_empty(&ep->queue))
-			WARN("ep %p not empty?\n", ep);
+	if (!ep)
+		return;
 
-		usb_put_dev(ep->udev);
-		kfree(ep);
-	}
-	return;
+	/* assume we'd just wait for the irq */
+	if (!list_empty(&hep->urb_list))
+		msleep(3);
+	if (!list_empty(&hep->urb_list))
+		WARN("ep %p not empty?\n", ep);
+
+	usb_put_dev(ep->udev);
+	kfree(ep);
+	hep->hcpriv = 0;
 }
 
 static int
@@ -1481,7 +1441,7 @@
 		sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
 	seq_printf(s, "\n");
 	list_for_each_entry (ep, &sl811->async, schedule) {
-		struct sl811h_req	*req;
+		struct urb		*urb;
 
 		seq_printf(s, "%s%sqh%p, ep%d%s, maxpacket %d"
 					" nak %d err %d\n",
@@ -1497,10 +1457,10 @@
 			}; s;}),
 			ep->maxpacket,
 			ep->nak_count, ep->error_count);
-		list_for_each_entry (req, &ep->queue, queue) {
-			seq_printf(s, "  urb%p, %d/%d\n", req->urb,
-				req->urb->actual_length,
-				req->urb->transfer_buffer_length);
+		list_for_each_entry (urb, &ep->hep->urb_list, urb_list) {
+			seq_printf(s, "  urb%p, %d/%d\n", urb,
+				urb->actual_length,
+				urb->transfer_buffer_length);
 		}
 	}
 	if (!list_empty(&sl811->async))
@@ -1743,11 +1703,6 @@
 	sl811->hcd.self.op = &usb_hcd_operations;
 	sl811->hcd.self.hcpriv = sl811;
 
-	// NOTE: 2.6.11 starts to change the hcd glue layer some more,
-	// eventually letting us eliminate struct sl811h_req and a
-	// lot of the boilerplate code here 
-
-	INIT_LIST_HEAD(&sl811->hcd.dev_list);
 	sl811->hcd.self.release = &usb_hcd_release;
 
 	sl811->hcd.description = sl811h_hc_driver.description;
--- 1.1/drivers/usb/host/sl811.h	2004-12-06 10:45:04 -08:00
+++ edited/drivers/usb/host/sl811.h	2004-12-15 20:03:54 -08:00
@@ -162,7 +162,7 @@
 }
 
 struct sl811h_ep {
-	struct list_head	queue;
+	struct usb_host_endpoint *hep;
 	struct usb_device	*udev;
 
 	u8			defctrl;
@@ -182,14 +182,6 @@
 
 	/* async schedule */
 	struct list_head	schedule;
-};
-
-struct sl811h_req {
-	/* FIXME usbcore should maintain endpoints' urb queues
-	 * directly in 'struct usb_host_endpoint'
-	 */
-	struct urb		*urb;
-	struct list_head	queue;
 };
 
 /*-------------------------------------------------------------------------*/

Reply via email to