PERFORCE change 166722 for review

Sylvestre Gallon syl at FreeBSD.org
Wed Jul 29 08:41:47 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=166722

Change 166722 by syl at syl_twoflowers on 2009/07/29 08:41:13

	Implement test and proposition part of the report.

Affected files ...

.. //depot/projects/soc2009/syl_usb/hps_report/DifferentAPI.tex#2 edit
.. //depot/projects/soc2009/syl_usb/hps_report/GenericCode.tex#3 edit
.. //depot/projects/soc2009/syl_usb/hps_report/Proposition.tex#2 edit
.. //depot/projects/soc2009/syl_usb/hps_report/SomeTests.tex#2 edit
.. //depot/projects/soc2009/syl_usb/hps_report/report.tex#2 edit

Differences ...

==== //depot/projects/soc2009/syl_usb/hps_report/DifferentAPI.tex#2 (text+ko) ====

@@ -1,7 +1,7 @@
 \chapter{Differents APIs}
 Only three portable Operating System have a USB Function Stack. 
 In this chapter we will focus on the different API for Adding a 
-new Device Controler Interface on Linux Windows CE and FreeBSD.
+new Device Controler Interface on Linux, Windows CE and FreeBSD.
 
 	\section{Linux}
 
@@ -162,7 +162,7 @@
 		The code is in dev/usb/usb\_controller.h. FreeBSD use the same 
 		structure for both Host and Device Controllers Interfaces.
 		An USB DCI must implement an usb\_bus\_methods structure. These
-		structure is share between DCI and HCI.
+		structure are shared between DCI and HCI.
 		\begin{lstlisting}
 	struct usb_bus_methods {
 
@@ -217,7 +217,7 @@
  	};
  		\end{lstlisting}
 
-		Concerning endpoint FreeBSD us usb\_pipe\_methods structure.
+		Concerning endpoint FreeBSD use usb\_pipe\_methods structure.
 
 		\begin{lstlisting}
  	/*
@@ -240,8 +240,10 @@
         	void   *info;
 	};
 		\end{lstlisting}
-		For describing possibilities of the differennt endpoints contain by the xCI 
-		FreeBSD have the structure usb\_hw\_ep\_profile.
+
+		For describing possibilities of the different endpoints contained 
+		by the xCI FreeBSD have the structure usb\_hw\_ep\_profile.
+
 		\begin{lstlisting}
 	/*
 	 * The following structure keeps information about what a hardware USB

==== //depot/projects/soc2009/syl_usb/hps_report/GenericCode.tex#3 (text+ko) ====

@@ -10,8 +10,9 @@
 		diff -uNp at91dci.c s3c24xxdci.c
 	\end{lstlisting}
 
-	We can see that only few function are different from a driver to another.
-	The code different is specific to the Hardware. Lets us describes this functions :
+	We can see that only few functions are different from a driver to another.
+	The different code is most of the time Hardware specific. Lets us describes 
+	these functions :
 
 	\section{Hardware Dependant Code}
 
@@ -56,11 +57,13 @@
 
 	- xxxdci\_start\_standard\_chain
 
-	Concerning clock\_on, clock\_off, pull\_up, pull\_down, wakeup\_peer can be a little bit 
-	factorised. A big part of this function do not move we can create a generic function called
-	directly after or before Hardware changes. Perhaps there is also something that could be
-	factorised in xxxdci\_uninit if there are not other possible access that interrupt disabling
-	in it.
+	Clock\_on, clock\_off, pull\_up, pull\_down, wakeup\_peer can be
+	factorised. A big part of this function do not move and we can create 
+	a generic function called directly after or before Hardware changes. 
+
+	Perhaps there is also something that could be factorised in xxxdci\_uninit 
+	if there are not other possible access to the Hardware that interrupt disabling
+	in this function.
 
 	There are pehaps something to do with xxxdci\_device\_done and xxxdci\_start\_standard\_chain 
 	beacuse the only hardware code present int this function just enable Endpoint interrupt.
@@ -95,3 +98,68 @@
 
 	- xxxdci\_xfer\_do\_fifo
 	
+	xxdci\_ep\_init and xxxdci\_xfer\_setup are more or less generic. The only change we can have 
+	between 2 controller afecting this function is the support or no of asynchronous endpoints. 
+	This problem could be resolved if we parse xxxdci\_ep\_profile to know if the device support 
+	asynchronous endpoints.
+
+	All the HUB descriptor code are the same between the controller drivers. We can easily factorise it
+	without performance modification.
+
+	There is some big change on the way to handle basic control request like GET\_STATUS etc. Linux and
+	Wince seems to handle That on a generic file who perform basic request during the configuration process.
+	In FreeBSD all these functionality are present in the controlleur code in the function roothub\_exec. 
+	This function looks like the same on each controller.
+
+	There is something for factorising the code for xxxdci\_device\_XXX\_methods. I have implemented it 
+	on s3c24xxxdci driver this way :
+
+	\begin{lstlisting}
+ /*
+  * s3c24xxdci ctrl/bulk/intr support
+  */
+ 
+ static void
+ s3c24dci_device_dummy(struct usb_xfer *xfer)
+ {
+         return ;
+ }
+ 
+ static void
+ s3c24dci_device_xxx_start(struct usb_xfer *xfer)
+ {
+         s3c24dci_setup_standard_chain(xfer);
+         s3c24dci_start_standard_chain(xfer);
+         return ;
+ }
+ 
+ static void
+ s3c24dci_device_xxx_close(struct usb_xfer *xfer)
+ {
+         s3c24dci_device_done(xfer, USB_ERR_CANCELLED);
+         return ;
+ }
+ 
+ struct usb_pipe_methods s3c24dci_device_ctrl_methods = {
+         .open = s3c24dci_device_dummy,
+         .enter = s3c24dci_device_dummy,
+         .close = s3c24dci_device_xxx_close,
+         .start = s3c24dci_device_xxx_start,
+ };
+ 
+ struct usb_pipe_methods s3c24dci_device_bulk_methods = {
+         .open = s3c24dci_device_dummy,
+         .enter = s3c24dci_device_dummy,
+         .close = s3c24dci_device_xxx_close,
+         .start = s3c24dci_device_xxx_start,
+ };
+ 
+ struct usb_pipe_methods s3c24dci_device_intr_methods = {
+         .open = s3c24dci_device_dummy,
+         .enter = s3c24dci_device_dummy,
+         .close = s3c24dci_device_xxx_close,
+         .start = s3c24dci_device_xxx_start,
+ };
+	\end{lstlisting}
+
+	All the others functions seems to be generic.

