[SRP] add SCSI errors to the logs
[mirror/winof/.git] / ulp / srp / kernel / srp_driver.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 "srp_data.h"\r
34 #include "srp_data_path.h"\r
35 #include "srp_debug.h"\r
36 #if defined(EVENT_TRACING)\r
37 #ifdef offsetof\r
38 #undef offsetof\r
39 #endif\r
40 #include "srp_driver.tmh"\r
41 #endif\r
42 #include "srp_descriptors.h"\r
43 #include "srp_hba.h"\r
44 #include "srp_session.h"\r
45 \r
46 #include <complib/cl_math.h>\r
47 #include <complib/cl_mutex.h>\r
48 #include <complib/cl_init.h>\r
49 \r
50 \r
51 #define SCSI_MAXIMUM_TRANSFER_SIZE (1024 * 1024)\r
52 \r
53 BOOLEAN             g_srp_system_shutdown = FALSE;\r
54 \r
55 \r
56 uint32_t                        g_srp_dbg_level = TRACE_LEVEL_ERROR;\r
57 uint32_t                        g_srp_dbg_flags = 0x0000ffff;\r
58 \r
59 char g_srb_function_name[][32] =\r
60 {\r
61         "EXECUTE_SCSI",          // 0x00\r
62         "CLAIM_DEVICE",          // 0x01\r
63         "IO_CONTROL",            // 0x02\r
64         "RECEIVE_EVENT",         // 0x03\r
65         "RELEASE_QUEUE",         // 0x04\r
66         "ATTACH_DEVICE",         // 0x05\r
67         "RELEASE_DEVICE",        // 0x06\r
68         "SHUTDOWN",              // 0x07\r
69         "FLUSH",                 // 0x08\r
70         "",                      // 0x09\r
71         "",                      // 0x0A\r
72         "",                      // 0x0B\r
73         "",                      // 0x0C\r
74         "",                      // 0x0D\r
75         "",                      // 0x0E\r
76         "",                      // 0x0F\r
77         "ABORT_COMMAND",         // 0x10\r
78         "RELEASE_RECOVERY",      // 0x11\r
79         "RESET_BUS",             // 0x12\r
80         "RESET_DEVICE",          // 0x13\r
81         "TERMINATE_IO",          // 0x14\r
82         "FLUSH_QUEUE",           // 0x15\r
83         "REMOVE_DEVICE",         // 0x16\r
84         "WMI",                   // 0x17\r
85         "LOCK_QUEUE",            // 0x18\r
86         "UNLOCK_QUEUE",          // 0x19\r
87         "",                      // 0x1A\r
88         "",                      // 0x1B\r
89         "",                      // 0x1C\r
90         "",                      // 0x1D\r
91         "",                      // 0x1E\r
92         "",                      // 0x1F\r
93         "RESET_LOGICAL_UNIT",    // 0x20\r
94         "SET_LINK_TIMEOUT",      // 0x21\r
95         "LINK_TIMEOUT_OCCURRED", // 0x22\r
96         "LINK_TIMEOUT_COMPLETE"  // 0x23\r
97 };\r
98 \r
99 char g_srb_status_name[][32] =\r
100 {\r
101         "PENDING",                // 0x00\r
102         "SUCCESS",                // 0x01\r
103         "ABORTED",                // 0x02\r
104         "ABORT_FAILED",           // 0x03\r
105         "ERROR",                  // 0x04\r
106         "BUSY",                   // 0x05\r
107         "INVALID_REQUEST",        // 0x06\r
108         "INVALID_PATH_ID",        // 0x07\r
109         "NO_DEVICE",              // 0x08\r
110         "TIMEOUT",                // 0x09\r
111         "SELECTION_TIMEOUT",      // 0x0A\r
112         "COMMAND_TIMEOUT",        // 0x0B\r
113         "",                       // 0x0C\r
114         "MESSAGE_REJECTED",       // 0x0D\r
115         "BUS_RESET",              // 0x0E\r
116         "PARITY_ERROR",           // 0x0F\r
117         "REQUEST_SENSE_FAILED",   // 0x10\r
118         "NO_HBA",                 // 0x11\r
119         "DATA_OVERRUN",           // 0x12\r
120         "UNEXPECTED_BUS_FREE",    // 0x13\r
121         "PHASE_SEQUENCE_FAILURE", // 0x14\r
122         "BAD_SRB_BLOCK_LENGTH",   // 0x15\r
123         "REQUEST_FLUSHED",        // 0x16\r
124         "",                       // 0x17\r
125         "",                       // 0x18\r
126         "",                       // 0x19\r
127         "",                       // 0x1A\r
128         "",                       // 0x1B\r
129         "",                       // 0x1C\r
130         "",                       // 0x1D\r
131         "",                       // 0x1E\r
132         "",                       // 0x1F\r
133         "INVALID_LUN",            // 0x20\r
134         "INVALID_TARGET_ID",      // 0x21\r
135         "BAD_FUNCTION",           // 0x22\r
136         "ERROR_RECOVERY",         // 0x23\r
137         "NOT_POWERED",            // 0x24\r
138         "LINK_DOWN"               // 0x25\r
139 };\r
140 \r
141 char g_srb_scsi_status_name[][32] =\r
142 {\r
143         "SCSISTAT_GOOD",                                //0x00\r
144         "",                                                             //0x01\r
145         " SCSISTAT_CHECK_CONDITION",    //0x02\r
146         "",                                                             //0x03\r
147         " SCSISTAT_CONDITION_MET",              //0x04\r
148         "",                                                             //0x05\r
149         "",                                                             //0x06\r
150         "",                                                             //0x07\r
151         " SCSISTAT_BUSY",                               //0x08\r
152         "",                                                             //0x09\r
153         "",                                                             //0x0A\r
154         "",                                                             //0x0B\r
155         "",                                                             //0x0C\r
156         "",                                                             //0x0D\r
157         "",                                                             //0x0E\r
158         "",                                                             //0x0F\r
159         " SCSISTAT_INTERMEDIATE",               //0x10\r
160         "",                                                             //0x11\r
161         "",                                                             //0x12\r
162         "",                                                             //0x13\r
163         " SCSISTAT_INTERMEDIATE_COND_MET", //0x14\r
164         "",                                                             //0x15\r
165         "",                                                             //0x16\r
166         "",                                                             //0x17\r
167         " SCSISTAT_RESERVATION_CONFLICT",  //0x18\r
168         "",                                                             //0x19\r
169         "",                                                             // 0x1A\r
170         "",                                                             // 0x1B\r
171         "",                                                             // 0x1C\r
172         "",                                                             // 0x1D\r
173         "",                                                             // 0x1E\r
174         "",                                                             // 0x1F\r
175         "",                                                             //0x20\r
176         "",                                                             //0x21\r
177         " SCSISTAT_COMMAND_TERMINATED",    //0x22\r
178         "",                                                             //0x23\r
179         "",                                                             //0x24\r
180         "",                                                             //0x25\r
181         "",                                                             //0x26\r
182         "",                                                             //0x27\r
183         " SCSISTAT_QUEUE_FULL",                 //0x28\r
184 };\r
185 \r
186 DRIVER_OBJECT       *gp_drv_obj;\r
187 cl_obj_t            g_drv_obj;\r
188 \r
189 /* Mutex protecting the next lower device object pointer. */\r
190 KMUTEX              g_srp_pnp_mutex;\r
191 \r
192 PDRIVER_DISPATCH    gpfn_pnp;\r
193 PDRIVER_ADD_DEVICE  gpfn_add_device;\r
194 PDRIVER_UNLOAD      gpfn_unload;\r
195 \r
196 \r
197 static NTSTATUS\r
198 __read_registry(\r
199         IN                              UNICODE_STRING* const           p_Param_Path );\r
200 \r
201 NTSTATUS\r
202 srp_add_device(\r
203         IN              DRIVER_OBJECT               *p_drv_obj,\r
204         IN              DEVICE_OBJECT               *p_pdo );\r
205 \r
206 NTSTATUS\r
207 srp_dispatch_pnp(\r
208         IN              DEVICE_OBJECT               *p_dev_obj,\r
209         IN              IRP                         *p_irp );\r
210 \r
211 BOOLEAN\r
212 srp_init(\r
213         IN              PVOID                       p_dev_ext );\r
214 \r
215 BOOLEAN\r
216 srp_start_io(\r
217         IN              PVOID                       p_dev_ext,\r
218         IN              PSCSI_REQUEST_BLOCK         p_srb );\r
219 \r
220 BOOLEAN\r
221 srp_isr(\r
222         IN              PVOID                       p_dev_ext );\r
223 \r
224 ULONG\r
225 srp_find_adapter(\r
226         IN              PVOID                       p_dev_ext,\r
227         IN              PVOID                       resv1,\r
228         IN              PVOID                       resv2,\r
229         IN              PCHAR                       arg_str,\r
230         IN  OUT         PPORT_CONFIGURATION_INFORMATION     p_config,\r
231                 OUT         PBOOLEAN                    resv3 );\r
232 \r
233 BOOLEAN\r
234 srp_reset(\r
235         IN              PVOID                       p_dev_ext,\r
236         IN              ULONG                       path_id );\r
237 \r
238 SCSI_ADAPTER_CONTROL_STATUS\r
239 srp_adapter_ctrl(\r
240         IN              PVOID                       p_dev_ext,\r
241         IN              SCSI_ADAPTER_CONTROL_TYPE   ctrl_type,\r
242         IN              PVOID                       params );\r
243 \r
244 BOOLEAN\r
245 srp_build_io(\r
246         IN              PVOID                       p_dev_ext,\r
247         IN              PSCSI_REQUEST_BLOCK         p_srb );\r
248 \r
249 static void\r
250 srp_unload(\r
251         IN              DRIVER_OBJECT               *p_drv_obj );\r
252 \r
253 static void\r
254 __srp_free(\r
255         IN              cl_obj_t                    *p_obj );\r
256 \r
257 \r
258 \r
259 static NTSTATUS\r
260 __read_registry(\r
261         IN                              UNICODE_STRING* const           p_registry_path )\r
262 {\r
263         NTSTATUS                                        status;\r
264         /* Remember the terminating entry in the table below. */\r
265         RTL_QUERY_REGISTRY_TABLE        table[3];\r
266         UNICODE_STRING                          param_path;\r
267 \r
268         SRP_ENTER( SRP_DBG_PNP );\r
269 \r
270         RtlInitUnicodeString( &param_path, NULL );\r
271         param_path.MaximumLength = p_registry_path->Length + \r
272                 sizeof(L"\\Parameters");\r
273         param_path.Buffer = cl_zalloc( param_path.MaximumLength );\r
274         if( !param_path.Buffer )\r
275         {\r
276                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, \r
277                         ("Failed to allocate parameters path buffer.\n") );\r
278                 return STATUS_INSUFFICIENT_RESOURCES;\r
279         }\r
280 \r
281         RtlAppendUnicodeStringToString( &param_path, p_registry_path );\r
282         RtlAppendUnicodeToString( &param_path, L"\\Parameters" );\r
283 \r
284         /*\r
285          * Clear the table.  This clears all the query callback pointers,\r
286          * and sets up the terminating table entry.\r
287          */\r
288         cl_memclr( table, sizeof(table) );\r
289 \r
290         /* Setup the table entries. */\r
291         table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
292         table[0].Name = L"DebugLevel";\r
293         table[0].EntryContext = &g_srp_dbg_level;\r
294         table[0].DefaultType = REG_DWORD;\r
295         table[0].DefaultData = &g_srp_dbg_level;\r
296         table[0].DefaultLength = sizeof(ULONG);\r
297 \r
298         table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
299         table[1].Name = L"DebugFlags";\r
300         table[1].EntryContext = &g_srp_dbg_flags;\r
301         table[1].DefaultType = REG_DWORD;\r
302         table[1].DefaultData = &g_srp_dbg_flags;\r
303         table[1].DefaultLength = sizeof(ULONG);\r
304         /* Have at it! */\r
305         status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
306                 param_path.Buffer, table, NULL, NULL );\r
307 \r
308 #ifndef EVENT_TRACING\r
309         if( g_srp_dbg_flags & SRP_DBG_ERR )\r
310                 g_srp_dbg_flags |= CL_DBG_ERROR;\r
311 #endif\r
312 \r
313         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
314                 ("debug level %d debug flags 0x%.8x\n",\r
315                 g_srp_dbg_level,\r
316                 g_srp_dbg_flags) );\r
317 \r
318         cl_free( param_path.Buffer );\r
319         SRP_EXIT( SRP_DBG_PNP );\r
320         return status;\r
321 }\r
322 \r
323 \r
324 ULONG\r
325 DriverEntry(\r
326         IN              DRIVER_OBJECT               *p_drv_obj,\r
327         IN              UNICODE_STRING              *p_registry_path )\r
328 {\r
329         ULONG                       status;\r
330         HW_INITIALIZATION_DATA      hw_data;\r
331         cl_status_t                 cl_status;\r
332 \r
333         SRP_ENTER( SRP_DBG_PNP );\r
334 \r
335 #if defined(EVENT_TRACING)\r
336         WPP_INIT_TRACING( p_drv_obj, p_registry_path );\r
337 #endif\r
338 \r
339         status = CL_INIT;\r
340         if( !NT_SUCCESS(status) )\r
341         {\r
342                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
343                         ("cl_init returned %08X.\n", status) );\r
344                 return status;\r
345         }\r
346 \r
347         gp_drv_obj = p_drv_obj;\r
348 \r
349         /* Get the registry values. */\r
350         status = __read_registry( p_registry_path );\r
351         if( !NT_SUCCESS(status) )\r
352         {\r
353                 CL_DEINIT;\r
354                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
355                         ("__read_registry returned %08x.\n", status) );\r
356                 return status;\r
357         }\r
358 \r
359         cl_obj_construct( &g_drv_obj, SRP_OBJ_TYPE_DRV );\r
360 \r
361         KeInitializeMutex( &g_srp_pnp_mutex, 0 );\r
362 \r
363         cl_memclr( &hw_data, sizeof(HW_INITIALIZATION_DATA) );\r
364 \r
365         hw_data.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);\r
366 \r
367         hw_data.AdapterInterfaceType = Internal;\r
368 \r
369         /* Miniport driver routines */\r
370         hw_data.HwInitialize     = srp_init;\r
371         hw_data.HwStartIo        = srp_start_io;\r
372 //      hw_data.HwInterrupt      = srp_isr;\r
373         hw_data.HwInterrupt      = NULL;\r
374         hw_data.HwFindAdapter    = srp_find_adapter;\r
375         hw_data.HwResetBus       = srp_reset;\r
376         hw_data.HwAdapterControl = srp_adapter_ctrl;\r
377         hw_data.HwBuildIo        = srp_build_io;\r
378         hw_data.HwDmaStarted     = NULL;\r
379         hw_data.HwAdapterState   = NULL;\r
380 \r
381         /* Extension sizes. */\r
382         hw_data.DeviceExtensionSize = sizeof(srp_ext_t);\r
383         /* TODO: Do we need per-LU data? */\r
384         hw_data.SpecificLuExtensionSize = 0;\r
385         hw_data.SrbExtensionSize = sizeof(srp_send_descriptor_t);\r
386 \r
387         /* Driver parameters. */\r
388         hw_data.NumberOfAccessRanges = 1;\r
389         /* TODO: Can this be STOR_MAP_NO_BUFFERS? */\r
390         hw_data.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;\r
391 \r
392         hw_data.NeedPhysicalAddresses = TRUE;\r
393         hw_data.TaggedQueuing = TRUE;\r
394         hw_data.AutoRequestSense = TRUE;\r
395         hw_data.MultipleRequestPerLu = TRUE;\r
396 \r
397         cl_status =\r
398                 cl_obj_init( &g_drv_obj, CL_DESTROY_SYNC, NULL, NULL, __srp_free );\r
399         if( cl_status == CL_SUCCESS )\r
400         {\r
401                 // Invoke the port initialization function.\r
402                 status = StorPortInitialize(p_drv_obj, p_registry_path, &hw_data, NULL);\r
403                 if( NT_SUCCESS( status ) )\r
404                 {\r
405                         /*\r
406                          * Overwrite the PnP entrypoint, but save the original\r
407                          * so we can call it.\r
408                          */\r
409                         gpfn_pnp = p_drv_obj->MajorFunction[IRP_MJ_PNP];\r
410                         p_drv_obj->MajorFunction[IRP_MJ_PNP] = srp_dispatch_pnp;\r
411                         gpfn_add_device = p_drv_obj->DriverExtension->AddDevice;\r
412                         p_drv_obj->DriverExtension->AddDevice = srp_add_device;\r
413                         gpfn_unload = p_drv_obj->DriverUnload;\r
414                         p_drv_obj->DriverUnload = srp_unload;\r
415                 }\r
416                 else\r
417                 {\r
418                         CL_DEINIT;\r
419                         SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
420                                 ("StorPortInitialize returned 0x%x.\n", status) );\r
421                 }\r
422         }\r
423         else\r
424         {\r
425                 CL_DEINIT;\r
426                 status = (ULONG)STATUS_INSUFFICIENT_RESOURCES;\r
427         }\r
428 \r
429         SRP_PRINT_EXIT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
430                 ("DriverEntry returning status of 0x%x.\n", status) );\r
431         return status;\r
432 }\r
433 \r
434 static void\r
435 srp_unload(\r
436         IN              DRIVER_OBJECT               *p_drv_obj )\r
437 {\r
438         SRP_ENTER( SRP_DBG_PNP );\r
439 #if defined(EVENT_TRACING)\r
440         WPP_CLEANUP( p_drv_obj );\r
441 #endif\r
442 \r
443         /* Kill all SRP objects. */\r
444         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
445                 ("Destroying all SRP objects.\n") );\r
446         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
447                 ("Driver Object ref_cnt = %d\n", g_drv_obj.ref_cnt) );\r
448         cl_obj_destroy( &g_drv_obj );\r
449 \r
450         CL_DEINIT;\r
451 \r
452         /* Invoke the port driver's unload routine. */\r
453         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
454                 ("Invoking the port driver's unload routine.\n") );\r
455         gpfn_unload( p_drv_obj );\r
456 \r
457         SRP_EXIT( SRP_DBG_PNP );\r
458 }\r
459 \r
460 \r
461 static void\r
462 __srp_free(\r
463         IN              cl_obj_t                    *p_obj )\r
464 {\r
465 //  CL_ASSERT( p_obj == &g_drv_obj );\r
466         UNUSED_PARAM ( p_obj );\r
467         cl_obj_deinit( &g_drv_obj );\r
468 }\r
469 \r
470 \r
471 NTSTATUS\r
472 srp_add_device(\r
473         IN              DRIVER_OBJECT               *p_drv_obj,\r
474         IN              DEVICE_OBJECT               *p_pdo )\r
475 {\r
476         NTSTATUS    status;\r
477 \r
478         SRP_ENTER( SRP_DBG_PNP );\r
479 \r
480         status = gpfn_add_device( p_drv_obj, p_pdo );\r
481         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
482                 ("srp_add_device status = 0x%x.\n", status) );\r
483 \r
484         SRP_EXIT( SRP_DBG_PNP );\r
485         return status;\r
486 }\r
487 \r
488 \r
489 NTSTATUS\r
490 srp_dispatch_pnp(\r
491         IN              DEVICE_OBJECT               *p_dev_obj,\r
492         IN              IRP                         *p_irp )\r
493 {\r
494         NTSTATUS            status;\r
495         IO_STACK_LOCATION   *p_stack;\r
496         UCHAR               minor;\r
497         SRP_ENTER( SRP_DBG_PNP );\r
498 \r
499         p_stack = IoGetCurrentIrpStackLocation( p_irp );\r
500         minor = p_stack->MinorFunction;\r
501         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
502                 ("Minor PNP Function = %d.\n", minor) );\r
503 \r
504         if( minor == IRP_MN_START_DEVICE )\r
505         {\r
506                 NTSTATUS    wait_status;\r
507 \r
508                 wait_status = KeWaitForMutexObject(\r
509                         &g_srp_pnp_mutex, Executive, KernelMode, FALSE, NULL );\r
510 \r
511                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
512                         ("KeWaitForMutexObject status = 0x%x.\n", wait_status) );\r
513                 gp_self_do = p_dev_obj;\r
514         }\r
515         status = gpfn_pnp( p_dev_obj, p_irp );\r
516         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
517                 ("gpfn_pnp status = 0x%x.\n", status) );\r
518 \r
519         if( minor == IRP_MN_START_DEVICE )\r
520         {\r
521                 LONG    release_status;\r
522                 gp_self_do = NULL;\r
523                 release_status = KeReleaseMutex( &g_srp_pnp_mutex, FALSE );\r
524                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
525                         ("KeReleaseMutex status = %d.\n", release_status) );\r
526         }\r
527 \r
528         SRP_EXIT( SRP_DBG_PNP );\r
529         return status;\r
530 }\r
531 \r
532 \r
533 ULONG\r
534 srp_find_adapter(\r
535         IN                              PVOID                                           p_dev_ext,\r
536         IN                              PVOID                                           resv1,\r
537         IN                              PVOID                                           resv2,\r
538         IN                              PCHAR                                           arg_str,\r
539         IN      OUT                     PPORT_CONFIGURATION_INFORMATION         p_config,\r
540                 OUT                     PBOOLEAN                                        resv3 )\r
541 {\r
542         srp_ext_t                       *p_ext;\r
543         ib_api_status_t         ib_status;\r
544 \r
545         SRP_ENTER( SRP_DBG_PNP );\r
546 \r
547         UNUSED_PARAM( resv1 );\r
548         UNUSED_PARAM( resv2 );\r
549         UNUSED_PARAM( resv3 );\r
550         UNUSED_PARAM( arg_str );\r
551         UNUSED_PARAM( p_config );\r
552 \r
553         if( KeGetCurrentIrql() >= DISPATCH_LEVEL )\r
554         {\r
555                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
556                         ("Improper IRQL!\n") );\r
557                 return SP_RETURN_ERROR;\r
558         }\r
559 \r
560         p_ext = (srp_ext_t*)p_dev_ext;\r
561 \r
562         ib_status = srp_hba_create( &g_drv_obj, p_ext );\r
563         if( ib_status != IB_SUCCESS )\r
564         {\r
565                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
566                         ("srp_hba_create returned %d\n", ib_status) );\r
567                 return SP_RETURN_ERROR;\r
568         }\r
569 \r
570         p_config->SrbExtensionSize            = MAX( p_ext->p_hba->max_srb_ext_sz, sizeof( srp_send_descriptor_t ));\r
571         //CL_ASSERT( p_config->SrbExtensionSize >= sizeof( srp_send_descriptor_t ) );\r
572 \r
573         p_config->MaximumTransferLength       = SCSI_MAXIMUM_TRANSFER_SIZE;\r
574         p_config->AlignmentMask               = 0; /* byte alignment */\r
575         p_config->NumberOfBuses               = 1;\r
576         p_config->ScatterGather               = TRUE;\r
577     p_config->Master                      = TRUE; // The HBA is a "bus" master.\r
578 //      p_config->CachesData                  = TRUE; // Assume the HBA does cache data.\r
579         p_config->CachesData                  = FALSE; // Assume the HBA does not cache data.\r
580         p_config->MaximumNumberOfTargets      = p_ext->p_hba->ioc_info.profile.num_svc_entries;\r
581         p_config->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LUNS_PER_TARGET;\r
582         p_config->MultipleRequestPerLu        = TRUE;\r
583         p_config->SynchronizationModel        = StorSynchronizeFullDuplex;\r
584         p_config->MapBuffers                  = STOR_MAP_NON_READ_WRITE_BUFFERS;\r
585         p_config->ResetTargetSupported        = FALSE;\r
586 \r
587 //      p_config->InitiatorBusId[0]           = 127;\r
588 //      p_config->DeviceExtensionSize         = sizeof( srp_ext_t );\r
589 \r
590         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
591                 ("NumberOfPhysicalBreaks passed in = %d.\n", p_config->NumberOfPhysicalBreaks) );\r
592 \r
593         if ( p_config->NumberOfPhysicalBreaks == SP_UNINITIALIZED_VALUE )\r
594         {\r
595                 p_config->NumberOfPhysicalBreaks = p_ext->p_hba->max_sg - 1;\r
596         }\r
597         else\r
598         {\r
599                 p_config->NumberOfPhysicalBreaks = MIN( p_ext->p_hba->max_sg - 1, p_config->NumberOfPhysicalBreaks );\r
600         }\r
601 \r
602         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
603                 ("NumberOfPhysicalBreaks set to = %d.\n", p_config->NumberOfPhysicalBreaks) );\r
604 \r
605         SRP_EXIT( SRP_DBG_PNP );\r
606         return SP_RETURN_FOUND;\r
607 }\r
608 \r
609 BOOLEAN\r
610 srp_init(\r
611         IN              PVOID                       p_dev_ext )\r
612 {\r
613         SRP_ENTER( SRP_DBG_PNP );\r
614 \r
615         UNUSED_PARAM( p_dev_ext );\r
616 \r
617         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
618                 ("called at IRQL %d\n", KeGetCurrentIrql()) );\r
619 \r
620         SRP_EXIT( SRP_DBG_PNP );\r
621         return TRUE;\r
622 }\r
623 \r
624 BOOLEAN\r
625 srp_start_io(\r
626         IN              PVOID                       p_dev_ext,\r
627         IN              PSCSI_REQUEST_BLOCK         p_srb )\r
628 {\r
629         SRP_ENTER( SRP_DBG_DEBUG );\r
630 \r
631         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
632                            ("Starting I/O for Function = %s(0x%x), Path = 0x%x, "\r
633                            "Target = 0x%x, Lun = 0x%x\n",\r
634                            g_srb_function_name[p_srb->Function],\r
635                            p_srb->Function,\r
636                            p_srb->PathId,\r
637                            p_srb->TargetId,\r
638                            p_srb->Lun) );\r
639 \r
640         CL_ASSERT( p_srb->SrbExtension != NULL );\r
641 \r
642         // Check the operation here\r
643         switch ( p_srb->Function )\r
644         {\r
645                 case SRB_FUNCTION_EXECUTE_SCSI:\r
646                         srp_post_io_request( p_dev_ext, p_srb );\r
647                         break;\r
648 \r
649                 case SRB_FUNCTION_ABORT_COMMAND:\r
650                         srp_abort_command( p_dev_ext, p_srb  );\r
651                         break;\r
652 #if !defined(WinXP)\r
653                 case SRB_FUNCTION_RESET_LOGICAL_UNIT:\r
654 #endif\r
655                 case SRB_FUNCTION_RESET_DEVICE:\r
656                         srp_lun_reset( p_dev_ext, p_srb  );\r
657                         break;\r
658 \r
659                 case SRB_FUNCTION_SHUTDOWN: /* Only receive this if CachesData is TRUE in PORT_CONFIGURATION_INFORMATION */\r
660                 {\r
661                         srp_hba_t       *p_hba         = ((srp_ext_t *)p_dev_ext)->p_hba;\r
662                         srp_session_t   *p_srp_session = p_hba->session_list[p_srb->TargetId];\r
663 \r
664                         g_srp_system_shutdown = TRUE;\r
665 \r
666                         if ( (p_srb->Lun == 0) && (p_srp_session != NULL) )\r
667                         {\r
668                                 p_hba->session_list[p_srb->TargetId] = NULL;\r
669 \r
670                                 CL_ASSERT( p_srp_session != NULL );\r
671 \r
672                                 p_srp_session->p_shutdown_srb = p_srb;\r
673                                 cl_obj_destroy( &p_srp_session->obj );\r
674 \r
675                                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
676                                                    ("Returning SrbStatus %s(0x%x) for "\r
677                                                    "Function = %s(0x%x), Path = 0x%x, "\r
678                                                    "Target = 0x%x, Lun = 0x%x\n",\r
679                                                    g_srb_status_name[p_srb->SrbStatus],\r
680                                                    p_srb->SrbStatus,\r
681                                                    g_srb_function_name[p_srb->Function],\r
682                                                    p_srb->Function,\r
683                                                    p_srb->PathId,\r
684                                                    p_srb->TargetId,\r
685                                                    p_srb->Lun) );\r
686                         }\r
687                         else\r
688                         {\r
689                                 p_srb->SrbStatus = SRB_STATUS_SUCCESS;\r
690                                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
691                                                    ("Returning SrbStatus %s(0x%x) for "\r
692                                                    "Function = %s(0x%x), Path = 0x%x, "\r
693                                                    "Target = 0x%x, Lun = 0x%x\n",\r
694                                                    g_srb_status_name[p_srb->SrbStatus],\r
695                                                    p_srb->SrbStatus,\r
696                                                    g_srb_function_name[p_srb->Function],\r
697                                                    p_srb->Function,\r
698                                                    p_srb->PathId,\r
699                                                    p_srb->TargetId,\r
700                                                    p_srb->Lun) );\r
701                                 StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
702                         }\r
703                         break;\r
704                 }\r
705 \r
706                 case SRB_FUNCTION_FLUSH: /* Only receive this if CachesData is TRUE in PORT_CONFIGURATION_INFORMATION */\r
707                         p_srb->SrbStatus = SRB_STATUS_SUCCESS;\r
708                         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
709                                            ("Returning SrbStatus %s(0x%x) for "\r
710                                            "Function = %s(0x%x), Path = 0x%x, "\r
711                                            "Target = 0x%x, Lun = 0x%x\n",\r
712                                            g_srb_status_name[p_srb->SrbStatus],\r
713                                            p_srb->SrbStatus,\r
714                                            g_srb_function_name[p_srb->Function],\r
715                                            p_srb->Function,\r
716                                            p_srb->PathId,\r
717                                            p_srb->TargetId,\r
718                                            p_srb->Lun) );\r
719                         StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
720                         break;\r
721 \r
722                 case SRB_FUNCTION_IO_CONTROL: /***** May Need To Support *****/\r
723 \r
724                 case SRB_FUNCTION_RESET_BUS:\r
725                 case SRB_FUNCTION_TERMINATE_IO:\r
726                 case SRB_FUNCTION_RELEASE_RECOVERY:\r
727                 case SRB_FUNCTION_RECEIVE_EVENT:\r
728                 case SRB_FUNCTION_LOCK_QUEUE:\r
729                 case SRB_FUNCTION_UNLOCK_QUEUE:\r
730                 case SRB_FUNCTION_CLAIM_DEVICE:\r
731                 case SRB_FUNCTION_RELEASE_QUEUE:\r
732                 case SRB_FUNCTION_ATTACH_DEVICE:\r
733                 case SRB_FUNCTION_RELEASE_DEVICE:\r
734                 case SRB_FUNCTION_FLUSH_QUEUE:\r
735                 case SRB_FUNCTION_REMOVE_DEVICE:\r
736                 case SRB_FUNCTION_WMI:\r
737 #if !defined(WinXP)\r
738                 case SRB_FUNCTION_SET_LINK_TIMEOUT:\r
739                 case SRB_FUNCTION_LINK_TIMEOUT_OCCURRED:\r
740                 case SRB_FUNCTION_LINK_TIMEOUT_COMPLETE:\r
741 #endif\r
742                 default:\r
743                         p_srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;\r
744                         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
745                                            ("Returning SrbStatus %s(0x%x) for "\r
746                                            "Function = %s(0x%x), Path = 0x%x, "\r
747                                            "Target = 0x%x, Lun = 0x%x\n",\r
748                                            g_srb_status_name[p_srb->SrbStatus],\r
749                                            p_srb->SrbStatus,\r
750                                            g_srb_function_name[p_srb->Function],\r
751                                            p_srb->Function,\r
752                                            p_srb->PathId,\r
753                                            p_srb->TargetId,\r
754                                            p_srb->Lun) );\r
755                         StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
756 \r
757         }\r
758 \r
759         SRP_EXIT( SRP_DBG_DEBUG );\r
760 \r
761         return ( TRUE );\r
762 }\r
763 \r
764 BOOLEAN\r
765 srp_isr(\r
766         IN              PVOID                       p_dev_ext )\r
767 {\r
768         SRP_ENTER( SRP_DBG_PNP );\r
769 \r
770         UNUSED_PARAM( p_dev_ext );\r
771 \r
772         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
773                 ("called at IRQL %d\n", KeGetCurrentIrql()) );\r
774 \r
775         SRP_EXIT( SRP_DBG_PNP );\r
776         return TRUE;\r
777 }\r
778 \r
779 BOOLEAN\r
780 srp_reset(\r
781         IN              PVOID                       p_dev_ext,\r
782         IN              ULONG                       path_id )\r
783 {\r
784         SRP_ENTER( SRP_DBG_PNP );\r
785 \r
786         UNUSED_PARAM( p_dev_ext );\r
787         UNUSED_PARAM( path_id );\r
788 \r
789         SRP_EXIT( SRP_DBG_PNP );\r
790         return FALSE;\r
791 }\r
792 \r
793 SCSI_ADAPTER_CONTROL_STATUS\r
794 srp_adapter_ctrl(\r
795         IN              PVOID                       p_dev_ext,\r
796         IN              SCSI_ADAPTER_CONTROL_TYPE   ctrl_type,\r
797         IN              PVOID                       params )\r
798 {\r
799         srp_ext_t                           *p_ext;\r
800         SCSI_SUPPORTED_CONTROL_TYPE_LIST    *p_ctrl_list;\r
801 \r
802         SRP_ENTER( SRP_DBG_PNP );\r
803 \r
804         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
805                 ("called at IRQL %d\n", KeGetCurrentIrql()) );\r
806 \r
807         p_ext = (srp_ext_t*)p_dev_ext;\r
808 \r
809         switch( ctrl_type )\r
810         {\r
811         case ScsiQuerySupportedControlTypes:\r
812                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
813                         ("ScsiQuerySupportedControlTypes\n") );\r
814                 p_ctrl_list = (SCSI_SUPPORTED_CONTROL_TYPE_LIST*)params;\r
815                 p_ctrl_list->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;\r
816                 p_ctrl_list->SupportedTypeList[ScsiStopAdapter] = TRUE;\r
817                 p_ctrl_list->SupportedTypeList[ScsiRestartAdapter] = FALSE;\r
818                 p_ctrl_list->SupportedTypeList[ScsiSetBootConfig] = FALSE;\r
819                 p_ctrl_list->SupportedTypeList[ScsiSetRunningConfig] = FALSE;\r
820                 break;\r
821 \r
822         case ScsiStopAdapter:\r
823                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
824                         ("ScsiStopAdapter\n") );\r
825                 if( p_ext->p_hba )\r
826                 {\r
827                         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
828                                 ("HBA Object ref_cnt = %d\n", p_ext->p_hba->obj.ref_cnt) );\r
829                         cl_obj_destroy( &p_ext->p_hba->obj );\r
830                         p_ext->p_hba = NULL;\r
831                 }\r
832                 break;\r
833 \r
834         case ScsiRestartAdapter:\r
835                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
836                         ("ScsiRestartAdapter\n") );\r
837                 break;\r
838 \r
839         case ScsiSetBootConfig:\r
840                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
841                         ("ScsiSetBootConfig\n") );\r
842                 break;\r
843 \r
844         case ScsiSetRunningConfig:\r
845                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
846                         ("ScsiSetRunningConfig\n") );\r
847                 break;\r
848         }\r
849 \r
850         SRP_EXIT( SRP_DBG_PNP );\r
851         return ScsiAdapterControlSuccess;\r
852 }\r
853 \r
854 BOOLEAN\r
855 srp_build_io(\r
856         IN              PVOID                       p_dev_ext,\r
857         IN              PSCSI_REQUEST_BLOCK         p_srb )\r
858 {\r
859         SRP_ENTER( SRP_DBG_DEBUG );\r
860 \r
861         if ( p_srb->Function == SRB_FUNCTION_EXECUTE_SCSI )\r
862         {\r
863 \r
864                 CL_ASSERT( p_srb->SrbExtension != NULL );\r
865 \r
866                 SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
867                                    ("Building I/O for Function = %s(0x%x), "\r
868                                    "Path = 0x%x, Target = 0x%x, Lun = 0x%x\n",\r
869                                    g_srb_function_name[p_srb->Function],\r
870                                    p_srb->Function,\r
871                                    p_srb->PathId,\r
872                                    p_srb->TargetId,\r
873                                    p_srb->Lun) );\r
874 \r
875                 if ( srp_format_io_request( p_dev_ext, p_srb ) == FALSE )\r
876                 {\r
877                         SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
878                                                         ("Returning SrbStatus %s(0x%x) for "\r
879                                                         "Function = %s(0x%x), Path = 0x%x, "\r
880                                                         "Target = 0x%x, Lun = 0x%x\n",\r
881                                                     g_srb_status_name[p_srb->SrbStatus],\r
882                                                         p_srb->SrbStatus,\r
883                                                         g_srb_function_name[p_srb->Function],\r
884                                                         p_srb->Function,\r
885                                                         p_srb->PathId,\r
886                                                         p_srb->TargetId,\r
887                                                         p_srb->Lun) );\r
888 \r
889                         StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
890 \r
891                         return ( FALSE );\r
892                 }\r
893         }\r
894 \r
895         SRP_EXIT( SRP_DBG_DEBUG );\r
896 \r
897         return ( TRUE );\r
898 }\r