[IBBUS] added support for creating vendor defined devices.
[mirror/winof/.git] / core / bus / kernel / bus_port_mgr.c
index 3742f71..e04d97f 100644 (file)
 #include "iba/ipoib_ifc.h"\r
 #include "al_dev.h"\r
 \r
-#define IPOIB_PART_DEVICE_ID   L"IBA\\IPoIBP"\r
-#define IPOIB_DEVICE_ID                        L"IBA\\IPoIB"\r
-#define IPOIB_COMPAT_ID                        L"IBA\\SID_1000066a00020000\0\0"\r
-/* Hardware ID is a MULTI_SZ, so is terminated with a double NULL. */\r
-#define IPOIB_HARDWARE_ID              IPOIB_DEVICE_ID L"\0"\r
-#define IPOIB_PART_HARDWARE_ID IPOIB_PART_DEVICE_ID L"\0"\r
-#define IPOIB_DESCRIPTION              L"OpenIB IPoIB Adapter"\r
-\r
 /* {5A9649F4-0101-4a7c-8337-796C48082DA2} */\r
 DEFINE_GUID(GUID_BUS_TYPE_IBA,\r
 0x5a9649f4, 0x101, 0x4a7c, 0x83, 0x37, 0x79, 0x6c, 0x48, 0x8, 0x2d, 0xa2);\r
@@ -176,6 +168,7 @@ port_query_description(
        IN                              DEVICE_OBJECT* const            p_dev_obj,\r
        IN                              IRP* const                                      p_irp );\r
 \r
