Skip to contentSkip to conversation

Enable big-endian processors to use EHCI interrupt transfers

PATCH New Adrian Cox 2 participants 2 messages Apr 9, 2014 – Apr 10, 2014

Subsystems (2)
lore
Share & tools
lore

Adrian Cox

author
#0 lore raw

PATCH 1/1 Enable big-endian processors to use EHCI interrupt transfers

Add endian support macros to interrupt transfers in the EHCI driver, to allow operation on PowerPC.

---
 drivers/usb/host/ehci-hcd.c |   50 +++++++++++++++++++++----------------------
 1 file changed, 25 insertions(+), 25 deletions(-)
drivers/usb/host/ehci-hcd.c +25 -25
index 6017090..a030f2b 100644
@@ -998,8 +998,8 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 	if (!ehcic[index].periodic_list)
 		return -ENOMEM;
 	for (i = 0; i < 1024; i++) {
-		ehcic[index].periodic_list[i] = (uint32_t)periodic
-						| QH_LINK_TYPE_QH;
+		ehcic[index].periodic_list[i] = cpu_to_hc32((uint32_t)periodic
+						| QH_LINK_TYPE_QH);
 	}
 
 	flush_dcache_range((uint32_t)ehcic[index].periodic_list,
@@ -1089,7 +1089,7 @@ struct int_queue {
 	struct qTD *tds;
 };
 
-#define NEXT_QH(qh) (struct QH *)((qh)->qh_link & ~0x1f)
+#define NEXT_QH(qh) (struct QH *)(hc32_to_cpu((qh)->qh_link) & ~0x1f)
 
 static int
 enable_periodic(struct ehci_ctrl *ctrl)
@@ -1184,41 +1184,41 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
 		struct qTD *td = result->tds + i;
 		void **buf = &qh->buffer;
 
-		qh->qh_link = (uint32_t)(qh+1) | QH_LINK_TYPE_QH;
+		qh->qh_link = cpu_to_hc32((uint32_t)(qh+1) | QH_LINK_TYPE_QH);
 		if (i == queuesize - 1)
-			qh->qh_link = QH_LINK_TERMINATE;
+			qh->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
 
-		qh->qh_overlay.qt_next = (uint32_t)td;
-		qh->qh_overlay.qt_altnext = QT_NEXT_TERMINATE;
-		qh->qh_endpt1 = (0 << 28) | /* No NAK reload (ehci 4.9) */
+		qh->qh_overlay.qt_next = cpu_to_hc32((uint32_t)td);
+		qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+		qh->qh_endpt1 = cpu_to_hc32((0 << 28) | /* No NAK reload (ehci 4.9) */
 			(usb_maxpacket(dev, pipe) << 16) | /* MPS */
 			(1 << 14) |
 			QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
 			(usb_pipeendpoint(pipe) << 8) | /* Endpoint Number */
-			(usb_pipedevice(pipe) << 0);
-		qh->qh_endpt2 = (1 << 30) | /* 1 Tx per mframe */
-			(1 << 0); /* S-mask: microframe 0 */
+			(usb_pipedevice(pipe) << 0));
+		qh->qh_endpt2 = cpu_to_hc32((1 << 30) | /* 1 Tx per mframe */
+			(1 << 0)); /* S-mask: microframe 0 */
 		if (dev->speed == USB_SPEED_LOW ||
 				dev->speed == USB_SPEED_FULL) {
 			debug("TT: port: %d, hub address: %d\n",
 				dev->portnr, dev->parent->devnum);
-			qh->qh_endpt2 |= (dev->portnr << 23) |
+			qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) |
 				(dev->parent->devnum << 16) |
-				(0x1c << 8); /* C-mask: microframes 2-4 */
+				(0x1c << 8)); /* C-mask: microframes 2-4 */
 		}
 
-		td->qt_next = QT_NEXT_TERMINATE;
-		td->qt_altnext = QT_NEXT_TERMINATE;
+		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
 		debug("communication direction is '%s'\n",
 		      usb_pipein(pipe) ? "in" : "out");
