[PATCH 2/7] usb/isp1760: Cleanup and bugfixes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch series is meant to clean up the code (removing more of the legacy from the original and quite frankly horrible Philips drivers), and also contain some small bug fixes.

* Patch 2: Removes the redundant hw_hext list pointer from struct isp1760_qtd, removes some unused #defines, removes redundant "urb" member from struct inter_packet_info.

 drivers/usb/host/isp1760-hcd.c |  123 ++++++++++++++-----------------
 drivers/usb/host/isp1760-hcd.h |    1 
 2 files changed, 56 insertions(+), 68 deletions(-)

diff -Nurp linux-2.6.37-isp1760-001/drivers/usb/host/isp1760-hcd.c linux-2.6.37-isp1760-002/drivers/usb/host/isp1760-hcd.c
--- linux-2.6.37-isp1760-001/drivers/usb/host/isp1760-hcd.c	2011-02-23 02:01:16.137344192 +0100
+++ linux-2.6.37-isp1760-002/drivers/usb/host/isp1760-hcd.c	2011-02-23 13:07:37.801345084 +0100
@@ -80,7 +80,6 @@ static inline struct usb_hcd *priv_to_hc
 #define PORT_RWC_BITS   (PORT_CSC)
 
 struct isp1760_qtd {
-	struct isp1760_qtd *hw_next;
 	u8 packet_type;
 	u8 toggle;
 
@@ -92,10 +91,7 @@ struct isp1760_qtd {
 
 	/* isp special*/
 	u32 status;
-#define URB_COMPLETE_NOTIFY	(1 << 0)
 #define URB_ENQUEUED		(1 << 1)
-#define URB_TYPE_ATL		(1 << 2)
-#define URB_TYPE_INT		(1 << 3)
 };
 
 struct isp1760_qh {
@@ -827,12 +823,11 @@ static void enqueue_one_atl_qtd(u32 payl
 	isp176x_ptd_write(hcd->regs, ATL_PTD_OFFSET, slot, &ptd);
 	enqueue_one_qtd(qtd, priv, payload);
 
-	priv->atl_ints[slot].urb = urb;
 	priv->atl_ints[slot].qh = qh;
 	priv->atl_ints[slot].qtd = qtd;
 	priv->atl_ints[slot].data_buffer = qtd->data_buffer;
 	priv->atl_ints[slot].payload = payload;
-	qtd->status |= URB_ENQUEUED | URB_TYPE_ATL;
+	qtd->status |= URB_ENQUEUED;
 	qtd->status |= slot << 16;
 }
 
@@ -847,12 +842,11 @@ static void enqueue_one_int_qtd(u32 payl
 	isp176x_ptd_write(hcd->regs, INT_PTD_OFFSET, slot, &ptd);
 	enqueue_one_qtd(qtd, priv, payload);
 
-	priv->int_ints[slot].urb = urb;
 	priv->int_ints[slot].qh = qh;
 	priv->int_ints[slot].qtd = qtd;
 	priv->int_ints[slot].data_buffer = qtd->data_buffer;
 	priv->int_ints[slot].payload = payload;
-	qtd->status |= URB_ENQUEUED | URB_TYPE_INT;
+	qtd->status |= URB_ENQUEUED;
 	qtd->status |= slot << 16;
 }
 
@@ -965,11 +959,15 @@ static void isp1760_qtd_free(struct isp1
 	kmem_cache_free(qtd_cachep, qtd);
 }
 
-static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd)
+static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd,
+							struct isp1760_qh *qh)
 {
 	struct isp1760_qtd *tmp_qtd;
 
-	tmp_qtd = qtd->hw_next;
+	if (list_is_last(&qtd->qtd_list, &qh->qtd_list))
+		tmp_qtd = NULL;
+	else
+		tmp_qtd = list_entry(qtd->qtd_list.next, struct isp1760_qtd, qtd_list);
 	list_del(&qtd->qtd_list);
 	isp1760_qtd_free(qtd);
 	return tmp_qtd;
@@ -980,22 +978,31 @@ static struct isp1760_qtd *clean_this_qt
  * isn't the last one than remove also his successor(s).
  * Returns the QTD which is part of an new URB and should be enqueued.
  */
-static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd)
+static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd,
+							struct isp1760_qh *qh)
 {
-	struct isp1760_qtd *tmp_qtd;
-	int last_one;
+	struct urb *urb;
 
+	urb = qtd->urb;
 	do {
-		tmp_qtd = qtd->hw_next;
-		last_one = qtd->status & URB_COMPLETE_NOTIFY;
-		list_del(&qtd->qtd_list);
-		isp1760_qtd_free(qtd);
-		qtd = tmp_qtd;
-	} while (!last_one && qtd);
+		qtd = clean_this_qtd(qtd, qh);
+	} while (qtd && (qtd->urb == urb));
 
 	return qtd;
 }
 
