[IBBUS] added support for creating vendor defined devices.
[mirror/winof/.git] / core / bus / kernel / bus_driver.c
index 63599f4..9004c1c 100644 (file)
@@ -66,6 +66,7 @@ bus_globals_t bus_globals = {
        TRUE,\r
        NULL,\r
        NULL,\r
+       NULL,\r
        NULL\r
 };\r
 \r
@@ -210,7 +211,7 @@ static void __prepare_pKey_array(IN const char *str, size_t str_len,OUT pkey_arr
        j = 0;\r
 \r
        for (i = 0; (i < str_len) && (cur_pkey->pkey_num < MAX_NUM_PKEY) ; i++)\r
-    {\r
+       {\r
                if(str[i] == ' ')\r
                        continue;\r
 \r
@@ -242,6 +243,257 @@ static void __prepare_pKey_array(IN const char *str, size_t str_len,OUT pkey_arr
        BUS_EXIT( BUS_DBG_DRV );\r
 }\r
 \r
+\r
+static void    _free_static_iodevices()\r
+{\r
+       child_device_info_list_t *pDevList, *pDevList1;\r
+\r
+       pDevList = bus_globals.p_device_list;\r
+\r
+       while(pDevList)\r
+       {\r
+               pDevList1 = pDevList->next_device_info;\r
+               cl_free(pDevList);\r
+               pDevList = pDevList1;\r
+       }\r
+\r
+}\r
+\r
+\r
+NTSTATUS _Create_Static_Devices(PUNICODE_STRING p_param_path)\r
+{\r
+       RTL_QUERY_REGISTRY_TABLE        table[2];\r
+       UNICODE_STRING                          keyPath;\r
+       UNICODE_STRING                          keyValue;\r
+       UNICODE_STRING                          defaultKeyValue;\r
+       UNICODE_STRING                          child_name;\r
+       WCHAR                                           *key_path_buffer;\r
+       WCHAR                                           *key_value_buffer;\r
+       WCHAR                                           *static_child_name;\r
+       NTSTATUS                                        status;\r
+       #define BUF_SIZE                        256             /* use hard-coded size to make it simple*/\r
+\r
+       cl_memclr( table, sizeof(table) );\r
+\r
+       \r
+       key_path_buffer = cl_zalloc(BUF_SIZE*sizeof(WCHAR)*3);\r
+\r
+       if(!key_path_buffer)\r
+       {\r
+               BUS_TRACE(BUS_DBG_ERROR ,("Not enough memory for key_path_buffer.\n") );\r
+               status = STATUS_UNSUCCESSFUL;\r
+               goto _Create_Static_Devices_exit;\r
+       }\r
+\r
+       key_value_buffer = key_path_buffer + BUF_SIZE;\r
+       static_child_name = key_value_buffer + BUF_SIZE;\r
+\r
+       RtlInitUnicodeString( &keyPath, NULL );\r
+       keyPath.MaximumLength = BUF_SIZE*sizeof(WCHAR);\r
+       keyPath.Buffer = key_path_buffer;\r
+\r
+       RtlInitUnicodeString( &keyValue, NULL );\r
+       keyValue.MaximumLength = BUF_SIZE*sizeof(WCHAR);\r
+       keyValue.Buffer = key_value_buffer;\r
+\r
+       RtlInitUnicodeString( &child_name, NULL );\r
+       child_name.MaximumLength = BUF_SIZE*sizeof(WCHAR);\r
+       child_name.Buffer = static_child_name;\r
+\r
+\r
+       RtlCopyUnicodeString( &keyPath, p_param_path );\r
+\r
+       RtlInitUnicodeString(&defaultKeyValue, L"IPoIB\0\0");\r
+\r
+       /* Setup the table entries. */\r
+       table[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND;\r
+       table[0].Name = L"StaticChild";\r
+       table[0].EntryContext = &child_name;\r
+       table[0].DefaultType = REG_MULTI_SZ;\r
+       table[0].DefaultData = defaultKeyValue.Buffer;\r
+       table[0].DefaultLength = defaultKeyValue.Length;\r
+\r
+       status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
+               keyPath.Buffer, table, NULL, NULL );\r
+\r
+       if(NT_SUCCESS(status))\r
+       {\r
+               WCHAR *curChild;\r
+               child_device_info_list_t *pPrevList, *pNewDevList;\r
+\r
+               curChild = static_child_name;\r
+               pPrevList = bus_globals.p_device_list;\r
+               while(*curChild)\r
+               {\r
+                       RtlCopyUnicodeString(&keyPath, p_param_path);\r
+                       RtlAppendUnicodeToString(&keyPath, L"\\");\r
+                       RtlAppendUnicodeToString(&keyPath, curChild);\r
+\r
+                       pNewDevList = cl_zalloc(sizeof(child_device_info_list_t));\r
+                       if(!pNewDevList)\r
+                       {\r
+                               BUS_TRACE(BUS_DBG_ERROR ,("Not enough memory for key_path_buffer.\n") );\r
+                               status = STATUS_UNSUCCESSFUL;\r
+                               goto _Create_Static_Devices_exit;\r
+                       }\r
+                       pNewDevList->next_device_info = NULL;\r
+\r
+                       if(pPrevList == NULL)\r
+                       {\r
+                               bus_globals.p_device_list = pNewDevList;\r
+                       }else\r
+                       {\r
+                               pPrevList->next_device_info = pNewDevList;\r
+                       }\r
+\r
+                       pPrevList = pNewDevList;\r
+\r
+                       /* get DeviceId*/\r
+                       RtlInitUnicodeString(&defaultKeyValue, L"IBA\\IPoIB\0");\r
+                       RtlInitUnicodeString( &keyValue, NULL );\r
+                       keyValue.MaximumLength = sizeof(pNewDevList->io_device_info.device_id);\r
+                       keyValue.Buffer = pNewDevList->io_device_info.device_id;\r
+\r
+                       /* Setup the table entries. */\r
+                       table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+                       table[0].Name = L"DeviceId";\r
+                       table[0].EntryContext = &keyValue; \r
+                       table[0].DefaultType = REG_SZ;\r
+                       table[0].DefaultData = defaultKeyValue.Buffer;\r
+                       table[0].DefaultLength = defaultKeyValue.Length;\r
+\r
+                       status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
+                               keyPath.Buffer, table, NULL, NULL );\r
+                       if(!NT_SUCCESS(status))\r
+                       {\r
+                               BUS_TRACE(BUS_DBG_ERROR ,("Failed to read DeviceId.\n") );\r
+                               goto _Create_Static_Devices_exit;\r
+                       }\r
+                       pNewDevList->io_device_info.device_id_size = keyValue.Length + sizeof(WCHAR);\r
+\r
+                       /* Get HardwareId*/\r
+                       RtlInitUnicodeString(&defaultKeyValue, L"IBA\\IPoIB\0\0");\r
+                       RtlInitUnicodeString( &keyValue, NULL );\r
+                       keyValue.MaximumLength = sizeof(pNewDevList->io_device_info.hardware_id);\r
+                       keyValue.Buffer = pNewDevList->io_device_info.hardware_id;\r
+\r
+                       /* Setup the table entries. */\r
+                       table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+                       table[0].Name = L"HardwareId";\r
+                       table[0].EntryContext = &keyValue; \r
+                       table[0].DefaultType = REG_MULTI_SZ;\r
+                       table[0].DefaultData = defaultKeyValue.Buffer;\r
+                       table[0].DefaultLength = defaultKeyValue.Length;\r
+\r
+                       status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
+                               keyPath.Buffer, table, NULL, NULL );\r
+                       if(!NT_SUCCESS(status))\r
+                       {\r
+                               BUS_TRACE(BUS_DBG_ERROR ,("Failed to read HardwareId.\n") );\r
+                               goto _Create_Static_Devices_exit;\r
+                       }\r
+                       pNewDevList->io_device_info.hardware_id_size = keyValue.Length + 2*sizeof(WCHAR);\r
+\r
+                       /* Get CompatibleId*/\r
+                       RtlInitUnicodeString(&defaultKeyValue, L"IBA\\SID_1000066a00020000\0\0");\r
+                       RtlInitUnicodeString( &keyValue, NULL );\r
+                       keyValue.MaximumLength = sizeof(pNewDevList->io_device_info.compatible_id);\r
+                       keyValue.Buffer = pNewDevList->io_device_info.compatible_id;\r
+\r
+                       /* Setup the table entries. */\r
+                       table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+                       table[0].Name = L"CompatibleId";\r
+                       table[0].EntryContext = &keyValue; \r
+                       table[0].DefaultType = REG_MULTI_SZ;\r
+                       table[0].DefaultData = defaultKeyValue.Buffer;\r
+                       table[0].DefaultLength = defaultKeyValue.Length;\r
+\r
+                       status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
+                               keyPath.Buffer, table, NULL, NULL );\r
+                       if(!NT_SUCCESS(status))\r
+                       {\r
+                               BUS_TRACE(BUS_DBG_ERROR ,("Failed to read CompatibleId.\n") );\r
+                               goto _Create_Static_Devices_exit;\r
+                       }\r
+                       pNewDevList->io_device_info.compatible_id_size = keyValue.Length + 2*sizeof(WCHAR); //2 null\r
+\r
+                       /* Get Description*/\r
+                       RtlInitUnicodeString(&defaultKeyValue, L"OpenIB IPoIB Adapter");\r
+                       RtlInitUnicodeString( &keyValue, NULL );\r
+                       keyValue.MaximumLength = sizeof(pNewDevList->io_device_info.description);\r
+                       keyValue.Buffer = pNewDevList->io_device_info.description;\r
+\r
+                       /* Setup the table entries. */\r
+                       table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+                       table[0].Name = L"Description";\r
+                       table[0].EntryContext = &keyValue; \r
+                       table[0].DefaultType = REG_SZ;\r
+                       table[0].DefaultData = defaultKeyValue.Buffer;\r
+                       table[0].DefaultLength = defaultKeyValue.Length;\r
+\r
+                       status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
+                               keyPath.Buffer, table, NULL, NULL );\r
+                       if(!NT_SUCCESS(status))\r
+                       {\r
+                               BUS_TRACE(BUS_DBG_ERROR ,("Failed to read Description.\n") );\r
+                               goto _Create_Static_Devices_exit;\r
+                       }\r
+\r
+                       pNewDevList->io_device_info.description_size = keyValue.Length + sizeof(WCHAR);\r
+\r
+\r
+                       if((pNewDevList->io_device_info.description_size > MAX_DEVICE_ID_LEN) ||\r
+                          (pNewDevList->io_device_info.hardware_id_size > MAX_DEVICE_ID_LEN) ||\r
+                          (pNewDevList->io_device_info.compatible_id_size > MAX_DEVICE_ID_LEN) ||\r
+                          (pNewDevList->io_device_info.device_id_size > MAX_DEVICE_ID_LEN)\r
+                          )\r
+                       {\r
+                               BUS_TRACE(BUS_DBG_ERROR ,("Id or description size is too big.\n") );\r
+                               status = STATUS_UNSUCCESSFUL;\r
+                               goto _Create_Static_Devices_exit;\r
+                       }\r
+\r
+                       /* Get Pkey */\r
+                       RtlInitUnicodeString(&defaultKeyValue, L"FFFF");\r
+                       RtlInitUnicodeString( &keyValue, NULL );\r
+                       keyValue.MaximumLength = sizeof(pNewDevList->io_device_info.pkey);\r
+                       keyValue.Buffer = pNewDevList->io_device_info.pkey;\r
+\r
+                       /* Setup the table entries. */\r
+                       table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+                       table[0].Name = L"PartitionKey";\r
+                       table[0].EntryContext = &keyValue; \r
+                       table[0].DefaultType = REG_SZ;\r
+                       table[0].DefaultData = defaultKeyValue.Buffer;\r
+                       table[0].DefaultLength = defaultKeyValue.Length;\r
+\r
+                       status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
+                               keyPath.Buffer, table, NULL, NULL );\r
+                       if(!NT_SUCCESS(status))\r
+                       {\r
+                               BUS_TRACE(BUS_DBG_ERROR ,("Failed to read PartitionKey.\n") );\r
+                               goto _Create_Static_Devices_exit;\r
+                       }\r
+\r
+                       while(*curChild) curChild++;\r
+                       curChild++;\r
+               }\r
+       }\r
+\r
+_Create_Static_Devices_exit:\r
+       if(key_path_buffer)\r
+       {\r
+               cl_free(key_path_buffer);\r
+       }\r
+\r
+       if(!NT_SUCCESS(status))\r
+       {\r
+               _free_static_iodevices();\r
+       }\r
+\r
+       return status;\r
+}\r
+\r
 static pkey_conf_t*\r
 create_pkey_conf(pkey_conf_t **pp_cur_conf, char *guid_str, uint32_t guid_str_len)\r
 {\r
@@ -485,6 +737,11 @@ __read_registry(
                        if( !NT_SUCCESS(__build_pkeys_per_port(&pkeyString)))\r
                                BUS_TRACE(BUS_DBG_ERROR ,\r
                                                 ("Failed to build pkey configuration\n"));\r
+\r
+                       if(!NT_SUCCESS(_Create_Static_Devices(&param_path))){\r
+                               BUS_TRACE(BUS_DBG_ERROR ,\r
+                                                ("Failed to create devices\n"));\r
+                       }\r
        }\r
 #if DBG\r
        if( g_al_dbg_flags & AL_DBG_ERR )\r
@@ -639,7 +896,7 @@ bus_add_pkey(cl_ioctl_handle_t                      h_ioctl)
        pIoStack = IoGetCurrentIrpStackLocation(h_ioctl);\r
        if ( (! h_ioctl->AssociatedIrp.SystemBuffer) || \r
                 pIoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof (pkey_array_t))\r
-    {\r
+       {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
                        ("Invalid parameters.\n") );\r
                return CL_INVALID_PARAMETER;\r
@@ -671,7 +928,7 @@ bus_rem_pkey(cl_ioctl_handle_t                      h_ioctl)
        pIoStack = IoGetCurrentIrpStackLocation(h_ioctl);\r
        if ( (! h_ioctl->AssociatedIrp.SystemBuffer) || \r
                 pIoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof (pkey_array_t))\r
-    {\r
+       {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
                        ("Invalid parameters.\n") );\r
                return CL_INVALID_PARAMETER;\r
@@ -740,6 +997,10 @@ bus_drv_unload(
                cur_conf = cur_conf->next_conf;\r
                cl_free(tmp);\r
        }\r
+\r
+       _free_static_iodevices();\r
+\r
+\r
        CL_DEINIT;\r
 \r
 #if defined(EVENT_TRACING)\r