/** * Create reate log handle * * This will update the module's global resource data. * * @param logLevel default log level of the handle * * @return VMK_OK log handle created successfully * @return VMK_BAD_PARAM invalid log level * @return VMK_EXISTS log handle already created */ static VMK_ReturnStatus LogHandleCreate(int logLevel) { VMK_ReturnStatus vmkStatus; vmk_LogProperties props; if (logLevel >= NVME_LOG_LEVEL_LAST) { return VMK_BAD_PARAM; } if (NVME_DRIVER_RES_LOG_HANDLE != VMK_INVALID_LOG_HANDLE) { return VMK_EXISTS; } props.module = vmk_ModuleCurrentID; props.heap = NVME_DRIVER_RES_HEAP_ID; props.defaultLevel = logLevel; props.throttle = NULL; vmk_NameInitialize(&props.name, NVME_DRIVER_PROPS_LOG_NAME); vmkStatus = vmk_LogRegister(&props, &(NVME_DRIVER_RES_LOG_HANDLE)); if (vmkStatus != VMK_OK) { return vmkStatus; } return VMK_OK; }
/** * Create the default heap of the module, and associate heap with the module. * * This will update the module's global resource data. * * @return VMK_OK: heap creation successful * @return VMK_EXISTS: driver's heap has already been created * @return Others: errors returned by vmk_HeapCreate */ static VMK_ReturnStatus HeapCreate() { VMK_ReturnStatus vmkStatus; vmk_HeapCreateProps props; /* Ensures that this function is not called twice. */ VMK_ASSERT(NVME_DRIVER_RES_HEAP_ID == VMK_INVALID_HEAP_ID); if (NVME_DRIVER_RES_HEAP_ID != VMK_INVALID_HEAP_ID) { return VMK_EXISTS; } props.type = VMK_HEAP_TYPE_SIMPLE; props.module = vmk_ModuleCurrentID; props.initial = NVME_DRIVER_PROPS_HEAP_INITIAL; props.max = NVME_DRIVER_PROPS_HEAP_MAX; props.creationTimeoutMS = VMK_TIMEOUT_UNLIMITED_MS; vmk_NameInitialize(&props.name, NVME_DRIVER_PROPS_HEAP_NAME); vmkStatus = vmk_HeapCreate(&props, &(NVME_DRIVER_RES_HEAP_ID)); if (vmkStatus != VMK_OK) { return vmkStatus; } vmk_ModuleSetHeapID(vmk_ModuleCurrentID, NVME_DRIVER_RES_HEAP_ID); return VMK_OK; }
/** * Create memory pool * * This will update the module's global resource data. * * @return VMK_OK log handle created successfully * @return VMK_EXISTS memory pool already created. * @return Others: errors returned by vmk_MemPoolCreate */ static VMK_ReturnStatus MemPoolCreate() { vmk_MemPoolProps props; if (NVME_DRIVER_RES_MEMPOOL != VMK_MEMPOOL_INVALID) { return VMK_EXISTS; } props.module = vmk_ModuleCurrentID; props.parentMemPool = VMK_MEMPOOL_INVALID; props.memPoolType = VMK_MEM_POOL_LEAF; props.resourceProps.reservation = NVME_DRIVER_PROPS_MPOOL_RESV; props.resourceProps.limit = NVME_DRIVER_PROPS_MPOOL_LIMIT; vmk_NameInitialize(&props.name, NVME_DRIVER_PROPS_MPOOL_NAME); return vmk_MemPoolCreate(&props, &(NVME_DRIVER_RES_MEMPOOL)); }
/** * Register driver * * This will update the module's global resource data. * * @return VMK_OK driver registration successful * @return VMK_EXISTS driver already registered */ VMK_ReturnStatus NvmeDriver_Register() { VMK_ReturnStatus vmkStatus; vmk_DriverProps props; DPRINT_TEMP("enter."); VMK_ASSERT(NVME_DRIVER_RES_DRIVER_HANDLE == VMK_DRIVER_NONE); if (NVME_DRIVER_RES_DRIVER_HANDLE != VMK_DRIVER_NONE) { return VMK_EXISTS; } props.moduleID = vmk_ModuleCurrentID; props.ops = &__driverOps; // defined and exported from nvme_driver.c props.privateData.ptr = NULL; vmk_NameInitialize(&props.name, NVME_DRIVER_PROPS_DRIVER_NAME); vmkStatus = vmk_DriverRegister(&props, &(NVME_DRIVER_RES_DRIVER_HANDLE)); return vmkStatus; }
/** * scanDevice callback of driver ops */ static VMK_ReturnStatus ScanDevice(vmk_Device device) { VMK_ReturnStatus vmkStatus; struct NvmeCtrlr *ctrlr; vmk_DeviceProps deviceProps; vmk_DeviceID deviceId; vmk_Name busName; vmk_BusType busType; DPRINT_TEMP("enter."); #if NVME_DEBUG_INJECT_STATE_DELAYS IPRINT("--SCAN STARTED--"); vmk_WorldSleep(NVME_DEBUG_STATE_DELAY_US); #endif vmkStatus = vmk_DeviceGetAttachedDriverData(device, (vmk_AddrCookie *)&ctrlr); if (vmkStatus != VMK_OK) { EPRINT("failed to get controller instance, 0x%x.", vmkStatus); return vmkStatus; } vmkStatus = NvmeScsi_Init(ctrlr); if (vmkStatus != VMK_OK) { EPRINT("failed to initialize scsi layer, 0x%x.", vmkStatus); return vmkStatus; } /* Create the logical device */ vmk_NameInitialize(&busName, VMK_LOGICAL_BUS_NAME); vmk_BusTypeFind(&busName, &busType); vmkStatus = vmk_LogicalCreateBusAddress(NVME_DRIVER_RES_DRIVER_HANDLE, device, 0, &deviceId.busAddress, &deviceId.busAddressLen); if (vmkStatus != VMK_OK) { EPRINT("failed to create logical bus address, 0x%x.", vmkStatus); goto out; } deviceId.busType = busType; deviceId.busIdentifier = VMK_SCSI_PSA_DRIVER_BUS_ID; deviceId.busIdentifierLen = vmk_Strnlen(deviceId.busIdentifier, VMK_MISC_NAME_MAX); deviceProps.registeringDriver = NVME_DRIVER_RES_DRIVER_HANDLE; deviceProps.deviceID = &deviceId; deviceProps.deviceOps = &__deviceOps; deviceProps.registeringDriverData.ptr = ctrlr; deviceProps.registrationData.ptr = ctrlr->ctrlOsResources.scsiAdapter; vmkStatus = vmk_DeviceRegister(&deviceProps, device, &ctrlr->ctrlOsResources.logicalDevice); vmk_LogicalFreeBusAddress(NVME_DRIVER_RES_DRIVER_HANDLE, deviceId.busAddress); vmk_BusTypeRelease(deviceId.busType); if (vmkStatus != VMK_OK) { EPRINT("failed to register logical device, 0x%x.", vmkStatus); goto out; } #if NVME_DEBUG_INJECT_STATE_DELAYS IPRINT("--SCAN COMPLETED--"); vmk_WorldSleep(NVME_DEBUG_STATE_DELAY_US); #endif return VMK_OK; out: NvmeScsi_Destroy(ctrlr); return vmkStatus; }