static int hpt_delete_array(_VBUS_ARG DEVICEID id, DWORD options) { PVDevice pArray = ID_TO_VDEV(id); BOOLEAN del_block0 = (options & DAF_KEEP_DATA_IF_POSSIBLE)?0:1; int i; PVDevice pa; if ((id==0) || check_VDevice_valid(pArray)) return -1; if(!mIsArray(pArray)) return -1; if (pArray->u.array.rf_rebuilding || pArray->u.array.rf_verifying || pArray->u.array.rf_initializing) return -1; for(i=0; i<pArray->u.array.bArnMember; i++) { pa = pArray->u.array.pMember[i]; if (pa && mIsArray(pa)) { if (pa->u.array.rf_rebuilding || pa->u.array.rf_verifying || pa->u.array.rf_initializing) return -1; } } if (pArray->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;} fDeleteArray(_VBUS_P pArray, del_block0); return 0; }
/* * flush a vdev (without retry). */ static int hpt_flush_vdev(PVBUS_EXT vbus_ext, PVDEV vd) { PCOMMAND pCmd; int result = 0, done; HPT_UINT count; KdPrint(("flusing dev %p", vd)); hpt_lock_vbus(vbus_ext); if (mIsArray(vd->type) && vd->u.array.transform) count = MAX(vd->u.array.transform->source->cmds_per_request, vd->u.array.transform->target->cmds_per_request); else count = vd->cmds_per_request; pCmd = ldm_alloc_cmds(vd->vbus, count); if (!pCmd) { hpt_unlock_vbus(vbus_ext); return -1; } pCmd->type = CMD_TYPE_FLUSH; pCmd->flags.hard_flush = 1; pCmd->target = vd; pCmd->done = hpt_flush_done; done = 0; pCmd->priv = &done; ldm_queue_cmd(pCmd); if (!done) { while (hpt_sleep(vbus_ext, pCmd, PPAUSE, "hptfls", HPT_OSM_TIMEOUT)) { ldm_reset_vbus(vd->vbus); } } KdPrint(("flush result %d", pCmd->Result)); if (pCmd->Result!=RETURN_SUCCESS) result = -1; ldm_free_cmds(pCmd); hpt_unlock_vbus(vbus_ext); return result; }
static void hpt_flush_done(PCOMMAND pCmd) { PVDEV vd = pCmd->target; if (mIsArray(vd->type) && vd->u.array.transform && vd!=vd->u.array.transform->target) { vd = vd->u.array.transform->target; HPT_ASSERT(vd); pCmd->target = vd; pCmd->Result = RETURN_PENDING; vdev_queue_cmd(pCmd); return; } *(int *)pCmd->priv = 1; wakeup(pCmd); }
static int hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length) { int orig_length = length+4; PVBus _vbus_p = &pAdapter->VBus; PVDevice pArray; PVDevice pSubArray, pVDev; UINT i, iarray, ichan; struct cam_periph *periph = NULL; intrmask_t oldspl; #ifdef SUPPORT_ARRAY if (length>=8 && strncmp(buffer, "rebuild ", 8)==0) { buffer+=8; length-=8; if (length>=5 && strncmp(buffer, "start", 5)==0) { oldspl = lock_driver(); for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) if ((pArray=ArrayTables(i))->u.array.dArStamp==0) continue; else{ if (pArray->u.array.rf_need_rebuild && !pArray->u.array.rf_rebuilding) hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, (UCHAR)((pArray->u.array.CriticalMembers || pArray->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY)); } unlock_driver(oldspl); return orig_length; } else if (length>=4 && strncmp(buffer, "stop", 4)==0) { oldspl = lock_driver(); for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) if ((pArray=ArrayTables(i))->u.array.dArStamp==0) continue; else{ if (pArray->u.array.rf_rebuilding) pArray->u.array.rf_abort_rebuild = 1; } unlock_driver(oldspl); return orig_length; } else if (length>=3 && buffer[1]==','&& buffer[0]>='1'&& buffer[2]>='1') { iarray = buffer[0]-'1'; ichan = buffer[2]-'1'; if(iarray >= MAX_VDEVICE_PER_VBUS || ichan >= MV_SATA_CHANNELS_NUM) return -EINVAL; pArray = _vbus_p->pVDevice[iarray]; if (!pArray || (pArray->vf_online == 0)) return -EINVAL; for (i=0;i<MV_SATA_CHANNELS_NUM;i++) if(i == ichan) goto rebuild; return -EINVAL; rebuild: pVDev = &pAdapter->VDevices[ichan]; if(!pVDev->u.disk.df_on_line || pVDev->pParent) return -EINVAL; /* Not allow to use a mounted disk ??? test*/ for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) if(pVDev == _vbus_p->pVDevice[i]) { periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId,i); if (periph != NULL && periph->refcount >= 1) { hpt_printk(("Can not use disk used by OS!\n")); return -EINVAL; } /* the Mounted Disk isn't delete */ } switch(pArray->VDeviceType) { case VD_RAID_1: case VD_RAID_5: { pSubArray = pArray; loop: oldspl = lock_driver(); if(hpt_add_disk_to_array(_VBUS_P VDEV_TO_ID(pSubArray), VDEV_TO_ID(pVDev)) == -1) { unlock_driver(oldspl); return -EINVAL; } pSubArray->u.array.rf_auto_rebuild = 0; pSubArray->u.array.rf_abort_rebuild = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pSubArray, DUPLICATE); unlock_driver(oldspl); break; } case VD_RAID_0: for (i = 0; (UCHAR)i < pArray->u.array.bArnMember; i++) if(pArray->u.array.pMember[i] && mIsArray(pArray->u.array.pMember[i]) && (pArray->u.array.pMember[i]->u.array.rf_broken == 1)) { pSubArray = pArray->u.array.pMember[i]; goto loop; } default: return -EINVAL; } return orig_length; } } else if (length>=7 && strncmp(buffer, "verify ", 7)==0) { buffer+=7; length-=7; if (length>=6 && strncmp(buffer, "start ", 6)==0) { buffer+=6; length-=6; if (length>=1 && *buffer>='1') { iarray = *buffer-'1'; if(iarray >= MAX_VDEVICE_PER_VBUS) return -EINVAL; pArray = _vbus_p->pVDevice[iarray]; if (!pArray || (pArray->vf_online == 0)) return -EINVAL; if(pArray->VDeviceType != VD_RAID_1 && pArray->VDeviceType != VD_RAID_5) return -EINVAL; if (!(pArray->u.array.rf_need_rebuild || pArray->u.array.rf_rebuilding || pArray->u.array.rf_verifying || pArray->u.array.rf_initializing)) { oldspl = lock_driver(); pArray->u.array.RebuildSectors = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, VERIFY); unlock_driver(oldspl); } return orig_length; } } else if (length>=5 && strncmp(buffer, "stop ", 5)==0) { buffer+=5; length-=5; if (length>=1 && *buffer>='1') { iarray = *buffer-'1'; if(iarray >= MAX_VDEVICE_PER_VBUS) return -EINVAL; pArray = _vbus_p->pVDevice[iarray]; if (!pArray || (pArray->vf_online == 0)) return -EINVAL; if(pArray->u.array.rf_verifying) { oldspl = lock_driver(); pArray->u.array.rf_abort_rebuild = 1; unlock_driver(oldspl); } return orig_length; } } } else #ifdef _RAID5N_ if (length>=10 && strncmp(buffer, "writeback ", 10)==0) { buffer+=10; length-=10; if (length>=1 && *buffer>='0' && *buffer<='1') { _vbus_(r5.enable_write_back) = *buffer-'0'; if (_vbus_(r5.enable_write_back)) hpt_printk(("RAID5 write back enabled")); return orig_length; } } else #endif #endif if (0) {} /* just to compile */ #ifdef DEBUG else if (length>=9 && strncmp(buffer, "dbglevel ", 9)==0) { buffer+=9; length-=9; if (length>=1 && *buffer>='0' && *buffer<='3') { hpt_dbg_level = *buffer-'0'; return orig_length; } } else if (length>=8 && strncmp(buffer, "disable ", 8)==0) { /* TO DO */ } #endif return -EINVAL; }
static void hpt_copy_array_info(HPT_GET_INFO *pinfo, int nld, PVDevice pArray) { int i; char *sType=0, *sStatus=0; char buf[32]; PVDevice pTmpArray; switch (pArray->VDeviceType) { case VD_RAID_0: for (i = 0; (UCHAR)i < pArray->u.array.bArnMember; i++) if(pArray->u.array.pMember[i]) { if(mIsArray(pArray->u.array.pMember[i])) sType = "RAID 1/0 "; /* TO DO */ else sType = "RAID 0 "; break; } break; case VD_RAID_1: sType = "RAID 1 "; break; case VD_JBOD: sType = "JBOD "; break; case VD_RAID_5: sType = "RAID 5 "; break; default: sType = "N/A "; break; } if (pArray->vf_online == 0) sStatus = "Disabled"; else if (pArray->u.array.rf_broken) sStatus = "Critical"; for (i = 0; (UCHAR)i < pArray->u.array.bArnMember; i++) { if (!sStatus) { if(mIsArray(pArray->u.array.pMember[i])) pTmpArray = pArray->u.array.pMember[i]; else pTmpArray = pArray; if (pTmpArray->u.array.rf_rebuilding) { #ifdef DEBUG sprintf(buf, "Rebuilding %lldMB", (pTmpArray->u.array.RebuildSectors>>11)); #else sprintf(buf, "Rebuilding %d%%", (UINT)((pTmpArray->u.array.RebuildSectors>>11)*100/((pTmpArray->VDeviceCapacity/(pTmpArray->u.array.bArnMember-1))>>11))); #endif sStatus = buf; } else if (pTmpArray->u.array.rf_verifying) { sprintf(buf, "Verifying %d%%", (UINT)((pTmpArray->u.array.RebuildSectors>>11)*100/((pTmpArray->VDeviceCapacity/(pTmpArray->u.array.bArnMember-1))>>11))); sStatus = buf; }
static int hpt_set_array_state(DEVICEID idArray, DWORD state) { IAL_ADAPTER_T *pAdapter; PVDevice pVDevice = ID_TO_VDEV(idArray); int i; if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1; if(!mIsArray(pVDevice)) return -1; if(!pVDevice->vf_online || pVDevice->u.array.rf_broken) return -1; pAdapter=(IAL_ADAPTER_T *)pVDevice->pVBus->OsExt; switch(state) { case MIRROR_REBUILD_START: { mtx_lock(&pAdapter->lock); if (pVDevice->u.array.rf_rebuilding || pVDevice->u.array.rf_verifying || pVDevice->u.array.rf_initializing) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_auto_rebuild = 0; pVDevice->u.array.rf_abort_rebuild = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, (UCHAR)((pVDevice->u.array.CriticalMembers || pVDevice->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY)); while (!pVDevice->u.array.rf_rebuilding) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptwait", hz * 20) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case MIRROR_REBUILD_ABORT: { for(i = 0; i < pVDevice->u.array.bArnMember; i++) { if(pVDevice->u.array.pMember[i] != 0 && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1) hpt_set_array_state(VDEV_TO_ID(pVDevice->u.array.pMember[i]), state); } mtx_lock(&pAdapter->lock); if(pVDevice->u.array.rf_rebuilding != 1) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_abort_rebuild = 1; while (pVDevice->u.array.rf_abort_rebuild) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptabrt", hz * 20) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_VERIFY_START: { /*if(pVDevice->u.array.rf_verifying) return -1;*/ mtx_lock(&pAdapter->lock); if (pVDevice->u.array.rf_rebuilding || pVDevice->u.array.rf_verifying || pVDevice->u.array.rf_initializing) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.RebuildSectors = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY); while (!pVDevice->u.array.rf_verifying) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptvrfy", hz * 20) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_VERIFY_ABORT: { mtx_lock(&pAdapter->lock); if(pVDevice->u.array.rf_verifying != 1) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_abort_rebuild = 1; while (pVDevice->u.array.rf_abort_rebuild) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptvrfy", hz * 80) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_INITIALIZE_START: { mtx_lock(&pAdapter->lock); if (pVDevice->u.array.rf_rebuilding || pVDevice->u.array.rf_verifying || pVDevice->u.array.rf_initializing) { mtx_unlock(&pAdapter->lock); return -1; } hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY); while (!pVDevice->u.array.rf_initializing) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptinit", hz * 80) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_INITIALIZE_ABORT: { mtx_lock(&pAdapter->lock); if(pVDevice->u.array.rf_initializing != 1) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_abort_rebuild = 1; while (pVDevice->u.array.rf_abort_rebuild) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptinit", hz * 80) != 0) break; } mtx_unlock(&pAdapter->lock); } break; default: return -1; } return 0; }
int Kernel_DeviceIoControl(_VBUS_ARG DWORD dwIoControlCode, /* operation control code */ PVOID lpInBuffer, /* input data buffer */ DWORD nInBufferSize, /* size of input data buffer */ PVOID lpOutBuffer, /* output data buffer */ DWORD nOutBufferSize, /* size of output data buffer */ PDWORD lpBytesReturned /* byte count */ ) { IAL_ADAPTER_T *pAdapter; switch(dwIoControlCode) { case HPT_IOCTL_DELETE_ARRAY: { DEVICEID idArray; int iSuccess; int i; PVDevice pArray; PVBus _vbus_p; struct cam_periph *periph = NULL; if (nInBufferSize!=sizeof(DEVICEID)+sizeof(DWORD)) return -1; if (nOutBufferSize!=sizeof(int)) return -1; idArray = *(DEVICEID *)lpInBuffer; pArray = ID_TO_VDEV(idArray); if((idArray == 0) || check_VDevice_valid(pArray)) return -1; if(!mIsArray(pArray)) return -1; _vbus_p=pArray->pVBus; pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt; for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) { if(pArray == _vbus_p->pVDevice[i]) { periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId, i); if (periph != NULL && periph->refcount >= 1) { hpt_printk(("Can not delete a mounted device.\n")); return -1; } } /* the Mounted Disk isn't delete */ } iSuccess = hpt_delete_array(_VBUS_P idArray, *(DWORD*)((DEVICEID *)lpInBuffer+1)); *(int*)lpOutBuffer = iSuccess; if(iSuccess != 0) return -1; break; } case HPT_IOCTL_GET_EVENT: { PHPT_EVENT pInfo; if (nInBufferSize!=0) return -1; if (nOutBufferSize!=sizeof(HPT_EVENT)) return -1; pInfo = (PHPT_EVENT)lpOutBuffer; if (hpt_get_event(pInfo)!=0) return -1; } break; case HPT_IOCTL_SET_ARRAY_STATE: { DEVICEID idArray; DWORD state; if (nInBufferSize!=sizeof(HPT_SET_STATE_PARAM)) return -1; if (nOutBufferSize!=0) return -1; idArray = ((PHPT_SET_STATE_PARAM)lpInBuffer)->idArray; state = ((PHPT_SET_STATE_PARAM)lpInBuffer)->state; if(hpt_set_array_state(idArray, state)!=0) return -1; } break; case HPT_IOCTL_RESCAN_DEVICES: { if (nInBufferSize!=0) return -1; if (nOutBufferSize!=0) return -1; #ifndef FOR_DEMO /* stop buzzer if user perform rescan */ for (pAdapter=gIal_Adapter; pAdapter; pAdapter=pAdapter->next) { if (pAdapter->beeping) { pAdapter->beeping = 0; BeepOff(pAdapter->mvSataAdapter.adapterIoBaseAddress); } } #endif } break; default: { PVDevice pVDev; switch(dwIoControlCode) { /* read-only ioctl functions can be called directly. */ case HPT_IOCTL_GET_VERSION: case HPT_IOCTL_GET_CONTROLLER_IDS: case HPT_IOCTL_GET_CONTROLLER_COUNT: case HPT_IOCTL_GET_CONTROLLER_INFO: case HPT_IOCTL_GET_CHANNEL_INFO: case HPT_IOCTL_GET_LOGICAL_DEVICES: case HPT_IOCTL_GET_DEVICE_INFO: case HPT_IOCTL_GET_DEVICE_INFO_V2: case HPT_IOCTL_GET_EVENT: case HPT_IOCTL_GET_DRIVER_CAPABILITIES: if(hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) return -1; break; default: /* * GUI always use /proc/scsi/hptmv/0, so the _vbus_p param will be * wrong for second controller. */ switch(dwIoControlCode) { case HPT_IOCTL_CREATE_ARRAY: pVDev = ID_TO_VDEV(((PCREATE_ARRAY_PARAMS)lpInBuffer)->Members[0]); break; case HPT_IOCTL_CREATE_ARRAY_V2: pVDev = ID_TO_VDEV(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->Members[0]); break; case HPT_IOCTL_SET_ARRAY_INFO: pVDev = ID_TO_VDEV(((PHPT_SET_ARRAY_INFO)lpInBuffer)->idArray); break; case HPT_IOCTL_SET_DEVICE_INFO: pVDev = ID_TO_VDEV(((PHPT_SET_DEVICE_INFO)lpInBuffer)->idDisk); break; case HPT_IOCTL_SET_DEVICE_INFO_V2: pVDev = ID_TO_VDEV(((PHPT_SET_DEVICE_INFO_V2)lpInBuffer)->idDisk); break; case HPT_IOCTL_SET_BOOT_MARK: case HPT_IOCTL_ADD_SPARE_DISK: case HPT_IOCTL_REMOVE_SPARE_DISK: pVDev = ID_TO_VDEV(*(DEVICEID *)lpInBuffer); break; case HPT_IOCTL_ADD_DISK_TO_ARRAY: pVDev = ID_TO_VDEV(((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray); break; default: pVDev = 0; } if (pVDev && !check_VDevice_valid(pVDev)){ _vbus_p = pVDev->pVBus; pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt; /* * create_array, and other functions can't be executed while channel is * perform I/O commands. Wait until driver is idle. */ lock_driver_idle(pAdapter); if (hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) { mtx_unlock(&pAdapter->lock); return -1; } mtx_unlock(&pAdapter->lock); } else return -1; break; } #ifdef SUPPORT_ARRAY switch(dwIoControlCode) { case HPT_IOCTL_CREATE_ARRAY: { pAdapter=(IAL_ADAPTER_T *)(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->pVBus->OsExt; mtx_lock(&pAdapter->lock); if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_AND_DUPLICATE) { (ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->u.array.rf_auto_rebuild = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), DUPLICATE); } else if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_R5_ZERO_INIT) { hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), INITIALIZE); } else if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_R5_BUILD_PARITY) { hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), REBUILD_PARITY); } mtx_unlock(&pAdapter->lock); break; } case HPT_IOCTL_CREATE_ARRAY_V2: { pAdapter=(IAL_ADAPTER_T *)(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->pVBus->OsExt; mtx_lock(&pAdapter->lock); if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_AND_DUPLICATE) { (ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->u.array.rf_auto_rebuild = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), DUPLICATE); } else if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_R5_ZERO_INIT) { hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), INITIALIZE); } else if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_R5_BUILD_PARITY) { hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), REBUILD_PARITY); } mtx_unlock(&pAdapter->lock); break; } case HPT_IOCTL_ADD_DISK_TO_ARRAY: { PVDevice pArray = ID_TO_VDEV(((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray); pAdapter=(IAL_ADAPTER_T *)pArray->pVBus->OsExt; if(pArray->u.array.rf_rebuilding == 0) { mtx_lock(&pAdapter->lock); pArray->u.array.rf_auto_rebuild = 0; pArray->u.array.rf_abort_rebuild = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, DUPLICATE); while (!pArray->u.array.rf_rebuilding) { if (mtx_sleep(pArray, &pAdapter->lock, 0, "hptwait", hz * 3) != 0) break; } mtx_unlock(&pAdapter->lock); } break; } } #endif return 0; } } if (lpBytesReturned) *lpBytesReturned = nOutBufferSize; return 0; }