1 2 #include "lm5710.h" 3 #include "lm_sp_req_mgr.h" 4 #include "context.h" 5 6 7 8 lm_status_t 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 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 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 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 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 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 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