+\r
 static NTSTATUS\r
 port_query_location(\r
        IN                              DEVICE_OBJECT* const            p_dev_obj,\r
@@ -234,7 +227,7 @@ port_set_power(
  * instances of Port PDOs.\r
  */\r
 static const cl_vfptr_pnp_po_t         vfptr_port_pnp = {\r
-       "IPoIB",\r
+       "IODEVICE",\r
        port_start,\r
        cl_irp_succeed,\r
        cl_irp_succeed,\r
@@ -278,6 +271,7 @@ static const cl_vfptr_query_txt_t           vfptr_port_query_txt = {
 };\r
 \r
 \r
+\r
 /*\r
  * Create the AL load service.\r
  */\r
@@ -439,7 +433,7 @@ free_port_mgr(
                                p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
                        continue;\r
                }\r
-               if( p_ext->h_ca && (!p_ext->is_partition_pdo))\r
+               if( p_ext->h_ca && p_ext->hca_acquired )\r
                {\r
                        /* Invalidate bus relations for the HCA. */\r
                        IoInvalidateDeviceRelations(\r
@@ -769,15 +763,16 @@ port_mgr_port_add(
        IN                              ib_pnp_port_rec_t*                      p_pnp_rec )\r
 {\r
        NTSTATUS                status;\r
-    DEVICE_OBJECT   *p_pdo[MAX_NUM_PKEY + 1];\r
-    uint8_t         num_pdo;\r
+       DEVICE_OBJECT   *p_pdo; \r
        bus_port_ext_t  *p_port_ext;\r
-       ib_net16_t      pdo_cnt;\r
-       pkey_conf_t             *cur_conf; \r
-       pkey_array_t    *cur_pkeys = NULL;\r
        bus_filter_t    *p_bfi;\r
        port_mgr_t              *p_port_mgr;\r
        port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;\r
+       child_device_info_list_t *pCurList;\r
+       ib_ca_handle_t  h_ca = NULL;\r
+       ULONG                   pKey;\r
+       UNICODE_STRING  uniKey;\r
+\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
@@ -812,6 +807,7 @@ port_mgr_port_add(
                                        p_bfi->whoami, p_bfi->ca_guid, \r
                                        p_pnp_rec->p_port_attr->port_num,p_ctx));\r
        }\r
+\r
        p_port_mgr = p_bfi->p_port_mgr;\r
 \r
        if( !bus_globals.b_report_port_nic )\r
@@ -831,32 +827,17 @@ port_mgr_port_add(
                return status;\r
        }\r
 \r
-       cur_conf = bus_globals.p_pkey_conf;\r
-       while(cur_conf)\r
-       {\r
-               if(p_pnp_rec->p_port_attr->port_guid == cur_conf->pkeys_per_port.port_guid)\r
-               {\r
-                       cur_pkeys = &cur_conf->pkeys_per_port;\r
-                       break;\r
-               }\r
-               cur_conf = cur_conf->next_conf;\r
-       }\r
-    p_port_ext = NULL;\r
-\r
-       if( !cur_pkeys)\r
-               pdo_cnt = 1;\r
-       else\r
-               pdo_cnt = cur_conf->pkeys_per_port.pkey_num + 1;\r
+       pCurList = bus_globals.p_device_list;\r
 \r
-    for (num_pdo = 0; num_pdo < pdo_cnt; num_pdo++)\r
-    {\r
+       while(pCurList)\r
+       {\r
                /* Create the PDO for the new port device. */\r
                status = IoCreateDevice( bus_globals.p_driver_obj,\r
                                                                 sizeof(bus_port_ext_t),\r
                                                                 NULL, FILE_DEVICE_CONTROLLER,\r
                                                                 FILE_DEVICE_SECURE_OPEN |\r
-                                                                                       FILE_AUTOGENERATED_DEVICE_NAME,\r
-                                                                FALSE, &p_pdo[num_pdo] );\r
+                                                                FILE_AUTOGENERATED_DEVICE_NAME,\r
+                                                                FALSE, &p_pdo );\r
                if( !NT_SUCCESS( status ) )\r
                {\r
                        BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
@@ -865,16 +846,16 @@ port_mgr_port_add(
                }\r
 \r
                /* clean the extension (must be before initializing) */\r
-               p_port_ext = p_pdo[num_pdo]->DeviceExtension;\r
+               p_port_ext = p_pdo->DeviceExtension;\r
                memset( p_port_ext, 0, sizeof(bus_port_ext_t) );\r
 \r
                /* Initialize the device extension. */\r
-               cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo],\r
+               cl_init_pnp_po_ext( p_pdo, NULL, p_pdo,\r
                                                        bus_globals.dbg_lvl, &vfptr_port_pnp,\r
                                                        &vfptr_port_query_txt );\r
 \r
                /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
-               p_pdo[num_pdo]->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
+               p_pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
 \r
                p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
                p_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
@@ -882,39 +863,46 @@ port_mgr_port_add(
                p_port_ext->pdo.b_reported_missing = FALSE;\r
                p_port_ext->pdo.b_hibernating = FALSE;\r
                p_port_ext->pdo.p_po_work_item = NULL;\r
+               p_port_ext->pdo.p_pdo_device_info = &pCurList->io_device_info;\r
                BUS_TRACE( BUS_DBG_PNP,\r
                        ("Created %s %s: PDO %p,ext %p, present %d, missing %d .\n",\r
                        p_bfi->whoami,\r
-                       p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo],\r
+                       p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo,\r
                        p_port_ext, p_port_ext->pdo.b_present,\r
                        p_port_ext->pdo.b_reported_missing ) );\r
 \r
                /* Cache the CA GUID. */\r
                p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid;\r
 \r
-               /* Take a reference on the parent HCA. */\r
-               if(num_pdo > 0)\r
+               /*Only acquire one hca for each port*/\r
+               if(h_ca)\r
                {\r
-                       p_port_ext->pdo.h_ca = ((bus_port_ext_t*)p_pdo[0]->DeviceExtension)->pdo.h_ca;\r
-                       p_port_ext->pdo.is_partition_pdo = TRUE;\r
+                       p_port_ext->pdo.h_ca = h_ca;\r
+                       p_port_ext->pdo.hca_acquired = FALSE;\r
+               }else\r
+               {\r
+                       /* Acquire CA for the first child pdo*/\r
+                       h_ca = p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
+                       p_port_ext->pdo.hca_acquired = TRUE;\r
                }\r
-               else\r
-                       p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
 \r
                if( !p_port_ext->pdo.h_ca )\r
                {\r
-                       BUS_TRACE( BUS_DBG_PNP, ("Deleted device: PDO %p\n", p_pdo[num_pdo]));\r
-                       IoDeleteDevice( p_pdo[num_pdo]);\r
+                       BUS_TRACE( BUS_DBG_PNP, ("Deleted device: PDO %p\n", p_pdo));\r
+                       IoDeleteDevice( p_pdo);\r
                        BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") );\r
                        return IB_INVALID_GUID;\r
                }\r
+\r
                p_port_ext->port_guid.guid = p_pnp_rec->p_port_attr->port_guid;\r
                p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num;\r
-               p_port_ext->port_guid.pkey = IB_DEFAULT_PKEY;\r
+\r
+               RtlInitUnicodeString(&uniKey, pCurList->io_device_info.pkey);\r
+               RtlUnicodeStringToInteger(&uniKey,16,&pKey);\r
+               p_port_ext->port_guid.pkey = (ib_net16_t)pKey;\r
+\r
                p_port_ext->n_ifc_ref = 0;\r
 \r
-               if(num_pdo > 0)\r
-                       p_port_ext->port_guid.pkey = cur_pkeys->pkey_array[num_pdo -1];\r
 \r
                /* Store the device extension in the port vector for future queries. */\r
                cl_mutex_acquire( &p_port_mgr->pdo_mutex );\r
@@ -926,13 +914,17 @@ port_mgr_port_add(
                 * Set the context of the PNP event. The context is passed in for future\r
                 * events on the same port.\r
                 */\r
-               if(num_pdo == 0) \r
+               if(p_port_ext->pdo.hca_acquired)\r
+               {\r
                        p_ctx->p_pdo_ext = p_port_ext;\r
-       }\r
+               }\r
 \r
-       /* Tell the PnP Manager to rescan for the HCA's bus relations. */\r
-       IoInvalidateDeviceRelations(\r
-               p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
+               pCurList = pCurList->next_device_info;\r
+\r
+               /* Tell the PnP Manager to rescan for the HCA's bus relations. */\r
+               IoInvalidateDeviceRelations(\r
+                       p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
+       }\r
 \r
        /* Invalidate removal relations for the bus driver. */\r
        IoInvalidateDeviceRelations(\r
@@ -942,6 +934,8 @@ port_mgr_port_add(
        return IB_SUCCESS;\r
 }\r
 \r
+\r
+\r
 /************************************************************************************\r
 * name :       port_mgr_pkey_rem\r
 *           removes pdo for each pkey value in pkey_array \r
@@ -1120,7 +1114,6 @@ cl_status_t _port_mgr_pkey_add( IN        pkey_array_t    *req_pkeys,
                pkey_port_ext->port_guid.guid = pmatched_guid_ext->port_guid.guid;\r
                pkey_port_ext->n_port = pmatched_guid_ext->n_port;\r
                pkey_port_ext->port_guid.pkey = req_pkeys->pkey_array[cnt];\r
-               pkey_port_ext->pdo.is_partition_pdo = TRUE;\r
                /* Store the device extension in the port vector for future queries. */\r
                cl_mutex_acquire( &p_port_mgr->pdo_mutex );\r
                cl_qlist_insert_tail( &p_port_mgr->port_list,\r
@@ -1564,11 +1557,10 @@ port_query_device_id(
                BUS_TRACE_EXIT( BUS_DBG_ERROR, ("Device not present.\n") );\r
                return STATUS_NO_SUCH_DEVICE;\r
        }\r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               dev_id_size = sizeof(IPOIB_DEVICE_ID);\r
-       else\r
-               dev_id_size = sizeof(IPOIB_PART_DEVICE_ID );\r
-       /* Device ID is "IBA\SID_<sid> where <sid> is the IPoIB Service ID. */\r
+\r
+       dev_id_size = p_ext->pdo.p_pdo_device_info->device_id_size;\r
+\r
+       /* Device ID is "IBA\SID_<sid> where <sid> is the IO device Service ID. */\r
        p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'vedq' );\r
        if( !p_string )\r
        {\r
@@ -1578,10 +1570,10 @@ port_query_device_id(
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
 \r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               cl_memcpy( p_string, IPOIB_DEVICE_ID, sizeof(IPOIB_DEVICE_ID) );\r
-       else\r
-               cl_memcpy( p_string, IPOIB_PART_DEVICE_ID, sizeof(IPOIB_PART_DEVICE_ID) );\r
+       RtlZeroMemory(p_string, dev_id_size);\r
+\r
+       cl_memcpy( p_string, p_ext->pdo.p_pdo_device_info->device_id, dev_id_size );\r
+\r
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -1603,10 +1595,7 @@ port_query_hardware_ids(
 \r
        p_ext = (bus_port_ext_t*)p_dev_obj->DeviceExtension;\r
 \r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               dev_id_size = sizeof(IPOIB_HARDWARE_ID);\r
-       else\r
-               dev_id_size = sizeof(IPOIB_PART_HARDWARE_ID );\r
+       dev_id_size = p_ext->pdo.p_pdo_device_info->hardware_id_size;\r
 \r
        p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'ihqp' );\r
        if( !p_string )\r
@@ -1616,10 +1605,11 @@ port_query_hardware_ids(
                        dev_id_size) );\r
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               cl_memcpy( p_string, IPOIB_HARDWARE_ID, sizeof(IPOIB_HARDWARE_ID) );\r
-       else\r
-               cl_memcpy( p_string, IPOIB_PART_HARDWARE_ID, sizeof(IPOIB_PART_HARDWARE_ID) );\r
+\r
+       RtlZeroMemory(p_string, dev_id_size);\r
+\r
+       cl_memcpy( p_string, p_ext->pdo.p_pdo_device_info->hardware_id, dev_id_size );\r
+\r
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -1633,20 +1623,28 @@ port_query_compatible_ids(
                OUT                             IRP* const                              p_irp )\r
 {\r
        WCHAR                           *p_string;\r
+       bus_port_ext_t          *p_ext;\r
+       size_t                          dev_id_size;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       UNUSED_PARAM( p_dev_obj );\r
+       p_ext = (bus_port_ext_t*)p_dev_obj->DeviceExtension;\r
+\r
+       dev_id_size = p_ext->pdo.p_pdo_device_info->compatible_id_size;\r
 \r
-       p_string = ExAllocatePoolWithTag( PagedPool, sizeof(IPOIB_COMPAT_ID), 'icqp' );\r
+       p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'ihqp' );\r
        if( !p_string )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
-                       ("Failed to allocate compatible ID buffer (%d bytes).\n",\r
-                       sizeof(IPOIB_COMPAT_ID)) );\r
+                       ("Failed to allocate hardware ID buffer (%d bytes).\n",\r
+                       dev_id_size) );\r
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
-       cl_memcpy( p_string, IPOIB_COMPAT_ID, sizeof(IPOIB_COMPAT_ID) );\r
+\r
+       RtlZeroMemory(p_string, dev_id_size);\r
+\r
+       cl_memcpy( p_string, p_ext->pdo.p_pdo_device_info->compatible_id, dev_id_size );\r
+\r
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -1718,16 +1716,20 @@ port_query_description(
        }\r
 \r
 \r
-       /* The instance ID is the port GUID. */\r
-       p_string = ExAllocatePoolWithTag( PagedPool, sizeof(IPOIB_DESCRIPTION), 'edqp' );\r
+       p_string = ExAllocatePoolWithTag( PagedPool, p_ext->pdo.p_pdo_device_info->description_size, 'edqp' );\r
+\r
        if( !p_string )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
                        ("Failed to allocate device description buffer (%d bytes).\n",\r
-                       sizeof(IPOIB_DESCRIPTION)) );\r
+                       p_ext->pdo.p_pdo_device_info->description_size) );\r
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
-       cl_memcpy( p_string, IPOIB_DESCRIPTION, sizeof(IPOIB_DESCRIPTION) );\r
+\r
+       RtlZeroMemory(p_string,p_ext->pdo.p_pdo_device_info->description_size);\r
+\r
+       cl_memcpy( p_string, p_ext->pdo.p_pdo_device_info->description, p_ext->pdo.p_pdo_device_info->description_size );\r
+\r
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -2101,3 +2103,6 @@ port_set_power(
        BUS_EXIT( BUS_DBG_POWER );\r
        return status;\r
 }\r
+\r
+\r
+\r