Esempio n. 1
0
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;

}
Esempio n. 2
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
			}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}