1
2 #include "lm5710.h"
3 #include "lm_sp_req_mgr.h"
4 #include "context.h"
5
6
7
8 lm_status_t
lm_sp_req_manager_init(struct _lm_device_t * pdev,u32_t cid)9 lm_sp_req_manager_init(
10 struct _lm_device_t *pdev,
11 u32_t cid
12 )
13 {
14 lm_sp_req_manager_t *sp_req_mgr = NULL;
15
16 if CHK_NULL(pdev)
17 {
18 return LM_STATUS_INVALID_PARAMETER;
19 }
20
21 sp_req_mgr = lm_cid_sp_req_mgr(pdev, cid);
22 if CHK_NULL(sp_req_mgr)
23 {
24 return LM_STATUS_INVALID_PARAMETER;
25 }
26
27 s_list_clear(&sp_req_mgr->pending_reqs);
28 sp_req_mgr->blocked = FALSE;
29 sp_req_mgr->req_seq_number = 1;
30 sp_req_mgr->sp_data_virt_addr = NULL;
31 sp_req_mgr->sp_data_phys_addr.as_u64 = 0;
32
33 return LM_STATUS_SUCCESS;
34 }
35
36
37
38 lm_status_t
lm_sp_req_manager_shutdown(struct _lm_device_t * pdev,u32_t cid)39 lm_sp_req_manager_shutdown(
40 struct _lm_device_t *pdev,
41 u32_t cid
42 )
43 {
44 lm_sp_req_manager_t *sp_req_mgr = NULL;
45
46 if CHK_NULL(pdev)
47 {
48 return LM_STATUS_INVALID_PARAMETER;
49 }
50
51 sp_req_mgr = lm_cid_sp_req_mgr(pdev, cid);
52 if CHK_NULL(sp_req_mgr)
53 {
54 return LM_STATUS_INVALID_PARAMETER;
55 }
56
57 if (ERR_IF(!s_list_is_empty(&sp_req_mgr->pending_reqs)))
58 {
59 DbgBreakIf( !s_list_is_empty(&sp_req_mgr->pending_reqs) );
60 return LM_STATUS_INVALID_PARAMETER;
61 }
62
63 sp_req_mgr->blocked = TRUE;
64 sp_req_mgr->sp_data_virt_addr = NULL;
65 sp_req_mgr->sp_data_phys_addr.as_u64 = 0;
66
67 return LM_STATUS_SUCCESS;
68 }
69
70
71
72 lm_status_t
lm_sp_req_manager_post(struct _lm_device_t * pdev,u32_t cid,struct _lm_sp_req_common_t * sp_req)73 lm_sp_req_manager_post(
74 struct _lm_device_t *pdev,
75 u32_t cid,
76 struct _lm_sp_req_common_t *sp_req
77 )
78 {
79 lm_sp_req_manager_t *sp_req_mgr = NULL;
80 lm_status_t lm_status = LM_STATUS_FAILURE;
81
82 if (CHK_NULL(pdev) || CHK_NULL(sp_req))
83 {
84 return LM_STATUS_INVALID_PARAMETER;
85 }
86
87 sp_req_mgr = lm_cid_sp_req_mgr(pdev, cid);
88 if CHK_NULL(sp_req_mgr)
89 {
90 return LM_STATUS_INVALID_PARAMETER;
91 }
92
93 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_post, before lock cid=%d\n", cid);
94 MM_ACQUIRE_SP_REQ_MGR_LOCK(pdev);
95 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_post, inside lock cid=%d\n", cid);
96
97 if (sp_req_mgr->blocked)
98 {
99 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_post, adding to list cid=%d\n", cid);
100
101 s_list_push_tail(&sp_req_mgr->pending_reqs, &sp_req->link);
102 sp_req = NULL;
103 lm_status = LM_STATUS_PENDING;
104 }
105 else
106 {
107 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_post, calling req_post_function, cid=%d\n", cid);
108
109 sp_req->req_seq_number = ++sp_req_mgr->req_seq_number;
110 sp_req_mgr->posted_req = sp_req;
111 sp_req_mgr->blocked = TRUE;
112 }
113 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
114
115 if (sp_req != NULL)
116 {
117 lm_status = ((req_post_function)sp_req->req_post_func)(pdev, sp_req->req_post_ctx, sp_req);
118 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_post, req_post_function, cid=%d, lm_status=%d\n", cid, lm_status);
119 }
120
121 return lm_status;
122 }
123
124
125
126 lm_status_t
lm_sp_req_manager_complete(struct _lm_device_t * pdev,u32_t cid,u32_t seq_num,lm_sp_req_common_t ** sp_req)127 lm_sp_req_manager_complete(
128 struct _lm_device_t *pdev,
129 u32_t cid,
130 u32_t seq_num,
131 lm_sp_req_common_t **sp_req
132 )
133 {
134 lm_sp_req_manager_t *sp_req_mgr = NULL;
135 lm_status_t lm_status = LM_STATUS_SUCCESS;
136
137 if (CHK_NULL(pdev) || CHK_NULL(sp_req))
138 {
139 return LM_STATUS_INVALID_PARAMETER;
140 }
141
142 *sp_req = NULL;
143
144 sp_req_mgr = lm_cid_sp_req_mgr(pdev, cid);
145 if CHK_NULL(sp_req_mgr)
146 {
147 return LM_STATUS_INVALID_PARAMETER;
148 }
149
150 MM_ACQUIRE_SP_REQ_MGR_LOCK(pdev);
151
152 /* in iscsi we use sp_req_mgr.posted_req to store last req, */
153 /* so instead of getting the seq num as param, we'll find it ourselves */
154 if (seq_num == 0)
155 {
156 if CHK_NULL(sp_req_mgr->posted_req)
157 {
158 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
159 return LM_STATUS_INVALID_PARAMETER;
160 }
161
162 seq_num = sp_req_mgr->posted_req->req_seq_number;
163 }
164
165 if ( ERR_IF( seq_num != sp_req_mgr->req_seq_number ) ||
166 ERR_IF( sp_req_mgr->blocked == FALSE ) )
167 {
168 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_complete, cid=%d, seq_num=%d, sp_req_mgr->req_seq_number=%d\n", cid, seq_num, sp_req_mgr->req_seq_number);
169 DbgBreakIf( seq_num != sp_req_mgr->req_seq_number );
170 DbgBreakIf( (sp_req_mgr->blocked == FALSE) && (sp_req_mgr->posted_req != NULL) );
171 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
172 return LM_STATUS_INVALID_PARAMETER;
173 }
174
175 if (!s_list_is_empty(&sp_req_mgr->pending_reqs))
176 {
177 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_complete, popping from list cid=%d\n", cid);
178
179 *sp_req = (lm_sp_req_common_t *)s_list_pop_head(&sp_req_mgr->pending_reqs);
180
181 if (CHK_NULL(*sp_req))
182 {
183 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
184 return LM_STATUS_INVALID_PARAMETER;
185 }
186
187 (*sp_req)->req_seq_number = ++sp_req_mgr->req_seq_number;
188 sp_req_mgr->posted_req = (*sp_req);
189 }
190 else
191 {
192 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_complete, no pending reqs, cid=%d\n", cid);
193
194 sp_req_mgr->blocked = FALSE;
195 sp_req_mgr->posted_req = NULL;
196 }
197
198 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
199
200 if ((*sp_req) != NULL)
201 {
202 lm_status = ((req_post_function)(*sp_req)->req_post_func)(pdev, (*sp_req)->req_post_ctx, *sp_req);
203 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_complete, req_post_function, cid=%d, lm_status=%d\n", cid, lm_status);
204 }
205
206 return lm_status;
207 }
208
209
210
211 lm_status_t
lm_sp_req_manager_block(struct _lm_device_t * pdev,u32_t cid)212 lm_sp_req_manager_block(
213 struct _lm_device_t *pdev,
214 u32_t cid
215 )
216 {
217 lm_sp_req_manager_t *sp_req_mgr = NULL;
218
219 if CHK_NULL(pdev)
220 {
221 return LM_STATUS_INVALID_PARAMETER;
222 }
223
224 sp_req_mgr = lm_cid_sp_req_mgr(pdev, cid);
225 if CHK_NULL(sp_req_mgr)
226 {
227 return LM_STATUS_INVALID_PARAMETER;
228 }
229
230 MM_ACQUIRE_SP_REQ_MGR_LOCK(pdev);
231
232 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_block, blocking sq req mgr, cid=%d\n", cid);
233 sp_req_mgr->blocked = TRUE;
234
235 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
236
237 return LM_STATUS_SUCCESS;
238 }
239
240
241
242 /* same as complete, execpt for seq number and asserts */
243 lm_status_t
lm_sp_req_manager_unblock(struct _lm_device_t * pdev,u32_t cid,lm_sp_req_common_t ** sp_req)244 lm_sp_req_manager_unblock(
245 struct _lm_device_t *pdev,
246 u32_t cid,
247 lm_sp_req_common_t **sp_req
248 )
249 {
250 lm_sp_req_manager_t *sp_req_mgr = NULL;
251 lm_status_t lm_status = LM_STATUS_SUCCESS;
252
253 if (CHK_NULL(pdev) || CHK_NULL(sp_req))
254 {
255 return LM_STATUS_INVALID_PARAMETER;
256 }
257
258 *sp_req = NULL;
259
260 sp_req_mgr = lm_cid_sp_req_mgr(pdev, cid);
261 if CHK_NULL(sp_req_mgr)
262 {
263 return LM_STATUS_INVALID_PARAMETER;
264 }
265
266 MM_ACQUIRE_SP_REQ_MGR_LOCK(pdev);
267
268 if (!s_list_is_empty(&sp_req_mgr->pending_reqs))
269 {
270 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_unblock, popping from list cid=%d\n", cid);
271
272 *sp_req = (lm_sp_req_common_t *)s_list_pop_head(&sp_req_mgr->pending_reqs);
273
274 if (CHK_NULL(*sp_req))
275 {
276 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
277 return LM_STATUS_INVALID_PARAMETER;
278 }
279
280 (*sp_req)->req_seq_number = ++sp_req_mgr->req_seq_number;
281 sp_req_mgr->posted_req = (*sp_req);
282 }
283 else
284 {
285 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_unblock, no pending reqs, cid=%d\n", cid);
286
287 sp_req_mgr->blocked = FALSE;
288 sp_req_mgr->posted_req = NULL;
289 }
290
291 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
292
293 if ((*sp_req) != NULL)
294 {
295 lm_status = ((req_post_function)(*sp_req)->req_post_func)(pdev, (*sp_req)->req_post_ctx, *sp_req);
296 // DbgMessage(pdev, FATAL/*INFORM*/, "###lm_sp_req_manager_unblock, req_post_function, cid=%d, lm_status=%d\n", cid, lm_status);
297 }
298
299 return lm_status;
300 }
301
302
303
304 lm_status_t
lm_sp_req_manager_set_sp_data(struct _lm_device_t * pdev,u32_t cid,void * virt_addr,lm_address_t phys_addr)305 lm_sp_req_manager_set_sp_data(
306 struct _lm_device_t *pdev,
307 u32_t cid,
308 void *virt_addr,
309 lm_address_t phys_addr
310 )
311 {
312 lm_sp_req_manager_t *sp_req_mgr = NULL;
313
314 if CHK_NULL(pdev)
315 {
316 return LM_STATUS_INVALID_PARAMETER;
317 }
318
319 sp_req_mgr = lm_cid_sp_req_mgr(pdev, cid);
320 if CHK_NULL(sp_req_mgr)
321 {
322 return LM_STATUS_INVALID_PARAMETER;
323 }
324
325 MM_ACQUIRE_SP_REQ_MGR_LOCK(pdev);
326
327 sp_req_mgr->sp_data_virt_addr = virt_addr;
328 sp_req_mgr->sp_data_phys_addr = phys_addr;
329
330 MM_RELEASE_SP_REQ_MGR_LOCK(pdev);
331
332 return LM_STATUS_SUCCESS;
333 }
334
335