==== //depot/projects/soc2009/syl_usb/hps_report/Proposition.tex#2 (text+ko) ====

@@ -1,1 +1,37 @@
 \chapter{What can be done ?}
+	\section{HUB Descriptor}
+
+		A good solution to factorise the USB descriptors is to add
+		another entry in the directory for HUB descripors.
+		/src/sys/dev/usb/template/
+
+		We implement this file like this one :
+
+		/src/sys/dev/usb/template/usb\_template\_cdce.c
+
+	\section{xxxdci\_device\_XXX\_methods}
+	
+	We can factorize some code on each driver with simply adding in a .h 
+	something like that:
+	
+	\begin{lstlisting}
+static inline void
+dci_device_dummy ( struct usb_xfer * xfer )
+{
+	return ;
+}
+	\end{lstlisting}
+
+	With this Change we can easily implement the xxxdci\_device\_XXX\_methods
+	with less code following the mothod used for the s3c2xxdci implementation.
+
+	\section{roothub}
+		We can Create A GenericRootHub function who will takes a 
+		struct with callback as parameters. 
+
+		It will permit the driver to implement roothub\_exec or call
+		GenericRootHub.
+
+	\section{other generic functions}
+
+	I Have no idea now how to factorise them, but any advices are welcome !

==== //depot/projects/soc2009/syl_usb/hps_report/SomeTests.tex#2 (text+ko) ====

@@ -1,2 +1,162 @@
 \chapter{Test}
