diff options
Diffstat (limited to 'arch/powerpc/sysdev/bestcomm/bestcomm.h')
-rw-r--r-- | arch/powerpc/sysdev/bestcomm/bestcomm.h | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.h b/arch/powerpc/sysdev/bestcomm/bestcomm.h index c960a8b49655..23a95f80dfdb 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.h +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.h | |||
@@ -16,8 +16,19 @@ | |||
16 | #ifndef __BESTCOMM_H__ | 16 | #ifndef __BESTCOMM_H__ |
17 | #define __BESTCOMM_H__ | 17 | #define __BESTCOMM_H__ |
18 | 18 | ||
19 | struct bcom_bd; /* defined later on ... */ | 19 | /** |
20 | 20 | * struct bcom_bd - Structure describing a generic BestComm buffer descriptor | |
21 | * @status: The current status of this buffer. Exact meaning depends on the | ||
22 | * task type | ||
23 | * @data: An array of u32 extra data. Size of array is task dependant. | ||
24 | * | ||
25 | * Note: Don't dereference a bcom_bd pointer as an array. The size of the | ||
26 | * bcom_bd is variable. Use bcom_get_bd() instead. | ||
27 | */ | ||
28 | struct bcom_bd { | ||
29 | u32 status; | ||
30 | u32 data[0]; /* variable payload size */ | ||
31 | }; | ||
21 | 32 | ||
22 | /* ======================================================================== */ | 33 | /* ======================================================================== */ |
23 | /* Generic task management */ | 34 | /* Generic task management */ |
@@ -84,17 +95,6 @@ bcom_get_task_irq(struct bcom_task *tsk) { | |||
84 | /* BD based tasks helpers */ | 95 | /* BD based tasks helpers */ |
85 | /* ======================================================================== */ | 96 | /* ======================================================================== */ |
86 | 97 | ||
87 | /** | ||
88 | * struct bcom_bd - Structure describing a generic BestComm buffer descriptor | ||
89 | * @status: The current status of this buffer. Exact meaning depends on the | ||
90 | * task type | ||
91 | * @data: An array of u32 whose meaning depends on the task type. | ||
92 | */ | ||
93 | struct bcom_bd { | ||
94 | u32 status; | ||
95 | u32 data[1]; /* variable, but at least 1 */ | ||
96 | }; | ||
97 | |||
98 | #define BCOM_BD_READY 0x40000000ul | 98 | #define BCOM_BD_READY 0x40000000ul |
99 | 99 | ||
100 | /** _bcom_next_index - Get next input index. | 100 | /** _bcom_next_index - Get next input index. |
@@ -140,15 +140,31 @@ bcom_queue_full(struct bcom_task *tsk) | |||
140 | } | 140 | } |
141 | 141 | ||
142 | /** | 142 | /** |
143 | * bcom_get_bd - Get a BD from the queue | ||
144 | * @tsk: The BestComm task structure | ||
145 | * index: Index of the BD to fetch | ||
146 | */ | ||
147 | static inline struct bcom_bd | ||
148 | *bcom_get_bd(struct bcom_task *tsk, unsigned int index) | ||
149 | { | ||
150 | /* A cast to (void*) so the address can be incremented by the | ||
151 | * real size instead of by sizeof(struct bcom_bd) */ | ||
152 | return ((void *)tsk->bd) + (index * tsk->bd_size); | ||
153 | } | ||
154 | |||
155 | /** | ||
143 | * bcom_buffer_done - Checks if a BestComm | 156 | * bcom_buffer_done - Checks if a BestComm |
144 | * @tsk: The BestComm task structure | 157 | * @tsk: The BestComm task structure |
145 | */ | 158 | */ |
146 | static inline int | 159 | static inline int |
147 | bcom_buffer_done(struct bcom_task *tsk) | 160 | bcom_buffer_done(struct bcom_task *tsk) |
148 | { | 161 | { |
162 | struct bcom_bd *bd; | ||
149 | if (bcom_queue_empty(tsk)) | 163 | if (bcom_queue_empty(tsk)) |
150 | return 0; | 164 | return 0; |
151 | return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY); | 165 | |
166 | bd = bcom_get_bd(tsk, tsk->outdex); | ||
167 | return !(bd->status & BCOM_BD_READY); | ||
152 | } | 168 | } |
153 | 169 | ||
154 | /** | 170 | /** |
@@ -160,16 +176,21 @@ bcom_buffer_done(struct bcom_task *tsk) | |||
160 | static inline struct bcom_bd * | 176 | static inline struct bcom_bd * |
161 | bcom_prepare_next_buffer(struct bcom_task *tsk) | 177 | bcom_prepare_next_buffer(struct bcom_task *tsk) |
162 | { | 178 | { |
163 | tsk->bd[tsk->index].status = 0; /* cleanup last status */ | 179 | struct bcom_bd *bd; |
164 | return &tsk->bd[tsk->index]; | 180 | |
181 | bd = bcom_get_bd(tsk, tsk->index); | ||
182 | bd->status = 0; /* cleanup last status */ | ||
183 | return bd; | ||
165 | } | 184 | } |
166 | 185 | ||
167 | static inline void | 186 | static inline void |
168 | bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie) | 187 | bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie) |
169 | { | 188 | { |
189 | struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index); | ||
190 | |||
170 | tsk->cookie[tsk->index] = cookie; | 191 | tsk->cookie[tsk->index] = cookie; |
171 | mb(); /* ensure the bd is really up-to-date */ | 192 | mb(); /* ensure the bd is really up-to-date */ |
172 | tsk->bd[tsk->index].status |= BCOM_BD_READY; | 193 | bd->status |= BCOM_BD_READY; |
173 | tsk->index = _bcom_next_index(tsk); | 194 | tsk->index = _bcom_next_index(tsk); |
174 | if (tsk->flags & BCOM_FLAGS_ENABLE_TASK) | 195 | if (tsk->flags & BCOM_FLAGS_ENABLE_TASK) |
175 | bcom_enable(tsk); | 196 | bcom_enable(tsk); |
@@ -179,10 +200,12 @@ static inline void * | |||
179 | bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd) | 200 | bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd) |
180 | { | 201 | { |
181 | void *cookie = tsk->cookie[tsk->outdex]; | 202 | void *cookie = tsk->cookie[tsk->outdex]; |
203 | struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex); | ||
204 | |||
182 | if (p_status) | 205 | if (p_status) |
183 | *p_status = tsk->bd[tsk->outdex].status; | 206 | *p_status = bd->status; |
184 | if (p_bd) | 207 | if (p_bd) |
185 | *p_bd = &tsk->bd[tsk->outdex]; | 208 | *p_bd = bd; |
186 | tsk->outdex = _bcom_next_outdex(tsk); | 209 | tsk->outdex = _bcom_next_outdex(tsk); |
187 | return cookie; | 210 | return cookie; |
188 | } | 211 | } |