Re: EHCI on armv6 with Write-Back caches

2012-12-20 Thread Hans Petter Selasky
Hi,

Please try the attached patch for 10-current. The patch is not tested yet, 
only compiles. I will try to test more later today. Let me know if you see any 
issues.

--HPS
=== dev/usb/serial/usb_serial.c
==
--- dev/usb/serial/usb_serial.c	(revision 244051)
+++ dev/usb/serial/usb_serial.c	(local)
@@ -797,10 +797,14 @@
 	DPRINTF(tp=%p\n, tp);
 
 	if (ttydisc_can_bypass(tp) != 0 || 
-	(sc-sc_flag  UCOM_FLAG_HL_READY) == 0) {
+	(sc-sc_flag  UCOM_FLAG_HL_READY) == 0 ||
+	(sc-sc_flag  UCOM_FLAG_INWAKEUP) != 0) {
 		return;
 	}
 
+	/* prevent recursion */
+	sc-sc_flag |= UCOM_FLAG_INWAKEUP;
+
 	pos = sc-sc_jitterbuf_out;
 
 	while (sc-sc_jitterbuf_in != pos) {
@@ -821,6 +825,8 @@
 	if ((sc-sc_jitterbuf_in == pos)  
 	(sc-sc_flag  UCOM_FLAG_RTS_IFLOW))
 		ucom_rts(sc, 0);
+
+	sc-sc_flag = ~UCOM_FLAG_INWAKEUP;
 }
 
 static int
=== dev/usb/serial/usb_serial.h
==
--- dev/usb/serial/usb_serial.h	(revision 244051)
+++ dev/usb/serial/usb_serial.h	(local)
@@ -183,6 +183,7 @@
 #define	UCOM_FLAG_CONSOLE	0x80	/* set if device is a console */
 #define	UCOM_FLAG_WAIT_REFS   0x0100	/* set if we must wait for refs */
 #define	UCOM_FLAG_FREE_UNIT   0x0200	/* set if we must free the unit */
+#define	UCOM_FLAG_INWAKEUP0x0400	/* set if we are in the tty_inwakeup callback */
 	uint8_t	sc_lsr;
 	uint8_t	sc_msr;
 	uint8_t	sc_mcr;
=== dev/usb/storage/ustorage_fs.c
==
--- dev/usb/storage/ustorage_fs.c	(revision 244051)
+++ dev/usb/storage/ustorage_fs.c	(local)
@@ -74,7 +74,7 @@
 /* Define some limits */
 
 #ifndef USTORAGE_FS_BULK_SIZE 
-#define	USTORAGE_FS_BULK_SIZE (1UL  17)	/* bytes */
+#define	USTORAGE_FS_BULK_SIZE	(1U  17)	/* bytes */
 #endif
 
 #ifndef	USTORAGE_FS_MAX_LUN
@@ -85,8 +85,6 @@
 #define	USTORAGE_QDATA_MAX	40	/* bytes */
 #endif
 
-#define sc_cmd_data sc_cbw.CBWCDB
-
 /*
  * The SCSI ID string must be exactly 28 characters long
  * exluding the terminating zero.
@@ -176,8 +174,9 @@
 
 struct ustorage_fs_softc {
 
-	ustorage_fs_bbb_cbw_t sc_cbw;	/* Command Wrapper Block */
-	ustorage_fs_bbb_csw_t sc_csw;	/* Command Status Block */
+	ustorage_fs_bbb_cbw_t *sc_cbw;	/* Command Wrapper Block */
+	ustorage_fs_bbb_csw_t *sc_csw;	/* Command Status Block */
+	void *sc_dma_ptr;		/* Main data buffer */
 
 	struct mtx sc_mtx;
 
@@ -275,7 +274,6 @@
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
 		.bufsize = sizeof(ustorage_fs_bbb_cbw_t),
-		.flags = {.ext_buffer = 1,},
 		.callback = ustorage_fs_t_bbb_command_callback,
 		.usb_mode = USB_MODE_DEVICE,
 	},
