aca2b49e2f87db81b4852abb4acd2b855d943ca9
[mirror/winof/.git] / ulp / srp / kernel / srp_data_path.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenIB.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  *\r
29  * $Id$\r
30  */\r
31 \r
32 \r
33 #include <complib/cl_math.h>\r
34 #include <complib/cl_obj.h>\r
35 \r
36 #include "srp_cmd.h"\r
37 #include "srp_data_path.h"\r
38 #include "srp_debug.h"\r
39 #include "srp_descriptors.h"\r
40 #include "srp_rsp.h"\r
41 #include "srp_session.h"\r
42 #include "srp_tsk_mgmt.h"\r
43 \r
44 //#include "srp_aer_req.h"\r
45 //#include "srp_aer_rsp.h"\r
46 \r
47 //#include "srp_cred_req.h"\r
48 //#include "srp_cred_rsp.h"\r
49 \r
50 //#include "srp_i_logout.h"\r
51 //#include "srp_t_logout.h"\r
52 \r
53 // Final address is of the form 0b00ttttttllllllll\r
54 #define BUILD_SCSI_ADDRESS(target, lun) ((((uint64_t)(target & 0x3f)<<8)+(uint64_t)lun) << 48)\r
55 \r
56 static inline\r
57 void\r
58 __srp_process_session_send_completions(\r
59         IN  srp_session_t   *p_session )\r
60 {\r
61         ib_api_status_t status;\r
62         ib_wc_t         *p_wc_done_list = NULL;\r
63         ib_wc_t         *p_wc;\r
64 \r
65         SRP_ENTER( SRP_DBG_FUNC );\r
66 \r
67         cl_obj_lock( &p_session->obj );\r
68 \r
69         if ( p_session->connection.state != SRP_CONNECTED )\r
70         {\r
71                 cl_obj_unlock( &p_session->obj );\r
72                 SRP_EXIT( SRP_DBG_FUNC );\r
73                 return;\r
74         }\r
75 \r
76         status = p_session->p_hba->ifc.poll_cq(\r
77                 p_session->connection.h_send_cq,\r
78                 &p_session->connection.p_wc_free_list,\r
79                 &p_wc_done_list );\r
80         if ( status != IB_SUCCESS )\r
81         {\r
82                 SRP_TRACE_EXIT( SRP_DBG_ERROR,\r
83                         ("ib_poll_cq() failed!, status 0x%x\n", status) );\r
84 \r
85                 // TODO: Kill session and inform port driver link down scsiportnotification\r
86                 cl_obj_unlock( &p_session->obj );\r
87                 return;\r
88         }\r
89 \r
90         cl_obj_ref( &p_session->obj );\r
91         cl_obj_unlock( &p_session->obj );\r
92 \r
93         while ( (p_wc = p_wc_done_list) != NULL )\r
94         {\r
95                 /* Remove head from list */\r
96                 p_wc_done_list = p_wc->p_next;\r
97                 p_wc->p_next = NULL;\r
98 \r
99                 if ( p_wc->status != IB_WCS_SUCCESS )\r
100                 {\r
101                         srp_send_descriptor_t   *p_send_descriptor;\r
102 \r
103                         p_send_descriptor = (srp_send_descriptor_t *)((uintn_t)p_wc->wr_id);\r
104 \r
105                         // TODO: Kill session and inform port driver link down scsiportnotification\r
106                         SRP_TRACE( SRP_DBG_ERROR,\r
107                                 ("Send failed!, status 0x%x\n", p_wc->status) );\r
108 \r
109                         SRP_TRACE( SRP_DBG_VERBOSE,\r
110                                            ("Send Completion Received for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag 0x%"PRIx64"\n",\r
111                                            g_srb_function_name[p_send_descriptor->p_srb->Function],\r
112                                            p_send_descriptor->p_srb->Function,\r
113                                            p_send_descriptor->p_srb->PathId,\r
114                                            p_send_descriptor->p_srb->TargetId,\r
115                                            p_send_descriptor->p_srb->Lun,\r
116                                            get_srp_command_tag( (srp_cmd_t *)p_send_descriptor->data_segment )) );\r
117                 }\r
118 \r
119                 /* Put onto head of free list */\r
120                 cl_obj_lock( &p_session->obj );\r
121                 p_wc->p_next = p_session->connection.p_wc_free_list;\r
122                 p_session->connection.p_wc_free_list = p_wc;\r
123                 cl_obj_unlock( &p_session->obj );\r
124 \r
125                 /* Get next completion */\r
126                 p_wc = p_wc_done_list;\r
127         }\r
128 \r
129         /* Re-arm the CQ for more completions */\r
130         status = p_session->p_hba->ifc.rearm_cq(\r
131                 p_session->connection.h_send_cq, FALSE );\r
132         if ( status != IB_SUCCESS)\r
133         {\r
134                 SRP_TRACE( SRP_DBG_ERROR,\r
135                         ("ib_rearm_cq() failed!, status 0x%x\n", status) );\r
136 \r
137                 // TODO: Kill session and inform port driver link down scsiportnotification\r
138         }\r
139 \r
140         cl_obj_deref( &p_session->obj );\r
141 \r
142         SRP_EXIT( SRP_DBG_FUNC );\r
143 }\r
144 \r
145 /* srp_send_completion_cb */\r
146 /*!\r
147 Set Timer to Process Send Completions - Usually bad if we get here\r
148 \r
149 @param p_context - context pointer to the owning session\r
150 \r
151 @return - none\r
152 */\r
153 void\r
154 srp_send_completion_cb(\r
155         IN      const   ib_cq_handle_t          h_cq,\r
156         IN                      void                            *p_context )\r
157 {\r
158         srp_session_t   *p_session = (srp_session_t *)p_context;\r
159 \r
160         SRP_ENTER( SRP_DBG_FUNC );\r
161 \r
162         UNUSED_PARAM( h_cq );\r
163 \r
164         __srp_process_session_send_completions( p_session );\r
165 \r
166         SRP_EXIT( SRP_DBG_FUNC );\r
167 }\r
168 \r
169 static inline\r
170 ib_api_status_t\r
171 __srp_process_recv_completion(\r
172         IN  srp_recv_descriptor_t   *p_recv_descriptor,\r
173         IN  srp_session_t           *p_session )\r
174 {\r
175         ib_api_status_t         status = IB_SUCCESS;\r
176         srp_rsp_t               *p_srp_rsp;\r
177         uint8_t                 response_status;\r
178         srp_send_descriptor_t   *p_send_descriptor;\r
179 \r
180         SRP_ENTER( SRP_DBG_FUNC );\r
181 \r
182         p_srp_rsp = (srp_rsp_t *)p_recv_descriptor->p_data_segment;\r
183 \r
184         set_srp_response_from_network_to_host( p_srp_rsp );\r
185 \r
186         response_status = get_srp_response_status( p_srp_rsp );\r
187 \r
188         p_send_descriptor = srp_find_matching_send_descriptor(\r
189                 &p_session->descriptors,\r
190                 get_srp_response_tag( (srp_rsp_t *)p_recv_descriptor->p_data_segment ) );\r
191         if ( p_send_descriptor == NULL )\r
192         {\r
193                 /* Repost the recv descriptor */\r
194                 status = p_session->p_hba->ifc.post_recv(\r
195                         p_session->connection.h_qp, &p_recv_descriptor->wr, NULL );\r
196                 if ( status != IB_SUCCESS )\r
197                 {\r
198                         SRP_TRACE( SRP_DBG_ERROR,\r
199                                 ("Failed to post send descriptor. Status = %d.\n", status) );\r
200                         // TODO: Kill session and inform port driver link down scsiportnotification\r
201                 }\r
202 \r
203                 cl_atomic_add( &p_session->connection.request_limit, get_srp_response_request_limit_delta( p_srp_rsp ) );\r
204 \r
205                 SRP_TRACE( SRP_DBG_WARN, ("Matching Send Descriptor Not Found.\n") );\r
206 \r
207                 goto exit;\r
208         }\r
209 \r
210         SRP_TRACE( SRP_DBG_VERBOSE,\r
211                            ("Recv Completion Received for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag 0x%"PRIx64"\n",\r
212                            g_srb_function_name[p_send_descriptor->p_srb->Function],\r
213                            p_send_descriptor->p_srb->Function,\r
214                            p_send_descriptor->p_srb->PathId,\r
215                            p_send_descriptor->p_srb->TargetId,\r
216                            p_send_descriptor->p_srb->Lun,\r
217                            get_srp_command_tag( (srp_cmd_t *)p_send_descriptor->data_segment )) );\r
218 \r
219         switch ( get_srp_iu_buffer_type( (srp_iu_buffer_t *)p_send_descriptor->data_segment ) )\r
220         {\r
221                 case SRP_TSK_MGMT:\r
222                 {\r
223                         srp_tsk_mgmt_t  *p_srp_tsk_mgmt = (srp_tsk_mgmt_t *)p_send_descriptor->data_segment;\r
224 \r
225                         set_srp_tsk_mgmt_from_network_to_host( p_srp_tsk_mgmt );\r
226 \r
227                         p_send_descriptor->p_srb->SrbStatus =\r
228                                 (response_status == SCSISTAT_GOOD) ? SRB_STATUS_SUCCESS : SRB_STATUS_ABORT_FAILED;\r
229 \r
230                         if ( get_srp_tsk_mgmt_task_management_flags( p_srp_tsk_mgmt ) == TMF_ABORT_TASK )\r
231                         {\r
232                                 /* Repost the recv descriptor */\r
233                                 status = p_session->p_hba->ifc.post_recv(\r
234                                         p_session->connection.h_qp, &p_recv_descriptor->wr, NULL );\r
235                                 if ( status != IB_SUCCESS )\r
236                                 {\r
237                                         SRP_TRACE( SRP_DBG_ERROR,\r
238                                                 ("Failed to post recv descriptor. Status = %d.\n", status) );\r
239                                         // TODO: Kill session and inform port driver link down storportnotification\r
240                                 }\r
241 \r
242                                 cl_atomic_add( &p_session->connection.request_limit, get_srp_response_request_limit_delta( p_srp_rsp ) );\r
243 \r
244                                 SRP_TRACE( SRP_DBG_VERBOSE,\r
245                                                    ("Srb Status = %s(0x%x)\n",\r
246                                                    g_srb_status_name[p_send_descriptor->p_srb->SrbStatus],\r
247                                                    p_send_descriptor->p_srb->SrbStatus) );\r
248 \r
249                                 SRP_TRACE( SRP_DBG_VERBOSE, ("Device Extension Address = %p\n", p_session->p_hba->p_ext) );\r
250                                 SRP_TRACE( SRP_DBG_VERBOSE, ("Srb Address              = %p\n", p_send_descriptor->p_srb) );\r
251                                 SRP_TRACE( SRP_DBG_VERBOSE, ("Srb DataBuffer Address   = %p\n", p_send_descriptor->p_srb->DataBuffer) );\r
252                                 SRP_TRACE( SRP_DBG_VERBOSE, ("Srb DataTransferLength   = %d\n", p_send_descriptor->p_srb->DataTransferLength) );\r
253 \r
254                                 SRP_TRACE( SRP_DBG_VERBOSE,\r
255                                                    ("Returning SrbStatus %s(0x%x) for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag 0x%"PRIx64"\n",\r
256                                                    g_srb_status_name[p_send_descriptor->p_srb->SrbStatus],\r
257                                                    p_send_descriptor->p_srb->SrbStatus,\r
258                                                    g_srb_function_name[p_send_descriptor->p_srb->Function],\r
259                                                    p_send_descriptor->p_srb->Function,\r
260                                                    p_send_descriptor->p_srb->PathId,\r
261                                                    p_send_descriptor->p_srb->TargetId,\r
262                                                    p_send_descriptor->p_srb->Lun,\r
263                                                    get_srp_command_tag( (srp_cmd_t *)p_send_descriptor->data_segment )) );\r
264 \r
265                                 StorPortNotification( RequestComplete, p_session->p_hba->p_ext, p_send_descriptor->p_srb );\r
266                         }\r
267                         break;\r
268                 }\r
269 \r
270                 case SRP_CMD:\r
271                         p_send_descriptor->p_srb->ScsiStatus = response_status;\r
272                         p_send_descriptor->p_srb->SrbStatus =\r
273                                 (response_status == SCSISTAT_GOOD) ? SRB_STATUS_SUCCESS : SRB_STATUS_ERROR;\r
274 \r
275                         if ( get_srp_response_flags( p_srp_rsp ) != 0 )\r
276                         {\r
277                                 uint32_t    resid;\r
278 \r
279                                 if ( (response_status != SCSISTAT_CHECK_CONDITION) && get_srp_response_di_under( p_srp_rsp ) )\r
280                                 {\r
281                                         resid = get_srp_response_data_in_residual_count( p_srp_rsp );\r
282 \r
283                                         SRP_TRACE( SRP_DBG_WARN,\r
284                                                 ("DI Underflow in response: expected %d got %d.\n",\r
285                                                 p_send_descriptor->p_srb->DataTransferLength,\r
286                                                 p_send_descriptor->p_srb->DataTransferLength - resid) );\r
287 \r
288                                         p_send_descriptor->p_srb->DataTransferLength -= resid;\r
289 \r
290                                         if ( p_send_descriptor->p_srb->SrbStatus == SRB_STATUS_SUCCESS )\r
291                                         {\r
292                                                 p_send_descriptor->p_srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; /* Also for underrun see DDK */\r
293                                         }\r
294                                 }\r
295 \r
296                                 if ( (response_status != SCSISTAT_CHECK_CONDITION) && get_srp_response_do_under( p_srp_rsp ) )\r
297                                 {\r
298                                         resid = get_srp_response_data_out_residual_count( p_srp_rsp );\r
299 \r
300                                         SRP_TRACE( SRP_DBG_WARN,\r
301                                                 ("DI Underflow in response: expected %d got %d.\n",\r
302                                                 p_send_descriptor->p_srb->DataTransferLength,\r
303                                                 p_send_descriptor->p_srb->DataTransferLength - resid) );\r
304 \r
305                                         p_send_descriptor->p_srb->DataTransferLength -= resid;\r
306 \r
307                                         if ( p_send_descriptor->p_srb->SrbStatus == SRB_STATUS_SUCCESS )\r
308                                         {\r
309                                                 p_send_descriptor->p_srb->SrbStatus = SRB_STATUS_DATA_OVERRUN; /* Also for underrun see DDK */\r
310                                         }\r
311                                 }\r
312 \r
313                                 if ( get_srp_response_sns_valid( p_srp_rsp ) )\r
314                                 {\r
315                                         uint8_t *p_sense_data = get_srp_response_sense_data( p_srp_rsp );\r
316 \r
317                                         /* Copy only as much of the sense data as we can hold. */\r
318                                         cl_memcpy( p_send_descriptor->p_srb->SenseInfoBuffer,\r
319                                                            p_sense_data,\r
320                                                            MIN( get_srp_response_sense_data_list_length( p_srp_rsp ),\r
321                                                                         p_send_descriptor->p_srb->SenseInfoBufferLength ) );\r
322 \r
323                                         if ( ((p_sense_data[2]&0xf) == 0x0b /*ABORTED_COMMAND*/) &&\r
324                                                 (p_sense_data[12] == 0x08) &&\r
325                                                 (p_sense_data[13] == 0x00) )\r
326 \r
327                                         {\r
328                                                 /* probably a problem with the Vfx FC san like wire pull*/\r
329                                                 /* initiate session recovery */\r
330                                                 SRP_TRACE( SRP_DBG_WARN,\r
331                                                         ("Sense Data indicates FC link connectivity has been lost.\n") );\r
332                                                 StorPortPauseDevice( p_session->p_hba->p_ext,\r
333                                                                                          p_send_descriptor->p_srb->PathId,\r
334                                                                                          p_send_descriptor->p_srb->TargetId,\r
335                                                                                          p_send_descriptor->p_srb->Lun,\r
336                                                                                          5 );\r
337                                         }\r
338                                 }\r
339 \r
340                                 if ( get_srp_response_di_over( p_srp_rsp ) || get_srp_response_do_over( p_srp_rsp ) )\r
341                                 {\r
342                                         SRP_TRACE( SRP_DBG_WARN,\r
343                                                 ("Overflow error in response.\n") );\r
344                                         if ( p_send_descriptor->p_srb->SrbStatus == SRB_STATUS_SUCCESS )\r
345                                         {\r
346                                                 p_send_descriptor->p_srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;\r
347                                         }\r
348                                 }\r
349                         }\r
350 \r
351                         SRP_TRACE( SRP_DBG_VERBOSE, ("DataBuffer = 0x%"PRIx64".\n",\r
352                                                                         MmGetPhysicalAddress( p_send_descriptor->p_srb->DataBuffer ).QuadPart) );\r
353 \r
354                         /* Repost the recv descriptor */\r
355                         status = p_session->p_hba->ifc.post_recv(\r
356                                 p_session->connection.h_qp, &p_recv_descriptor->wr, NULL );\r
357                         if ( status != IB_SUCCESS )\r
358                         {\r
359                                 SRP_TRACE( SRP_DBG_ERROR,\r
360                                         ("Failed to post recv descriptor. Status = %d.\n", status) );\r
361                                 // TODO: Kill session and inform port driver link down storportnotification\r
362                         }\r
363 \r
364                         cl_atomic_add( &p_session->connection.request_limit, get_srp_response_request_limit_delta( p_srp_rsp ) );\r
365 \r
366                         SRP_TRACE( SRP_DBG_VERBOSE,\r
367                                            ("Srb Status = %s(0x%x)\n",\r
368                                            g_srb_status_name[p_send_descriptor->p_srb->SrbStatus],\r
369                                            p_send_descriptor->p_srb->SrbStatus) );\r
370 \r
371                         SRP_TRACE( SRP_DBG_VERBOSE, ("Device Extension Address = %p\n", p_session->p_hba->p_ext) );\r
372                         SRP_TRACE( SRP_DBG_VERBOSE, ("Srb Address              = %p\n", p_send_descriptor->p_srb) );\r
373                         SRP_TRACE( SRP_DBG_VERBOSE, ("Srb DataBuffer Address   = %p\n", p_send_descriptor->p_srb->DataBuffer) );\r
374                         SRP_TRACE( SRP_DBG_VERBOSE, ("Srb DataTransferLength   = %d\n", p_send_descriptor->p_srb->DataTransferLength) );\r
375 \r
376                         SRP_TRACE( SRP_DBG_VERBOSE,\r
377                                            ("Returning SrbStatus %s(0x%x) for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag 0x%"PRIx64"\n",\r
378                                            g_srb_status_name[p_send_descriptor->p_srb->SrbStatus],\r
379                                            p_send_descriptor->p_srb->SrbStatus,\r
380                                            g_srb_function_name[p_send_descriptor->p_srb->Function],\r
381                                            p_send_descriptor->p_srb->Function,\r
382                                            p_send_descriptor->p_srb->PathId,\r
383                                            p_send_descriptor->p_srb->TargetId,\r
384                                            p_send_descriptor->p_srb->Lun,\r
385                                            get_srp_command_tag( (srp_cmd_t *)p_send_descriptor->data_segment )) );\r
386 \r
387                         StorPortNotification( RequestComplete, p_session->p_hba->p_ext, p_send_descriptor->p_srb );\r
388                         break;\r
389 \r
390                 case SRP_LOGIN_REQ:\r
391                 case SRP_I_LOGOUT:\r
392                 case SRP_CRED_RSP:\r
393                 case SRP_AER_RSP:\r
394                 default:\r
395                         CL_ASSERT ( 0 );\r
396                         break;\r
397         }\r
398 \r
399 exit:\r
400         SRP_EXIT( SRP_DBG_FUNC );\r
401 \r
402         return ( status );\r
403 }\r
404 \r
405 static inline\r
406 void\r
407 __srp_process_session_recv_completions(\r
408         IN  srp_session_t   *p_session )\r
409 {\r
410         ib_api_status_t status;\r
411         ib_wc_t         *p_wc_done_list;\r
412         ib_wc_t         *p_wc;\r
413 \r
414         SRP_ENTER( SRP_DBG_FUNC );\r
415 \r
416         cl_obj_lock( &p_session->obj );\r
417 \r
418         if ( p_session->connection.state != SRP_CONNECTED )\r
419         {\r
420                 cl_obj_unlock( &p_session->obj );\r
421                 SRP_EXIT( SRP_DBG_FUNC );\r
422                 return;\r
423         }\r
424 \r
425         status = p_session->p_hba->ifc.poll_cq(\r
426                 p_session->connection.h_recv_cq,\r
427                 &p_session->connection.p_wc_free_list,\r
428                 &p_wc_done_list );\r
429         if ( status != IB_SUCCESS )\r
430         {\r
431                 SRP_TRACE( SRP_DBG_ERROR,\r
432                         ("ib_poll_cq() failed!, status 0x%x\n", status) );\r
433 \r
434                 // TODO: Kill session and inform port driver link down scsiportnotification\r
435                 SRP_EXIT( SRP_DBG_FUNC );\r
436                 cl_obj_unlock( &p_session->obj );\r
437                 return;\r
438         }\r
439 \r
440         cl_obj_ref( &p_session->obj );\r
441         cl_obj_unlock( &p_session->obj );\r
442 \r
443         while ( (p_wc = p_wc_done_list) != NULL )\r
444         {\r
445                 srp_recv_descriptor_t   *p_recv_descriptor;\r
446 \r
447                 /* Remove head from list */\r
448                 p_wc_done_list = p_wc->p_next;\r
449                 p_wc->p_next = NULL;\r
450 \r
451                 p_recv_descriptor = (srp_recv_descriptor_t *)((uintn_t)p_wc->wr_id);\r
452 \r
453                 if ( p_wc->status == IB_WCS_SUCCESS )\r
454                 {\r
455                         status = __srp_process_recv_completion( p_recv_descriptor, p_session );\r
456                         if ( status != IB_SUCCESS )\r
457                         {\r
458                                 // TODO: Kill session and inform port driver link down scsiportnotification\r
459                         }\r
460                 }\r
461                 else\r
462                 {\r
463                         SRP_TRACE( SRP_DBG_ERROR,\r
464                                 ("Recv failed!, status 0x%x\n", p_wc->status) );\r
465                 }\r
466 \r
467                 /* Put onto head of free list */\r
468                 cl_obj_lock( &p_session->obj );\r
469                 p_wc->p_next = p_session->connection.p_wc_free_list;\r
470                 p_session->connection.p_wc_free_list = p_wc;\r
471                 cl_obj_unlock( &p_session->obj );\r
472 \r
473                 /* Get next completion */\r
474                 p_wc = p_wc_done_list;\r
475         }\r
476 \r
477         /* Re-arm the CQ for more completions */\r
478         status = p_session->p_hba->ifc.rearm_cq(\r
479                 p_session->connection.h_recv_cq, FALSE );\r
480         if ( status != IB_SUCCESS)\r
481         {\r
482                 SRP_TRACE( SRP_DBG_ERROR,\r
483                         ("ib_rearm_cq() failed!, status 0x%x\n", status) );\r
484 \r
485                 // TODO: Kill session and inform port driver link down scsiportnotification\r
486         }\r
487 \r
488         cl_obj_deref( &p_session->obj );\r
489 \r
490         SRP_EXIT( SRP_DBG_FUNC );\r
491 }\r
492 \r
493 /* srp_recv_completion_cb */\r
494 /*!\r
495 Set Timer to Process Receive Completions - Responses to our requests\r
496 \r
497 @param p_context - context pointer to the owning session\r
498 \r
499 @return - none\r
500 */\r
501 void\r
502 srp_recv_completion_cb(\r
503         IN      const   ib_cq_handle_t          h_cq,\r
504         IN                      void                            *p_context )\r
505 {\r
506         srp_session_t   *p_session = (srp_session_t *)p_context;\r
507 \r
508         SRP_ENTER( SRP_DBG_FUNC );\r
509 \r
510         UNUSED_PARAM( h_cq );\r
511 \r
512         __srp_process_session_recv_completions( p_session );\r
513 \r
514         SRP_EXIT( SRP_DBG_FUNC );\r
515 }\r
516 \r
517 /* __srp_build_cmd */\r
518 /*!\r
519 Build the SRP Cmd to be sent to the VFx target\r
520 \r
521 @param p_dev_ext - our context pointer\r
522 @param p_srb     - scsi request to send to target\r
523 \r
524 @return - none\r
525 */\r
526 static inline\r
527 void\r
528 __srp_build_cmd(\r
529         IN      PVOID               p_dev_ext,\r
530         IN OUT  PSCSI_REQUEST_BLOCK p_srb,\r
531         IN      srp_conn_info_t     *p_srp_conn_info )\r
532 {\r
533         srp_send_descriptor_t           *p_send_descriptor = (srp_send_descriptor_t *)p_srb->SrbExtension;\r
534         srp_cmd_t                       *p_srp_cmd = (srp_cmd_t *)p_send_descriptor->data_segment;\r
535         UCHAR                           *p_cdb;\r
536         PSTOR_SCATTER_GATHER_LIST       p_scatter_gather_list = NULL;\r
537         uint8_t                         scatter_gather_count = 0;\r
538         srp_memory_descriptor_t         *p_memory_descriptor = NULL;\r
539         srp_memory_table_descriptor_t   *p_table_descriptor = NULL;\r
540         uint32_t                        i;\r
541         ULONG                           scsi_direction = p_srb->SrbFlags & ( SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT );\r
542         DATA_BUFFER_DESCRIPTOR_FORMAT   format = p_srp_conn_info->descriptor_format & DBDF_INDIRECT_DATA_BUFFER_DESCRIPTORS;\r
543         ULONG                                                   length;\r
544         SRP_ENTER( SRP_DBG_FUNC );\r
545 \r
546         SRP_TRACE( SRP_DBG_VERBOSE,\r
547                            ("Sending I/O to Path = 0x%x, Target = 0x%x, Lun = 0x%x\n",\r
548                            p_srb->PathId,\r
549                            p_srb->TargetId,\r
550                            p_srb->Lun) );\r
551 \r
552         setup_srp_command( p_srp_cmd,\r
553                                            p_send_descriptor->tag,\r
554                                            DBDF_NO_DATA_BUFFER_DESCRIPTOR_PRESENT,\r
555                                            DBDF_NO_DATA_BUFFER_DESCRIPTOR_PRESENT,\r
556                                            0,\r
557                                            0,\r
558                                            BUILD_SCSI_ADDRESS( p_srb->TargetId, p_srb->Lun ),\r
559                                            TAV_SIMPLE_TASK,\r
560                                            0 );\r
561 \r
562         p_cdb = get_srp_command_cdb( p_srp_cmd );\r
563         cl_memcpy( p_cdb, p_srb->Cdb, p_srb->CdbLength );\r
564 \r
565         SRP_TRACE( SRP_DBG_VERBOSE, ("CDB Length = %d.\n", p_srb->CdbLength) );\r
566         SRP_TRACE( SRP_DBG_VERBOSE, ("CDB = 0x") );\r
567         for ( i = 0; i < p_srb->CdbLength; i++ )\r
568         {\r
569                 SRP_TRACE( SRP_DBG_VERBOSE, ("%0.2x", p_srb->Cdb[i]) );\r
570         }\r
571         SRP_TRACE( SRP_DBG_VERBOSE, ("\n.") );\r
572         \r
573         if ( !format )\r
574         {\r
575                 format = DBDF_DIRECT_DATA_BUFFER_DESCRIPTOR;\r
576         }\r
577 \r
578         if ( scsi_direction )\r
579         {\r
580                 p_scatter_gather_list = StorPortGetScatterGatherList( p_dev_ext, p_srb );\r
581                 CL_ASSERT( p_scatter_gather_list != NULL );\r
582                 scatter_gather_count = (uint8_t)p_scatter_gather_list->NumberOfElements;\r
583         }\r
584 \r
585         /* Cap the length of the inline descriptors to the maximum IU size. */\r
586         if( p_srp_conn_info->max_scatter_gather_entries < scatter_gather_count )\r
587         {\r
588                 scatter_gather_count =\r
589                         (uint8_t)p_srp_conn_info->max_scatter_gather_entries;\r
590         }\r
591 \r
592         if ( scsi_direction == SRB_FLAGS_DATA_IN )\r
593         {\r
594                 set_srp_command_data_in_buffer_desc_fmt( p_srp_cmd, format );\r
595                 set_srp_command_data_in_buffer_desc_count( p_srp_cmd, scatter_gather_count );\r
596                 p_memory_descriptor = get_srp_command_data_in_buffer_desc( p_srp_cmd );\r
597         }\r
598 \r
599         else if ( scsi_direction == SRB_FLAGS_DATA_OUT )\r
600         {\r
601                 set_srp_command_data_out_buffer_desc_fmt( p_srp_cmd, format );\r
602                 set_srp_command_data_out_buffer_desc_count( p_srp_cmd, scatter_gather_count );\r
603                 p_memory_descriptor = get_srp_command_data_out_buffer_desc( p_srp_cmd );\r
604         }\r
605 \r
606         if ( p_memory_descriptor != NULL )\r
607         {\r
608                 PSTOR_SCATTER_GATHER_ELEMENT    p_sg_element;\r
609                 uint32_t                                                totalLength;\r
610                 uint64_t                                                buf_addr;\r
611                 if ( format == DBDF_INDIRECT_DATA_BUFFER_DESCRIPTORS )\r
612                 {\r
613                         p_table_descriptor = (srp_memory_table_descriptor_t *)p_memory_descriptor;\r
614                         p_memory_descriptor = ( srp_memory_descriptor_t *)(p_table_descriptor + 1 );\r
615 \r
616                         buf_addr = (StorPortGetPhysicalAddress( p_dev_ext,p_srb, p_memory_descriptor, &length)).QuadPart;\r
617 \r
618                         /* we don't swap rkey - it is already in network order*/\r
619                         p_table_descriptor->descriptor.virtual_address =  cl_hton64( buf_addr );\r
620                         p_table_descriptor->descriptor.memory_handle = p_srp_conn_info->rkey;\r
621 \r
622                         p_table_descriptor->descriptor.data_length =\r
623                                 cl_hton32( sizeof(srp_memory_descriptor_t) *\r
624                                 p_scatter_gather_list->NumberOfElements );\r
625                         \r
626                         for ( i = 0, totalLength = 0, p_sg_element = p_scatter_gather_list->List;\r
627                                   i < p_scatter_gather_list->NumberOfElements;\r
628                                   i++, p_memory_descriptor++, p_sg_element++ )\r
629                         {\r
630                                 buf_addr =  p_srp_conn_info->vaddr + p_sg_element->PhysicalAddress.QuadPart;\r
631                         \r
632                                 p_memory_descriptor->virtual_address = cl_hton64( buf_addr );\r
633                                 p_memory_descriptor->memory_handle   = p_srp_conn_info->rkey;\r
634                                 p_memory_descriptor->data_length     =  cl_hton32( p_sg_element->Length );\r
635                                 totalLength += p_sg_element->Length;\r
636                         }\r
637                         p_table_descriptor->total_length = cl_hton32( totalLength );\r
638                 }\r
639                 else if ( format == DBDF_DIRECT_DATA_BUFFER_DESCRIPTOR )\r
640                 {\r
641                         CL_ASSERT( scatter_gather_count ==\r
642                                 p_scatter_gather_list->NumberOfElements );\r
643                         for ( i = 0, p_sg_element = p_scatter_gather_list->List;\r
644                                   i < scatter_gather_count;     i++, p_memory_descriptor++, p_sg_element++ )\r
645                         {\r
646                                 buf_addr =  p_srp_conn_info->vaddr + p_sg_element->PhysicalAddress.QuadPart;\r
647                                 p_memory_descriptor->virtual_address = cl_hton64( buf_addr );\r
648                                 p_memory_descriptor->memory_handle   = p_srp_conn_info->rkey;\r
649                                 p_memory_descriptor->data_length     = cl_hton32( p_sg_element->Length );\r
650 \r
651                                 SRP_TRACE( SRP_DBG_VERBOSE, ("virtual_address[%d] = 0x%"PRIx64".\n", i, cl_ntoh64(p_memory_descriptor->virtual_address) ) );\r
652                                 SRP_TRACE( SRP_DBG_VERBOSE, ("memory_handle[%d]   = 0x%x.\n", i, cl_ntoh32( p_memory_descriptor->memory_handle) ) );\r
653                                 SRP_TRACE( SRP_DBG_VERBOSE, ("data_length[%d]     = %d.\n", i, cl_ntoh32( p_memory_descriptor->data_length) ) );\r
654                         }\r
655                 }\r
656                 SRP_TRACE( SRP_DBG_VERBOSE, ("scatter/gather count = %d.\n", scatter_gather_count));\r
657         }\r
658 \r
659         p_srp_cmd->logical_unit_number = cl_hton64( p_srp_cmd->logical_unit_number );\r
660 \r
661         //set_srp_command_from_host_to_network( p_srp_cmd );\r
662 \r
663         SRP_EXIT( SRP_DBG_FUNC );\r
664 }\r
665 \r
666 /* srp_format_io_request */\r
667 /*!\r
668 Format the SRP Cmd for the VFx target\r
669 \r
670 @param p_dev_ext - our context pointer\r
671 @param p_srb     - scsi request to send to target\r
672 \r
673 @return - TRUE for success, FALSE for failure\r
674 */\r
675 BOOLEAN\r
676 srp_format_io_request(\r
677         IN      PVOID               p_dev_ext,\r
678         IN OUT  PSCSI_REQUEST_BLOCK p_srb  )\r
679 {\r
680         srp_hba_t       *p_hba = ((srp_ext_t *)p_dev_ext)->p_hba;\r
681         BOOLEAN         result = TRUE;\r
682         srp_session_t   *p_srp_session;\r
683 \r
684         SRP_ENTER( SRP_DBG_FUNC );\r
685 \r
686         SRP_TRACE( SRP_DBG_VERBOSE, ("Device Extension Address = %p\n", p_dev_ext) );\r
687         SRP_TRACE( SRP_DBG_VERBOSE, ("Srb Address              = %p\n", p_srb) );\r
688         SRP_TRACE( SRP_DBG_VERBOSE, ("Srb DataBuffer Address   = %p\n", p_srb->DataBuffer) );\r
689         SRP_TRACE( SRP_DBG_VERBOSE, ("Srb DataTransferLength   = %d\n", p_srb->DataTransferLength) );\r
690 \r
691         cl_obj_lock( &p_hba->obj );\r
692 \r
693         p_srp_session = p_hba->session_list[p_srb->TargetId];\r
694 \r
695         if ( p_srp_session != NULL )\r
696         {\r
697                 srp_conn_info_t srp_conn_info;\r
698 \r
699                 cl_obj_ref( &p_srp_session->obj );\r
700                 cl_obj_unlock( &p_hba->obj );\r
701 \r
702                 srp_conn_info.vaddr = p_srp_session->hca.vaddr;\r
703                 srp_conn_info.lkey  = p_srp_session->hca.lkey;\r
704                 srp_conn_info.rkey  = p_srp_session->hca.rkey;\r
705                 srp_conn_info.descriptor_format = p_srp_session->connection.descriptor_format;\r
706                 srp_conn_info.init_to_targ_iu_sz         = p_srp_session->connection.init_to_targ_iu_sz;\r
707                 srp_conn_info.max_scatter_gather_entries = p_srp_session->connection.max_scatter_gather_entries;\r
708                 srp_conn_info.tag                        = cl_atomic_inc( &p_srp_session->connection.tag );\r
709                 srp_conn_info.signal_send_completion     =\r
710                         ((srp_conn_info.tag % p_srp_session->connection.signaled_send_completion_count) == 0) ? TRUE : FALSE;\r
711 \r
712                 cl_obj_deref( &p_srp_session->obj );\r
713 \r
714                 srp_build_send_descriptor( p_dev_ext, p_srb, &srp_conn_info );\r
715 \r
716                 __srp_build_cmd( p_dev_ext, p_srb, &srp_conn_info );\r
717         }\r
718         else\r
719         {\r
720                 // Handle the error case here\r
721                 SRP_TRACE( SRP_DBG_ERROR, ("Cannot Find Session For Target ID = %d\n", p_srb->TargetId) );\r
722                 cl_obj_unlock( &p_hba->obj );\r
723                 p_srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID;\r
724                 result = FALSE;\r
725         }\r
726 \r
727 \r
728         SRP_EXIT( SRP_DBG_FUNC );\r
729         return ( result );\r
730 }\r
731 \r
732 void\r
733 srp_post_io_request(\r
734         IN      PVOID               p_dev_ext,\r
735         IN OUT  PSCSI_REQUEST_BLOCK p_srb  )\r
736 {\r
737         ib_api_status_t                 status;\r
738         srp_hba_t               *p_hba = ((srp_ext_t *)p_dev_ext)->p_hba;\r
739         srp_send_descriptor_t   *p_send_descriptor = (srp_send_descriptor_t *)p_srb->SrbExtension;\r
740         srp_session_t           *p_srp_session;\r
741 \r
742         SRP_ENTER( SRP_DBG_FUNC );\r
743 \r
744         cl_obj_lock( &p_hba->obj );\r
745 \r
746         p_srp_session = p_hba->session_list[p_srb->TargetId];\r
747 \r
748         if ( p_srp_session != NULL )\r
749         {\r
750                 cl_obj_ref( &p_srp_session->obj );\r
751                 cl_obj_unlock( &p_hba->obj );\r
752 \r
753                 status = srp_post_send_descriptor( &p_srp_session->descriptors,\r
754                                                                                    p_send_descriptor,\r
755                                                                                    p_srp_session );\r
756 \r
757                 if ( status == IB_SUCCESS )\r
758                 {\r
759                         cl_atomic_dec( &p_srp_session->connection.request_limit );\r
760 \r
761                         if ( p_srp_session->connection.request_limit < 3 )\r
762                         {\r
763                                 SRP_TRACE( SRP_DBG_WARN, ("Calling StorPortBusy.\n") );\r
764                                 StorPortBusy( p_dev_ext, 1 );\r
765                         }\r
766 \r
767                         cl_obj_deref( &p_srp_session->obj );\r
768                         goto exit;\r
769                 }\r
770 \r
771                 cl_obj_deref( &p_srp_session->obj );\r
772         }\r
773         else\r
774         {\r
775                 cl_obj_unlock( &p_hba->obj );\r
776         }\r
777 \r
778         p_srb->SrbStatus = SRB_STATUS_NO_HBA;\r
779         SRP_TRACE( SRP_DBG_ERROR,\r
780                            ("Returning SrbStatus %s(0x%x) for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag 0x%"PRIx64"\n",\r
781                            g_srb_status_name[p_srb->SrbStatus],\r
782                            p_srb->SrbStatus,\r
783                            g_srb_function_name[p_srb->Function],\r
784                            p_srb->Function,\r
785                            p_srb->PathId,\r
786                            p_srb->TargetId,\r
787                            p_srb->Lun,\r
788                            get_srp_command_tag( (srp_cmd_t *)p_send_descriptor->data_segment )) );\r
789         StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
790 \r
791 exit:\r
792         SRP_EXIT( SRP_DBG_FUNC );\r
793 }\r
794 \r
795 void\r
796 srp_abort_command(\r
797         IN      PVOID               p_dev_ext,\r
798         IN OUT  PSCSI_REQUEST_BLOCK p_srb  )\r
799 {\r
800         srp_hba_t               *p_hba = ((srp_ext_t *)p_dev_ext)->p_hba;\r
801         srp_session_t           *p_srp_session;\r
802         uint64_t                iu_tag;\r
803         srp_send_descriptor_t   *p_srb_send_descriptor;\r
804         srp_send_descriptor_t   *p_send_descriptor;\r
805         srp_conn_info_t         srp_conn_info;\r
806         srp_tsk_mgmt_t          *p_srp_tsk_mgmt;\r
807 \r
808         SRP_ENTER( SRP_DBG_FUNC );\r
809 \r
810         cl_obj_lock( &p_hba->obj );\r
811 \r
812         p_srp_session = p_hba->session_list[p_srb->TargetId];\r
813         if ( p_srp_session == NULL )\r
814         {\r
815                 /* If the session is NULL there is no connection and cannot be aborted */\r
816                 p_srb->SrbStatus = SRB_STATUS_ABORT_FAILED;\r
817                 goto exit;\r
818         }\r
819 \r
820         p_srb_send_descriptor = (srp_send_descriptor_t *)p_srb->NextSrb->SrbExtension;\r
821 \r
822         iu_tag = get_srp_information_unit_tag( (srp_information_unit_t *)p_srb_send_descriptor->data_segment );\r
823 \r
824         p_send_descriptor = srp_find_matching_send_descriptor( &p_srp_session->descriptors, iu_tag );\r
825         if ( p_send_descriptor == NULL )\r
826         {\r
827                 /* Cannot find the command so it must have been completed */\r
828                 p_srb->SrbStatus = SRB_STATUS_ABORT_FAILED;\r
829                 goto exit;\r
830         }\r
831 \r
832         CL_ASSERT( p_srb_send_descriptor == p_send_descriptor );\r
833 \r
834         p_srb->NextSrb->SrbStatus = SRB_STATUS_ABORTED;\r
835 \r
836         /* create and send abort request to the VFx */\r
837 \r
838         srp_conn_info.vaddr = p_srp_session->hca.vaddr;\r
839         srp_conn_info.lkey  = p_srp_session->hca.lkey;\r
840         srp_conn_info.rkey  = p_srp_session->hca.rkey;\r
841 \r
842         srp_conn_info.init_to_targ_iu_sz         = p_srp_session->connection.init_to_targ_iu_sz;\r
843         srp_conn_info.max_scatter_gather_entries = p_srp_session->connection.max_scatter_gather_entries;\r
844         srp_conn_info.tag                        = cl_atomic_inc( &p_srp_session->connection.tag );\r
845         srp_conn_info.signal_send_completion     =\r
846                 ((srp_conn_info.tag % p_srp_session->connection.signaled_send_completion_count) == 0) ? TRUE : FALSE;\r
847 \r
848         srp_build_send_descriptor( p_dev_ext, p_srb, &srp_conn_info );\r
849 \r
850         p_srp_tsk_mgmt = (srp_tsk_mgmt_t *)p_send_descriptor->data_segment;\r
851 \r
852         setup_srp_tsk_mgmt( p_srp_tsk_mgmt,\r
853                                                 p_send_descriptor->tag,\r
854                                                 BUILD_SCSI_ADDRESS( p_srb->TargetId, p_srb->Lun ),\r
855                                                 TMF_ABORT_TASK,\r
856                                                 iu_tag );\r
857 \r
858         set_srp_tsk_mgmt_from_host_to_network( p_srp_tsk_mgmt );\r
859 \r
860         srp_post_io_request( p_dev_ext, p_srb );\r
861 \r
862 exit:\r
863         cl_obj_unlock( &p_hba->obj );\r
864         if ( p_srb->SrbStatus == SRB_STATUS_ABORT_FAILED )\r
865         {\r
866                 SRP_TRACE( SRP_DBG_DEBUG,\r
867                                    ("Returning SrbStatus %s(0x%x) for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x\n",\r
868                                    g_srb_status_name[p_srb->SrbStatus],\r
869                                    p_srb->SrbStatus,\r
870                                    g_srb_function_name[p_srb->Function],\r
871                                    p_srb->Function,\r
872                                    p_srb->PathId,\r
873                                    p_srb->TargetId,\r
874                                    p_srb->Lun) );\r
875                 StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
876         }\r
877 \r
878         SRP_EXIT( SRP_DBG_FUNC );\r
879 }\r
880 \r
881 void\r
882 srp_lun_reset(\r
883         IN      PVOID               p_dev_ext,\r
884         IN OUT  PSCSI_REQUEST_BLOCK p_srb  )\r
885 {\r
886 \r
887         srp_hba_t               *p_hba = ((srp_ext_t *)p_dev_ext)->p_hba;\r
888         srp_session_t           *p_srp_session;\r
889 \r
890         SRP_ENTER( SRP_DBG_FUNC );\r
891 \r
892         cl_obj_lock( &p_hba->obj );\r
893 \r
894         p_srp_session = p_hba->session_list[p_srb->TargetId];\r
895         if ( p_srp_session != NULL )\r
896         {\r
897                 srp_send_descriptor_t   *p_send_descriptor;\r
898                 UCHAR                   path_id   = p_srb->PathId;\r
899                 UCHAR                   target_id = p_srb->TargetId;\r
900                 UCHAR                   lun       = p_srb->Lun;\r
901 \r
902             StorPortPauseDevice( p_dev_ext, p_srb->PathId, p_srb->TargetId, p_srb->Lun, 10 );\r
903 \r
904                 while ( (p_send_descriptor = srp_remove_lun_head_send_descriptor( &p_srp_session->descriptors, p_srb->Lun )) != NULL )\r
905                 {\r
906                         SRP_TRACE( SRP_DBG_VERBOSE,\r
907                                            ("Returning SrbStatus %s(0x%x) for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x, tag 0x%"PRIx64"\n",\r
908                                            g_srb_status_name[SRB_STATUS_BUS_RESET],\r
909                                            SRB_STATUS_BUS_RESET,\r
910                                            g_srb_function_name[p_send_descriptor->p_srb->Function],\r
911                                            p_send_descriptor->p_srb->Function,\r
912                                            p_send_descriptor->p_srb->PathId,\r
913                                            p_send_descriptor->p_srb->TargetId,\r
914                                            p_send_descriptor->p_srb->Lun,\r
915                                            get_srp_command_tag( (srp_cmd_t *)p_send_descriptor->data_segment )) );\r
916                 }\r
917 \r
918                 p_srb->SrbStatus = SRB_STATUS_SUCCESS;\r
919 \r
920                 SRP_TRACE( SRP_DBG_DEBUG,\r
921                                    ("Returning SrbStatus %s(0x%x) for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x\n",\r
922                                    g_srb_status_name[p_srb->SrbStatus],\r
923                                    p_srb->SrbStatus,\r
924                                    g_srb_function_name[p_srb->Function],\r
925                                    p_srb->Function,\r
926                                    p_srb->PathId,\r
927                                    p_srb->TargetId,\r
928                                    p_srb->Lun) );\r
929 \r
930                 StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
931 \r
932                 StorPortCompleteRequest( p_dev_ext, path_id, target_id, lun, SRB_STATUS_BUS_RESET );\r
933 \r
934                 StorPortResumeDevice( p_dev_ext, path_id, target_id, lun );\r
935         }\r
936         else\r
937         {\r
938                 // Handle the error case here\r
939                 p_srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID;\r
940                 SRP_TRACE( SRP_DBG_DEBUG,\r
941                                    ("Returning SrbStatus %s(0x%x) for Function = %s(0x%x), Path = 0x%x, Target = 0x%x, Lun = 0x%x\n",\r
942                                    g_srb_status_name[p_srb->SrbStatus],\r
943                                    p_srb->SrbStatus,\r
944                                    g_srb_function_name[p_srb->Function],\r
945                                    p_srb->Function,\r
946                                    p_srb->PathId,\r
947                                    p_srb->TargetId,\r
948                                    p_srb->Lun) );\r
949 \r
950                 StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
951         }\r
952 \r
953         cl_obj_unlock( &p_hba->obj );\r
954 \r
955         SRP_EXIT( SRP_DBG_FUNC );\r
956 }\r