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