@@ -295,7 +293,7 @@
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
 		.bufsize = USTORAGE_FS_BULK_SIZE,
-		.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1},
+		.flags = {.proxy_buffer = 1,.short_xfer_ok = 1},
 		.callback = ustorage_fs_t_bbb_data_read_callback,
 		.usb_mode = USB_MODE_DEVICE,
 	},
@@ -315,7 +313,7 @@
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
 		.bufsize = sizeof(ustorage_fs_bbb_csw_t),
-		.flags = {.short_xfer_ok = 1,.ext_buffer = 1,},
+		.flags = {.short_xfer_ok = 1},
 		.callback = ustorage_fs_t_bbb_status_callback,
 		.usb_mode = USB_MODE_DEVICE,
 	},
@@ -409,6 +407,14 @@
 		transfers, %s\n, usbd_errstr(err));
 		goto detach;
 	}
+
+	sc-sc_cbw = usbd_xfer_get_frame_buffer(sc-sc_xfer[
+	USTORAGE_FS_T_BBB_COMMAND], 0);
+	sc-sc_csw = usbd_xfer_get_frame_buffer(sc-sc_xfer[
+	USTORAGE_FS_T_BBB_STATUS], 0);
+ 	sc-sc_dma_ptr = usbd_xfer_get_frame_buffer(sc-sc_xfer[
+	USTORAGE_FS_T_BBB_DATA_READ], 0);
+
 	/* start Mass Storage State Machine */
 
 	mtx_lock(sc-sc_mtx);
@@ -518,44 +524,44 @@
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
 
-		tag = UGETDW(sc-sc_cbw.dCBWSignature);
+		tag = UGETDW(sc-sc_cbw-dCBWSignature);
 
 		if (tag != CBWSIGNATURE) {
 			/* do nothing */
 			DPRINTF(invalid signature 0x%08x\n, tag);
 			break;
 		}
-		tag = UGETDW(sc-sc_cbw.dCBWTag);
+		tag = UGETDW(sc-sc_cbw-dCBWTag);
 
 		/* echo back tag */
-		USETDW(sc-sc_csw.dCSWTag, tag);
+		USETDW(sc-sc_csw-dCSWTag, tag);
 
 		/* reset status */
-		sc-sc_csw.bCSWStatus = 0;
+		sc-sc_csw-bCSWStatus = 0;
 
 		/* reset data offset, data length and data remainder */
 		sc-sc_transfer.offset = 0;
 		sc-sc_transfer.data_rem =
-		UGETDW(sc-sc_cbw.dCBWDataTransferLength);
+		UGETDW(sc-sc_cbw-dCBWDataTransferLength);
 
 		/* reset data flags */
 		sc-sc_transfer.data_short = 0;
 
 		/* extract LUN */