+static int last_qtd_of_urb(struct isp1760_qtd *qtd, struct isp1760_qh *qh)
+{
+	struct urb *urb;
+
+	if (list_is_last(&qtd->qtd_list, &qh->qtd_list))
+		return 1;
+
+	urb = qtd->urb;
+	qtd = list_entry(qtd->qtd_list.next, typeof(*qtd), qtd_list);
+	return (qtd->urb != urb);
+}
+
 static void do_atl_int(struct usb_hcd *hcd)
 {
 	struct isp1760_hcd *priv = hcd_to_priv(hcd);
@@ -1029,8 +1036,8 @@ static void do_atl_int(struct usb_hcd *h
 		done_map &= ~(1 << queue_entry);
 		skip_map |= 1 << queue_entry;
 
-		urb = priv->atl_ints[queue_entry].urb;
 		qtd = priv->atl_ints[queue_entry].qtd;
+		urb = qtd->urb;
 		qh = priv->atl_ints[queue_entry].qh;
 		payload = priv->atl_ints[queue_entry].payload;
 
@@ -1143,7 +1150,6 @@ static void do_atl_int(struct usb_hcd *h
 		}
 
 		priv->atl_ints[queue_entry].data_buffer = NULL;
-		priv->atl_ints[queue_entry].urb = NULL;
 		priv->atl_ints[queue_entry].qtd = NULL;
 		priv->atl_ints[queue_entry].qh = NULL;
 
@@ -1154,7 +1160,7 @@ static void do_atl_int(struct usb_hcd *h
 		if (urb->status == -EPIPE) {
 			/* HALT was received */
 
-			qtd = clean_up_qtdlist(qtd);
+			qtd = clean_up_qtdlist(qtd, qh);
 			isp1760_urb_done(priv, urb, urb->status);
 
 		} else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) {
@@ -1170,23 +1176,23 @@ static void do_atl_int(struct usb_hcd *h
 			if (urb->status == -EINPROGRESS)
 				urb->status = 0;
 
-			qtd = clean_up_qtdlist(qtd);
+			qtd = clean_up_qtdlist(qtd, qh);
 
 			isp1760_urb_done(priv, urb, urb->status);
 
-		} else if (qtd->status & URB_COMPLETE_NOTIFY) {
+		} else if (last_qtd_of_urb(qtd, qh)) {
 			/* that was the last qtd of that URB */
 
 			if (urb->status == -EINPROGRESS)
 				urb->status = 0;
 
-			qtd = clean_this_qtd(qtd);
+			qtd = clean_this_qtd(qtd, qh);
 			isp1760_urb_done(priv, urb, urb->status);
 
 		} else {
 			/* next QTD of this URB */
 
-			qtd = clean_this_qtd(qtd);
+			qtd = clean_this_qtd(qtd, qh);
 			BUG_ON(!qtd);
 		}
 
@@ -1226,8 +1232,8 @@ static void do_intl_int(struct usb_hcd *
 		done_map &= ~(1 << queue_entry);
 		skip_map |= 1 << queue_entry;
 
-		urb = priv->int_ints[queue_entry].urb;
 		qtd = priv->int_ints[queue_entry].qtd;
+		urb = qtd->urb;
 		qh = priv->int_ints[queue_entry].qh;
 		payload = priv->int_ints[queue_entry].payload;
 
@@ -1280,7 +1286,6 @@ static void do_intl_int(struct usb_hcd *
 		}
 
 		priv->int_ints[queue_entry].data_buffer = NULL;
-		priv->int_ints[queue_entry].urb = NULL;
 		priv->int_ints[queue_entry].qtd = NULL;
 		priv->int_ints[queue_entry].qh = NULL;
 
@@ -1290,21 +1295,21 @@ static void do_intl_int(struct usb_hcd *
 		if (urb->status == -EPIPE) {
 			/* HALT received */
 
-			 qtd = clean_up_qtdlist(qtd);
+			 qtd = clean_up_qtdlist(qtd, qh);
 			 isp1760_urb_done(priv, urb, urb->status);
 
-		} else if (qtd->status & URB_COMPLETE_NOTIFY) {
+		} else if (last_qtd_of_urb(qtd, qh)) {
 
 			if (urb->status == -EINPROGRESS)
 				urb->status = 0;
 
-			qtd = clean_this_qtd(qtd);
+			qtd = clean_this_qtd(qtd, qh);
 			isp1760_urb_done(priv, urb, urb->status);
 
 		} else {
 			/* next QTD of this URB */
 
-			qtd = clean_this_qtd(qtd);
+			qtd = clean_this_qtd(qtd, qh);
 			BUG_ON(!qtd);
 		}
 
@@ -1373,8 +1378,6 @@ static struct isp1760_qh *qh_append_tds(
 		void **ptr)
 {
 	struct isp1760_qh *qh;
-	struct isp1760_qtd *qtd;
-	struct isp1760_qtd *prev_qtd;
 
 	qh = (struct isp1760_qh *)*ptr;
 	if (!qh) {
@@ -1385,21 +1388,8 @@ static struct isp1760_qh *qh_append_tds(
 		*ptr = qh;
 	}
 
-	qtd = list_entry(qtd_list->next, struct isp1760_qtd,
-			qtd_list);
-	if (!list_empty(&qh->qtd_list))
-		prev_qtd = list_entry(qh->qtd_list.prev,
-				struct isp1760_qtd, qtd_list);
-	else
-		prev_qtd = NULL;
-
 	list_splice(qtd_list, qh->qtd_list.prev);
-	if (prev_qtd) {
-		BUG_ON(prev_qtd->hw_next);
-		prev_qtd->hw_next = qtd;
-	}
 
-	urb->hcpriv = qh;
 	return qh;
 }
 
@@ -1480,7 +1470,7 @@ static struct isp1760_qtd *isp1760_qtd_a
 static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv,
 		struct urb *urb, struct list_head *head, gfp_t flags)
 {
-	struct isp1760_qtd *qtd, *qtd_prev;
+	struct isp1760_qtd *qtd;
 	void *buf;
 	int len, maxpacket;
 	int is_input;
@@ -1510,12 +1500,10 @@ static struct list_head *qh_urb_transact
 
 		/* ... and always at least one more pid */
 		token ^= DATA_TOGGLE;
-		qtd_prev = qtd;
 		qtd = isp1760_qtd_alloc(priv, flags);
 		if (!qtd)
 			goto cleanup;
 		qtd->urb = urb;
-		qtd_prev->hw_next = qtd;
 		list_add_tail(&qtd->qtd_list, head);
 
 		/* for zero length DATA stages, STATUS is always IN */
@@ -1561,12 +1549,10 @@ static struct list_head *qh_urb_transact
 		if (len <= 0)
 			break;
 
-		qtd_prev = qtd;
 		qtd = isp1760_qtd_alloc(priv, flags);
 		if (!qtd)
 			goto cleanup;
 		qtd->urb = urb;
-		qtd_prev->hw_next = qtd;
 		list_add_tail(&qtd->qtd_list, head);
 	}
 
@@ -1589,12 +1575,10 @@ static struct list_head *qh_urb_transact
 			one_more = 1;
 		}
 		if (one_more) {
-			qtd_prev = qtd;
 			qtd = isp1760_qtd_alloc(priv, flags);
 			if (!qtd)
 				goto cleanup;
 			qtd->urb = urb;
-			qtd_prev->hw_next = qtd;
 			list_add_tail(&qtd->qtd_list, head);
 
 			/* never any data in such packets */
@@ -1602,7 +1586,7 @@ static struct list_head *qh_urb_transact
 		}
 	}
 
-	qtd->status = URB_COMPLETE_NOTIFY;
+	qtd->status = 0;
 	return head;
 
 cleanup:
@@ -1680,11 +1664,15 @@ static int isp1760_urb_dequeue(struct us
 	spin_lock_irqsave(&priv->lock, flags);
 
 	for (i = 0; i < 32; i++) {
-		if (ints->urb == urb) {
+		if (!ints[i].qh)
+			continue;
+		BUG_ON(!ints[i].qtd);
+
+		if (ints[i].qtd->urb == urb) {
 			u32 skip_map;
 			u32 or_map;
 			struct isp1760_qtd *qtd;
-			struct isp1760_qh *qh = ints->qh;
+			struct isp1760_qh *qh;
 
 			skip_map = isp176x_reg_read32(hcd->regs, skip_reg);
 			skip_map |= 1 << i;
@@ -1697,11 +1685,11 @@ static int isp1760_urb_dequeue(struct us
 			isp176x_ptd_write(hcd->regs, reg_base, i, &ptd);
 
 			qtd = ints->qtd;
-			qtd = clean_up_qtdlist(qtd);
+			qh = ints[i].qh;
+			qtd = clean_up_qtdlist(qtd, qh);
 
 			free_mem(priv, ints->payload);
 
-			ints->urb = NULL;
 			ints->qh = NULL;
 			ints->qtd = NULL;
 			ints->data_buffer = NULL;
@@ -1712,19 +1700,20 @@ static int isp1760_urb_dequeue(struct us
 				pe(hcd, qh, qtd);
 			break;
 
-		} else if (ints->qtd) {
-			struct isp1760_qtd *qtd, *prev_qtd = ints->qtd;
+		} else {
+			struct isp1760_qtd *qtd;
 
-			for (qtd = ints->qtd->hw_next; qtd; qtd = qtd->hw_next) {
+			list_for_each_entry(qtd, &ints[i].qtd->qtd_list, qtd_list) {
 				if (qtd->urb == urb) {
-					prev_qtd->hw_next = clean_up_qtdlist(qtd);
+					clean_up_qtdlist(qtd, ints[i].qh);
 					isp1760_urb_done(priv, urb, status);
+					qtd = NULL;
 					break;
 				}
-				prev_qtd = qtd;
 			}
-			/* we found the urb before the end of the list */
-			if (qtd)
+
+			/* We found the urb before the last slot */
+			if (!qtd)
 				break;
 		}
 		ints++;
@@ -2158,7 +2147,7 @@ static void isp1760_endpoint_disable(str
 			struct urb *urb;
 
 			urb = qtd->urb;
-			clean_up_qtdlist(qtd);
+			clean_up_qtdlist(qtd, qh);
 			isp1760_urb_done(priv, urb, -ECONNRESET);
 		}
 	} while (1);
diff -Nurp linux-2.6.37-isp1760-001/drivers/usb/host/isp1760-hcd.h linux-2.6.37-isp1760-002/drivers/usb/host/isp1760-hcd.h
--- linux-2.6.37-isp1760-001/drivers/usb/host/isp1760-hcd.h	2011-02-23 02:01:07.757097305 +0100
+++ linux-2.6.37-isp1760-002/drivers/usb/host/isp1760-hcd.h	2011-02-23 02:07:30.453345726 +0100
@@ -110,7 +110,6 @@ struct inter_packet_info {
 	u32 payload;
 #define PTD_FIRE_NEXT		(1 << 0)
 #define PTD_URB_FINISHED	(1 << 1)
-	struct urb *urb;
 	struct isp1760_qh *qh;
 	struct isp1760_qtd *qtd;
 };

Signed-off-by: Arvid Brodin <arvid.brodin@xxxxxxxx>


-- 
Arvid Brodin
Enea Services Stockholm AB

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux