diff options
Diffstat (limited to 'sys/contrib/dev/hptmv/ioctl.c')
-rw-r--r-- | sys/contrib/dev/hptmv/ioctl.c | 928 |
1 files changed, 0 insertions, 928 deletions
diff --git a/sys/contrib/dev/hptmv/ioctl.c b/sys/contrib/dev/hptmv/ioctl.c deleted file mode 100644 index 2cfe979..0000000 --- a/sys/contrib/dev/hptmv/ioctl.c +++ /dev/null @@ -1,928 +0,0 @@ -/* - * Copyright (c) 2003-2004 HighPoint Technologies, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * ioctl.c ioctl interface implementation - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> - -#include <dev/hptmv/global.h> -#include <dev/hptmv/hptintf.h> -#include <dev/hptmv/osbsd.h> -#include <contrib/dev/hptmv/access601.h> - -#pragma pack(1) - -typedef struct _HPT_REBUILD_PARAM -{ - DEVICEID idMirror; - DWORD Lba; - UCHAR nSector; -} HPT_REBUILD_PARAM, *PHPT_REBUILD_PARAM; - -#pragma pack() - -#define MAX_EVENTS 10 -static HPT_EVENT hpt_event_queue[MAX_EVENTS]; -static int event_queue_head=0, event_queue_tail=0; - -static int hpt_get_event(PHPT_EVENT pEvent); -static int hpt_set_array_state(DEVICEID idArray, DWORD state); -static intrmask_t lock_driver_idle(IAL_ADAPTER_T *pAdapter); -static void HPTLIBAPI thread_io_done(_VBUS_ARG PCommand pCmd); -static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd, - FPSCAT_GATH pSgTable, int logical); - -static void get_disk_location(PDevice pDev, int *controller, int *channel) -{ - IAL_ADAPTER_T *pAdapTemp; - int i, j; - - for (i=1, pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next, i++) { - for (j=0; j<MV_SATA_CHANNELS_NUM; j++) - if (pDev==&pAdapTemp->VDevices[j].u.disk) { - *controller = i; - *channel = j; - return; - } - } -} - -static int event_queue_add(PHPT_EVENT pEvent) -{ - int p; - p = (event_queue_tail + 1) % MAX_EVENTS; - if (p==event_queue_head) - { - return -1; - } - hpt_event_queue[event_queue_tail] = *pEvent; - event_queue_tail = p; - return 0; -} - -static int event_queue_remove(PHPT_EVENT pEvent) -{ - if (event_queue_head != event_queue_tail) - { - *pEvent = hpt_event_queue[event_queue_head]; - event_queue_head++; - event_queue_head %= MAX_EVENTS; - return 0; - } - return -1; -} - -void HPTLIBAPI ioctl_ReportEvent(UCHAR event, PVOID param) -{ - HPT_EVENT e; - ZeroMemory(&e, sizeof(e)); - e.EventType = event; - switch(event) - { - case ET_INITIALIZE_ABORTED: - case ET_INITIALIZE_FAILED: - memcpy(e.Data, ((PVDevice)param)->u.array.ArrayName, MAX_ARRAY_NAME); - case ET_INITIALIZE_STARTED: - case ET_INITIALIZE_FINISHED: - - case ET_REBUILD_STARTED: - case ET_REBUILD_ABORTED: - case ET_REBUILD_FAILED: - case ET_REBUILD_FINISHED: - - case ET_VERIFY_STARTED: - case ET_VERIFY_ABORTED: - case ET_VERIFY_FAILED: - case ET_VERIFY_FINISHED: - case ET_VERIFY_DATA_ERROR: - - case ET_SPARE_TOOK_OVER: - case ET_DEVICE_REMOVED: - case ET_DEVICE_PLUGGED: - case ET_DEVICE_ERROR: - e.DeviceID = VDEV_TO_ID((PVDevice)param); - break; - - default: - break; - } - event_queue_add(&e); - if (event==ET_DEVICE_REMOVED) { - int controller, channel; - get_disk_location(&((PVDevice)param)->u.disk, &controller, &channel); - hpt_printk(("Device removed: controller %d channel %d\n", controller, channel)); - } -} - -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== HPT_NULL_ID) || 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; - -} - -/* just to prevent driver from sending more commands */ -static void HPTLIBAPI nothing(_VBUS_ARG void *notused){} - -static intrmask_t lock_driver_idle(IAL_ADAPTER_T *pAdapter) -{ - intrmask_t oldspl; - _VBUS_INST(&pAdapter->VBus) - oldspl = lock_driver(); - while (pAdapter->outstandingCommands) { - KdPrint(("outstandingCommands is %d, wait..\n", pAdapter->outstandingCommands)); - if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0); - unlock_driver(oldspl); - oldspl = lock_driver(); - } - CheckIdleCall(_VBUS_P0); - return oldspl; -} - -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 == HPT_NULL_ID) || 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; -#ifdef SUPPORT_ARRAY - intrmask_t oldspl; -#endif - 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_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_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_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. - */ - oldspl = lock_driver_idle(pAdapter); - if (hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize, - lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) { - unlock_driver(oldspl); - return -1; - } - unlock_driver(oldspl); - } - 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; - oldspl = lock_driver(); - 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); - } - unlock_driver(oldspl); - 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 == HPT_NULL_ID) - { - DWORD timeout = 0; - oldspl = lock_driver(); - 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); - unlock_driver(oldspl); - while (!pArray->u.array.rf_rebuilding) - { - tsleep((caddr_t)Kernel_DeviceIoControl, PPAUSE, "pause", 1); - if ( timeout >= hz*3) - break; - timeout ++; - } - } - break; - } - } -#endif - return 0; - } - } - - if (lpBytesReturned) - *lpBytesReturned = nOutBufferSize; - return 0; -} - -static int hpt_get_event(PHPT_EVENT pEvent) -{ - intrmask_t oldspl = lock_driver(); - int ret = event_queue_remove(pEvent); - unlock_driver(oldspl); - return ret; -} - -static int hpt_set_array_state(DEVICEID idArray, DWORD state) -{ - IAL_ADAPTER_T *pAdapter; - PVDevice pVDevice = ID_TO_VDEV(idArray); - int i; - DWORD timeout = 0; - intrmask_t oldspl; - - if(idArray == HPT_NULL_ID || 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: - { - if (pVDevice->u.array.rf_rebuilding || - pVDevice->u.array.rf_verifying || - pVDevice->u.array.rf_initializing) - return -1; - - oldspl = lock_driver(); - - 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)); - - unlock_driver(oldspl); - - while (!pVDevice->u.array.rf_rebuilding) - { - tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1); - if ( timeout >= hz*20) - break; - timeout ++; - } - } - - break; - - case MIRROR_REBUILD_ABORT: - { - for(i = 0; i < pVDevice->u.array.bArnMember; i++) { - if(pVDevice->u.array.pMember[i] != NULL && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1) - hpt_set_array_state(VDEV_TO_ID(pVDevice->u.array.pMember[i]), state); - } - - if(pVDevice->u.array.rf_rebuilding != 1) - return -1; - - oldspl = lock_driver(); - pVDevice->u.array.rf_abort_rebuild = 1; - unlock_driver(oldspl); - - while (pVDevice->u.array.rf_abort_rebuild) - { - tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1); - if ( timeout >= hz*20) - break; - timeout ++; - } - } - break; - - case AS_VERIFY_START: - { - /*if(pVDevice->u.array.rf_verifying) - return -1;*/ - if (pVDevice->u.array.rf_rebuilding || - pVDevice->u.array.rf_verifying || - pVDevice->u.array.rf_initializing) - return -1; - - oldspl = lock_driver(); - pVDevice->u.array.RebuildSectors = 0; - hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY); - unlock_driver(oldspl); - - while (!pVDevice->u.array.rf_verifying) - { - tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1); - if ( timeout >= hz*20) - break; - timeout ++; - } - } - break; - - case AS_VERIFY_ABORT: - { - if(pVDevice->u.array.rf_verifying != 1) - return -1; - - oldspl = lock_driver(); - pVDevice->u.array.rf_abort_rebuild = 1; - unlock_driver(oldspl); - - while (pVDevice->u.array.rf_abort_rebuild) - { - tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1); - if ( timeout >= hz*80) - break; - timeout ++; - } - } - break; - - case AS_INITIALIZE_START: - { - if (pVDevice->u.array.rf_rebuilding || - pVDevice->u.array.rf_verifying || - pVDevice->u.array.rf_initializing) - return -1; - - oldspl = lock_driver(); - hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY); - unlock_driver(oldspl); - - while (!pVDevice->u.array.rf_initializing) - { - tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1); - if ( timeout >= hz*80) - break; - timeout ++; - } - } - break; - - case AS_INITIALIZE_ABORT: - { - if(pVDevice->u.array.rf_initializing != 1) - return -1; - - oldspl = lock_driver(); - pVDevice->u.array.rf_abort_rebuild = 1; - unlock_driver(oldspl); - - while (pVDevice->u.array.rf_abort_rebuild) - { - tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1); - if ( timeout >= hz*80) - break; - timeout ++; - } - } - break; - - default: - return -1; - } - - return 0; -} - -static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical) -{ - ULONG bufferSize = SECTOR_TO_BYTE(pCmd->uCmd.R1Control.nSectors); - if (pCmd->uCmd.R1Control.Command==CTRL_CMD_VERIFY) - bufferSize<<=1; - if (logical) { - pSgTable->dSgAddress = (ULONG_PTR)pCmd->uCmd.R1Control.Buffer; - pSgTable->wSgSize = (USHORT)bufferSize; - pSgTable->wSgFlag = SG_FLAG_EOT; - } - else { - /* build physical SG table for pCmd->uCmd.R1Control.Buffer */ - ADDRESS dataPointer, v, nextpage, currvaddr, nextvaddr, currphypage, nextphypage; - ULONG length; - int idx = 0; - - v = pCmd->uCmd.R1Control.Buffer; - dataPointer = (ADDRESS)fOsPhysicalAddress(v); - - if ((ULONG_PTR)dataPointer & 0x1) - return FALSE; - - #define ON64KBOUNDARY(x) (((ULONG_PTR)(x) & 0xFFFF) == 0) - #define NOTNEIGHBORPAGE(highvaddr, lowvaddr) ((ULONG_PTR)(highvaddr) - (ULONG_PTR)(lowvaddr) != PAGE_SIZE) - - do { - if (idx >= MAX_SG_DESCRIPTORS) return FALSE; - - pSgTable[idx].dSgAddress = fOsPhysicalAddress(v); - currvaddr = v; - currphypage = (ADDRESS)fOsPhysicalAddress((void*)trunc_page((ULONG_PTR)currvaddr)); - - - do { - nextpage = (ADDRESS)trunc_page(((ULONG_PTR)currvaddr + PAGE_SIZE)); - nextvaddr = (ADDRESS)MIN(((ULONG_PTR)v + bufferSize), (ULONG_PTR)(nextpage)); - - if (nextvaddr == (ADDRESS)((ULONG_PTR)v + bufferSize)) break; - nextphypage = (ADDRESS)fOsPhysicalAddress(nextpage); - - if (NOTNEIGHBORPAGE(nextphypage, currphypage) || ON64KBOUNDARY(nextphypage)) { - nextvaddr = nextpage; - break; - } - - currvaddr = nextvaddr; - currphypage = nextphypage; - }while (1); - - length = (ULONG_PTR)nextvaddr - (ULONG_PTR)v; - v = nextvaddr; - bufferSize -= length; - - pSgTable[idx].wSgSize = (USHORT)length; - pSgTable[idx].wSgFlag = (bufferSize)? 0 : SG_FLAG_EOT; - idx++; - - }while (bufferSize); - } - return 1; -} - -static int End_Job=0; -static void HPTLIBAPI thread_io_done(_VBUS_ARG PCommand pCmd) -{ - End_Job = 1; - wakeup((caddr_t)pCmd); -} - -void hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags) -{ - DWORD timeout = 0; - ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1); - PCommand pCmd; - UINT result; - int needsync=0, retry=0, needdelete=0; - void *buffer = 0; - intrmask_t oldspl; - - _VBUS_INST(&pAdapter->VBus) - - if (pArray->u.array.rf_broken==1 || - pArray->u.array.RebuildSectors>=capacity) - return; - - oldspl = lock_driver(); - - switch(flags) - { - case DUPLICATE: - case REBUILD_PARITY: - if(pArray->u.array.rf_rebuilding == 0) - { - pArray->u.array.rf_rebuilding = 1; - hpt_printk(("Rebuilding started.\n")); - ioctl_ReportEvent(ET_REBUILD_STARTED, pArray); - } - break; - - case INITIALIZE: - if(pArray->u.array.rf_initializing == 0) - { - pArray->u.array.rf_initializing = 1; - hpt_printk(("Initializing started.\n")); - ioctl_ReportEvent(ET_INITIALIZE_STARTED, pArray); - } - break; - - case VERIFY: - if(pArray->u.array.rf_verifying == 0) - { - pArray->u.array.rf_verifying = 1; - hpt_printk(("Verifying started.\n")); - ioctl_ReportEvent(ET_VERIFY_STARTED, pArray); - } - break; - } - -retry_cmd: - pCmd = AllocateCommand(_VBUS_P0); - HPT_ASSERT(pCmd); - pCmd->cf_control = 1; - End_Job = 0; - - if (pArray->VDeviceType==VD_RAID_1) - { - #define MAX_REBUILD_SECTORS 0x40 - - /* take care for discontinuous buffer in R1ControlSgl */ - buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT); - if(!buffer) { - FreeCommand(_VBUS_P pCmd); - hpt_printk(("can't allocate rebuild buffer\n")); - goto fail; - } - switch(flags) - { - case DUPLICATE: - pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD; - pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS; - break; - - case VERIFY: - pCmd->uCmd.R1Control.Command = CTRL_CMD_VERIFY; - pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS/2; - break; - - case INITIALIZE: - pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD; - pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS; - break; - } - - pCmd->uCmd.R1Control.Lba = pArray->u.array.RebuildSectors; - - if (capacity - pArray->u.array.RebuildSectors < pCmd->uCmd.R1Control.nSectors) - pCmd->uCmd.R1Control.nSectors = capacity - pArray->u.array.RebuildSectors; - - pCmd->uCmd.R1Control.Buffer = buffer; - pCmd->pfnBuildSgl = R1ControlSgl; - } - else if (pArray->VDeviceType==VD_RAID_5) - { - switch(flags) - { - case DUPLICATE: - case REBUILD_PARITY: - pCmd->uCmd.R5Control.Command = CTRL_CMD_REBUILD; break; - case VERIFY: - pCmd->uCmd.R5Control.Command = CTRL_CMD_VERIFY; break; - case INITIALIZE: - pCmd->uCmd.R5Control.Command = CTRL_CMD_INIT; break; - } - pCmd->uCmd.R5Control.StripeLine=pArray->u.array.RebuildSectors>>pArray->u.array.bArBlockSizeShift; - } - else - HPT_ASSERT(0); - - pCmd->pVDevice = pArray; - pCmd->pfnCompletion = thread_io_done; - pArray->pfnSendCommand(_VBUS_P pCmd); - CheckPendingCall(_VBUS_P0); - - if (!End_Job) { - unlock_driver(oldspl); - while (!End_Job) { - tsleep((caddr_t)pCmd, PPAUSE, "pause", hz); - if (timeout++>60) break; - } - oldspl = lock_driver(); - if (!End_Job) { - hpt_printk(("timeout, reset\n")); - fResetVBus(_VBUS_P0); - } - } - - result = pCmd->Result; - FreeCommand(_VBUS_P pCmd); - if (buffer) { - free(buffer, M_DEVBUF); - /* beware of goto retry_cmd below */ - buffer = NULL; - } - KdPrintI(("cmd finished %d", result)); - - switch(result) - { - case RETURN_SUCCESS: - if (!pArray->u.array.rf_abort_rebuild) - { - if(pArray->u.array.RebuildSectors < capacity) - { - hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, flags); - } - else - { - switch (flags) - { - case DUPLICATE: - case REBUILD_PARITY: - needsync = 1; - pArray->u.array.rf_rebuilding = 0; - pArray->u.array.rf_need_rebuild = 0; - pArray->u.array.CriticalMembers = 0; - pArray->u.array.RebuildSectors = MAX_LBA_T; - pArray->u.array.rf_duplicate_and_create = 0; - hpt_printk(("Rebuilding finished.\n")); - ioctl_ReportEvent(ET_REBUILD_FINISHED, pArray); - break; - case INITIALIZE: - needsync = 1; - pArray->u.array.rf_initializing = 0; - pArray->u.array.rf_need_rebuild = 0; - pArray->u.array.RebuildSectors = MAX_LBA_T; - hpt_printk(("Initializing finished.\n")); - ioctl_ReportEvent(ET_INITIALIZE_FINISHED, pArray); - break; - case VERIFY: - pArray->u.array.rf_verifying = 0; - hpt_printk(("Verifying finished.\n")); - ioctl_ReportEvent(ET_VERIFY_FINISHED, pArray); - break; - } - } - } - else - { - pArray->u.array.rf_abort_rebuild = 0; - if (pArray->u.array.rf_rebuilding) - { - hpt_printk(("Abort rebuilding.\n")); - pArray->u.array.rf_rebuilding = 0; - pArray->u.array.rf_duplicate_and_create = 0; - ioctl_ReportEvent(ET_REBUILD_ABORTED, pArray); - } - else if (pArray->u.array.rf_verifying) - { - hpt_printk(("Abort verifying.\n")); - pArray->u.array.rf_verifying = 0; - ioctl_ReportEvent(ET_VERIFY_ABORTED, pArray); - } - else if (pArray->u.array.rf_initializing) - { - hpt_printk(("Abort initializing.\n")); - pArray->u.array.rf_initializing = 0; - ioctl_ReportEvent(ET_INITIALIZE_ABORTED, pArray); - } - needdelete=1; - } - break; - - case RETURN_DATA_ERROR: - if (flags==VERIFY) - { - needsync = 1; - pArray->u.array.rf_verifying = 0; - pArray->u.array.rf_need_rebuild = 1; - hpt_printk(("Verifying failed: found inconsistency\n")); - ioctl_ReportEvent(ET_VERIFY_DATA_ERROR, pArray); - ioctl_ReportEvent(ET_VERIFY_FAILED, pArray); - - if (!pArray->vf_online || pArray->u.array.rf_broken) break; - - 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, - (pArray->VDeviceType == VD_RAID_1) ? DUPLICATE : REBUILD_PARITY); - } - break; - - default: - hpt_printk(("command failed with error %d\n", result)); - if (++retry<3) - { - hpt_printk(("retry (%d)\n", retry)); - goto retry_cmd; - } -fail: - pArray->u.array.rf_abort_rebuild = 0; - switch (flags) - { - case DUPLICATE: - case REBUILD_PARITY: - needsync = 1; - pArray->u.array.rf_rebuilding = 0; - pArray->u.array.rf_duplicate_and_create = 0; - hpt_printk(((flags==DUPLICATE)? "Duplicating failed.\n":"Rebuilding failed.\n")); - ioctl_ReportEvent(ET_REBUILD_FAILED, pArray); - break; - - case INITIALIZE: - needsync = 1; - pArray->u.array.rf_initializing = 0; - hpt_printk(("Initializing failed.\n")); - ioctl_ReportEvent(ET_INITIALIZE_FAILED, pArray); - break; - - case VERIFY: - needsync = 1; - pArray->u.array.rf_verifying = 0; - hpt_printk(("Verifying failed.\n")); - ioctl_ReportEvent(ET_VERIFY_FAILED, pArray); - break; - } - needdelete=1; - } - - while (pAdapter->outstandingCommands) - { - KdPrintI(("currcmds is %d, wait..\n", pAdapter->outstandingCommands)); - /* put this to have driver stop processing system commands quickly */ - if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0); - unlock_driver(oldspl); - oldspl = lock_driver(); - } - - if (needsync) SyncArrayInfo(pArray); - if(needdelete && (pArray->u.array.rf_duplicate_must_done || (flags == INITIALIZE))) - fDeleteArray(_VBUS_P pArray, TRUE); - - Check_Idle_Call(pAdapter); - unlock_driver(oldspl); -} |