-		sc-sc_transfer.lun = sc-sc_cbw.bCBWLUN;
+		sc-sc_transfer.lun = sc-sc_cbw-bCBWLUN;
 
 		if (sc-sc_transfer.data_rem == 0) {
 			sc-sc_transfer.cbw_dir = DIR_NONE;
 		} else {
-			if (sc-sc_cbw.bCBWFlags  CBWFLAGS_IN) {
+			if (sc-sc_cbw-bCBWFlags  CBWFLAGS_IN) {
 sc-sc_transfer.cbw_dir = DIR_WRITE;
 			} else {
 sc-sc_transfer.cbw_dir = DIR_READ;
 			}
 		}
 
-		sc-sc_transfer.cmd_len = 

Re: EHCI on armv6 with Write-Back caches

2012-12-20 Thread Hans Petter Selasky
Hi,

I've run some basic tests over here (x86) which passed after some patch 
modifications. Please test and verify for your ARM targets:

http://svnweb.freebsd.org/changeset/base/244500
http://svnweb.freebsd.org/changeset/base/244503

Please also verify that upgt and uwrt and uath still works like expected.

--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org


Re: EHCI on armv6 with Write-Back caches

2012-12-20 Thread Oleksandr Tymoshenko

On 12/20/2012 10:46 AM, Hans Petter Selasky wrote:

Hi,

I've run some basic tests over here (x86) which passed after some patch
modifications. Please test and verify for your ARM targets:

http://svnweb.freebsd.org/changeset/base/244500
http://svnweb.freebsd.org/changeset/base/244503

Please also verify that upgt and uwrt and uath still works like expected.



Thanks! I'll test umass on my ARM devices. EHCI driver suffers from this 
too. QH, QTD and
other structures mixes DMA data and non-DMA fields. Splitting them would 
be a right thing
to do too. Though I believe  EHCI vs. WB caches issue is more 
complicated then just this.

___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org


Re: usb/173666: [USB, LIBUSB] usb_reset() behavior different between GNU/Linux and FreeBSD

2012-12-20 Thread Xiaofan Chen
On Sat, Nov 17, 2012 at 8:19 PM, Hans Petter Selasky hsela...@c2i.net wrote:
 On Friday 16 November 2012 23:47:29 Wojciech A. Koszek wrote:
 Number: 173666
 Category:   usb
 Synopsis:   [USB, LIBUSB] usb_reset() behavior different between
 GNU/Linux and FreeBSD Confidential:   no
 Severity:   non-critical
 Priority:   low
 Responsible:freebsd-usb
 State:  open
 Quarter:
 Keywords:
 Date-Required:
 Class:  sw-bug
 Submitter-Id:   current-users
 Arrival-Date:   Fri Nov 16 22:50:00 UTC 2012
 Closed-Date:
 Last-Modified:
 Originator: Wojciech A. Koszek
 Release:9.0-RELEASE

 Organization:
 FreeBSD

 Environment:
 FreeBSD seu 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:15:25 UTC
 2012 r...@obrian.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

 Description:
 I have a driver written for libusb, which works fine under GNU/Linux and
 libusb. Device:

 gen0.2: JSB283 Relay Module J-Works,Inc at usbus0, cfg=0 md=HOST spd=LOW
 (1.5Mbps) pwr=ON

 (I used USB sniffer to uncover traffic based on what Windows was doing)

 Under Linux usb_reset()+usb_set_configuration() calls works fine. Under
 FreeBSD I have to disable calling usb_reset(), otherwise
 usb_set_configuration() fails with I/O error.


 According to:

 http://libusb.sourceforge.net/doc/function.usbreset.html

 What you describe is the expected behaviour.

The above document is really meant for libusb-0.1 but the
behavior of libusb-compat's usb_reset() is different since
it is based on libusb-1.0's libusb_reset_device.

http://git.libusb.org/?p=libusb-compat-0.1.git;a=blob;f=libusb/core.c
 743 API_EXPORTED int usb_reset(usb_dev_handle *dev)
 744 {
 745 usbi_dbg();
 746 return compat_err(libusb_reset_device(dev-handle));
 747 }

For libusb-1.0 under Linux and Mac OS X, usually
 libusb_reset_device will not cause enumeration.

Reference:
http://libusb.6.n5.nabble.com/PATCH-make-libusb-reset-force-re-enumeration-on-Mac-td4499375.html

http://libusb.sourceforge.net/api-1.0/group__dev.html#ga7321bd8dc28e9a20b411bf18e6d0e9aa

int libusb_reset_device (   libusb_device_handle *  dev )   
Perform a USB port reset to reinitialize a device.

The system will attempt to restore the previous configuration and
alternate settings after the reset has completed.

If the reset fails, the descriptors change, or the previous state
cannot be restored, the device will appear to be disconnected
and reconnected. This means that the device handle is no longer
valid (you should close it) and rediscover the device. A return code
of LIBUSB_ERROR_NOT_FOUND indicates when this is the case.

This is a blocking function which usually incurs a noticeable delay.

Parameters:
   deva handle of the device to reset
Returns:
   0 on success
   LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the
  device has been disconnected
   another LIBUSB_ERROR code on other failure


-- 
Xiaofan
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org