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