-	\section{callback versus switch}
+
+Here is the result of some test used for finding the best implementation
+for the Improvement into USB.
+
+	\section{ops structure Versus Simple call}
+
+		\begin{lstlisting}
+
+#include <stdio.h>
+
+struct fops {
+        void (*f)(int i);
+};
+
+void
+toto(int i)
+{
+        printf("%i\n", i);
+}
+
+struct fops fops =
+        {
+                .f = &toto
+        };
+
+int main()
+{
+        __asm("nop");
+        __asm("nop");
+        __asm("nop");
+        __asm("nop");
+        toto(42);
+        __asm("nop");
+        __asm("nop");
+        __asm("nop");
+        __asm("nop");
+        fops.f(42);
+}
+		\end{lstlisting}
+
+		Here is the assembly done by this code for x86.
+
+		\begin{lstlisting}
+ 80483d4:       90                      nop
+ 80483d5:       90                      nop
+ 80483d6:       90                      nop
+ 80483d7:       90                      nop
+ 80483d8:       c7 04 24 2a 00 00 00    movl   $0x2a,(%esp)
+ 80483df:       e8 c0 ff ff ff          call   80483a4 <toto>
+ 80483e4:       90                      nop
+ 80483e5:       90                      nop
+ 80483e6:       90                      nop
+ 80483e7:       90                      nop
+ 80483e8:       a1 e0 95 04 08          mov    0x80495e0,%eax
+ 80483ed:       c7 04 24 2a 00 00 00    movl   $0x2a,(%esp)
+ 80483f4:       ff d0                   call   *%eax
+		\end{lstlisting}
+
+		Here is the assembly done by this code for armv4i
+
+		\begin{lstlisting}
+    84ac:       e1a00000        	nop                     (mov r0,r0)
+    84b0:       e1a00000        	nop                     (mov r0,r0)
+    84b4:       e1a00000       		nop                     (mov r0,r0)
+    84b8:       e1a00000        	nop                    	(mov r0,r0)
+    84bc:       e3a0002a        	mov     r0, #42 ; 0x2a
+    84c0:       ebffffe5        	bl      845c <toto>
+    84c4:       e1a00000        	nop                     (mov r0,r0)
+    84c8:       e1a00000        	nop                     (mov r0,r0)
+    84cc:       e1a00000        	nop                     (mov r0,r0)
+    84d0:       e1a00000        	nop                     (mov r0,r0)
+    84d4:       e59f3028        	ldr     r3, [pc, #40]   ; 8504 <main+0x78>
+    84d8:       e5933000        	ldr     r3, [r3]
+    84dc:       e3a0002a        	mov     r0, #42 ; 0x2a
+    84e0:       e1a0e00f        	mov     lr, pc
+    84e4:       e12fff13        	bx      r3
+		\end{lstlisting}
+
+	\section{Single demultiplex vs multiple demultiplex}
+
+	Finally there is no great difference between callbacks and simple call. 
+
+		\begin{lstlisting}
+int
+switcha(int toto)
+{
+        switch(toto) {
+        case 3:
+                break ;
+        case 4:
+                break ;
+        }
+
+}
+
+int
+switchb(int toto)
+{
+        switch(toto) {
+        case 5:
+                break ;
+        case 6:
+                break ;
+        }
+}
+
+int
+multipleswitch(int toto)
+{
+        __asm("nop");
+        __asm("nop");
+        switch(toto) {
+        case 1:
+                switcha(toto -2 );
+                break;
+        case 2:
+                switchb(toto - 4);
+                break;
+        }
+        __asm("nop");
+        __asm("nop");
+}
+
+int
+singleswitch(int toto)
+{
+        __asm("nop");
+        __asm("nop");
+        switch (toto) {
+        case 1:
+                switch (toto - 2) {
+                case 3:
+                        break ;
+                case 4:
+                        break ;
+                }
+                break ;
+        case 2:
+                switch(toto -4) {
+                case 5:
+                        break ;
+                case 6:
+                        break ;
+                }
+                break ;
+        }
+        __asm("nop");
+        __asm("nop");
+}
+
+int
+main()
+{
+	singleswitch(a);
+	singleswitch(b);
+}
+		\end{lstlisting}
+
+		With this code gcc dump exactly the same switch function that do nothing. 
+		But for the multipleswitch the functionn switcha and switchb are also generated.
+

==== //depot/projects/soc2009/syl_usb/hps_report/report.tex#2 (text+ko) ====



More information about the p4-projects mailing list