[SRP] Add WPP
[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 \r
142 DRIVER_OBJECT       *gp_drv_obj;\r
143 cl_obj_t            g_drv_obj;\r
144 \r
145 /* Mutex protecting the next lower device object pointer. */\r
146 KMUTEX              g_srp_pnp_mutex;\r
147 \r
148 PDRIVER_DISPATCH    gpfn_pnp;\r
149 PDRIVER_ADD_DEVICE  gpfn_add_device;\r
150 PDRIVER_UNLOAD      gpfn_unload;\r
151 \r
152 \r
153 static NTSTATUS\r
154 __read_registry(\r
155         IN                              UNICODE_STRING* const           p_Param_Path );\r
156 \r
157 NTSTATUS\r
158 srp_add_device(\r
159         IN              DRIVER_OBJECT               *p_drv_obj,\r
160         IN              DEVICE_OBJECT               *p_pdo );\r
161 \r
162 NTSTATUS\r
163 srp_dispatch_pnp(\r
164         IN              DEVICE_OBJECT               *p_dev_obj,\r
165         IN              IRP                         *p_irp );\r
166 \r
167 BOOLEAN\r
168 srp_init(\r
169         IN              PVOID                       p_dev_ext );\r
170 \r
171 BOOLEAN\r
172 srp_start_io(\r
173         IN              PVOID                       p_dev_ext,\r
174         IN              PSCSI_REQUEST_BLOCK         p_srb );\r
175 \r
176 BOOLEAN\r
177 srp_isr(\r
178         IN              PVOID                       p_dev_ext );\r
179 \r
180 ULONG\r
181 srp_find_adapter(\r
182         IN              PVOID                       p_dev_ext,\r
183         IN              PVOID                       resv1,\r
184         IN              PVOID                       resv2,\r
185         IN              PCHAR                       arg_str,\r
186         IN  OUT         PPORT_CONFIGURATION_INFORMATION     p_config,\r
187                 OUT         PBOOLEAN                    resv3 );\r
188 \r
189 BOOLEAN\r
190 srp_reset(\r
191         IN              PVOID                       p_dev_ext,\r
192         IN              ULONG                       path_id );\r
193 \r
194 SCSI_ADAPTER_CONTROL_STATUS\r
195 srp_adapter_ctrl(\r
196         IN              PVOID                       p_dev_ext,\r
197         IN              SCSI_ADAPTER_CONTROL_TYPE   ctrl_type,\r
198         IN              PVOID                       params );\r
199 \r
200 BOOLEAN\r
201 srp_build_io(\r
202         IN              PVOID                       p_dev_ext,\r
203         IN              PSCSI_REQUEST_BLOCK         p_srb );\r
204 \r
205 static void\r
206 srp_unload(\r
207         IN              DRIVER_OBJECT               *p_drv_obj );\r
208 \r
209 static void\r
210 __srp_free(\r
211         IN              cl_obj_t                    *p_obj );\r
212 \r
213 \r
214 \r
215 static NTSTATUS\r
216 __read_registry(\r
217         IN                              UNICODE_STRING* const           p_registry_path )\r
218 {\r
219         NTSTATUS                                        status;\r
220         /* Remember the terminating entry in the table below. */\r
221         RTL_QUERY_REGISTRY_TABLE        table[3];\r
222         UNICODE_STRING                          param_path;\r
223 \r
224         SRP_ENTER( SRP_DBG_PNP );\r
225 \r
226         RtlInitUnicodeString( &param_path, NULL );\r
227         param_path.MaximumLength = p_registry_path->Length + \r
228                 sizeof(L"\\Parameters");\r
229         param_path.Buffer = cl_zalloc( param_path.MaximumLength );\r
230         if( !param_path.Buffer )\r
231         {\r
232                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR, \r
233                         ("Failed to allocate parameters path buffer.\n") );\r
234                 return STATUS_INSUFFICIENT_RESOURCES;\r
235         }\r
236 \r
237         RtlAppendUnicodeStringToString( &param_path, p_registry_path );\r
238         RtlAppendUnicodeToString( &param_path, L"\\Parameters" );\r
239 \r
240         /*\r
241          * Clear the table.  This clears all the query callback pointers,\r
242          * and sets up the terminating table entry.\r
243          */\r
244         cl_memclr( table, sizeof(table) );\r
245 \r
246         /* Setup the table entries. */\r
247         table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
248         table[0].Name = L"DebugLevel";\r
249         table[0].EntryContext = &g_srp_dbg_level;\r
250         table[0].DefaultType = REG_DWORD;\r
251         table[0].DefaultData = &g_srp_dbg_level;\r
252         table[0].DefaultLength = sizeof(ULONG);\r
253 \r
254         table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
255         table[1].Name = L"DebugFlags";\r
256         table[1].EntryContext = &g_srp_dbg_flags;\r
257         table[1].DefaultType = REG_DWORD;\r
258         table[1].DefaultData = &g_srp_dbg_flags;\r
259         table[1].DefaultLength = sizeof(ULONG);\r
260         /* Have at it! */\r
261         status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
262                 param_path.Buffer, table, NULL, NULL );\r
263 \r
264 #ifndef EVENT_TRACING\r
265         if( g_srp_dbg_flags & SRP_DBG_ERR )\r
266                 g_srp_dbg_flags |= CL_DBG_ERROR;\r
267 #endif\r
268 \r
269         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
270                 ("debug level %d debug flags 0x%.8x\n",\r
271                 g_srp_dbg_level,\r
272                 g_srp_dbg_flags) );\r
273 \r
274         cl_free( param_path.Buffer );\r
275         SRP_EXIT( SRP_DBG_PNP );\r
276         return status;\r
277 }\r
278 \r
279 \r
280 ULONG\r
281 DriverEntry(\r
282         IN              DRIVER_OBJECT               *p_drv_obj,\r
283         IN              UNICODE_STRING              *p_registry_path )\r
284 {\r
285         ULONG                       status;\r
286         HW_INITIALIZATION_DATA      hw_data;\r
287         cl_status_t                 cl_status;\r
288 \r
289         SRP_ENTER( SRP_DBG_PNP );\r
290 \r
291 #if defined(EVENT_TRACING)\r
292         WPP_INIT_TRACING( p_drv_obj, p_registry_path );\r
293 #endif\r
294 \r
295         status = CL_INIT;\r
296         if( !NT_SUCCESS(status) )\r
297         {\r
298                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
299                         ("cl_init returned %08X.\n", status) );\r
300                 return status;\r
301         }\r
302 \r
303         gp_drv_obj = p_drv_obj;\r
304 \r
305         /* Get the registry values. */\r
306         status = __read_registry( p_registry_path );\r
307         if( !NT_SUCCESS(status) )\r
308         {\r
309                 CL_DEINIT;\r
310                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
311                         ("__read_registry returned %08x.\n", status) );\r
312                 return status;\r
313         }\r
314 \r
315         cl_obj_construct( &g_drv_obj, SRP_OBJ_TYPE_DRV );\r
316 \r
317         KeInitializeMutex( &g_srp_pnp_mutex, 0 );\r
318 \r
319         cl_memclr( &hw_data, sizeof(HW_INITIALIZATION_DATA) );\r
320 \r
321         hw_data.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);\r
322 \r
323         hw_data.AdapterInterfaceType = Internal;\r
324 \r
325         /* Miniport driver routines */\r
326         hw_data.HwInitialize     = srp_init;\r
327         hw_data.HwStartIo        = srp_start_io;\r
328 //      hw_data.HwInterrupt      = srp_isr;\r
329         hw_data.HwInterrupt      = NULL;\r
330         hw_data.HwFindAdapter    = srp_find_adapter;\r
331         hw_data.HwResetBus       = srp_reset;\r
332         hw_data.HwAdapterControl = srp_adapter_ctrl;\r
333         hw_data.HwBuildIo        = srp_build_io;\r
334         hw_data.HwDmaStarted     = NULL;\r
335         hw_data.HwAdapterState   = NULL;\r
336 \r
337         /* Extension sizes. */\r
338         hw_data.DeviceExtensionSize = sizeof(srp_ext_t);\r
339         /* TODO: Do we need per-LU data? */\r
340         hw_data.SpecificLuExtensionSize = 0;\r
341         hw_data.SrbExtensionSize = sizeof(srp_send_descriptor_t);\r
342 \r
343         /* Driver parameters. */\r
344         hw_data.NumberOfAccessRanges = 1;\r
345         /* TODO: Can this be STOR_MAP_NO_BUFFERS? */\r
346         hw_data.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;\r
347 \r
348         hw_data.NeedPhysicalAddresses = TRUE;\r
349         hw_data.TaggedQueuing = TRUE;\r
350         hw_data.AutoRequestSense = TRUE;\r
351         hw_data.MultipleRequestPerLu = TRUE;\r
352 \r
353         cl_status =\r
354                 cl_obj_init( &g_drv_obj, CL_DESTROY_SYNC, NULL, NULL, __srp_free );\r
355         if( cl_status == CL_SUCCESS )\r
356         {\r
357                 // Invoke the port initialization function.\r
358                 status = StorPortInitialize(p_drv_obj, p_registry_path, &hw_data, NULL);\r
359                 if( NT_SUCCESS( status ) )\r
360                 {\r
361                         /*\r
362                          * Overwrite the PnP entrypoint, but save the original\r
363                          * so we can call it.\r
364                          */\r
365                         gpfn_pnp = p_drv_obj->MajorFunction[IRP_MJ_PNP];\r
366                         p_drv_obj->MajorFunction[IRP_MJ_PNP] = srp_dispatch_pnp;\r
367                         gpfn_add_device = p_drv_obj->DriverExtension->AddDevice;\r
368                         p_drv_obj->DriverExtension->AddDevice = srp_add_device;\r
369                         gpfn_unload = p_drv_obj->DriverUnload;\r
370                         p_drv_obj->DriverUnload = srp_unload;\r
371                 }\r
372                 else\r
373                 {\r
374                         CL_DEINIT;\r
375                         SRP_PRINT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
376                                 ("StorPortInitialize returned 0x%x.\n", status) );\r
377                 }\r
378         }\r
379         else\r
380         {\r
381                 CL_DEINIT;\r
382                 status = (ULONG)STATUS_INSUFFICIENT_RESOURCES;\r
383         }\r
384 \r
385         SRP_PRINT_EXIT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
386                 ("DriverEntry returning status of 0x%x.\n", status) );\r
387         return status;\r
388 }\r
389 \r
390 static void\r
391 srp_unload(\r
392         IN              DRIVER_OBJECT               *p_drv_obj )\r
393 {\r
394         SRP_ENTER( SRP_DBG_PNP );\r
395 #if defined(EVENT_TRACING)\r
396         WPP_CLEANUP( p_drv_obj );\r
397 #endif\r
398 \r
399         /* Kill all SRP objects. */\r
400         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
401                 ("Destroying all SRP objects.\n") );\r
402         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
403                 ("Driver Object ref_cnt = %d\n", g_drv_obj.ref_cnt) );\r
404         cl_obj_destroy( &g_drv_obj );\r
405 \r
406         CL_DEINIT;\r
407 \r
408         /* Invoke the port driver's unload routine. */\r
409         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
410                 ("Invoking the port driver's unload routine.\n") );\r
411         gpfn_unload( p_drv_obj );\r
412 \r
413         SRP_EXIT( SRP_DBG_PNP );\r
414 }\r
415 \r
416 \r
417 static void\r
418 __srp_free(\r
419         IN              cl_obj_t                    *p_obj )\r
420 {\r
421 //  CL_ASSERT( p_obj == &g_drv_obj );\r
422         UNUSED_PARAM ( p_obj );\r
423         cl_obj_deinit( &g_drv_obj );\r
424 }\r
425 \r
426 \r
427 NTSTATUS\r
428 srp_add_device(\r
429         IN              DRIVER_OBJECT               *p_drv_obj,\r
430         IN              DEVICE_OBJECT               *p_pdo )\r
431 {\r
432         NTSTATUS    status;\r
433 \r
434         SRP_ENTER( SRP_DBG_PNP );\r
435 \r
436         status = gpfn_add_device( p_drv_obj, p_pdo );\r
437         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
438                 ("srp_add_device status = 0x%x.\n", status) );\r
439 \r
440         SRP_EXIT( SRP_DBG_PNP );\r
441         return status;\r
442 }\r
443 \r
444 \r
445 NTSTATUS\r
446 srp_dispatch_pnp(\r
447         IN              DEVICE_OBJECT               *p_dev_obj,\r
448         IN              IRP                         *p_irp )\r
449 {\r
450         NTSTATUS            status;\r
451         IO_STACK_LOCATION   *p_stack;\r
452         UCHAR               minor;\r
453         SRP_ENTER( SRP_DBG_PNP );\r
454 \r
455         p_stack = IoGetCurrentIrpStackLocation( p_irp );\r
456         minor = p_stack->MinorFunction;\r
457         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
458                 ("Minor PNP Function = %d.\n", minor) );\r
459 \r
460         if( minor == IRP_MN_START_DEVICE )\r
461         {\r
462                 NTSTATUS    wait_status;\r
463 \r
464                 wait_status = KeWaitForMutexObject(\r
465                         &g_srp_pnp_mutex, Executive, KernelMode, FALSE, NULL );\r
466 \r
467                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
468                         ("KeWaitForMutexObject status = 0x%x.\n", wait_status) );\r
469                 gp_self_do = p_dev_obj;\r
470         }\r
471         status = gpfn_pnp( p_dev_obj, p_irp );\r
472         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
473                 ("gpfn_pnp status = 0x%x.\n", status) );\r
474 \r
475         if( minor == IRP_MN_START_DEVICE )\r
476         {\r
477                 LONG    release_status;\r
478                 gp_self_do = NULL;\r
479                 release_status = KeReleaseMutex( &g_srp_pnp_mutex, FALSE );\r
480                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
481                         ("KeReleaseMutex status = %d.\n", release_status) );\r
482         }\r
483 \r
484         SRP_EXIT( SRP_DBG_PNP );\r
485         return status;\r
486 }\r
487 \r
488 \r
489 ULONG\r
490 srp_find_adapter(\r
491         IN                              PVOID                                           p_dev_ext,\r
492         IN                              PVOID                                           resv1,\r
493         IN                              PVOID                                           resv2,\r
494         IN                              PCHAR                                           arg_str,\r
495         IN      OUT                     PPORT_CONFIGURATION_INFORMATION         p_config,\r
496                 OUT                     PBOOLEAN                                        resv3 )\r
497 {\r
498         srp_ext_t                       *p_ext;\r
499         ib_api_status_t         ib_status;\r
500 \r
501         SRP_ENTER( SRP_DBG_PNP );\r
502 \r
503         UNUSED_PARAM( resv1 );\r
504         UNUSED_PARAM( resv2 );\r
505         UNUSED_PARAM( resv3 );\r
506         UNUSED_PARAM( arg_str );\r
507         UNUSED_PARAM( p_config );\r
508 \r
509         if( KeGetCurrentIrql() >= DISPATCH_LEVEL )\r
510         {\r
511                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
512                         ("Improper IRQL!\n") );\r
513                 return SP_RETURN_ERROR;\r
514         }\r
515 \r
516         p_ext = (srp_ext_t*)p_dev_ext;\r
517 \r
518         ib_status = srp_hba_create( &g_drv_obj, p_ext );\r
519         if( ib_status != IB_SUCCESS )\r
520         {\r
521                 SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
522                         ("srp_hba_create returned %d\n", ib_status) );\r
523                 return SP_RETURN_ERROR;\r
524         }\r
525 \r
526         p_config->SrbExtensionSize            = MAX( p_ext->p_hba->max_srb_ext_sz, sizeof( srp_send_descriptor_t ));\r
527         //CL_ASSERT( p_config->SrbExtensionSize >= sizeof( srp_send_descriptor_t ) );\r
528 \r
529         p_config->MaximumTransferLength       = SCSI_MAXIMUM_TRANSFER_SIZE;\r
530         p_config->AlignmentMask               = 0; /* byte alignment */\r
531         p_config->NumberOfBuses               = 1;\r
532         p_config->ScatterGather               = TRUE;\r
533     p_config->Master                      = TRUE; // The HBA is a "bus" master.\r
534 //      p_config->CachesData                  = TRUE; // Assume the HBA does cache data.\r
535         p_config->CachesData                  = FALSE; // Assume the HBA does not cache data.\r
536         p_config->MaximumNumberOfTargets      = p_ext->p_hba->ioc_info.profile.num_svc_entries;\r
537         p_config->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LUNS_PER_TARGET;\r
538         p_config->MultipleRequestPerLu        = TRUE;\r
539         p_config->SynchronizationModel        = StorSynchronizeFullDuplex;\r
540         p_config->MapBuffers                  = STOR_MAP_NON_READ_WRITE_BUFFERS;\r
541         p_config->ResetTargetSupported        = FALSE;\r
542 \r
543 //      p_config->InitiatorBusId[0]           = 127;\r
544 //      p_config->DeviceExtensionSize         = sizeof( srp_ext_t );\r
545 \r
546         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
547                 ("NumberOfPhysicalBreaks passed in = %d.\n", p_config->NumberOfPhysicalBreaks) );\r
548 \r
549         if ( p_config->NumberOfPhysicalBreaks == SP_UNINITIALIZED_VALUE )\r
550         {\r
551                 p_config->NumberOfPhysicalBreaks = p_ext->p_hba->max_sg - 1;\r
552         }\r
553         else\r
554         {\r
555                 p_config->NumberOfPhysicalBreaks = MIN( p_ext->p_hba->max_sg - 1, p_config->NumberOfPhysicalBreaks );\r
556         }\r
557 \r
558         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
559                 ("NumberOfPhysicalBreaks set to = %d.\n", p_config->NumberOfPhysicalBreaks) );\r
560 \r
561         SRP_EXIT( SRP_DBG_PNP );\r
562         return SP_RETURN_FOUND;\r
563 }\r
564 \r
565 BOOLEAN\r
566 srp_init(\r
567         IN              PVOID                       p_dev_ext )\r
568 {\r
569         SRP_ENTER( SRP_DBG_PNP );\r
570 \r
571         UNUSED_PARAM( p_dev_ext );\r
572 \r
573         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
574                 ("called at IRQL %d\n", KeGetCurrentIrql()) );\r
575 \r
576         SRP_EXIT( SRP_DBG_PNP );\r
577         return TRUE;\r
578 }\r
579 \r
580 BOOLEAN\r
581 srp_start_io(\r
582         IN              PVOID                       p_dev_ext,\r
583         IN              PSCSI_REQUEST_BLOCK         p_srb )\r
584 {\r
585         SRP_ENTER( SRP_DBG_DEBUG );\r
586 \r
587         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
588                            ("Starting I/O for Function = %s(0x%x), Path = 0x%x, "\r
589                            "Target = 0x%x, Lun = 0x%x\n",\r
590                            g_srb_function_name[p_srb->Function],\r
591                            p_srb->Function,\r
592                            p_srb->PathId,\r
593                            p_srb->TargetId,\r
594                            p_srb->Lun) );\r
595 \r
596         CL_ASSERT( p_srb->SrbExtension != NULL );\r
597 \r
598         // Check the operation here\r
599         switch ( p_srb->Function )\r
600         {\r
601                 case SRB_FUNCTION_EXECUTE_SCSI:\r
602                         srp_post_io_request( p_dev_ext, p_srb );\r
603                         break;\r
604 \r
605                 case SRB_FUNCTION_ABORT_COMMAND:\r
606                         srp_abort_command( p_dev_ext, p_srb  );\r
607                         break;\r
608 #if !defined(WinXP)\r
609                 case SRB_FUNCTION_RESET_LOGICAL_UNIT:\r
610 #endif\r
611                 case SRB_FUNCTION_RESET_DEVICE:\r
612                         srp_lun_reset( p_dev_ext, p_srb  );\r
613                         break;\r
614 \r
615                 case SRB_FUNCTION_SHUTDOWN: /* Only receive this if CachesData is TRUE in PORT_CONFIGURATION_INFORMATION */\r
616                 {\r
617                         srp_hba_t       *p_hba         = ((srp_ext_t *)p_dev_ext)->p_hba;\r
618                         srp_session_t   *p_srp_session = p_hba->session_list[p_srb->TargetId];\r
619 \r
620                         g_srp_system_shutdown = TRUE;\r
621 \r
622                         if ( (p_srb->Lun == 0) && (p_srp_session != NULL) )\r
623                         {\r
624                                 p_hba->session_list[p_srb->TargetId] = NULL;\r
625 \r
626                                 CL_ASSERT( p_srp_session != NULL );\r
627 \r
628                                 p_srp_session->p_shutdown_srb = p_srb;\r
629                                 cl_obj_destroy( &p_srp_session->obj );\r
630 \r
631                                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
632                                                    ("Returning SrbStatus %s(0x%x) for "\r
633                                                    "Function = %s(0x%x), Path = 0x%x, "\r
634                                                    "Target = 0x%x, Lun = 0x%x\n",\r
635                                                    g_srb_status_name[p_srb->SrbStatus],\r
636                                                    p_srb->SrbStatus,\r
637                                                    g_srb_function_name[p_srb->Function],\r
638                                                    p_srb->Function,\r
639                                                    p_srb->PathId,\r
640                                                    p_srb->TargetId,\r
641                                                    p_srb->Lun) );\r
642                         }\r
643                         else\r
644                         {\r
645                                 p_srb->SrbStatus = SRB_STATUS_SUCCESS;\r
646                                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
647                                                    ("Returning SrbStatus %s(0x%x) for "\r
648                                                    "Function = %s(0x%x), Path = 0x%x, "\r
649                                                    "Target = 0x%x, Lun = 0x%x\n",\r
650                                                    g_srb_status_name[p_srb->SrbStatus],\r
651                                                    p_srb->SrbStatus,\r
652                                                    g_srb_function_name[p_srb->Function],\r
653                                                    p_srb->Function,\r
654                                                    p_srb->PathId,\r
655                                                    p_srb->TargetId,\r
656                                                    p_srb->Lun) );\r
657                                 StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
658                         }\r
659                         break;\r
660                 }\r
661 \r
662                 case SRB_FUNCTION_FLUSH: /* Only receive this if CachesData is TRUE in PORT_CONFIGURATION_INFORMATION */\r
663                         p_srb->SrbStatus = SRB_STATUS_SUCCESS;\r
664                         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
665                                            ("Returning SrbStatus %s(0x%x) for "\r
666                                            "Function = %s(0x%x), Path = 0x%x, "\r
667                                            "Target = 0x%x, Lun = 0x%x\n",\r
668                                            g_srb_status_name[p_srb->SrbStatus],\r
669                                            p_srb->SrbStatus,\r
670                                            g_srb_function_name[p_srb->Function],\r
671                                            p_srb->Function,\r
672                                            p_srb->PathId,\r
673                                            p_srb->TargetId,\r
674                                            p_srb->Lun) );\r
675                         StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
676                         break;\r
677 \r
678                 case SRB_FUNCTION_IO_CONTROL: /***** May Need To Support *****/\r
679 \r
680                 case SRB_FUNCTION_RESET_BUS:\r
681                 case SRB_FUNCTION_TERMINATE_IO:\r
682                 case SRB_FUNCTION_RELEASE_RECOVERY:\r
683                 case SRB_FUNCTION_RECEIVE_EVENT:\r
684                 case SRB_FUNCTION_LOCK_QUEUE:\r
685                 case SRB_FUNCTION_UNLOCK_QUEUE:\r
686                 case SRB_FUNCTION_CLAIM_DEVICE:\r
687                 case SRB_FUNCTION_RELEASE_QUEUE:\r
688                 case SRB_FUNCTION_ATTACH_DEVICE:\r
689                 case SRB_FUNCTION_RELEASE_DEVICE:\r
690                 case SRB_FUNCTION_FLUSH_QUEUE:\r
691                 case SRB_FUNCTION_REMOVE_DEVICE:\r
692                 case SRB_FUNCTION_WMI:\r
693 #if !defined(WinXP)\r
694                 case SRB_FUNCTION_SET_LINK_TIMEOUT:\r
695                 case SRB_FUNCTION_LINK_TIMEOUT_OCCURRED:\r
696                 case SRB_FUNCTION_LINK_TIMEOUT_COMPLETE:\r
697 #endif\r
698                 default:\r
699                         p_srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;\r
700                         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
701                                            ("Returning SrbStatus %s(0x%x) for "\r
702                                            "Function = %s(0x%x), Path = 0x%x, "\r
703                                            "Target = 0x%x, Lun = 0x%x\n",\r
704                                            g_srb_status_name[p_srb->SrbStatus],\r
705                                            p_srb->SrbStatus,\r
706                                            g_srb_function_name[p_srb->Function],\r
707                                            p_srb->Function,\r
708                                            p_srb->PathId,\r
709                                            p_srb->TargetId,\r
710                                            p_srb->Lun) );\r
711                         StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
712 \r
713         }\r
714 \r
715         SRP_EXIT( SRP_DBG_DEBUG );\r
716 \r
717         return ( TRUE );\r
718 }\r
719 \r
720 BOOLEAN\r
721 srp_isr(\r
722         IN              PVOID                       p_dev_ext )\r
723 {\r
724         SRP_ENTER( SRP_DBG_PNP );\r
725 \r
726         UNUSED_PARAM( p_dev_ext );\r
727 \r
728         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
729                 ("called at IRQL %d\n", KeGetCurrentIrql()) );\r
730 \r
731         SRP_EXIT( SRP_DBG_PNP );\r
732         return TRUE;\r
733 }\r
734 \r
735 BOOLEAN\r
736 srp_reset(\r
737         IN              PVOID                       p_dev_ext,\r
738         IN              ULONG                       path_id )\r
739 {\r
740         SRP_ENTER( SRP_DBG_PNP );\r
741 \r
742         UNUSED_PARAM( p_dev_ext );\r
743         UNUSED_PARAM( path_id );\r
744 \r
745         SRP_EXIT( SRP_DBG_PNP );\r
746         return FALSE;\r
747 }\r
748 \r
749 SCSI_ADAPTER_CONTROL_STATUS\r
750 srp_adapter_ctrl(\r
751         IN              PVOID                       p_dev_ext,\r
752         IN              SCSI_ADAPTER_CONTROL_TYPE   ctrl_type,\r
753         IN              PVOID                       params )\r
754 {\r
755         srp_ext_t                           *p_ext;\r
756         SCSI_SUPPORTED_CONTROL_TYPE_LIST    *p_ctrl_list;\r
757 \r
758         SRP_ENTER( SRP_DBG_PNP );\r
759 \r
760         SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_PNP,\r
761                 ("called at IRQL %d\n", KeGetCurrentIrql()) );\r
762 \r
763         p_ext = (srp_ext_t*)p_dev_ext;\r
764 \r
765         switch( ctrl_type )\r
766         {\r
767         case ScsiQuerySupportedControlTypes:\r
768                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
769                         ("ScsiQuerySupportedControlTypes\n") );\r
770                 p_ctrl_list = (SCSI_SUPPORTED_CONTROL_TYPE_LIST*)params;\r
771                 p_ctrl_list->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;\r
772                 p_ctrl_list->SupportedTypeList[ScsiStopAdapter] = TRUE;\r
773                 p_ctrl_list->SupportedTypeList[ScsiRestartAdapter] = FALSE;\r
774                 p_ctrl_list->SupportedTypeList[ScsiSetBootConfig] = FALSE;\r
775                 p_ctrl_list->SupportedTypeList[ScsiSetRunningConfig] = FALSE;\r
776                 break;\r
777 \r
778         case ScsiStopAdapter:\r
779                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
780                         ("ScsiStopAdapter\n") );\r
781                 if( p_ext->p_hba )\r
782                 {\r
783                         SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
784                                 ("HBA Object ref_cnt = %d\n", p_ext->p_hba->obj.ref_cnt) );\r
785                         cl_obj_destroy( &p_ext->p_hba->obj );\r
786                         p_ext->p_hba = NULL;\r
787                 }\r
788                 break;\r
789 \r
790         case ScsiRestartAdapter:\r
791                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
792                         ("ScsiRestartAdapter\n") );\r
793                 break;\r
794 \r
795         case ScsiSetBootConfig:\r
796                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
797                         ("ScsiSetBootConfig\n") );\r
798                 break;\r
799 \r
800         case ScsiSetRunningConfig:\r
801                 SRP_PRINT( TRACE_LEVEL_INFORMATION, SRP_DBG_DEBUG,\r
802                         ("ScsiSetRunningConfig\n") );\r
803                 break;\r
804         }\r
805 \r
806         SRP_EXIT( SRP_DBG_PNP );\r
807         return ScsiAdapterControlSuccess;\r
808 }\r
809 \r
810 BOOLEAN\r
811 srp_build_io(\r
812         IN              PVOID                       p_dev_ext,\r
813         IN              PSCSI_REQUEST_BLOCK         p_srb )\r
814 {\r
815         SRP_ENTER( SRP_DBG_DEBUG );\r
816 \r
817         if ( p_srb->Function == SRB_FUNCTION_EXECUTE_SCSI )\r
818         {\r
819 \r
820                 CL_ASSERT( p_srb->SrbExtension != NULL );\r
821 \r
822                 SRP_PRINT( TRACE_LEVEL_VERBOSE, SRP_DBG_DEBUG,\r
823                                    ("Building I/O for Function = %s(0x%x), "\r
824                                    "Path = 0x%x, Target = 0x%x, Lun = 0x%x\n",\r
825                                    g_srb_function_name[p_srb->Function],\r
826                                    p_srb->Function,\r
827                                    p_srb->PathId,\r
828                                    p_srb->TargetId,\r
829                                    p_srb->Lun) );\r
830 \r
831                 if ( srp_format_io_request( p_dev_ext, p_srb ) == FALSE )\r
832                 {\r
833                         SRP_PRINT_EXIT( TRACE_LEVEL_ERROR, SRP_DBG_ERROR,\r
834                                                         ("Returning SrbStatus %s(0x%x) for "\r
835                                                         "Function = %s(0x%x), Path = 0x%x, "\r
836                                                         "Target = 0x%x, Lun = 0x%x\n",\r
837                                                     g_srb_status_name[p_srb->SrbStatus],\r
838                                                         p_srb->SrbStatus,\r
839                                                         g_srb_function_name[p_srb->Function],\r
840                                                         p_srb->Function,\r
841                                                         p_srb->PathId,\r
842                                                         p_srb->TargetId,\r
843                                                         p_srb->Lun) );\r
844 \r
845                         StorPortNotification( RequestComplete, p_dev_ext, p_srb );\r
846 \r
847                         return ( FALSE );\r
848                 }\r
849         }\r
850 \r
851         SRP_EXIT( SRP_DBG_DEBUG );\r
852 \r
853         return ( TRUE );\r
854 }\r