-		td->qt_token = (elementsize << 16) |
+		td->qt_token = cpu_to_hc32((elementsize << 16) |
 			((usb_pipein(pipe) ? 1 : 0) << 8) | /* IN/OUT token */
-			0x80; /* active */
-		td->qt_buffer[0] = (uint32_t)buffer + i * elementsize;
-		td->qt_buffer[1] = (td->qt_buffer[0] + 0x1000) & ~0xfff;
-		td->qt_buffer[2] = (td->qt_buffer[0] + 0x2000) & ~0xfff;
-		td->qt_buffer[3] = (td->qt_buffer[0] + 0x3000) & ~0xfff;
-		td->qt_buffer[4] = (td->qt_buffer[0] + 0x4000) & ~0xfff;
+			0x80); /* active */
+		td->qt_buffer[0] = cpu_to_hc32((uint32_t)buffer + i * elementsize);
+		td->qt_buffer[1] = cpu_to_hc32((td->qt_buffer[0] + 0x1000) & ~0xfff);
+		td->qt_buffer[2] = cpu_to_hc32((td->qt_buffer[0] + 0x2000) & ~0xfff);
+		td->qt_buffer[3] = cpu_to_hc32((td->qt_buffer[0] + 0x3000) & ~0xfff);
+		td->qt_buffer[4] = cpu_to_hc32((td->qt_buffer[0] + 0x4000) & ~0xfff);
 
 		*buf = buffer + i * elementsize;
 	}
@@ -1241,7 +1241,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
 	/* hook up to periodic list */
 	struct QH *list = &ctrl->periodic_queue;
 	result->last->qh_link = list->qh_link;
-	list->qh_link = (uint32_t)result->first | QH_LINK_TYPE_QH;
+	list->qh_link = cpu_to_hc32((uint32_t)result->first | QH_LINK_TYPE_QH);
 
 	flush_dcache_range((uint32_t)result->last,
 			   ALIGN_END_ADDR(struct QH, result->last, 1));
@@ -1280,7 +1280,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
 	/* still active */
 	invalidate_dcache_range((uint32_t)cur,
 				ALIGN_END_ADDR(struct QH, cur, 1));
-	if (cur->qh_overlay.qt_token & 0x80) {
+	if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) {
 		debug("Exit poll_int_queue with no completed intr transfer. "
 		      "token is %x\n", cur->qh_overlay.qt_token);
 		return NULL;
@@ -1311,7 +1311,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
 
 	struct QH *cur = &ctrl->periodic_queue;
 	timeout = get_timer(0) + 500; /* abort after 500ms */
-	while (!(cur->qh_link & QH_LINK_TERMINATE)) {
+	while (!(cur->qh_link & cpu_to_hc32(QH_LINK_TERMINATE))) {
 		debug("considering %p, with qh_link %x\n", cur, cur->qh_link);
 		if (NEXT_QH(cur) == queue->first) {
 			debug("found candidate. removing from chain\n");
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/1 Enable big-endian processors to use EHCI interrupt transfers

Quoted 4 lines · Adrian Cox

Add endian support macros to interrupt transfers in the EHCI driver, to allow operation on PowerPC.

Other than style issues, which need to be fixes (you can check for them with ./scripts/checkpatch.pl /path/to/your/0001-patch.patch) :

WARNING: line over 80 characters
#103: FILE: drivers/usb/host/ehci-hcd.c:1193:
+ qh->qh_endpt1 = cpu_to_hc32((0 << 28) | /* No NAK reload (ehci
4.9) */

WARNING: line over 80 characters
#141: FILE: drivers/usb/host/ehci-hcd.c:1217:
+ td->qt_buffer[0] = cpu_to_hc32((uint32_t)buffer + i *
elementsize);

WARNING: line over 80 characters
#142: FILE: drivers/usb/host/ehci-hcd.c:1218:
+ td->qt_buffer[1] = cpu_to_hc32((td->qt_buffer[0] + 0x1000) &
~0xfff);

WARNING: line over 80 characters
#143: FILE: drivers/usb/host/ehci-hcd.c:1219:
+ td->qt_buffer[2] = cpu_to_hc32((td->qt_buffer[0] + 0x2000) &
~0xfff);

WARNING: line over 80 characters
#144: FILE: drivers/usb/host/ehci-hcd.c:1220:
+ td->qt_buffer[3] = cpu_to_hc32((td->qt_buffer[0] + 0x3000) &
~0xfff);

WARNING: line over 80 characters
#145: FILE: drivers/usb/host/ehci-hcd.c:1221:
+ td->qt_buffer[4] = cpu_to_hc32((td->qt_buffer[0] + 0x4000) &
~0xfff);

total: 0 errors, 6 warnings, 0 checks, 102 lines checked

NOTE: Ignored message types: COMPLEX_MACRO CONSIDER_KSTRTO MINMAX MULTISTATEMENT_MACRO_USE_DO_WHILE NETWORKING_BLOCK_COMMENT_STYLE USLEEP_RANGE

Also, use:

$ git format-patch HEAD~1 -o /path/to/your/patch
$ git send-email --annotate --to=u-boot..... /path/to/your/patch/00*.patch

Best regards,
Marek Vasut