vmod/vmodttl: fixed bug related to luns not ordered and/or not starting from zero.
[ht-drivers.git] / cdcm / README
blobbc37f9771c51259e360d0b0c4954b925af5fe7aa
1 +-------------------------------------------------+
2 |  Author:          Yury Georgievskiy, CERN       |
3 |  Creation date:   01.06.2006                    |
4 |  Current version: 3 (as of 17.12.2007)          |
5 |  State:           Techical note                 |
6 +-------------------------------------------------+
9 ###############################################################################
10 #                       CDCM technical notes.                                 #
11 ###############################################################################
13 First of all - pay in mind, that it's (still) not perfect.
14 There are some rules and limitations on HOWTO use CDCM.
15 One should take care following this rules and limitations.
17 Here comes the 'limitation list'
19 1. 'struct file' that is passed into the common part of the LynxOS-like code
20     is screwed up in case of Linux!! It's adapted partially.
23 2. Stream task limitatioins.
24 ----------------------------
25    For now there is no way to emulate LynxOS threads completely.
26    The 'oblitary code demand' concerns a function that is passed as a payload
27    function to 'ststart' call (firs parameter of ststart).
28    Let's examain it in more details:
29    Usually, a stream task payload is looped in a cycle, doing it's work.
30    The demand for this functions is that
31    EACH TIME BEFORE TO JUMP TO THE BEGINNING OF THE LOOP - ONE SHOULD INSERT
32    A PREDEFINED CDCM MACRO IN IT'S CODE.
33    The macro is 'CDCM_LOOP_AGAIN'.
35    The only perpose of this macro is to be able to quit (or to kill, as you
36    prefer) system thread on Linux platform. Othervise it's not possible to get
37    out of the 'for' loop. Note that we are speaking only about Linux platform.
38    Want to know why? Here you go:
39    It's not possible to add signal handler to kernel thread in Linux.
40    They will never been called. Signals are delivered only on exit from kernel
41    mode (which happens either at the end of a syscall or after interrupt, which
42    may have caused the signal), scheduling being a special case ot this.
43    Since kernel thread never leaves a kernel mode, the code to run signal
44    handlers is never executed.
46    Here are some examples that illustrates how stream task should look like
47    in CDCM:
49 ----------------------------------+---------------------------------
50         Normal Lynx thread        |        CDCM adapted Lynx thread
51 ----------------------------------+---------------------------------
52                                   |
53    void kthread(void param) {     |   void kthread(void param) {
54           for (;;) {              |          for (;;) {
55             ....                  |            ...
56             /* do the job */      |            /* do the job */
57             ...                   |            ...
58           }                       |            CDCM_LOOP_AGAIN;
59         }                         |          }
60                                   |        }
61 ----------------------------------+---------------------------------
62                                   |
63    void kthread(void param) {     |   void kthread(void param) {
64           do {                    |          do {
65             ...                   |            ...
66             /* payload */         |            /* payload */
67             ...                   |            ...
68           } while (1)             |            CDCM_LOOP_AGAIN;
69         }                         |          } while (1)
70                                   |        }
71 ----------------------------------+---------------------------------
72                                   |
73    void kthread(void param) {     |    void kthread(void param) {
74         tag:                      |         tag:
75         ...                       |         ...
76         /* do the job here */     |         /* do the job here */
77         ...                       |         ...
78         goto tag;                 |         CDCM_LOOP_AGAIN;
79         }                         |         goto tag;
80                                   |         }
81 ----------------------------------+---------------------------------
83    As you can see - all 'adapted' functions contain CDCM_LOOP_AGAIN macro just
84    before the end of the loop cycle. This is the bottleneck of thread stub
85    implementation, because already existing driver code will not be completely
86    portable. It should be affected (CDCM_LOOP_AGAIN macro insertion) to be
87    able to run under Linux.
90 3. Copy data to/from user address space.
91 ----------------------------------------
92    Special CDCM functions can be used when transferring data to/from user
93    address space. These functions are:
95    A. cdcm_copy_from_user(void *to, void *from, int size)
96    B. cdcm_copy_to_user(void *to, void *from, int size)
98 4. DMA API
99 ----------
100 Documentation to be written.
102 5. Interrupt handler
103 --------------------
104 Documentation to be written.
106 6. Return values to user-space
107 ------------------------------
108 Programs that run in user space always see -1 as the error return value.
109 They need to access the errno variable to find out what happened; this is
110 imposed by the POSIX standard.
111 For CDCM-compliant drivers we follow the LynxOs approach:
112 * If an error happens, first set pseterr(code), where code is one of the
113 POSIX error codes defined in include/errno.h.
114 * Once the error code has been set, return SYSERR.
116 Note that the procedure below refers _only_ to the communication between
117 the kernel and user-space, which is defined by POSIX (i.e. this standard
118 does not make requirements on how the kernel operates internally).
120 Sources: LynxOS man, ldd3@pp66.
122 7. Timeouts
123 -----------
124 Timeouts respect the original LynxOs interface (man timeout).
125 The interval passed to the timeout is the number of ticks we want to wait.
126 Since all the LynxOS boxes we run have 100 ticks per second (i.e. 1 tick
127 every 10ms), we have decided that timeout assumes that value when getting the
128 ticks interval from the user. This does _not_ mean that all our machines
129 are configured with tickspersec=100 (NB. tickspersec is HZ in Linux); it
130 means that irrespective of the machine you're running on, if you want
131 to wait, say 40ms, then you give to timeout() an interval of 4 ticks.
133 8. I/O operations
134 -----------------
135 I/O operations to/from hardware must be done using the provided helpers
136 cdcm_io{read,write}{8,16,32}(). The address fed to these helpers is a void
137 pointer, *not* volatile. The reason is well explained in the Linux kernel
138 documentation ('Documentation/volatile-considered-harmful.txt'). Basically
139 proceeding this way has two benefits:
140 - Code portability
141 - No memory barriers needed (since they are included in the helpers)
143 Bear in mind endianness issues when dealing with hardware: use the
144 provided helpers to swap according to the host machine endianness and that
145 of the hardware (cdcm_cpu_to_le{16,32,64},etc.).
147 Use fixed-width types to describe hardware (ideally use standard C99 types).
149 In the (rare) case you need a memory barrier, use the helpers provided
150 (cdcm_{mb,rmb,wmb}) and insert a comment to explain why you need the barrier.
152 For further info check the file cdcmIo.h.