1*35878b55SSascha Wildner /* 2*35878b55SSascha Wildner * Copyright (c) 2004-2005 HighPoint Technologies, Inc. 3*35878b55SSascha Wildner * All rights reserved. 4*35878b55SSascha Wildner * 5*35878b55SSascha Wildner * Redistribution and use in source and binary forms, with or without 6*35878b55SSascha Wildner * modification, are permitted provided that the following conditions 7*35878b55SSascha Wildner * are met: 8*35878b55SSascha Wildner * 1. Redistributions of source code must retain the above copyright 9*35878b55SSascha Wildner * notice, this list of conditions and the following disclaimer. 10*35878b55SSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright 11*35878b55SSascha Wildner * notice, this list of conditions and the following disclaimer in the 12*35878b55SSascha Wildner * documentation and/or other materials provided with the distribution. 13*35878b55SSascha Wildner * 14*35878b55SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*35878b55SSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*35878b55SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*35878b55SSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*35878b55SSascha Wildner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*35878b55SSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*35878b55SSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*35878b55SSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*35878b55SSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*35878b55SSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*35878b55SSascha Wildner * SUCH DAMAGE. 25*35878b55SSascha Wildner * 26*35878b55SSascha Wildner * $FreeBSD: src/sys/dev/hptmv/gui_lib.c,v 1.6 2009/04/07 16:38:25 delphij Exp $ 27*35878b55SSascha Wildner */ 28*35878b55SSascha Wildner /* 29*35878b55SSascha Wildner * gui_lib.c 30*35878b55SSascha Wildner * Copyright (c) 2002-2004 HighPoint Technologies, Inc. All rights reserved. 31*35878b55SSascha Wildner * 32*35878b55SSascha Wildner * Platform independent ioctl interface implementation. 33*35878b55SSascha Wildner * The platform dependent part may reuse this function and/or use it own 34*35878b55SSascha Wildner * implementation for each ioctl function. 35*35878b55SSascha Wildner * 36*35878b55SSascha Wildner * This implementation doesn't use any synchronization; the caller must 37*35878b55SSascha Wildner * assure the proper context when calling these functions. 38*35878b55SSascha Wildner */ 39*35878b55SSascha Wildner 40*35878b55SSascha Wildner #include <sys/param.h> 41*35878b55SSascha Wildner #include <sys/systm.h> 42*35878b55SSascha Wildner #include <sys/kernel.h> 43*35878b55SSascha Wildner #include <sys/malloc.h> 44*35878b55SSascha Wildner 45*35878b55SSascha Wildner #ifndef __KERNEL__ 46*35878b55SSascha Wildner #define __KERNEL__ 47*35878b55SSascha Wildner #endif 48*35878b55SSascha Wildner 49*35878b55SSascha Wildner #include <dev/raid/hptmv/global.h> 50*35878b55SSascha Wildner #include <dev/raid/hptmv/hptintf.h> 51*35878b55SSascha Wildner #include <dev/raid/hptmv/osbsd.h> 52*35878b55SSascha Wildner #include <dev/raid/hptmv/access601.h> 53*35878b55SSascha Wildner 54*35878b55SSascha Wildner static int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap); 55*35878b55SSascha Wildner static int hpt_get_controller_count(void); 56*35878b55SSascha Wildner static int hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo); 57*35878b55SSascha Wildner static int hpt_get_channel_info(int id, int bus, PCHANNEL_INFO pInfo); 58*35878b55SSascha Wildner static int hpt_get_logical_devices(DEVICEID * pIds, int nMaxCount); 59*35878b55SSascha Wildner static int hpt_get_device_info(DEVICEID id, PLOGICAL_DEVICE_INFO pInfo); 60*35878b55SSascha Wildner static int hpt_get_device_info_v2(DEVICEID id, PLOGICAL_DEVICE_INFO_V2 pInfo); 61*35878b55SSascha Wildner static DEVICEID hpt_create_array(_VBUS_ARG PCREATE_ARRAY_PARAMS pParam); 62*35878b55SSascha Wildner static DEVICEID hpt_create_array_v2(_VBUS_ARG PCREATE_ARRAY_PARAMS_V2 pParam); 63*35878b55SSascha Wildner static int hpt_add_spare_disk(_VBUS_ARG DEVICEID idDisk); 64*35878b55SSascha Wildner static int hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk); 65*35878b55SSascha Wildner static int hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO pInfo); 66*35878b55SSascha Wildner static int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO pInfo); 67*35878b55SSascha Wildner static int hpt_set_device_info_v2(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO_V2 pInfo); 68*35878b55SSascha Wildner 69*35878b55SSascha Wildner int 70*35878b55SSascha Wildner check_VDevice_valid(PVDevice p) 71*35878b55SSascha Wildner { 72*35878b55SSascha Wildner int i; 73*35878b55SSascha Wildner PVDevice pVDevice; 74*35878b55SSascha Wildner PVBus _vbus_p; 75*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapter = gIal_Adapter; 76*35878b55SSascha Wildner 77*35878b55SSascha Wildner while(pAdapter != 0) 78*35878b55SSascha Wildner { 79*35878b55SSascha Wildner for (i = 0; i < MV_SATA_CHANNELS_NUM; i++) 80*35878b55SSascha Wildner if(&(pAdapter->VDevices[i]) == p) return 0; 81*35878b55SSascha Wildner pAdapter = pAdapter->next; 82*35878b55SSascha Wildner } 83*35878b55SSascha Wildner 84*35878b55SSascha Wildner #ifdef SUPPORT_ARRAY 85*35878b55SSascha Wildner pAdapter = gIal_Adapter; 86*35878b55SSascha Wildner while(pAdapter != 0) 87*35878b55SSascha Wildner { 88*35878b55SSascha Wildner _vbus_p = &pAdapter->VBus; 89*35878b55SSascha Wildner for (i=0;i<MAX_ARRAY_PER_VBUS;i++) 90*35878b55SSascha Wildner { 91*35878b55SSascha Wildner pVDevice=ArrayTables(i); 92*35878b55SSascha Wildner if ((pVDevice->u.array.dArStamp != 0) && (pVDevice == p)) 93*35878b55SSascha Wildner return 0; 94*35878b55SSascha Wildner } 95*35878b55SSascha Wildner pAdapter = pAdapter->next; 96*35878b55SSascha Wildner } 97*35878b55SSascha Wildner #endif 98*35878b55SSascha Wildner 99*35878b55SSascha Wildner return -1; 100*35878b55SSascha Wildner } 101*35878b55SSascha Wildner 102*35878b55SSascha Wildner #ifdef SUPPORT_ARRAY 103*35878b55SSascha Wildner 104*35878b55SSascha Wildner static UCHAR get_vdev_type(PVDevice pVDevice) 105*35878b55SSascha Wildner { 106*35878b55SSascha Wildner switch (pVDevice->VDeviceType) { 107*35878b55SSascha Wildner case VD_RAID_0: return AT_RAID0; 108*35878b55SSascha Wildner case VD_RAID_1: return AT_RAID1; 109*35878b55SSascha Wildner case VD_JBOD: return AT_JBOD; 110*35878b55SSascha Wildner case VD_RAID_5: return AT_RAID5; 111*35878b55SSascha Wildner default: return AT_UNKNOWN; 112*35878b55SSascha Wildner } 113*35878b55SSascha Wildner } 114*35878b55SSascha Wildner 115*35878b55SSascha Wildner static DWORD get_array_flag(PVDevice pVDevice) 116*35878b55SSascha Wildner { 117*35878b55SSascha Wildner int i; 118*35878b55SSascha Wildner DWORD f = 0; 119*35878b55SSascha Wildner 120*35878b55SSascha Wildner /* The array is disabled */ 121*35878b55SSascha Wildner if(!pVDevice->vf_online) { 122*35878b55SSascha Wildner f |= ARRAY_FLAG_DISABLED; 123*35878b55SSascha Wildner /* Ignore other info */ 124*35878b55SSascha Wildner return f; 125*35878b55SSascha Wildner } 126*35878b55SSascha Wildner 127*35878b55SSascha Wildner /* array need synchronizing */ 128*35878b55SSascha Wildner if(pVDevice->u.array.rf_need_rebuild && !pVDevice->u.array.rf_duplicate_and_create) 129*35878b55SSascha Wildner f |= ARRAY_FLAG_NEEDBUILDING; 130*35878b55SSascha Wildner 131*35878b55SSascha Wildner /* array is in rebuilding process */ 132*35878b55SSascha Wildner if(pVDevice->u.array.rf_rebuilding) 133*35878b55SSascha Wildner f |= ARRAY_FLAG_REBUILDING; 134*35878b55SSascha Wildner 135*35878b55SSascha Wildner /* array is being verified */ 136*35878b55SSascha Wildner if(pVDevice->u.array.rf_verifying) 137*35878b55SSascha Wildner f |= ARRAY_FLAG_VERIFYING; 138*35878b55SSascha Wildner 139*35878b55SSascha Wildner /* array is being initialized */ 140*35878b55SSascha Wildner if(pVDevice->u.array.rf_initializing) 141*35878b55SSascha Wildner f |= ARRAY_FLAG_INITIALIZING; 142*35878b55SSascha Wildner 143*35878b55SSascha Wildner /* broken but may still working */ 144*35878b55SSascha Wildner if(pVDevice->u.array.rf_broken) 145*35878b55SSascha Wildner f |= ARRAY_FLAG_BROKEN; 146*35878b55SSascha Wildner 147*35878b55SSascha Wildner /* array has a active partition */ 148*35878b55SSascha Wildner if(pVDevice->vf_bootable) 149*35878b55SSascha Wildner f |= ARRAY_FLAG_BOOTDISK; 150*35878b55SSascha Wildner 151*35878b55SSascha Wildner /* a newly created array */ 152*35878b55SSascha Wildner if(pVDevice->u.array.rf_newly_created) 153*35878b55SSascha Wildner f |= ARRAY_FLAG_NEWLY_CREATED; 154*35878b55SSascha Wildner 155*35878b55SSascha Wildner /* array has boot mark set */ 156*35878b55SSascha Wildner if(pVDevice->vf_bootmark) 157*35878b55SSascha Wildner f |= ARRAY_FLAG_BOOTMARK; 158*35878b55SSascha Wildner 159*35878b55SSascha Wildner /* auto-rebuild should start */ 160*35878b55SSascha Wildner if(pVDevice->u.array.rf_auto_rebuild) 161*35878b55SSascha Wildner f |= ARRAY_FLAG_NEED_AUTOREBUILD; 162*35878b55SSascha Wildner 163*35878b55SSascha Wildner for(i = 0; i < pVDevice->u.array.bArnMember; i++) 164*35878b55SSascha Wildner { 165*35878b55SSascha Wildner PVDevice pMember = pVDevice->u.array.pMember[i]; 166*35878b55SSascha Wildner if (!pMember || !pMember->vf_online || (pMember->VDeviceType==VD_SINGLE_DISK)) 167*35878b55SSascha Wildner continue; 168*35878b55SSascha Wildner 169*35878b55SSascha Wildner /* array need synchronizing */ 170*35878b55SSascha Wildner if(pMember->u.array.rf_need_rebuild && 171*35878b55SSascha Wildner !pMember->u.array.rf_duplicate_and_create) 172*35878b55SSascha Wildner f |= ARRAY_FLAG_NEEDBUILDING; 173*35878b55SSascha Wildner 174*35878b55SSascha Wildner /* array is in rebuilding process */ 175*35878b55SSascha Wildner if(pMember->u.array.rf_rebuilding) 176*35878b55SSascha Wildner f |= ARRAY_FLAG_REBUILDING; 177*35878b55SSascha Wildner 178*35878b55SSascha Wildner /* array is being verified */ 179*35878b55SSascha Wildner if(pMember->u.array.rf_verifying) 180*35878b55SSascha Wildner f |= ARRAY_FLAG_VERIFYING; 181*35878b55SSascha Wildner 182*35878b55SSascha Wildner /* array is being initialized */ 183*35878b55SSascha Wildner if(pMember->u.array.rf_initializing) 184*35878b55SSascha Wildner f |= ARRAY_FLAG_INITIALIZING; 185*35878b55SSascha Wildner 186*35878b55SSascha Wildner /* broken but may still working */ 187*35878b55SSascha Wildner if(pMember->u.array.rf_broken) 188*35878b55SSascha Wildner f |= ARRAY_FLAG_BROKEN; 189*35878b55SSascha Wildner 190*35878b55SSascha Wildner /* a newly created array */ 191*35878b55SSascha Wildner if(pMember->u.array.rf_newly_created) 192*35878b55SSascha Wildner f |= ARRAY_FLAG_NEWLY_CREATED; 193*35878b55SSascha Wildner 194*35878b55SSascha Wildner /* auto-rebuild should start */ 195*35878b55SSascha Wildner if(pMember->u.array.rf_auto_rebuild) 196*35878b55SSascha Wildner f |= ARRAY_FLAG_NEED_AUTOREBUILD; 197*35878b55SSascha Wildner } 198*35878b55SSascha Wildner 199*35878b55SSascha Wildner return f; 200*35878b55SSascha Wildner } 201*35878b55SSascha Wildner 202*35878b55SSascha Wildner static DWORD calc_rebuild_progress(PVDevice pVDevice) 203*35878b55SSascha Wildner { 204*35878b55SSascha Wildner int i; 205*35878b55SSascha Wildner DWORD result = ((ULONG)(pVDevice->u.array.RebuildSectors>>11)*1000 / 206*35878b55SSascha Wildner (ULONG)(pVDevice->VDeviceCapacity>>11) * (pVDevice->u.array.bArnMember-1)) * 10; 207*35878b55SSascha Wildner 208*35878b55SSascha Wildner for(i = 0; i < pVDevice->u.array.bArnMember; i++) 209*35878b55SSascha Wildner { 210*35878b55SSascha Wildner PVDevice pMember = pVDevice->u.array.pMember[i]; 211*35878b55SSascha Wildner if (!pMember || !pMember->vf_online || (pMember->VDeviceType==VD_SINGLE_DISK)) 212*35878b55SSascha Wildner continue; 213*35878b55SSascha Wildner 214*35878b55SSascha Wildner /* for RAID1/0 case */ 215*35878b55SSascha Wildner if (pMember->u.array.rf_rebuilding || 216*35878b55SSascha Wildner pMember->u.array.rf_verifying || 217*35878b55SSascha Wildner pMember->u.array.rf_initializing) 218*35878b55SSascha Wildner { 219*35878b55SSascha Wildner DWORD percent = ((ULONG)(pMember->u.array.RebuildSectors>>11)*1000 / 220*35878b55SSascha Wildner (ULONG)(pMember->VDeviceCapacity>>11) * (pMember->u.array.bArnMember-1)) * 10; 221*35878b55SSascha Wildner if (result==0 || result>percent) 222*35878b55SSascha Wildner result = percent; 223*35878b55SSascha Wildner } 224*35878b55SSascha Wildner } 225*35878b55SSascha Wildner 226*35878b55SSascha Wildner if (result>10000) result = 10000; 227*35878b55SSascha Wildner return result; 228*35878b55SSascha Wildner } 229*35878b55SSascha Wildner 230*35878b55SSascha Wildner static void get_array_info(PVDevice pVDevice, PHPT_ARRAY_INFO pArrayInfo) 231*35878b55SSascha Wildner { 232*35878b55SSascha Wildner int i; 233*35878b55SSascha Wildner 234*35878b55SSascha Wildner memcpy(pArrayInfo->Name, pVDevice->u.array.ArrayName, MAX_ARRAY_NAME); 235*35878b55SSascha Wildner pArrayInfo->ArrayType = get_vdev_type(pVDevice); 236*35878b55SSascha Wildner pArrayInfo->BlockSizeShift = pVDevice->u.array.bArBlockSizeShift; 237*35878b55SSascha Wildner pArrayInfo->RebuiltSectors = pVDevice->u.array.RebuildSectors; 238*35878b55SSascha Wildner pArrayInfo->Flags = get_array_flag(pVDevice); 239*35878b55SSascha Wildner pArrayInfo->RebuildingProgress = calc_rebuild_progress(pVDevice); 240*35878b55SSascha Wildner 241*35878b55SSascha Wildner pArrayInfo->nDisk = 0; 242*35878b55SSascha Wildner 243*35878b55SSascha Wildner for(i = 0; i < pVDevice->u.array.bArnMember; i++) 244*35878b55SSascha Wildner if(pVDevice->u.array.pMember[i] != NULL) 245*35878b55SSascha Wildner pArrayInfo->Members[pArrayInfo->nDisk++] = VDEV_TO_ID(pVDevice->u.array.pMember[i]); 246*35878b55SSascha Wildner 247*35878b55SSascha Wildner for(i=pArrayInfo->nDisk; i<MAX_ARRAY_MEMBERS; i++) 248*35878b55SSascha Wildner pArrayInfo->Members[i] = INVALID_DEVICEID; 249*35878b55SSascha Wildner } 250*35878b55SSascha Wildner 251*35878b55SSascha Wildner static void get_array_info_v2(PVDevice pVDevice, PHPT_ARRAY_INFO_V2 pArrayInfo) 252*35878b55SSascha Wildner { 253*35878b55SSascha Wildner int i; 254*35878b55SSascha Wildner 255*35878b55SSascha Wildner memcpy(pArrayInfo->Name, pVDevice->u.array.ArrayName, MAX_ARRAYNAME_LEN); 256*35878b55SSascha Wildner pArrayInfo->ArrayType = get_vdev_type(pVDevice); 257*35878b55SSascha Wildner pArrayInfo->BlockSizeShift = pVDevice->u.array.bArBlockSizeShift; 258*35878b55SSascha Wildner pArrayInfo->RebuiltSectors.lo32 = pVDevice->u.array.RebuildSectors; 259*35878b55SSascha Wildner pArrayInfo->RebuiltSectors.hi32 = sizeof(LBA_T)>4? (pVDevice->u.array.RebuildSectors>>32) : 0; 260*35878b55SSascha Wildner pArrayInfo->Flags = get_array_flag(pVDevice); 261*35878b55SSascha Wildner pArrayInfo->RebuildingProgress = calc_rebuild_progress(pVDevice); 262*35878b55SSascha Wildner 263*35878b55SSascha Wildner pArrayInfo->nDisk = 0; 264*35878b55SSascha Wildner 265*35878b55SSascha Wildner for(i = 0; i < pVDevice->u.array.bArnMember; i++) 266*35878b55SSascha Wildner if(pVDevice->u.array.pMember[i] != NULL) 267*35878b55SSascha Wildner pArrayInfo->Members[pArrayInfo->nDisk++] = VDEV_TO_ID(pVDevice->u.array.pMember[i]); 268*35878b55SSascha Wildner 269*35878b55SSascha Wildner for(i=pArrayInfo->nDisk; i<MAX_ARRAY_MEMBERS_V2; i++) 270*35878b55SSascha Wildner pArrayInfo->Members[i] = INVALID_DEVICEID; 271*35878b55SSascha Wildner } 272*35878b55SSascha Wildner #endif 273*35878b55SSascha Wildner 274*35878b55SSascha Wildner static int get_disk_info(PVDevice pVDevice, PDEVICE_INFO pDiskInfo) 275*35878b55SSascha Wildner { 276*35878b55SSascha Wildner MV_SATA_ADAPTER *pSataAdapter; 277*35878b55SSascha Wildner MV_SATA_CHANNEL *pSataChannel; 278*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapter; 279*35878b55SSascha Wildner MV_CHANNEL *channelInfo; 280*35878b55SSascha Wildner char *p; 281*35878b55SSascha Wildner int i; 282*35878b55SSascha Wildner 283*35878b55SSascha Wildner /* device location */ 284*35878b55SSascha Wildner pSataChannel = pVDevice->u.disk.mv; 285*35878b55SSascha Wildner if(pSataChannel == NULL) return -1; 286*35878b55SSascha Wildner pDiskInfo->TargetId = 0; 287*35878b55SSascha Wildner pSataAdapter = pSataChannel->mvSataAdapter; 288*35878b55SSascha Wildner if(pSataAdapter == NULL) return -1; 289*35878b55SSascha Wildner 290*35878b55SSascha Wildner pAdapter = pSataAdapter->IALData; 291*35878b55SSascha Wildner 292*35878b55SSascha Wildner pDiskInfo->PathId = pSataChannel->channelNumber; 293*35878b55SSascha Wildner pDiskInfo->ControllerId = (UCHAR)pSataAdapter->adapterId; 294*35878b55SSascha Wildner 295*35878b55SSascha Wildner /*GUI uses DeviceModeSetting to display to users 296*35878b55SSascha Wildner (1) if users select a mode, GUI/BIOS should display that mode. 297*35878b55SSascha Wildner (2) if SATA/150, GUI/BIOS should display 150 if case (1) isn't satisfied. 298*35878b55SSascha Wildner (3) display real mode if case (1)&&(2) not satisfied. 299*35878b55SSascha Wildner */ 300*35878b55SSascha Wildner if (pVDevice->u.disk.df_user_mode_set) 301*35878b55SSascha Wildner pDiskInfo->DeviceModeSetting = pVDevice->u.disk.bDeUserSelectMode; 302*35878b55SSascha Wildner else if (((((PIDENTIFY_DATA)pVDevice->u.disk.mv->identifyDevice)->SataCapability) & 3)==2) 303*35878b55SSascha Wildner pDiskInfo->DeviceModeSetting = 15; 304*35878b55SSascha Wildner else { 305*35878b55SSascha Wildner p = (char *)&((PIDENTIFY_DATA)pVDevice->u.disk.mv->identifyDevice)->ModelNumber; 306*35878b55SSascha Wildner if (*(WORD*)p==(0x5354) /*'ST'*/ && 307*35878b55SSascha Wildner (*(WORD*)(p+8)==(0x4153)/*'AS'*/ || (p[8]=='A' && p[11]=='S'))) 308*35878b55SSascha Wildner pDiskInfo->DeviceModeSetting = 15; 309*35878b55SSascha Wildner else 310*35878b55SSascha Wildner pDiskInfo->DeviceModeSetting = pVDevice->u.disk.bDeModeSetting; 311*35878b55SSascha Wildner } 312*35878b55SSascha Wildner 313*35878b55SSascha Wildner pDiskInfo->UsableMode = pVDevice->u.disk.bDeUsable_Mode; 314*35878b55SSascha Wildner 315*35878b55SSascha Wildner pDiskInfo->DeviceType = PDT_HARDDISK; 316*35878b55SSascha Wildner 317*35878b55SSascha Wildner pDiskInfo->Flags = 0x0; 318*35878b55SSascha Wildner 319*35878b55SSascha Wildner /* device is disabled */ 320*35878b55SSascha Wildner if(!pVDevice->u.disk.df_on_line) 321*35878b55SSascha Wildner pDiskInfo->Flags |= DEVICE_FLAG_DISABLED; 322*35878b55SSascha Wildner 323*35878b55SSascha Wildner /* disk has a active partition */ 324*35878b55SSascha Wildner if(pVDevice->vf_bootable) 325*35878b55SSascha Wildner pDiskInfo->Flags |= DEVICE_FLAG_BOOTDISK; 326*35878b55SSascha Wildner 327*35878b55SSascha Wildner /* disk has boot mark set */ 328*35878b55SSascha Wildner if(pVDevice->vf_bootmark) 329*35878b55SSascha Wildner pDiskInfo->Flags |= DEVICE_FLAG_BOOTMARK; 330*35878b55SSascha Wildner 331*35878b55SSascha Wildner pDiskInfo->Flags |= DEVICE_FLAG_SATA; 332*35878b55SSascha Wildner 333*35878b55SSascha Wildner /* is a spare disk */ 334*35878b55SSascha Wildner if(pVDevice->VDeviceType == VD_SPARE) 335*35878b55SSascha Wildner pDiskInfo->Flags |= DEVICE_FLAG_IS_SPARE; 336*35878b55SSascha Wildner 337*35878b55SSascha Wildner memcpy(&(pDiskInfo->IdentifyData), (pSataChannel->identifyDevice), sizeof(IDENTIFY_DATA2)); 338*35878b55SSascha Wildner p = (char *)&pDiskInfo->IdentifyData.ModelNumber; 339*35878b55SSascha Wildner for (i = 0; i < 20; i++) 340*35878b55SSascha Wildner ((WORD*)p)[i] = shortswap(pSataChannel->identifyDevice[IDEN_MODEL_OFFSET+i]); 341*35878b55SSascha Wildner p[39] = '\0'; 342*35878b55SSascha Wildner 343*35878b55SSascha Wildner channelInfo = &pAdapter->mvChannel[pSataChannel->channelNumber]; 344*35878b55SSascha Wildner pDiskInfo->ReadAheadSupported = channelInfo->readAheadSupported; 345*35878b55SSascha Wildner pDiskInfo->ReadAheadEnabled = channelInfo->readAheadEnabled; 346*35878b55SSascha Wildner pDiskInfo->WriteCacheSupported = channelInfo->writeCacheSupported; 347*35878b55SSascha Wildner pDiskInfo->WriteCacheEnabled = channelInfo->writeCacheEnabled; 348*35878b55SSascha Wildner pDiskInfo->TCQSupported = (pSataChannel->identifyDevice[IDEN_SUPPORTED_COMMANDS2] & (0x2))!=0; 349*35878b55SSascha Wildner pDiskInfo->TCQEnabled = pSataChannel->queuedDMA==MV_EDMA_MODE_QUEUED; 350*35878b55SSascha Wildner pDiskInfo->NCQSupported = MV_SATA_GEN_2(pSataAdapter) && 351*35878b55SSascha Wildner (pSataChannel->identifyDevice[IDEN_SATA_CAPABILITIES] & (0x0100)); 352*35878b55SSascha Wildner pDiskInfo->NCQEnabled = pSataChannel->queuedDMA==MV_EDMA_MODE_NATIVE_QUEUING; 353*35878b55SSascha Wildner return 0; 354*35878b55SSascha Wildner } 355*35878b55SSascha Wildner 356*35878b55SSascha Wildner int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap) 357*35878b55SSascha Wildner { 358*35878b55SSascha Wildner ZeroMemory(cap, sizeof(DRIVER_CAPABILITIES)); 359*35878b55SSascha Wildner cap->dwSize = sizeof(DRIVER_CAPABILITIES); 360*35878b55SSascha Wildner cap->MaximumControllers = MAX_VBUS; 361*35878b55SSascha Wildner 362*35878b55SSascha Wildner /* cap->SupportCrossControllerRAID = 0; */ 363*35878b55SSascha Wildner /* take care for various OSes! */ 364*35878b55SSascha Wildner cap->SupportCrossControllerRAID = 0; 365*35878b55SSascha Wildner 366*35878b55SSascha Wildner 367*35878b55SSascha Wildner cap->MinimumBlockSizeShift = MinBlockSizeShift; 368*35878b55SSascha Wildner cap->MaximumBlockSizeShift = MaxBlockSizeShift; 369*35878b55SSascha Wildner cap->SupportDiskModeSetting = 0; 370*35878b55SSascha Wildner cap->SupportSparePool = 1; 371*35878b55SSascha Wildner cap->MaximumArrayNameLength = MAX_ARRAY_NAME - 1; 372*35878b55SSascha Wildner cap->SupportDedicatedSpare = 0; 373*35878b55SSascha Wildner 374*35878b55SSascha Wildner 375*35878b55SSascha Wildner #ifdef SUPPORT_ARRAY 376*35878b55SSascha Wildner /* Stripe */ 377*35878b55SSascha Wildner cap->SupportedRAIDTypes[0] = AT_RAID0; 378*35878b55SSascha Wildner cap->MaximumArrayMembers[0] = MAX_MEMBERS; 379*35878b55SSascha Wildner /* Mirror */ 380*35878b55SSascha Wildner cap->SupportedRAIDTypes[1] = AT_RAID1; 381*35878b55SSascha Wildner cap->MaximumArrayMembers[1] = 2; 382*35878b55SSascha Wildner /* Mirror + Stripe */ 383*35878b55SSascha Wildner #ifdef ARRAY_V2_ONLY 384*35878b55SSascha Wildner cap->SupportedRAIDTypes[2] = (AT_RAID1<<4)|AT_RAID0; /* RAID0/1 */ 385*35878b55SSascha Wildner #else 386*35878b55SSascha Wildner cap->SupportedRAIDTypes[2] = (AT_RAID0<<4)|AT_RAID1; /* RAID1/0 */ 387*35878b55SSascha Wildner #endif 388*35878b55SSascha Wildner cap->MaximumArrayMembers[2] = MAX_MEMBERS; 389*35878b55SSascha Wildner /* Jbod */ 390*35878b55SSascha Wildner cap->SupportedRAIDTypes[3] = AT_JBOD; 391*35878b55SSascha Wildner cap->MaximumArrayMembers[3] = MAX_MEMBERS; 392*35878b55SSascha Wildner /* RAID5 */ 393*35878b55SSascha Wildner #if SUPPORT_RAID5 394*35878b55SSascha Wildner cap->SupportedRAIDTypes[4] = AT_RAID5; 395*35878b55SSascha Wildner cap->MaximumArrayMembers[4] = MAX_MEMBERS; 396*35878b55SSascha Wildner #endif 397*35878b55SSascha Wildner #endif 398*35878b55SSascha Wildner return 0; 399*35878b55SSascha Wildner } 400*35878b55SSascha Wildner 401*35878b55SSascha Wildner int hpt_get_controller_count(void) 402*35878b55SSascha Wildner { 403*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapTemp = gIal_Adapter; 404*35878b55SSascha Wildner int iControllerCount = 0; 405*35878b55SSascha Wildner 406*35878b55SSascha Wildner while(pAdapTemp != 0) 407*35878b55SSascha Wildner { 408*35878b55SSascha Wildner iControllerCount++; 409*35878b55SSascha Wildner pAdapTemp = pAdapTemp->next; 410*35878b55SSascha Wildner } 411*35878b55SSascha Wildner 412*35878b55SSascha Wildner return iControllerCount; 413*35878b55SSascha Wildner } 414*35878b55SSascha Wildner 415*35878b55SSascha Wildner int hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo) 416*35878b55SSascha Wildner { 417*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapTemp; 418*35878b55SSascha Wildner int iControllerCount = 0; 419*35878b55SSascha Wildner 420*35878b55SSascha Wildner for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) { 421*35878b55SSascha Wildner if (iControllerCount++==id) { 422*35878b55SSascha Wildner pInfo->InterruptLevel = 0; 423*35878b55SSascha Wildner pInfo->ChipType = 0; 424*35878b55SSascha Wildner pInfo->ChipFlags = CHIP_SUPPORT_ULTRA_100; 425*35878b55SSascha Wildner strcpy( pInfo->szVendorID, "HighPoint Technologies, Inc."); 426*35878b55SSascha Wildner #ifdef GUI_CONTROLLER_NAME 427*35878b55SSascha Wildner #ifdef FORCE_ATA150_DISPLAY 428*35878b55SSascha Wildner /* show "Bus Type: ATA/150" in GUI for SATA controllers */ 429*35878b55SSascha Wildner pInfo->ChipFlags = CHIP_SUPPORT_ULTRA_150; 430*35878b55SSascha Wildner #endif 431*35878b55SSascha Wildner strcpy(pInfo->szProductID, GUI_CONTROLLER_NAME); 432*35878b55SSascha Wildner #define _set_product_id(x) 433*35878b55SSascha Wildner #else 434*35878b55SSascha Wildner #define _set_product_id(x) strcpy(pInfo->szProductID, x) 435*35878b55SSascha Wildner #endif 436*35878b55SSascha Wildner _set_product_id("RocketRAID 18xx SATA Controller"); 437*35878b55SSascha Wildner pInfo->NumBuses = 8; 438*35878b55SSascha Wildner pInfo->ChipFlags |= CHIP_SUPPORT_ULTRA_133|CHIP_SUPPORT_ULTRA_150; 439*35878b55SSascha Wildner return 0; 440*35878b55SSascha Wildner } 441*35878b55SSascha Wildner } 442*35878b55SSascha Wildner return -1; 443*35878b55SSascha Wildner } 444*35878b55SSascha Wildner 445*35878b55SSascha Wildner 446*35878b55SSascha Wildner int hpt_get_channel_info(int id, int bus, PCHANNEL_INFO pInfo) 447*35878b55SSascha Wildner { 448*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapTemp = gIal_Adapter; 449*35878b55SSascha Wildner int i,iControllerCount = 0; 450*35878b55SSascha Wildner 451*35878b55SSascha Wildner while(pAdapTemp != 0) 452*35878b55SSascha Wildner { 453*35878b55SSascha Wildner if (iControllerCount++==id) 454*35878b55SSascha Wildner goto found; 455*35878b55SSascha Wildner pAdapTemp = pAdapTemp->next; 456*35878b55SSascha Wildner } 457*35878b55SSascha Wildner return -1; 458*35878b55SSascha Wildner 459*35878b55SSascha Wildner found: 460*35878b55SSascha Wildner 461*35878b55SSascha Wildner pInfo->IoPort = 0; 462*35878b55SSascha Wildner pInfo->ControlPort = 0; 463*35878b55SSascha Wildner 464*35878b55SSascha Wildner for (i=0; i<2 ;i++) 465*35878b55SSascha Wildner { 466*35878b55SSascha Wildner pInfo->Devices[i] = (DEVICEID)INVALID_DEVICEID; 467*35878b55SSascha Wildner } 468*35878b55SSascha Wildner 469*35878b55SSascha Wildner if (pAdapTemp->mvChannel[bus].online == MV_TRUE) 470*35878b55SSascha Wildner pInfo->Devices[0] = VDEV_TO_ID(&pAdapTemp->VDevices[bus]); 471*35878b55SSascha Wildner else 472*35878b55SSascha Wildner pInfo->Devices[0] = (DEVICEID)INVALID_DEVICEID; 473*35878b55SSascha Wildner 474*35878b55SSascha Wildner return 0; 475*35878b55SSascha Wildner 476*35878b55SSascha Wildner 477*35878b55SSascha Wildner } 478*35878b55SSascha Wildner 479*35878b55SSascha Wildner int hpt_get_logical_devices(DEVICEID * pIds, int nMaxCount) 480*35878b55SSascha Wildner { 481*35878b55SSascha Wildner int count = 0; 482*35878b55SSascha Wildner int i,j; 483*35878b55SSascha Wildner PVDevice pPhysical, pLogical; 484*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapTemp; 485*35878b55SSascha Wildner 486*35878b55SSascha Wildner for(i = 0; i < nMaxCount; i++) 487*35878b55SSascha Wildner pIds[i] = INVALID_DEVICEID; 488*35878b55SSascha Wildner 489*35878b55SSascha Wildner /* append the arrays not registered on VBus */ 490*35878b55SSascha Wildner for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) { 491*35878b55SSascha Wildner for(i = 0; i < MV_SATA_CHANNELS_NUM; i++) 492*35878b55SSascha Wildner { 493*35878b55SSascha Wildner pPhysical = &pAdapTemp->VDevices[i]; 494*35878b55SSascha Wildner pLogical = pPhysical; 495*35878b55SSascha Wildner 496*35878b55SSascha Wildner while (pLogical->pParent) pLogical = pLogical->pParent; 497*35878b55SSascha Wildner if (pLogical->VDeviceType==VD_SPARE) 498*35878b55SSascha Wildner continue; 499*35878b55SSascha Wildner 500*35878b55SSascha Wildner for (j=0; j<count; j++) 501*35878b55SSascha Wildner if (pIds[j]==VDEV_TO_ID(pLogical)) goto next; 502*35878b55SSascha Wildner pIds[count++] = VDEV_TO_ID(pLogical); 503*35878b55SSascha Wildner if (count>=nMaxCount) goto done; 504*35878b55SSascha Wildner next:; 505*35878b55SSascha Wildner } 506*35878b55SSascha Wildner } 507*35878b55SSascha Wildner 508*35878b55SSascha Wildner done: 509*35878b55SSascha Wildner return count; 510*35878b55SSascha Wildner } 511*35878b55SSascha Wildner 512*35878b55SSascha Wildner int hpt_get_device_info(DEVICEID id, PLOGICAL_DEVICE_INFO pInfo) 513*35878b55SSascha Wildner { 514*35878b55SSascha Wildner PVDevice pVDevice = ID_TO_VDEV(id); 515*35878b55SSascha Wildner 516*35878b55SSascha Wildner if((id == 0) || check_VDevice_valid(pVDevice)) 517*35878b55SSascha Wildner return -1; 518*35878b55SSascha Wildner 519*35878b55SSascha Wildner #ifdef SUPPORT_ARRAY 520*35878b55SSascha Wildner if (mIsArray(pVDevice)) { 521*35878b55SSascha Wildner pInfo->Type = LDT_ARRAY; 522*35878b55SSascha Wildner pInfo->Capacity = pVDevice->VDeviceCapacity; 523*35878b55SSascha Wildner pInfo->ParentArray = VDEV_TO_ID(pVDevice->pParent); 524*35878b55SSascha Wildner get_array_info(pVDevice, &pInfo->u.array); 525*35878b55SSascha Wildner return 0; 526*35878b55SSascha Wildner } 527*35878b55SSascha Wildner #endif 528*35878b55SSascha Wildner 529*35878b55SSascha Wildner pInfo->Type = LDT_DEVICE; 530*35878b55SSascha Wildner pInfo->ParentArray = pVDevice->pParent? VDEV_TO_ID(pVDevice->pParent) : INVALID_DEVICEID; 531*35878b55SSascha Wildner /* report real capacity to be compatible with old arrays */ 532*35878b55SSascha Wildner pInfo->Capacity = pVDevice->u.disk.dDeRealCapacity; 533*35878b55SSascha Wildner return get_disk_info(pVDevice, &pInfo->u.device); 534*35878b55SSascha Wildner } 535*35878b55SSascha Wildner 536*35878b55SSascha Wildner int hpt_get_device_info_v2(DEVICEID id, PLOGICAL_DEVICE_INFO_V2 pInfo) 537*35878b55SSascha Wildner { 538*35878b55SSascha Wildner PVDevice pVDevice = ID_TO_VDEV(id); 539*35878b55SSascha Wildner 540*35878b55SSascha Wildner if((id == 0) || check_VDevice_valid(pVDevice)) 541*35878b55SSascha Wildner return -1; 542*35878b55SSascha Wildner 543*35878b55SSascha Wildner #ifdef SUPPORT_ARRAY 544*35878b55SSascha Wildner if (mIsArray(pVDevice)) { 545*35878b55SSascha Wildner pInfo->Type = LDT_ARRAY; 546*35878b55SSascha Wildner pInfo->Capacity.lo32 = pVDevice->VDeviceCapacity; 547*35878b55SSascha Wildner pInfo->Capacity.hi32 = sizeof(LBA_T)>4? (pVDevice->VDeviceCapacity>>32) : 0; 548*35878b55SSascha Wildner pInfo->ParentArray = VDEV_TO_ID(pVDevice->pParent); 549*35878b55SSascha Wildner get_array_info_v2(pVDevice, &pInfo->u.array); 550*35878b55SSascha Wildner return 0; 551*35878b55SSascha Wildner } 552*35878b55SSascha Wildner #endif 553*35878b55SSascha Wildner 554*35878b55SSascha Wildner pInfo->Type = LDT_DEVICE; 555*35878b55SSascha Wildner pInfo->ParentArray = pVDevice->pParent? VDEV_TO_ID(pVDevice->pParent) : INVALID_DEVICEID; 556*35878b55SSascha Wildner /* report real capacity to be compatible with old arrays */ 557*35878b55SSascha Wildner pInfo->Capacity.lo32 = pVDevice->u.disk.dDeRealCapacity; 558*35878b55SSascha Wildner pInfo->Capacity.hi32 = 0; 559*35878b55SSascha Wildner return get_disk_info(pVDevice, &pInfo->u.device); 560*35878b55SSascha Wildner } 561*35878b55SSascha Wildner 562*35878b55SSascha Wildner #ifdef SUPPORT_ARRAY 563*35878b55SSascha Wildner DEVICEID hpt_create_array_v2(_VBUS_ARG PCREATE_ARRAY_PARAMS_V2 pParam) 564*35878b55SSascha Wildner { 565*35878b55SSascha Wildner ULONG Stamp = GetStamp(); 566*35878b55SSascha Wildner int i,j; 567*35878b55SSascha Wildner LBA_T capacity = MAX_LBA_T; 568*35878b55SSascha Wildner PVDevice pArray,pChild; 569*35878b55SSascha Wildner int Loca = -1; 570*35878b55SSascha Wildner 571*35878b55SSascha Wildner if (pParam->nDisk > MAX_MEMBERS) 572*35878b55SSascha Wildner return INVALID_DEVICEID; 573*35878b55SSascha Wildner /* check in verify_vd 574*35878b55SSascha Wildner for(i = 0; i < pParam->nDisk; i++) 575*35878b55SSascha Wildner { 576*35878b55SSascha Wildner PVDevice pVDev = ID_TO_VDEV(pParam->Members[i]); 577*35878b55SSascha Wildner if (check_VDevice_valid(pVDev)) return INVALID_DEVICEID; 578*35878b55SSascha Wildner if (mIsArray(pVDev)) return INVALID_DEVICEID; 579*35878b55SSascha Wildner if (!pVDev->vf_online) return INVALID_DEVICEID; 580*35878b55SSascha Wildner if (!_vbus_p) 581*35878b55SSascha Wildner _vbus_p = pVDev->u.disk.pVBus; 582*35878b55SSascha Wildner else if (_vbus_p != pVDev->u.disk.pVBus) 583*35878b55SSascha Wildner return INVALID_DEVICEID; 584*35878b55SSascha Wildner } 585*35878b55SSascha Wildner */ 586*35878b55SSascha Wildner _vbus_p = (ID_TO_VDEV(pParam->Members[0]))->u.disk.pVBus; 587*35878b55SSascha Wildner if (!_vbus_p) return INVALID_DEVICEID; 588*35878b55SSascha Wildner 589*35878b55SSascha Wildner mArGetArrayTable(pArray); 590*35878b55SSascha Wildner if(!pArray) return INVALID_DEVICEID; 591*35878b55SSascha Wildner 592*35878b55SSascha Wildner switch (pParam->ArrayType) 593*35878b55SSascha Wildner { 594*35878b55SSascha Wildner case AT_JBOD: 595*35878b55SSascha Wildner pArray->VDeviceType = VD_JBOD; 596*35878b55SSascha Wildner goto simple; 597*35878b55SSascha Wildner 598*35878b55SSascha Wildner case AT_RAID0: 599*35878b55SSascha Wildner if((pParam->BlockSizeShift < MinBlockSizeShift) || (pParam->BlockSizeShift > MaxBlockSizeShift)) 600*35878b55SSascha Wildner goto error; 601*35878b55SSascha Wildner pArray->VDeviceType = VD_RAID_0; 602*35878b55SSascha Wildner goto simple; 603*35878b55SSascha Wildner 604*35878b55SSascha Wildner case AT_RAID5: 605*35878b55SSascha Wildner if((pParam->BlockSizeShift < MinBlockSizeShift) || (pParam->BlockSizeShift > MaxBlockSizeShift)) 606*35878b55SSascha Wildner goto error; 607*35878b55SSascha Wildner pArray->VDeviceType = VD_RAID_5; 608*35878b55SSascha Wildner /* only "no build" R5 is not critical after creation. */ 609*35878b55SSascha Wildner if ((pParam->CreateFlags & CAF_CREATE_R5_NO_BUILD)==0) 610*35878b55SSascha Wildner pArray->u.array.rf_need_rebuild = 1; 611*35878b55SSascha Wildner goto simple; 612*35878b55SSascha Wildner 613*35878b55SSascha Wildner case AT_RAID1: 614*35878b55SSascha Wildner if(pParam->nDisk <= 2) 615*35878b55SSascha Wildner { 616*35878b55SSascha Wildner pArray->VDeviceType = VD_RAID_1; 617*35878b55SSascha Wildner simple: 618*35878b55SSascha Wildner pArray->u.array.bArnMember = pParam->nDisk; 619*35878b55SSascha Wildner pArray->u.array.bArRealnMember = pParam->nDisk; 620*35878b55SSascha Wildner pArray->u.array.bArBlockSizeShift = pParam->BlockSizeShift; 621*35878b55SSascha Wildner pArray->u.array.bStripeWitch = (1 << pParam->BlockSizeShift); 622*35878b55SSascha Wildner pArray->u.array.dArStamp = Stamp; 623*35878b55SSascha Wildner 624*35878b55SSascha Wildner pArray->u.array.rf_need_sync = 1; 625*35878b55SSascha Wildner pArray->u.array.rf_newly_created = 1; 626*35878b55SSascha Wildner 627*35878b55SSascha Wildner if ((pParam->CreateFlags & CAF_CREATE_AND_DUPLICATE) && 628*35878b55SSascha Wildner (pArray->VDeviceType == VD_RAID_1)) 629*35878b55SSascha Wildner { 630*35878b55SSascha Wildner pArray->u.array.rf_newly_created = 0; /* R1 shall still be accessible */ 631*35878b55SSascha Wildner pArray->u.array.rf_need_rebuild = 1; 632*35878b55SSascha Wildner pArray->u.array.rf_auto_rebuild = 1; 633*35878b55SSascha Wildner pArray->u.array.rf_duplicate_and_create = 1; 634*35878b55SSascha Wildner 635*35878b55SSascha Wildner for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) 636*35878b55SSascha Wildner if (_vbus_p->pVDevice[i] == ID_TO_VDEV(pParam->Members[0])) 637*35878b55SSascha Wildner Loca = i; 638*35878b55SSascha Wildner } 639*35878b55SSascha Wildner 640*35878b55SSascha Wildner pArray->u.array.RebuildSectors = pArray->u.array.rf_need_rebuild? 0 : MAX_LBA_T; 641*35878b55SSascha Wildner 642*35878b55SSascha Wildner memcpy(pArray->u.array.ArrayName, pParam->ArrayName, MAX_ARRAY_NAME); 643*35878b55SSascha Wildner 644*35878b55SSascha Wildner for(i = 0; i < pParam->nDisk; i++) 645*35878b55SSascha Wildner { 646*35878b55SSascha Wildner pArray->u.array.pMember[i] = ID_TO_VDEV(pParam->Members[i]); 647*35878b55SSascha Wildner pArray->u.array.pMember[i]->bSerialNumber = i; 648*35878b55SSascha Wildner pArray->u.array.pMember[i]->pParent = pArray; 649*35878b55SSascha Wildner 650*35878b55SSascha Wildner /* don't unregister source disk for duplicate RAID1 */ 651*35878b55SSascha Wildner if (i || 652*35878b55SSascha Wildner pArray->VDeviceType!=VD_RAID_1 || 653*35878b55SSascha Wildner (pParam->CreateFlags & CAF_CREATE_AND_DUPLICATE)==0) 654*35878b55SSascha Wildner UnregisterVDevice(pArray->u.array.pMember[i]); 655*35878b55SSascha Wildner 656*35878b55SSascha Wildner if(pArray->VDeviceType == VD_RAID_5) 657*35878b55SSascha Wildner pArray->u.array.pMember[i]->vf_cache_disk = 1; 658*35878b55SSascha Wildner } 659*35878b55SSascha Wildner } 660*35878b55SSascha Wildner else 661*35878b55SSascha Wildner { 662*35878b55SSascha Wildner for(i = 0; i < (pParam->nDisk / 2); i++) 663*35878b55SSascha Wildner { 664*35878b55SSascha Wildner mArGetArrayTable(pChild); 665*35878b55SSascha Wildner pChild->VDeviceType = VD_RAID_1; 666*35878b55SSascha Wildner 667*35878b55SSascha Wildner pChild->u.array.bArnMember = 2; 668*35878b55SSascha Wildner pChild->u.array.bArRealnMember = 2; 669*35878b55SSascha Wildner pChild->u.array.bArBlockSizeShift = pParam->BlockSizeShift; 670*35878b55SSascha Wildner pChild->u.array.bStripeWitch = (1 << pParam->BlockSizeShift); 671*35878b55SSascha Wildner pChild->u.array.dArStamp = Stamp; 672*35878b55SSascha Wildner 673*35878b55SSascha Wildner pChild->u.array.rf_need_sync = 1; 674*35878b55SSascha Wildner pChild->u.array.rf_newly_created = 1; 675*35878b55SSascha Wildner 676*35878b55SSascha Wildner pChild->u.array.RebuildSectors = MAX_LBA_T; 677*35878b55SSascha Wildner 678*35878b55SSascha Wildner memcpy(pChild->u.array.ArrayName, pParam->ArrayName, MAX_ARRAY_NAME); 679*35878b55SSascha Wildner 680*35878b55SSascha Wildner for(j = 0; j < 2; j++) 681*35878b55SSascha Wildner { 682*35878b55SSascha Wildner pChild->u.array.pMember[j] = ID_TO_VDEV(pParam->Members[i*2 + j]); 683*35878b55SSascha Wildner pChild->u.array.pMember[j]->bSerialNumber = j; 684*35878b55SSascha Wildner pChild->u.array.pMember[j]->pParent = pChild; 685*35878b55SSascha Wildner pChild->u.array.pMember[j]->pfnDeviceFailed = pfnDeviceFailed[pChild->VDeviceType]; 686*35878b55SSascha Wildner UnregisterVDevice(pChild->u.array.pMember[j]); 687*35878b55SSascha Wildner } 688*35878b55SSascha Wildner 689*35878b55SSascha Wildner pArray->u.array.pMember[i] = pChild; 690*35878b55SSascha Wildner 691*35878b55SSascha Wildner pChild->vf_online = 1; 692*35878b55SSascha Wildner pChild->bSerialNumber = i; 693*35878b55SSascha Wildner pChild->pParent = pArray; 694*35878b55SSascha Wildner pChild->VDeviceCapacity = MIN(pChild->u.array.pMember[0]->VDeviceCapacity, 695*35878b55SSascha Wildner pChild->u.array.pMember[1]->VDeviceCapacity); 696*35878b55SSascha Wildner 697*35878b55SSascha Wildner pChild->pfnSendCommand = pfnSendCommand[pChild->VDeviceType]; 698*35878b55SSascha Wildner pChild->pfnDeviceFailed = pfnDeviceFailed[VD_RAID_0]; 699*35878b55SSascha Wildner } 700*35878b55SSascha Wildner 701*35878b55SSascha Wildner pArray->VDeviceType = VD_RAID_0; 702*35878b55SSascha Wildner 703*35878b55SSascha Wildner pArray->u.array.bArnMember = pParam->nDisk / 2; 704*35878b55SSascha Wildner pArray->u.array.bArRealnMember = pParam->nDisk / 2; 705*35878b55SSascha Wildner pArray->u.array.bArBlockSizeShift = pParam->BlockSizeShift; 706*35878b55SSascha Wildner pArray->u.array.bStripeWitch = (1 << pParam->BlockSizeShift); 707*35878b55SSascha Wildner pArray->u.array.dArStamp = Stamp; 708*35878b55SSascha Wildner 709*35878b55SSascha Wildner pArray->u.array.rf_need_sync = 1; 710*35878b55SSascha Wildner pArray->u.array.rf_newly_created = 1; 711*35878b55SSascha Wildner 712*35878b55SSascha Wildner memcpy(pArray->u.array.ArrayName, pParam->ArrayName, MAX_ARRAY_NAME); 713*35878b55SSascha Wildner } 714*35878b55SSascha Wildner break; 715*35878b55SSascha Wildner 716*35878b55SSascha Wildner default: 717*35878b55SSascha Wildner goto error; 718*35878b55SSascha Wildner } 719*35878b55SSascha Wildner 720*35878b55SSascha Wildner for(i = 0; i < pArray->u.array.bArnMember; i++) 721*35878b55SSascha Wildner pArray->u.array.pMember[i]->pfnDeviceFailed = pfnDeviceFailed[pArray->VDeviceType]; 722*35878b55SSascha Wildner 723*35878b55SSascha Wildner if ((pParam->CreateFlags & CAF_CREATE_AND_DUPLICATE) && 724*35878b55SSascha Wildner (pArray->VDeviceType == VD_RAID_1)) 725*35878b55SSascha Wildner { 726*35878b55SSascha Wildner pArray->vf_bootmark = pArray->u.array.pMember[0]->vf_bootmark; 727*35878b55SSascha Wildner pArray->vf_bootable = pArray->u.array.pMember[0]->vf_bootable; 728*35878b55SSascha Wildner pArray->u.array.pMember[0]->vf_bootable = 0; 729*35878b55SSascha Wildner pArray->u.array.pMember[0]->vf_bootmark = 0; 730*35878b55SSascha Wildner if (Loca>=0) { 731*35878b55SSascha Wildner _vbus_p->pVDevice[Loca] = pArray; 732*35878b55SSascha Wildner /* to comfort OS */ 733*35878b55SSascha Wildner pArray->u.array.rf_duplicate_and_created = 1; 734*35878b55SSascha Wildner pArray->pVBus = _vbus_p; 735*35878b55SSascha Wildner } 736*35878b55SSascha Wildner } 737*35878b55SSascha Wildner else { 738*35878b55SSascha Wildner UCHAR TempBuffer[512]; 739*35878b55SSascha Wildner ZeroMemory(TempBuffer, 512); 740*35878b55SSascha Wildner for(i = 0; i < pParam->nDisk; i++) 741*35878b55SSascha Wildner { 742*35878b55SSascha Wildner PVDevice pDisk = ID_TO_VDEV(pParam->Members[i]); 743*35878b55SSascha Wildner pDisk->vf_bootmark = pDisk->vf_bootable = 0; 744*35878b55SSascha Wildner fDeReadWrite(&pDisk->u.disk, 0, IDE_COMMAND_WRITE, TempBuffer); 745*35878b55SSascha Wildner } 746*35878b55SSascha Wildner } 747*35878b55SSascha Wildner 748*35878b55SSascha Wildner pArray->vf_online = 1; 749*35878b55SSascha Wildner pArray->pParent = NULL; 750*35878b55SSascha Wildner 751*35878b55SSascha Wildner switch(pArray->VDeviceType) 752*35878b55SSascha Wildner { 753*35878b55SSascha Wildner case VD_RAID_0: 754*35878b55SSascha Wildner for(i = 0; i < pArray->u.array.bArnMember; i++) 755*35878b55SSascha Wildner if(pArray->u.array.pMember[i]->VDeviceCapacity < capacity) 756*35878b55SSascha Wildner capacity = pArray->u.array.pMember[i]->VDeviceCapacity; 757*35878b55SSascha Wildner #ifdef ARRAY_V2_ONLY 758*35878b55SSascha Wildner capacity -= 10; 759*35878b55SSascha Wildner #endif 760*35878b55SSascha Wildner capacity &= ~(pArray->u.array.bStripeWitch - 1); 761*35878b55SSascha Wildner /* shrink member capacity for RAID 1/0 */ 762*35878b55SSascha Wildner for(i = 0; i < pArray->u.array.bArnMember; i++) 763*35878b55SSascha Wildner if (mIsArray(pArray->u.array.pMember[i])) 764*35878b55SSascha Wildner pArray->u.array.pMember[i]->VDeviceCapacity = capacity; 765*35878b55SSascha Wildner pArray->VDeviceCapacity = capacity * pArray->u.array.bArnMember; 766*35878b55SSascha Wildner break; 767*35878b55SSascha Wildner 768*35878b55SSascha Wildner case VD_RAID_1: 769*35878b55SSascha Wildner pArray->VDeviceCapacity = MIN(pArray->u.array.pMember[0]->VDeviceCapacity, 770*35878b55SSascha Wildner pArray->u.array.pMember[1]->VDeviceCapacity); 771*35878b55SSascha Wildner break; 772*35878b55SSascha Wildner 773*35878b55SSascha Wildner case VD_JBOD: 774*35878b55SSascha Wildner for(i = 0; i < pArray->u.array.bArnMember; i++) 775*35878b55SSascha Wildner pArray->VDeviceCapacity += pArray->u.array.pMember[i]->VDeviceCapacity 776*35878b55SSascha Wildner #ifdef ARRAY_V2_ONLY 777*35878b55SSascha Wildner -10 778*35878b55SSascha Wildner #endif 779*35878b55SSascha Wildner ; 780*35878b55SSascha Wildner break; 781*35878b55SSascha Wildner 782*35878b55SSascha Wildner case VD_RAID_5: 783*35878b55SSascha Wildner for(i = 0; i < pArray->u.array.bArnMember; i++) 784*35878b55SSascha Wildner if(pArray->u.array.pMember[i]->VDeviceCapacity < capacity) 785*35878b55SSascha Wildner capacity = pArray->u.array.pMember[i]->VDeviceCapacity; 786*35878b55SSascha Wildner pArray->VDeviceCapacity = (capacity & ~(pArray->u.array.bStripeWitch - 1)) 787*35878b55SSascha Wildner * (pArray->u.array.bArnMember - 1); 788*35878b55SSascha Wildner break; 789*35878b55SSascha Wildner 790*35878b55SSascha Wildner default: 791*35878b55SSascha Wildner goto error; 792*35878b55SSascha Wildner } 793*35878b55SSascha Wildner 794*35878b55SSascha Wildner pArray->pfnSendCommand = pfnSendCommand[pArray->VDeviceType]; 795*35878b55SSascha Wildner pArray->pfnDeviceFailed = fOsDiskFailed; 796*35878b55SSascha Wildner SyncArrayInfo(pArray); 797*35878b55SSascha Wildner 798*35878b55SSascha Wildner if (!pArray->u.array.rf_duplicate_and_created) 799*35878b55SSascha Wildner RegisterVDevice(pArray); 800*35878b55SSascha Wildner return VDEV_TO_ID(pArray); 801*35878b55SSascha Wildner 802*35878b55SSascha Wildner error: 803*35878b55SSascha Wildner for(i = 0; i < pArray->u.array.bArnMember; i++) 804*35878b55SSascha Wildner { 805*35878b55SSascha Wildner pChild = pArray->u.array.pMember[i]; 806*35878b55SSascha Wildner if((pChild != NULL) && (pChild->VDeviceType != VD_SINGLE_DISK)) 807*35878b55SSascha Wildner mArFreeArrayTable(pChild); 808*35878b55SSascha Wildner } 809*35878b55SSascha Wildner mArFreeArrayTable(pArray); 810*35878b55SSascha Wildner return INVALID_DEVICEID; 811*35878b55SSascha Wildner } 812*35878b55SSascha Wildner 813*35878b55SSascha Wildner DEVICEID hpt_create_array(_VBUS_ARG PCREATE_ARRAY_PARAMS pParam) 814*35878b55SSascha Wildner { 815*35878b55SSascha Wildner CREATE_ARRAY_PARAMS_V2 param2; 816*35878b55SSascha Wildner param2.ArrayType = pParam->ArrayType; 817*35878b55SSascha Wildner param2.nDisk = pParam->nDisk; 818*35878b55SSascha Wildner param2.BlockSizeShift = pParam->BlockSizeShift; 819*35878b55SSascha Wildner param2.CreateFlags = pParam->CreateFlags; 820*35878b55SSascha Wildner param2.CreateTime = pParam->CreateTime; 821*35878b55SSascha Wildner memcpy(param2.ArrayName, pParam->ArrayName, sizeof(param2.ArrayName)); 822*35878b55SSascha Wildner memcpy(param2.Description, pParam->Description, sizeof(param2.Description)); 823*35878b55SSascha Wildner memcpy(param2.CreateManager, pParam->CreateManager, sizeof(param2.CreateManager)); 824*35878b55SSascha Wildner param2.Capacity.lo32 = param2.Capacity.hi32 = 0; 825*35878b55SSascha Wildner memcpy(param2.Members, pParam->Members, sizeof(pParam->Members)); 826*35878b55SSascha Wildner return hpt_create_array_v2(_VBUS_P ¶m2); 827*35878b55SSascha Wildner } 828*35878b55SSascha Wildner 829*35878b55SSascha Wildner #ifdef SUPPORT_OLD_ARRAY 830*35878b55SSascha Wildner /* this is only for old RAID 0/1 */ 831*35878b55SSascha Wildner int old_add_disk_to_raid01(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk) 832*35878b55SSascha Wildner { 833*35878b55SSascha Wildner PVDevice pArray1 = ID_TO_VDEV(idArray); 834*35878b55SSascha Wildner PVDevice pArray2 = 0; 835*35878b55SSascha Wildner PVDevice pDisk = ID_TO_VDEV(idDisk); 836*35878b55SSascha Wildner int i; 837*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapter = gIal_Adapter; 838*35878b55SSascha Wildner 839*35878b55SSascha Wildner if (pArray1->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;} 840*35878b55SSascha Wildner 841*35878b55SSascha Wildner if(pDisk->u.disk.dDeRealCapacity < (pArray1->VDeviceCapacity / 2)) 842*35878b55SSascha Wildner return -1; 843*35878b55SSascha Wildner 844*35878b55SSascha Wildner pArray2 = pArray1->u.array.pMember[1]; 845*35878b55SSascha Wildner if(pArray2 == NULL) { 846*35878b55SSascha Wildner /* create a Stripe */ 847*35878b55SSascha Wildner mArGetArrayTable(pArray2); 848*35878b55SSascha Wildner pArray2->VDeviceType = VD_RAID_0; 849*35878b55SSascha Wildner pArray2->u.array.dArStamp = GetStamp(); 850*35878b55SSascha Wildner pArray2->vf_format_v2 = 1; 851*35878b55SSascha Wildner pArray2->u.array.rf_broken = 1; 852*35878b55SSascha Wildner pArray2->u.array.bArBlockSizeShift = pArray1->u.array.bArBlockSizeShift; 853*35878b55SSascha Wildner pArray2->u.array.bStripeWitch = (1 << pArray2->u.array.bArBlockSizeShift); 854*35878b55SSascha Wildner pArray2->u.array.bArnMember = 2; 855*35878b55SSascha Wildner pArray2->VDeviceCapacity = pArray1->VDeviceCapacity; 856*35878b55SSascha Wildner pArray2->pfnSendCommand = pfnSendCommand[pArray2->VDeviceType]; 857*35878b55SSascha Wildner pArray2->pfnDeviceFailed = pfnDeviceFailed[pArray1->VDeviceType]; 858*35878b55SSascha Wildner memcpy(pArray2->u.array.ArrayName, pArray1->u.array.ArrayName, MAX_ARRAY_NAME); 859*35878b55SSascha Wildner pArray2->pParent = pArray1; 860*35878b55SSascha Wildner pArray2->bSerialNumber = 1; 861*35878b55SSascha Wildner pArray1->u.array.pMember[1] = pArray2; 862*35878b55SSascha Wildner pArray1->u.array.bArRealnMember++; 863*35878b55SSascha Wildner } 864*35878b55SSascha Wildner 865*35878b55SSascha Wildner for(i = 0; i < pArray2->u.array.bArnMember; i++) 866*35878b55SSascha Wildner if((pArray2->u.array.pMember[i] == NULL) || !pArray2->u.array.pMember[i]->vf_online) 867*35878b55SSascha Wildner { 868*35878b55SSascha Wildner if(pArray2->u.array.pMember[i] != NULL) 869*35878b55SSascha Wildner pArray2->u.array.pMember[i]->pParent = NULL; 870*35878b55SSascha Wildner pArray2->u.array.pMember[i] = pDisk; 871*35878b55SSascha Wildner goto find; 872*35878b55SSascha Wildner } 873*35878b55SSascha Wildner return -1; 874*35878b55SSascha Wildner 875*35878b55SSascha Wildner find: 876*35878b55SSascha Wildner UnregisterVDevice(pDisk); 877*35878b55SSascha Wildner pDisk->VDeviceType = VD_SINGLE_DISK; 878*35878b55SSascha Wildner pDisk->bSerialNumber = i; 879*35878b55SSascha Wildner pDisk->pParent = pArray2; 880*35878b55SSascha Wildner pDisk->vf_format_v2 = 1; 881*35878b55SSascha Wildner pDisk->u.disk.dDeHiddenLba = i? 10 : 0; 882*35878b55SSascha Wildner pDisk->VDeviceCapacity = pDisk->u.disk.dDeRealCapacity; 883*35878b55SSascha Wildner pDisk->pfnDeviceFailed = pfnDeviceFailed[pArray2->VDeviceType]; 884*35878b55SSascha Wildner 885*35878b55SSascha Wildner pArray2->u.array.bArRealnMember++; 886*35878b55SSascha Wildner if(pArray2->u.array.bArnMember == pArray2->u.array.bArRealnMember){ 887*35878b55SSascha Wildner pArray2->vf_online = 1; 888*35878b55SSascha Wildner pArray2->u.array.rf_broken = 0; 889*35878b55SSascha Wildner } 890*35878b55SSascha Wildner 891*35878b55SSascha Wildner if(pArray1->u.array.pMember[0]->vf_online && pArray1->u.array.pMember[1]->vf_online){ 892*35878b55SSascha Wildner pArray1->u.array.bArRealnMember = pArray1->u.array.bArnMember; 893*35878b55SSascha Wildner pArray1->u.array.rf_broken = 0; 894*35878b55SSascha Wildner pArray1->u.array.rf_need_rebuild = 1; 895*35878b55SSascha Wildner pArray1->u.array.rf_auto_rebuild = 1; 896*35878b55SSascha Wildner 897*35878b55SSascha Wildner } 898*35878b55SSascha Wildner pArray1->u.array.RebuildSectors = 0; 899*35878b55SSascha Wildner pArray1->u.array.dArStamp = GetStamp(); 900*35878b55SSascha Wildner SyncArrayInfo(pArray1); 901*35878b55SSascha Wildner return 1; 902*35878b55SSascha Wildner } 903*35878b55SSascha Wildner #endif 904*35878b55SSascha Wildner 905*35878b55SSascha Wildner int hpt_add_disk_to_array(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk) 906*35878b55SSascha Wildner { 907*35878b55SSascha Wildner int i; 908*35878b55SSascha Wildner 909*35878b55SSascha Wildner LBA_T Capacity; 910*35878b55SSascha Wildner PVDevice pArray = ID_TO_VDEV(idArray); 911*35878b55SSascha Wildner PVDevice pDisk = ID_TO_VDEV(idDisk); 912*35878b55SSascha Wildner 913*35878b55SSascha Wildner if((idArray == 0) || (idDisk == 0)) return -1; 914*35878b55SSascha Wildner if(check_VDevice_valid(pArray) || check_VDevice_valid(pDisk)) return -1; 915*35878b55SSascha Wildner if(!pArray->u.array.rf_broken) return -1; 916*35878b55SSascha Wildner 917*35878b55SSascha Wildner if(pArray->VDeviceType != VD_RAID_1 && pArray->VDeviceType != VD_RAID_5) 918*35878b55SSascha Wildner return -1; 919*35878b55SSascha Wildner if((pDisk->VDeviceType != VD_SINGLE_DISK) && (pDisk->VDeviceType != VD_SPARE)) 920*35878b55SSascha Wildner return -1; 921*35878b55SSascha Wildner 922*35878b55SSascha Wildner #ifdef SUPPORT_OLD_ARRAY 923*35878b55SSascha Wildner /* RAID 0 + 1 */ 924*35878b55SSascha Wildner if (pArray->vf_format_v2 && pArray->VDeviceType==VD_RAID_1 && 925*35878b55SSascha Wildner pArray->u.array.pMember[0] && 926*35878b55SSascha Wildner mIsArray(pArray->u.array.pMember[0])) 927*35878b55SSascha Wildner { 928*35878b55SSascha Wildner if(old_add_disk_to_raid01(_VBUS_P idArray, idDisk)) 929*35878b55SSascha Wildner return 0; 930*35878b55SSascha Wildner else 931*35878b55SSascha Wildner return -1; 932*35878b55SSascha Wildner } 933*35878b55SSascha Wildner #endif 934*35878b55SSascha Wildner 935*35878b55SSascha Wildner Capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember - 1); 936*35878b55SSascha Wildner 937*35878b55SSascha Wildner if (pArray->vf_format_v2) { 938*35878b55SSascha Wildner if(pDisk->u.disk.dDeRealCapacity < Capacity) return -1; 939*35878b55SSascha Wildner } 940*35878b55SSascha Wildner else 941*35878b55SSascha Wildner if(pDisk->VDeviceCapacity < Capacity) return -1; 942*35878b55SSascha Wildner 943*35878b55SSascha Wildner if (pArray->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;} 944*35878b55SSascha Wildner 945*35878b55SSascha Wildner for(i = 0; i < pArray->u.array.bArnMember; i++) 946*35878b55SSascha Wildner if((pArray->u.array.pMember[i] == 0) || !pArray->u.array.pMember[i]->vf_online) 947*35878b55SSascha Wildner { 948*35878b55SSascha Wildner if(pArray->u.array.pMember[i] != NULL) 949*35878b55SSascha Wildner pArray->u.array.pMember[i]->pParent = NULL; 950*35878b55SSascha Wildner pArray->u.array.pMember[i] = pDisk; 951*35878b55SSascha Wildner goto find; 952*35878b55SSascha Wildner } 953*35878b55SSascha Wildner return -1; 954*35878b55SSascha Wildner 955*35878b55SSascha Wildner find: 956*35878b55SSascha Wildner UnregisterVDevice(pDisk); 957*35878b55SSascha Wildner pDisk->VDeviceType = VD_SINGLE_DISK; 958*35878b55SSascha Wildner pDisk->bSerialNumber = i; 959*35878b55SSascha Wildner pDisk->pParent = pArray; 960*35878b55SSascha Wildner if (pArray->VDeviceType==VD_RAID_5) pDisk->vf_cache_disk = 1; 961*35878b55SSascha Wildner pDisk->pfnDeviceFailed = pfnDeviceFailed[pArray->VDeviceType]; 962*35878b55SSascha Wildner if (pArray->vf_format_v2) { 963*35878b55SSascha Wildner pDisk->vf_format_v2 = 1; 964*35878b55SSascha Wildner pDisk->VDeviceCapacity = pDisk->u.disk.dDeRealCapacity; 965*35878b55SSascha Wildner } 966*35878b55SSascha Wildner 967*35878b55SSascha Wildner pArray->u.array.bArRealnMember++; 968*35878b55SSascha Wildner if(pArray->u.array.bArnMember == pArray->u.array.bArRealnMember) 969*35878b55SSascha Wildner { 970*35878b55SSascha Wildner pArray->u.array.rf_need_rebuild = 1; 971*35878b55SSascha Wildner pArray->u.array.RebuildSectors = 0; 972*35878b55SSascha Wildner pArray->u.array.rf_auto_rebuild = 1; 973*35878b55SSascha Wildner pArray->u.array.rf_broken = 0; 974*35878b55SSascha Wildner } 975*35878b55SSascha Wildner pArray->u.array.RebuildSectors = 0; 976*35878b55SSascha Wildner 977*35878b55SSascha Wildner /* sync the whole array */ 978*35878b55SSascha Wildner while (pArray->pParent) pArray = pArray->pParent; 979*35878b55SSascha Wildner pArray->u.array.dArStamp = GetStamp(); 980*35878b55SSascha Wildner SyncArrayInfo(pArray); 981*35878b55SSascha Wildner return 0; 982*35878b55SSascha Wildner } 983*35878b55SSascha Wildner 984*35878b55SSascha Wildner int hpt_add_spare_disk(_VBUS_ARG DEVICEID idDisk) 985*35878b55SSascha Wildner { 986*35878b55SSascha Wildner PVDevice pVDevice = ID_TO_VDEV(idDisk); 987*35878b55SSascha Wildner DECLARE_BUFFER(PUCHAR, pbuffer); 988*35878b55SSascha Wildner 989*35878b55SSascha Wildner if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1; 990*35878b55SSascha Wildner if (pVDevice->VDeviceType != VD_SINGLE_DISK || pVDevice->pParent) 991*35878b55SSascha Wildner return -1; 992*35878b55SSascha Wildner 993*35878b55SSascha Wildner if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 994*35878b55SSascha Wildner 995*35878b55SSascha Wildner UnregisterVDevice(pVDevice); 996*35878b55SSascha Wildner pVDevice->VDeviceType = VD_SPARE; 997*35878b55SSascha Wildner pVDevice->vf_bootmark = 0; 998*35878b55SSascha Wildner 999*35878b55SSascha Wildner ZeroMemory((char *)pbuffer, 512); 1000*35878b55SSascha Wildner fDeReadWrite(&pVDevice->u.disk, 0, IDE_COMMAND_WRITE, pbuffer); 1001*35878b55SSascha Wildner SyncArrayInfo(pVDevice); 1002*35878b55SSascha Wildner return 0; 1003*35878b55SSascha Wildner } 1004*35878b55SSascha Wildner 1005*35878b55SSascha Wildner int hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk) 1006*35878b55SSascha Wildner { 1007*35878b55SSascha Wildner PVDevice pVDevice = ID_TO_VDEV(idDisk); 1008*35878b55SSascha Wildner 1009*35878b55SSascha Wildner if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1; 1010*35878b55SSascha Wildner 1011*35878b55SSascha Wildner if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 1012*35878b55SSascha Wildner 1013*35878b55SSascha Wildner pVDevice->VDeviceType = VD_SINGLE_DISK; 1014*35878b55SSascha Wildner 1015*35878b55SSascha Wildner SyncArrayInfo(pVDevice); 1016*35878b55SSascha Wildner RegisterVDevice(pVDevice); 1017*35878b55SSascha Wildner return 0; 1018*35878b55SSascha Wildner } 1019*35878b55SSascha Wildner 1020*35878b55SSascha Wildner int hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO pInfo) 1021*35878b55SSascha Wildner { 1022*35878b55SSascha Wildner PVDevice pVDevice = ID_TO_VDEV(idArray); 1023*35878b55SSascha Wildner 1024*35878b55SSascha Wildner if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1; 1025*35878b55SSascha Wildner if (!mIsArray(pVDevice)) return -1; 1026*35878b55SSascha Wildner 1027*35878b55SSascha Wildner /* if the pVDevice isn't a top level, return -1; */ 1028*35878b55SSascha Wildner if(pVDevice->pParent != NULL) return -1; 1029*35878b55SSascha Wildner 1030*35878b55SSascha Wildner if (pVDevice->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;} 1031*35878b55SSascha Wildner 1032*35878b55SSascha Wildner if (pInfo->ValidFields & AAIF_NAME) { 1033*35878b55SSascha Wildner memset(pVDevice->u.array.ArrayName, 0, MAX_ARRAY_NAME); 1034*35878b55SSascha Wildner memcpy(pVDevice->u.array.ArrayName, pInfo->Name, sizeof(pInfo->Name)); 1035*35878b55SSascha Wildner pVDevice->u.array.rf_need_sync = 1; 1036*35878b55SSascha Wildner } 1037*35878b55SSascha Wildner 1038*35878b55SSascha Wildner if (pInfo->ValidFields & AAIF_DESCRIPTION) { 1039*35878b55SSascha Wildner memcpy(pVDevice->u.array.Description, pInfo->Description, sizeof(pInfo->Description)); 1040*35878b55SSascha Wildner pVDevice->u.array.rf_need_sync = 1; 1041*35878b55SSascha Wildner } 1042*35878b55SSascha Wildner 1043*35878b55SSascha Wildner if (pVDevice->u.array.rf_need_sync) 1044*35878b55SSascha Wildner SyncArrayInfo(pVDevice); 1045*35878b55SSascha Wildner return 0; 1046*35878b55SSascha Wildner } 1047*35878b55SSascha Wildner 1048*35878b55SSascha Wildner static int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO pInfo) 1049*35878b55SSascha Wildner { 1050*35878b55SSascha Wildner PVDevice pVDevice = ID_TO_VDEV(idDisk); 1051*35878b55SSascha Wildner 1052*35878b55SSascha Wildner if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1; 1053*35878b55SSascha Wildner if (mIsArray(pVDevice)) 1054*35878b55SSascha Wildner return -1; 1055*35878b55SSascha Wildner 1056*35878b55SSascha Wildner if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 1057*35878b55SSascha Wildner 1058*35878b55SSascha Wildner /* TODO */ 1059*35878b55SSascha Wildner return 0; 1060*35878b55SSascha Wildner } 1061*35878b55SSascha Wildner 1062*35878b55SSascha Wildner static int hpt_set_device_info_v2(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO_V2 pInfo) 1063*35878b55SSascha Wildner { 1064*35878b55SSascha Wildner PVDevice pVDevice = ID_TO_VDEV(idDisk); 1065*35878b55SSascha Wildner int sync = 0; 1066*35878b55SSascha Wildner 1067*35878b55SSascha Wildner if(idDisk==0 || check_VDevice_valid(pVDevice)) return -1; 1068*35878b55SSascha Wildner if (mIsArray(pVDevice)) 1069*35878b55SSascha Wildner return -1; 1070*35878b55SSascha Wildner 1071*35878b55SSascha Wildner if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 1072*35878b55SSascha Wildner 1073*35878b55SSascha Wildner if (pInfo->ValidFields & ADIF_MODE) { 1074*35878b55SSascha Wildner pVDevice->u.disk.bDeModeSetting = pInfo->DeviceModeSetting; 1075*35878b55SSascha Wildner pVDevice->u.disk.bDeUserSelectMode = pInfo->DeviceModeSetting; 1076*35878b55SSascha Wildner pVDevice->u.disk.df_user_mode_set = 1; 1077*35878b55SSascha Wildner fDeSelectMode((PDevice)&(pVDevice->u.disk), (UCHAR)pInfo->DeviceModeSetting); 1078*35878b55SSascha Wildner sync = 1; 1079*35878b55SSascha Wildner } 1080*35878b55SSascha Wildner 1081*35878b55SSascha Wildner if (pInfo->ValidFields & ADIF_TCQ) { 1082*35878b55SSascha Wildner if (fDeSetTCQ(&pVDevice->u.disk, pInfo->TCQEnabled, 0)) { 1083*35878b55SSascha Wildner pVDevice->u.disk.df_tcq_set = 1; 1084*35878b55SSascha Wildner pVDevice->u.disk.df_tcq = pInfo->TCQEnabled!=0; 1085*35878b55SSascha Wildner sync = 1; 1086*35878b55SSascha Wildner } 1087*35878b55SSascha Wildner } 1088*35878b55SSascha Wildner 1089*35878b55SSascha Wildner if (pInfo->ValidFields & ADIF_NCQ) { 1090*35878b55SSascha Wildner if (fDeSetNCQ(&pVDevice->u.disk, pInfo->NCQEnabled, 0)) { 1091*35878b55SSascha Wildner pVDevice->u.disk.df_ncq_set = 1; 1092*35878b55SSascha Wildner pVDevice->u.disk.df_ncq = pInfo->NCQEnabled!=0; 1093*35878b55SSascha Wildner sync = 1; 1094*35878b55SSascha Wildner } 1095*35878b55SSascha Wildner } 1096*35878b55SSascha Wildner 1097*35878b55SSascha Wildner if (pInfo->ValidFields & ADIF_WRITE_CACHE) { 1098*35878b55SSascha Wildner if (fDeSetWriteCache(&pVDevice->u.disk, pInfo->WriteCacheEnabled)) { 1099*35878b55SSascha Wildner pVDevice->u.disk.df_write_cache_set = 1; 1100*35878b55SSascha Wildner pVDevice->u.disk.df_write_cache = pInfo->WriteCacheEnabled!=0; 1101*35878b55SSascha Wildner sync = 1; 1102*35878b55SSascha Wildner } 1103*35878b55SSascha Wildner } 1104*35878b55SSascha Wildner 1105*35878b55SSascha Wildner if (pInfo->ValidFields & ADIF_READ_AHEAD) { 1106*35878b55SSascha Wildner if (fDeSetReadAhead(&pVDevice->u.disk, pInfo->ReadAheadEnabled)) { 1107*35878b55SSascha Wildner pVDevice->u.disk.df_read_ahead_set = 1; 1108*35878b55SSascha Wildner pVDevice->u.disk.df_read_ahead = pInfo->ReadAheadEnabled!=0; 1109*35878b55SSascha Wildner sync = 1; 1110*35878b55SSascha Wildner } 1111*35878b55SSascha Wildner } 1112*35878b55SSascha Wildner 1113*35878b55SSascha Wildner if (sync) 1114*35878b55SSascha Wildner SyncArrayInfo(pVDevice); 1115*35878b55SSascha Wildner return 0; 1116*35878b55SSascha Wildner } 1117*35878b55SSascha Wildner 1118*35878b55SSascha Wildner #endif 1119*35878b55SSascha Wildner 1120*35878b55SSascha Wildner /* hpt_default_ioctl() 1121*35878b55SSascha Wildner * This is a default implementation. The platform dependent part 1122*35878b55SSascha Wildner * may reuse this function and/or use it own implementation for 1123*35878b55SSascha Wildner * each ioctl function. 1124*35878b55SSascha Wildner */ 1125*35878b55SSascha Wildner int hpt_default_ioctl(_VBUS_ARG 1126*35878b55SSascha Wildner DWORD dwIoControlCode, /* operation control code */ 1127*35878b55SSascha Wildner PVOID lpInBuffer, /* input data buffer */ 1128*35878b55SSascha Wildner DWORD nInBufferSize, /* size of input data buffer */ 1129*35878b55SSascha Wildner PVOID lpOutBuffer, /* output data buffer */ 1130*35878b55SSascha Wildner DWORD nOutBufferSize, /* size of output data buffer */ 1131*35878b55SSascha Wildner PDWORD lpBytesReturned /* byte count */ 1132*35878b55SSascha Wildner ) 1133*35878b55SSascha Wildner { 1134*35878b55SSascha Wildner switch(dwIoControlCode) { 1135*35878b55SSascha Wildner 1136*35878b55SSascha Wildner case HPT_IOCTL_GET_VERSION: 1137*35878b55SSascha Wildner 1138*35878b55SSascha Wildner if (nInBufferSize != 0) return -1; 1139*35878b55SSascha Wildner if (nOutBufferSize != sizeof(DWORD)) return -1; 1140*35878b55SSascha Wildner *((DWORD*)lpOutBuffer) = HPT_INTERFACE_VERSION; 1141*35878b55SSascha Wildner break; 1142*35878b55SSascha Wildner 1143*35878b55SSascha Wildner case HPT_IOCTL_GET_CONTROLLER_COUNT: 1144*35878b55SSascha Wildner 1145*35878b55SSascha Wildner if (nOutBufferSize!=sizeof(DWORD)) return -1; 1146*35878b55SSascha Wildner *(PDWORD)lpOutBuffer = hpt_get_controller_count(); 1147*35878b55SSascha Wildner break; 1148*35878b55SSascha Wildner 1149*35878b55SSascha Wildner case HPT_IOCTL_GET_CONTROLLER_INFO: 1150*35878b55SSascha Wildner { 1151*35878b55SSascha Wildner int id; 1152*35878b55SSascha Wildner PCONTROLLER_INFO pInfo; 1153*35878b55SSascha Wildner 1154*35878b55SSascha Wildner if (nInBufferSize!=sizeof(DWORD)) return -1; 1155*35878b55SSascha Wildner if (nOutBufferSize!=sizeof(CONTROLLER_INFO)) return -1; 1156*35878b55SSascha Wildner 1157*35878b55SSascha Wildner id = *(DWORD *)lpInBuffer; 1158*35878b55SSascha Wildner pInfo = (PCONTROLLER_INFO)lpOutBuffer; 1159*35878b55SSascha Wildner if (hpt_get_controller_info(id, pInfo)!=0) 1160*35878b55SSascha Wildner return -1; 1161*35878b55SSascha Wildner } 1162*35878b55SSascha Wildner break; 1163*35878b55SSascha Wildner 1164*35878b55SSascha Wildner case HPT_IOCTL_GET_CHANNEL_INFO: 1165*35878b55SSascha Wildner { 1166*35878b55SSascha Wildner int id, bus; 1167*35878b55SSascha Wildner PCHANNEL_INFO pInfo; 1168*35878b55SSascha Wildner 1169*35878b55SSascha Wildner if (nInBufferSize!=8) return -1; 1170*35878b55SSascha Wildner if (nOutBufferSize!=sizeof(CHANNEL_INFO)) return -1; 1171*35878b55SSascha Wildner 1172*35878b55SSascha Wildner id = *(DWORD *)lpInBuffer; 1173*35878b55SSascha Wildner bus = ((DWORD *)lpInBuffer)[1]; 1174*35878b55SSascha Wildner pInfo = (PCHANNEL_INFO)lpOutBuffer; 1175*35878b55SSascha Wildner 1176*35878b55SSascha Wildner if (hpt_get_channel_info(id, bus, pInfo)!=0) 1177*35878b55SSascha Wildner return -1; 1178*35878b55SSascha Wildner } 1179*35878b55SSascha Wildner break; 1180*35878b55SSascha Wildner 1181*35878b55SSascha Wildner case HPT_IOCTL_GET_LOGICAL_DEVICES: 1182*35878b55SSascha Wildner { 1183*35878b55SSascha Wildner DWORD nMax; 1184*35878b55SSascha Wildner DEVICEID *pIds; 1185*35878b55SSascha Wildner 1186*35878b55SSascha Wildner if (nInBufferSize!=sizeof(DWORD)) return -1; 1187*35878b55SSascha Wildner nMax = *(DWORD *)lpInBuffer; 1188*35878b55SSascha Wildner if (nOutBufferSize < sizeof(DWORD)+sizeof(DWORD)*nMax) return -1; 1189*35878b55SSascha Wildner 1190*35878b55SSascha Wildner pIds = ((DEVICEID *)lpOutBuffer)+1; 1191*35878b55SSascha Wildner *(DWORD*)lpOutBuffer = hpt_get_logical_devices(pIds, nMax); 1192*35878b55SSascha Wildner } 1193*35878b55SSascha Wildner break; 1194*35878b55SSascha Wildner 1195*35878b55SSascha Wildner case HPT_IOCTL_GET_DEVICE_INFO: 1196*35878b55SSascha Wildner { 1197*35878b55SSascha Wildner DEVICEID id; 1198*35878b55SSascha Wildner PLOGICAL_DEVICE_INFO pInfo; 1199*35878b55SSascha Wildner 1200*35878b55SSascha Wildner if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1201*35878b55SSascha Wildner if (nOutBufferSize!=sizeof(LOGICAL_DEVICE_INFO)) return -1; 1202*35878b55SSascha Wildner 1203*35878b55SSascha Wildner id = *(DWORD *)lpInBuffer; 1204*35878b55SSascha Wildner if (id == INVALID_DEVICEID) return -1; 1205*35878b55SSascha Wildner 1206*35878b55SSascha Wildner pInfo = (PLOGICAL_DEVICE_INFO)lpOutBuffer; 1207*35878b55SSascha Wildner memset(pInfo, 0, sizeof(LOGICAL_DEVICE_INFO)); 1208*35878b55SSascha Wildner 1209*35878b55SSascha Wildner if (hpt_get_device_info(id, pInfo)!=0) 1210*35878b55SSascha Wildner return -1; 1211*35878b55SSascha Wildner } 1212*35878b55SSascha Wildner break; 1213*35878b55SSascha Wildner 1214*35878b55SSascha Wildner case HPT_IOCTL_GET_DEVICE_INFO_V2: 1215*35878b55SSascha Wildner { 1216*35878b55SSascha Wildner DEVICEID id; 1217*35878b55SSascha Wildner PLOGICAL_DEVICE_INFO_V2 pInfo; 1218*35878b55SSascha Wildner 1219*35878b55SSascha Wildner if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1220*35878b55SSascha Wildner if (nOutBufferSize!=sizeof(LOGICAL_DEVICE_INFO_V2)) return -1; 1221*35878b55SSascha Wildner 1222*35878b55SSascha Wildner id = *(DWORD *)lpInBuffer; 1223*35878b55SSascha Wildner if (id == INVALID_DEVICEID) return -1; 1224*35878b55SSascha Wildner 1225*35878b55SSascha Wildner pInfo = (PLOGICAL_DEVICE_INFO_V2)lpOutBuffer; 1226*35878b55SSascha Wildner memset(pInfo, 0, sizeof(LOGICAL_DEVICE_INFO_V2)); 1227*35878b55SSascha Wildner 1228*35878b55SSascha Wildner if (hpt_get_device_info_v2(id, pInfo)!=0) 1229*35878b55SSascha Wildner return -1; 1230*35878b55SSascha Wildner } 1231*35878b55SSascha Wildner break; 1232*35878b55SSascha Wildner 1233*35878b55SSascha Wildner #ifdef SUPPORT_ARRAY 1234*35878b55SSascha Wildner case HPT_IOCTL_CREATE_ARRAY: 1235*35878b55SSascha Wildner { 1236*35878b55SSascha Wildner if (nInBufferSize!=sizeof(CREATE_ARRAY_PARAMS)) return -1; 1237*35878b55SSascha Wildner if (nOutBufferSize!=sizeof(DEVICEID)) return -1; 1238*35878b55SSascha Wildner 1239*35878b55SSascha Wildner *(DEVICEID *)lpOutBuffer = hpt_create_array(_VBUS_P (PCREATE_ARRAY_PARAMS)lpInBuffer); 1240*35878b55SSascha Wildner 1241*35878b55SSascha Wildner if(*(DEVICEID *)lpOutBuffer == INVALID_DEVICEID) 1242*35878b55SSascha Wildner return -1; 1243*35878b55SSascha Wildner } 1244*35878b55SSascha Wildner break; 1245*35878b55SSascha Wildner 1246*35878b55SSascha Wildner case HPT_IOCTL_CREATE_ARRAY_V2: 1247*35878b55SSascha Wildner { 1248*35878b55SSascha Wildner if (nInBufferSize!=sizeof(CREATE_ARRAY_PARAMS_V2)) return -1; 1249*35878b55SSascha Wildner if (nOutBufferSize!=sizeof(DEVICEID)) return -1; 1250*35878b55SSascha Wildner 1251*35878b55SSascha Wildner *(DEVICEID *)lpOutBuffer = hpt_create_array_v2(_VBUS_P (PCREATE_ARRAY_PARAMS_V2)lpInBuffer); 1252*35878b55SSascha Wildner 1253*35878b55SSascha Wildner if (*(DEVICEID *)lpOutBuffer == INVALID_DEVICEID) 1254*35878b55SSascha Wildner return -1; 1255*35878b55SSascha Wildner } 1256*35878b55SSascha Wildner break; 1257*35878b55SSascha Wildner 1258*35878b55SSascha Wildner case HPT_IOCTL_SET_ARRAY_INFO: 1259*35878b55SSascha Wildner { 1260*35878b55SSascha Wildner DEVICEID idArray; 1261*35878b55SSascha Wildner PALTERABLE_ARRAY_INFO pInfo; 1262*35878b55SSascha Wildner 1263*35878b55SSascha Wildner if (nInBufferSize!=sizeof(HPT_SET_ARRAY_INFO)) return -1; 1264*35878b55SSascha Wildner if (nOutBufferSize!=0) return -1; 1265*35878b55SSascha Wildner 1266*35878b55SSascha Wildner idArray = ((PHPT_SET_ARRAY_INFO)lpInBuffer)->idArray; 1267*35878b55SSascha Wildner pInfo = &((PHPT_SET_ARRAY_INFO)lpInBuffer)->Info; 1268*35878b55SSascha Wildner 1269*35878b55SSascha Wildner if(hpt_set_array_info(_VBUS_P idArray, pInfo)) 1270*35878b55SSascha Wildner return -1; 1271*35878b55SSascha Wildner } 1272*35878b55SSascha Wildner break; 1273*35878b55SSascha Wildner 1274*35878b55SSascha Wildner case HPT_IOCTL_SET_DEVICE_INFO: 1275*35878b55SSascha Wildner { 1276*35878b55SSascha Wildner DEVICEID idDisk; 1277*35878b55SSascha Wildner PALTERABLE_DEVICE_INFO pInfo; 1278*35878b55SSascha Wildner 1279*35878b55SSascha Wildner if (nInBufferSize!=sizeof(HPT_SET_DEVICE_INFO)) return -1; 1280*35878b55SSascha Wildner if (nOutBufferSize!=0) return -1; 1281*35878b55SSascha Wildner 1282*35878b55SSascha Wildner idDisk = ((PHPT_SET_DEVICE_INFO)lpInBuffer)->idDisk; 1283*35878b55SSascha Wildner pInfo = &((PHPT_SET_DEVICE_INFO)lpInBuffer)->Info; 1284*35878b55SSascha Wildner if(hpt_set_device_info(_VBUS_P idDisk, pInfo) != 0) 1285*35878b55SSascha Wildner return -1; 1286*35878b55SSascha Wildner } 1287*35878b55SSascha Wildner break; 1288*35878b55SSascha Wildner 1289*35878b55SSascha Wildner case HPT_IOCTL_SET_DEVICE_INFO_V2: 1290*35878b55SSascha Wildner { 1291*35878b55SSascha Wildner DEVICEID idDisk; 1292*35878b55SSascha Wildner PALTERABLE_DEVICE_INFO_V2 pInfo; 1293*35878b55SSascha Wildner 1294*35878b55SSascha Wildner if (nInBufferSize < sizeof(HPT_SET_DEVICE_INFO_V2)) return -1; 1295*35878b55SSascha Wildner if (nOutBufferSize!=0) return -1; 1296*35878b55SSascha Wildner 1297*35878b55SSascha Wildner idDisk = ((PHPT_SET_DEVICE_INFO_V2)lpInBuffer)->idDisk; 1298*35878b55SSascha Wildner pInfo = &((PHPT_SET_DEVICE_INFO_V2)lpInBuffer)->Info; 1299*35878b55SSascha Wildner if(hpt_set_device_info_v2(_VBUS_P idDisk, pInfo) != 0) 1300*35878b55SSascha Wildner return -1; 1301*35878b55SSascha Wildner } 1302*35878b55SSascha Wildner break; 1303*35878b55SSascha Wildner 1304*35878b55SSascha Wildner case HPT_IOCTL_SET_BOOT_MARK: 1305*35878b55SSascha Wildner { 1306*35878b55SSascha Wildner DEVICEID id; 1307*35878b55SSascha Wildner PVDevice pTop; 1308*35878b55SSascha Wildner int i; 1309*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapter = gIal_Adapter; 1310*35878b55SSascha Wildner PVBus pVBus; 1311*35878b55SSascha Wildner 1312*35878b55SSascha Wildner if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1313*35878b55SSascha Wildner id = *(DEVICEID *)lpInBuffer; 1314*35878b55SSascha Wildner while(pAdapter != 0) 1315*35878b55SSascha Wildner { 1316*35878b55SSascha Wildner pVBus = &pAdapter->VBus; 1317*35878b55SSascha Wildner for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) 1318*35878b55SSascha Wildner { 1319*35878b55SSascha Wildner if(!(pTop = pVBus->pVDevice[i])) continue; 1320*35878b55SSascha Wildner if (pTop->pVBus!=_vbus_p) return -1; 1321*35878b55SSascha Wildner while (pTop->pParent) pTop = pTop->pParent; 1322*35878b55SSascha Wildner if (id==0 && pTop->vf_bootmark) 1323*35878b55SSascha Wildner pTop->vf_bootmark = 0; 1324*35878b55SSascha Wildner else if (pTop==ID_TO_VDEV(id) && !pTop->vf_bootmark) 1325*35878b55SSascha Wildner pTop->vf_bootmark = 1; 1326*35878b55SSascha Wildner else 1327*35878b55SSascha Wildner continue; 1328*35878b55SSascha Wildner SyncArrayInfo(pTop); 1329*35878b55SSascha Wildner break; 1330*35878b55SSascha Wildner } 1331*35878b55SSascha Wildner pAdapter = pAdapter->next; 1332*35878b55SSascha Wildner } 1333*35878b55SSascha Wildner } 1334*35878b55SSascha Wildner break; 1335*35878b55SSascha Wildner 1336*35878b55SSascha Wildner case HPT_IOCTL_ADD_SPARE_DISK: 1337*35878b55SSascha Wildner { 1338*35878b55SSascha Wildner DEVICEID id; 1339*35878b55SSascha Wildner 1340*35878b55SSascha Wildner if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1341*35878b55SSascha Wildner if (nOutBufferSize!=0) return -1; 1342*35878b55SSascha Wildner 1343*35878b55SSascha Wildner id = *(DEVICEID *)lpInBuffer; 1344*35878b55SSascha Wildner 1345*35878b55SSascha Wildner if(hpt_add_spare_disk(_VBUS_P id)) 1346*35878b55SSascha Wildner return -1; 1347*35878b55SSascha Wildner } 1348*35878b55SSascha Wildner break; 1349*35878b55SSascha Wildner 1350*35878b55SSascha Wildner case HPT_IOCTL_REMOVE_SPARE_DISK: 1351*35878b55SSascha Wildner { 1352*35878b55SSascha Wildner DEVICEID id; 1353*35878b55SSascha Wildner 1354*35878b55SSascha Wildner if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1355*35878b55SSascha Wildner if (nOutBufferSize!=0) return -1; 1356*35878b55SSascha Wildner 1357*35878b55SSascha Wildner id = *(DEVICEID *)lpInBuffer; 1358*35878b55SSascha Wildner 1359*35878b55SSascha Wildner if(hpt_remove_spare_disk(_VBUS_P id)) 1360*35878b55SSascha Wildner return -1; 1361*35878b55SSascha Wildner } 1362*35878b55SSascha Wildner break; 1363*35878b55SSascha Wildner 1364*35878b55SSascha Wildner case HPT_IOCTL_ADD_DISK_TO_ARRAY: 1365*35878b55SSascha Wildner { 1366*35878b55SSascha Wildner DEVICEID id1,id2; 1367*35878b55SSascha Wildner id1 = ((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray; 1368*35878b55SSascha Wildner id2 = ((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idDisk; 1369*35878b55SSascha Wildner 1370*35878b55SSascha Wildner if (nInBufferSize != sizeof(HPT_ADD_DISK_TO_ARRAY)) return -1; 1371*35878b55SSascha Wildner if (nOutBufferSize != 0) return -1; 1372*35878b55SSascha Wildner 1373*35878b55SSascha Wildner if(hpt_add_disk_to_array(_VBUS_P id1, id2)) 1374*35878b55SSascha Wildner return -1; 1375*35878b55SSascha Wildner } 1376*35878b55SSascha Wildner break; 1377*35878b55SSascha Wildner #endif 1378*35878b55SSascha Wildner case HPT_IOCTL_GET_DRIVER_CAPABILITIES: 1379*35878b55SSascha Wildner { 1380*35878b55SSascha Wildner PDRIVER_CAPABILITIES cap; 1381*35878b55SSascha Wildner if (nOutBufferSize<sizeof(DRIVER_CAPABILITIES)) return -1; 1382*35878b55SSascha Wildner cap = (PDRIVER_CAPABILITIES)lpOutBuffer; 1383*35878b55SSascha Wildner 1384*35878b55SSascha Wildner if(hpt_get_driver_capabilities(cap)) 1385*35878b55SSascha Wildner return -1; 1386*35878b55SSascha Wildner } 1387*35878b55SSascha Wildner break; 1388*35878b55SSascha Wildner 1389*35878b55SSascha Wildner case HPT_IOCTL_GET_CONTROLLER_VENID: 1390*35878b55SSascha Wildner { 1391*35878b55SSascha Wildner DWORD id = ((DWORD*)lpInBuffer)[0]; 1392*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapTemp; 1393*35878b55SSascha Wildner int iControllerCount = 0; 1394*35878b55SSascha Wildner 1395*35878b55SSascha Wildner for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) 1396*35878b55SSascha Wildner if (iControllerCount++==id) 1397*35878b55SSascha Wildner break; 1398*35878b55SSascha Wildner 1399*35878b55SSascha Wildner if (!pAdapTemp) 1400*35878b55SSascha Wildner return -1; 1401*35878b55SSascha Wildner 1402*35878b55SSascha Wildner if (nOutBufferSize < 4) 1403*35878b55SSascha Wildner return -1; 1404*35878b55SSascha Wildner 1405*35878b55SSascha Wildner *(DWORD*)lpOutBuffer = ((DWORD)pAdapTemp->mvSataAdapter.pciConfigDeviceId << 16) | 0x11AB; 1406*35878b55SSascha Wildner return 0; 1407*35878b55SSascha Wildner } 1408*35878b55SSascha Wildner 1409*35878b55SSascha Wildner case HPT_IOCTL_EPROM_IO: 1410*35878b55SSascha Wildner { 1411*35878b55SSascha Wildner DWORD id = ((DWORD*)lpInBuffer)[0]; 1412*35878b55SSascha Wildner DWORD offset = ((DWORD*)lpInBuffer)[1]; 1413*35878b55SSascha Wildner DWORD direction = ((DWORD*)lpInBuffer)[2]; 1414*35878b55SSascha Wildner DWORD length = ((DWORD*)lpInBuffer)[3]; 1415*35878b55SSascha Wildner IAL_ADAPTER_T *pAdapTemp; 1416*35878b55SSascha Wildner int iControllerCount = 0; 1417*35878b55SSascha Wildner 1418*35878b55SSascha Wildner for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) 1419*35878b55SSascha Wildner if (iControllerCount++==id) 1420*35878b55SSascha Wildner break; 1421*35878b55SSascha Wildner 1422*35878b55SSascha Wildner if (!pAdapTemp) 1423*35878b55SSascha Wildner return -1; 1424*35878b55SSascha Wildner 1425*35878b55SSascha Wildner if (nInBufferSize < sizeof(DWORD) * 4 + (direction? length : 0) || 1426*35878b55SSascha Wildner nOutBufferSize < (direction? 0 : length)) 1427*35878b55SSascha Wildner return -1; 1428*35878b55SSascha Wildner 1429*35878b55SSascha Wildner if (direction == 0) /* read */ 1430*35878b55SSascha Wildner sx508x_flash_access(&pAdapTemp->mvSataAdapter, 1431*35878b55SSascha Wildner offset, lpOutBuffer, length, 1); 1432*35878b55SSascha Wildner else 1433*35878b55SSascha Wildner sx508x_flash_access(&pAdapTemp->mvSataAdapter, 1434*35878b55SSascha Wildner offset, (char *)lpInBuffer + 16, length, 0); 1435*35878b55SSascha Wildner 1436*35878b55SSascha Wildner return 0; 1437*35878b55SSascha Wildner } 1438*35878b55SSascha Wildner break; 1439*35878b55SSascha Wildner 1440*35878b55SSascha Wildner default: 1441*35878b55SSascha Wildner return -1; 1442*35878b55SSascha Wildner } 1443*35878b55SSascha Wildner 1444*35878b55SSascha Wildner if (lpBytesReturned) 1445*35878b55SSascha Wildner *lpBytesReturned = nOutBufferSize; 1446*35878b55SSascha Wildner return 0; 1447*35878b55SSascha Wildner } 1448