1136849Sscottl/* 2149871Sscottl * Copyright (c) 2004-2005 HighPoint Technologies, Inc. 3136849Sscottl * All rights reserved. 4136849Sscottl * 5136849Sscottl * Redistribution and use in source and binary forms, with or without 6136849Sscottl * modification, are permitted provided that the following conditions 7136849Sscottl * are met: 8136849Sscottl * 1. Redistributions of source code must retain the above copyright 9136849Sscottl * notice, this list of conditions and the following disclaimer. 10136849Sscottl * 2. Redistributions in binary form must reproduce the above copyright 11136849Sscottl * notice, this list of conditions and the following disclaimer in the 12136849Sscottl * documentation and/or other materials provided with the distribution. 13136849Sscottl * 14136849Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15136849Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16136849Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17136849Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18136849Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19136849Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20136849Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21136849Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22136849Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23136849Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24136849Sscottl * SUCH DAMAGE. 25142988Sscottl * 26142988Sscottl * $FreeBSD$ 27136849Sscottl */ 28136849Sscottl/* 29136849Sscottl * gui_lib.c 30136849Sscottl * Copyright (c) 2002-2004 HighPoint Technologies, Inc. All rights reserved. 31136849Sscottl * 32136849Sscottl * Platform independent ioctl interface implementation. 33136849Sscottl * The platform dependent part may reuse this function and/or use it own 34136849Sscottl * implementation for each ioctl function. 35136849Sscottl * 36136849Sscottl * This implementation doesn't use any synchronization; the caller must 37136849Sscottl * assure the proper context when calling these functions. 38136849Sscottl */ 39136849Sscottl 40136849Sscottl#include <sys/param.h> 41136849Sscottl#include <sys/systm.h> 42136849Sscottl#include <sys/kernel.h> 43136849Sscottl#include <sys/malloc.h> 44136849Sscottl 45149871Sscottl#ifndef __KERNEL__ 46149871Sscottl#define __KERNEL__ 47149871Sscottl#endif 48149871Sscottl 49136849Sscottl#include <dev/hptmv/global.h> 50136849Sscottl#include <dev/hptmv/hptintf.h> 51136849Sscottl#include <dev/hptmv/osbsd.h> 52143039Sscottl#include <dev/hptmv/access601.h> 53136849Sscottl 54136849Sscottlstatic int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap); 55136849Sscottlstatic int hpt_get_controller_count(void); 56136849Sscottlstatic int hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo); 57136849Sscottlstatic int hpt_get_channel_info(int id, int bus, PCHANNEL_INFO pInfo); 58136849Sscottlstatic int hpt_get_logical_devices(DEVICEID * pIds, int nMaxCount); 59136849Sscottlstatic int hpt_get_device_info(DEVICEID id, PLOGICAL_DEVICE_INFO pInfo); 60190809Sdelphijstatic int hpt_get_device_info_v2(DEVICEID id, PLOGICAL_DEVICE_INFO_V2 pInfo); 61136849Sscottlstatic DEVICEID hpt_create_array(_VBUS_ARG PCREATE_ARRAY_PARAMS pParam); 62190809Sdelphijstatic DEVICEID hpt_create_array_v2(_VBUS_ARG PCREATE_ARRAY_PARAMS_V2 pParam); 63136849Sscottlstatic int hpt_add_spare_disk(_VBUS_ARG DEVICEID idDisk); 64136849Sscottlstatic int hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk); 65136849Sscottlstatic int hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO pInfo); 66136849Sscottlstatic int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO pInfo); 67190809Sdelphijstatic int hpt_set_device_info_v2(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO_V2 pInfo); 68136849Sscottl 69149871Sscottlint 70149871Sscottlcheck_VDevice_valid(PVDevice p) 71136849Sscottl{ 72136849Sscottl int i; 73136849Sscottl PVDevice pVDevice; 74136849Sscottl PVBus _vbus_p; 75136849Sscottl IAL_ADAPTER_T *pAdapter = gIal_Adapter; 76136849Sscottl 77136849Sscottl while(pAdapter != 0) 78136849Sscottl { 79136849Sscottl for (i = 0; i < MV_SATA_CHANNELS_NUM; i++) 80136849Sscottl if(&(pAdapter->VDevices[i]) == p) return 0; 81136849Sscottl pAdapter = pAdapter->next; 82136849Sscottl } 83136849Sscottl 84136849Sscottl#ifdef SUPPORT_ARRAY 85136849Sscottl pAdapter = gIal_Adapter; 86136849Sscottl while(pAdapter != 0) 87136849Sscottl { 88136849Sscottl _vbus_p = &pAdapter->VBus; 89136849Sscottl for (i=0;i<MAX_ARRAY_PER_VBUS;i++) 90136849Sscottl { 91136849Sscottl pVDevice=ArrayTables(i); 92136849Sscottl if ((pVDevice->u.array.dArStamp != 0) && (pVDevice == p)) 93136849Sscottl return 0; 94136849Sscottl } 95136849Sscottl pAdapter = pAdapter->next; 96136849Sscottl } 97136849Sscottl#endif 98136849Sscottl 99136849Sscottl return -1; 100136849Sscottl} 101136849Sscottl 102136849Sscottl#ifdef SUPPORT_ARRAY 103136849Sscottl 104190809Sdelphijstatic UCHAR get_vdev_type(PVDevice pVDevice) 105136849Sscottl { 106190809Sdelphij switch (pVDevice->VDeviceType) { 107190809Sdelphij case VD_RAID_0: return AT_RAID0; 108190809Sdelphij case VD_RAID_1: return AT_RAID1; 109190809Sdelphij case VD_JBOD: return AT_JBOD; 110190809Sdelphij case VD_RAID_5: return AT_RAID5; 111190809Sdelphij default: return AT_UNKNOWN; 112136849Sscottl } 113190809Sdelphij } 114136849Sscottl 115190809Sdelphijstatic DWORD get_array_flag(PVDevice pVDevice) 116190809Sdelphij{ 117190809Sdelphij int i; 118190809Sdelphij DWORD f = 0; 119136849Sscottl 120136849Sscottl /* The array is disabled */ 121136849Sscottl if(!pVDevice->vf_online) { 122190809Sdelphij f |= ARRAY_FLAG_DISABLED; 123190809Sdelphij /* Ignore other info */ 124190809Sdelphij return f; 125136849Sscottl } 126136849Sscottl 127136849Sscottl /* array need synchronizing */ 128136849Sscottl if(pVDevice->u.array.rf_need_rebuild && !pVDevice->u.array.rf_duplicate_and_create) 129190809Sdelphij f |= ARRAY_FLAG_NEEDBUILDING; 130136849Sscottl 131136849Sscottl /* array is in rebuilding process */ 132136849Sscottl if(pVDevice->u.array.rf_rebuilding) 133190809Sdelphij f |= ARRAY_FLAG_REBUILDING; 134136849Sscottl 135136849Sscottl /* array is being verified */ 136136849Sscottl if(pVDevice->u.array.rf_verifying) 137190809Sdelphij f |= ARRAY_FLAG_VERIFYING; 138136849Sscottl 139136849Sscottl /* array is being initialized */ 140136849Sscottl if(pVDevice->u.array.rf_initializing) 141190809Sdelphij f |= ARRAY_FLAG_INITIALIZING; 142136849Sscottl 143136849Sscottl /* broken but may still working */ 144136849Sscottl if(pVDevice->u.array.rf_broken) 145190809Sdelphij f |= ARRAY_FLAG_BROKEN; 146136849Sscottl 147136849Sscottl /* array has a active partition */ 148136849Sscottl if(pVDevice->vf_bootable) 149190809Sdelphij f |= ARRAY_FLAG_BOOTDISK; 150136849Sscottl 151136849Sscottl /* a newly created array */ 152136849Sscottl if(pVDevice->u.array.rf_newly_created) 153190809Sdelphij f |= ARRAY_FLAG_NEWLY_CREATED; 154136849Sscottl 155136849Sscottl /* array has boot mark set */ 156136849Sscottl if(pVDevice->vf_bootmark) 157190809Sdelphij f |= ARRAY_FLAG_BOOTMARK; 158136849Sscottl 159136849Sscottl /* auto-rebuild should start */ 160136849Sscottl if(pVDevice->u.array.rf_auto_rebuild) 161190809Sdelphij f |= ARRAY_FLAG_NEED_AUTOREBUILD; 162136849Sscottl 163136849Sscottl for(i = 0; i < pVDevice->u.array.bArnMember; i++) 164136849Sscottl { 165136849Sscottl PVDevice pMember = pVDevice->u.array.pMember[i]; 166136849Sscottl if (!pMember || !pMember->vf_online || (pMember->VDeviceType==VD_SINGLE_DISK)) 167136849Sscottl continue; 168136849Sscottl 169136849Sscottl /* array need synchronizing */ 170136849Sscottl if(pMember->u.array.rf_need_rebuild && 171136849Sscottl !pMember->u.array.rf_duplicate_and_create) 172190809Sdelphij f |= ARRAY_FLAG_NEEDBUILDING; 173136849Sscottl 174136849Sscottl /* array is in rebuilding process */ 175136849Sscottl if(pMember->u.array.rf_rebuilding) 176190809Sdelphij f |= ARRAY_FLAG_REBUILDING; 177136849Sscottl 178136849Sscottl /* array is being verified */ 179136849Sscottl if(pMember->u.array.rf_verifying) 180190809Sdelphij f |= ARRAY_FLAG_VERIFYING; 181136849Sscottl 182136849Sscottl /* array is being initialized */ 183136849Sscottl if(pMember->u.array.rf_initializing) 184190809Sdelphij f |= ARRAY_FLAG_INITIALIZING; 185136849Sscottl 186136849Sscottl /* broken but may still working */ 187136849Sscottl if(pMember->u.array.rf_broken) 188190809Sdelphij f |= ARRAY_FLAG_BROKEN; 189136849Sscottl 190136849Sscottl /* a newly created array */ 191136849Sscottl if(pMember->u.array.rf_newly_created) 192190809Sdelphij f |= ARRAY_FLAG_NEWLY_CREATED; 193136849Sscottl 194136849Sscottl /* auto-rebuild should start */ 195136849Sscottl if(pMember->u.array.rf_auto_rebuild) 196190809Sdelphij f |= ARRAY_FLAG_NEED_AUTOREBUILD; 197190809Sdelphij } 198136849Sscottl 199190809Sdelphij return f; 200190809Sdelphij} 201190809Sdelphij 202190809Sdelphijstatic DWORD calc_rebuild_progress(PVDevice pVDevice) 203190809Sdelphij{ 204190809Sdelphij int i; 205190809Sdelphij DWORD result = ((ULONG)(pVDevice->u.array.RebuildSectors>>11)*1000 / 206190809Sdelphij (ULONG)(pVDevice->VDeviceCapacity>>11) * (pVDevice->u.array.bArnMember-1)) * 10; 207190809Sdelphij 208190809Sdelphij for(i = 0; i < pVDevice->u.array.bArnMember; i++) 209190809Sdelphij { 210190809Sdelphij PVDevice pMember = pVDevice->u.array.pMember[i]; 211190809Sdelphij if (!pMember || !pMember->vf_online || (pMember->VDeviceType==VD_SINGLE_DISK)) 212190809Sdelphij continue; 213190809Sdelphij 214136849Sscottl /* for RAID1/0 case */ 215136849Sscottl if (pMember->u.array.rf_rebuilding || 216136849Sscottl pMember->u.array.rf_verifying || 217136849Sscottl pMember->u.array.rf_initializing) 218136849Sscottl { 219190809Sdelphij DWORD percent = ((ULONG)(pMember->u.array.RebuildSectors>>11)*1000 / 220190809Sdelphij (ULONG)(pMember->VDeviceCapacity>>11) * (pMember->u.array.bArnMember-1)) * 10; 221190809Sdelphij if (result==0 || result>percent) 222190809Sdelphij result = percent; 223136849Sscottl } 224190809Sdelphij } 225190809Sdelphij 226190809Sdelphij if (result>10000) result = 10000; 227190809Sdelphij return result; 228136849Sscottl } 229136849Sscottl 230190809Sdelphijstatic void get_array_info(PVDevice pVDevice, PHPT_ARRAY_INFO pArrayInfo) 231190809Sdelphij{ 232190809Sdelphij int i; 233136849Sscottl 234190809Sdelphij memcpy(pArrayInfo->Name, pVDevice->u.array.ArrayName, MAX_ARRAY_NAME); 235190809Sdelphij pArrayInfo->ArrayType = get_vdev_type(pVDevice); 236190809Sdelphij pArrayInfo->BlockSizeShift = pVDevice->u.array.bArBlockSizeShift; 237190809Sdelphij pArrayInfo->RebuiltSectors = pVDevice->u.array.RebuildSectors; 238190809Sdelphij pArrayInfo->Flags = get_array_flag(pVDevice); 239190809Sdelphij pArrayInfo->RebuildingProgress = calc_rebuild_progress(pVDevice); 240136849Sscottl 241190809Sdelphij pArrayInfo->nDisk = 0; 242136849Sscottl 243136849Sscottl for(i = 0; i < pVDevice->u.array.bArnMember; i++) 244190809Sdelphij if(pVDevice->u.array.pMember[i] != NULL) 245190809Sdelphij pArrayInfo->Members[pArrayInfo->nDisk++] = VDEV_TO_ID(pVDevice->u.array.pMember[i]); 246190809Sdelphij 247190809Sdelphij for(i=pArrayInfo->nDisk; i<MAX_ARRAY_MEMBERS; i++) 248190809Sdelphij pArrayInfo->Members[i] = INVALID_DEVICEID; 249136849Sscottl } 250190809Sdelphij 251190809Sdelphijstatic void get_array_info_v2(PVDevice pVDevice, PHPT_ARRAY_INFO_V2 pArrayInfo) 252190809Sdelphij{ 253190809Sdelphij int i; 254190809Sdelphij 255190809Sdelphij memcpy(pArrayInfo->Name, pVDevice->u.array.ArrayName, MAX_ARRAYNAME_LEN); 256190809Sdelphij pArrayInfo->ArrayType = get_vdev_type(pVDevice); 257190809Sdelphij pArrayInfo->BlockSizeShift = pVDevice->u.array.bArBlockSizeShift; 258190809Sdelphij pArrayInfo->RebuiltSectors.lo32 = pVDevice->u.array.RebuildSectors; 259190809Sdelphij pArrayInfo->RebuiltSectors.hi32 = sizeof(LBA_T)>4? (pVDevice->u.array.RebuildSectors>>32) : 0; 260190809Sdelphij pArrayInfo->Flags = get_array_flag(pVDevice); 261190809Sdelphij pArrayInfo->RebuildingProgress = calc_rebuild_progress(pVDevice); 262190809Sdelphij 263190809Sdelphij pArrayInfo->nDisk = 0; 264190809Sdelphij 265190809Sdelphij for(i = 0; i < pVDevice->u.array.bArnMember; i++) 266190809Sdelphij if(pVDevice->u.array.pMember[i] != NULL) 267190809Sdelphij pArrayInfo->Members[pArrayInfo->nDisk++] = VDEV_TO_ID(pVDevice->u.array.pMember[i]); 268190809Sdelphij 269190809Sdelphij for(i=pArrayInfo->nDisk; i<MAX_ARRAY_MEMBERS_V2; i++) 270190809Sdelphij pArrayInfo->Members[i] = INVALID_DEVICEID; 271136849Sscottl} 272136849Sscottl#endif 273136849Sscottl 274190809Sdelphijstatic int get_disk_info(PVDevice pVDevice, PDEVICE_INFO pDiskInfo) 275136849Sscottl{ 276136849Sscottl MV_SATA_ADAPTER *pSataAdapter; 277136849Sscottl MV_SATA_CHANNEL *pSataChannel; 278136849Sscottl IAL_ADAPTER_T *pAdapter; 279190809Sdelphij MV_CHANNEL *channelInfo; 280136849Sscottl char *p; 281136849Sscottl int i; 282136849Sscottl 283136849Sscottl /* device location */ 284136849Sscottl pSataChannel = pVDevice->u.disk.mv; 285136849Sscottl if(pSataChannel == NULL) return -1; 286190809Sdelphij pDiskInfo->TargetId = 0; 287136849Sscottl pSataAdapter = pSataChannel->mvSataAdapter; 288136849Sscottl if(pSataAdapter == NULL) return -1; 289136849Sscottl 290136849Sscottl pAdapter = pSataAdapter->IALData; 291136849Sscottl 292190809Sdelphij pDiskInfo->PathId = pSataChannel->channelNumber; 293190809Sdelphij pDiskInfo->ControllerId = (UCHAR)pSataAdapter->adapterId; 294136849Sscottl 295136849Sscottl/*GUI uses DeviceModeSetting to display to users 296136849Sscottl(1) if users select a mode, GUI/BIOS should display that mode. 297136849Sscottl(2) if SATA/150, GUI/BIOS should display 150 if case (1) isn't satisfied. 298136849Sscottl(3) display real mode if case (1)&&(2) not satisfied. 299136849Sscottl*/ 300136849Sscottl if (pVDevice->u.disk.df_user_mode_set) 301190809Sdelphij pDiskInfo->DeviceModeSetting = pVDevice->u.disk.bDeUserSelectMode; 302190809Sdelphij else if (((((PIDENTIFY_DATA)pVDevice->u.disk.mv->identifyDevice)->SataCapability) & 3)==2) 303190809Sdelphij pDiskInfo->DeviceModeSetting = 15; 304136849Sscottl else { 305136849Sscottl p = (char *)&((PIDENTIFY_DATA)pVDevice->u.disk.mv->identifyDevice)->ModelNumber; 306190809Sdelphij if (*(WORD*)p==(0x5354) /*'ST'*/ && 307190809Sdelphij (*(WORD*)(p+8)==(0x4153)/*'AS'*/ || (p[8]=='A' && p[11]=='S'))) 308190809Sdelphij pDiskInfo->DeviceModeSetting = 15; 309136849Sscottl else 310190809Sdelphij pDiskInfo->DeviceModeSetting = pVDevice->u.disk.bDeModeSetting; 311136849Sscottl } 312136849Sscottl 313190809Sdelphij pDiskInfo->UsableMode = pVDevice->u.disk.bDeUsable_Mode; 314136849Sscottl 315190809Sdelphij pDiskInfo->DeviceType = PDT_HARDDISK; 316136849Sscottl 317190809Sdelphij pDiskInfo->Flags = 0x0; 318136849Sscottl 319136849Sscottl /* device is disabled */ 320136849Sscottl if(!pVDevice->u.disk.df_on_line) 321190809Sdelphij pDiskInfo->Flags |= DEVICE_FLAG_DISABLED; 322136849Sscottl 323136849Sscottl /* disk has a active partition */ 324136849Sscottl if(pVDevice->vf_bootable) 325190809Sdelphij pDiskInfo->Flags |= DEVICE_FLAG_BOOTDISK; 326136849Sscottl 327136849Sscottl /* disk has boot mark set */ 328136849Sscottl if(pVDevice->vf_bootmark) 329190809Sdelphij pDiskInfo->Flags |= DEVICE_FLAG_BOOTMARK; 330136849Sscottl 331190809Sdelphij pDiskInfo->Flags |= DEVICE_FLAG_SATA; 332136849Sscottl 333136849Sscottl /* is a spare disk */ 334136849Sscottl if(pVDevice->VDeviceType == VD_SPARE) 335190809Sdelphij pDiskInfo->Flags |= DEVICE_FLAG_IS_SPARE; 336136849Sscottl 337190809Sdelphij memcpy(&(pDiskInfo->IdentifyData), (pSataChannel->identifyDevice), sizeof(IDENTIFY_DATA2)); 338190809Sdelphij p = (char *)&pDiskInfo->IdentifyData.ModelNumber; 339136849Sscottl for (i = 0; i < 20; i++) 340136849Sscottl ((WORD*)p)[i] = shortswap(pSataChannel->identifyDevice[IDEN_MODEL_OFFSET+i]); 341136849Sscottl p[39] = '\0'; 342136849Sscottl 343190809Sdelphij channelInfo = &pAdapter->mvChannel[pSataChannel->channelNumber]; 344190809Sdelphij pDiskInfo->ReadAheadSupported = channelInfo->readAheadSupported; 345190809Sdelphij pDiskInfo->ReadAheadEnabled = channelInfo->readAheadEnabled; 346190809Sdelphij pDiskInfo->WriteCacheSupported = channelInfo->writeCacheSupported; 347190809Sdelphij pDiskInfo->WriteCacheEnabled = channelInfo->writeCacheEnabled; 348190809Sdelphij pDiskInfo->TCQSupported = (pSataChannel->identifyDevice[IDEN_SUPPORTED_COMMANDS2] & (0x2))!=0; 349190809Sdelphij pDiskInfo->TCQEnabled = pSataChannel->queuedDMA==MV_EDMA_MODE_QUEUED; 350190809Sdelphij pDiskInfo->NCQSupported = MV_SATA_GEN_2(pSataAdapter) && 351190809Sdelphij (pSataChannel->identifyDevice[IDEN_SATA_CAPABILITIES] & (0x0100)); 352190809Sdelphij pDiskInfo->NCQEnabled = pSataChannel->queuedDMA==MV_EDMA_MODE_NATIVE_QUEUING; 353136849Sscottl return 0; 354136849Sscottl} 355136849Sscottl 356149871Sscottlint hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap) 357136849Sscottl{ 358136849Sscottl ZeroMemory(cap, sizeof(DRIVER_CAPABILITIES)); 359136849Sscottl cap->dwSize = sizeof(DRIVER_CAPABILITIES); 360136849Sscottl cap->MaximumControllers = MAX_VBUS; 361136849Sscottl 362136849Sscottl /* cap->SupportCrossControllerRAID = 0; */ 363136849Sscottl /* take care for various OSes! */ 364136849Sscottl cap->SupportCrossControllerRAID = 0; 365136849Sscottl 366136849Sscottl 367136849Sscottl cap->MinimumBlockSizeShift = MinBlockSizeShift; 368136849Sscottl cap->MaximumBlockSizeShift = MaxBlockSizeShift; 369136849Sscottl cap->SupportDiskModeSetting = 0; 370136849Sscottl cap->SupportSparePool = 1; 371136849Sscottl cap->MaximumArrayNameLength = MAX_ARRAY_NAME - 1; 372136849Sscottl cap->SupportDedicatedSpare = 0; 373136849Sscottl 374136849Sscottl 375136849Sscottl#ifdef SUPPORT_ARRAY 376136849Sscottl /* Stripe */ 377136849Sscottl cap->SupportedRAIDTypes[0] = AT_RAID0; 378136849Sscottl cap->MaximumArrayMembers[0] = MAX_MEMBERS; 379136849Sscottl /* Mirror */ 380136849Sscottl cap->SupportedRAIDTypes[1] = AT_RAID1; 381136849Sscottl cap->MaximumArrayMembers[1] = 2; 382136849Sscottl /* Mirror + Stripe */ 383136849Sscottl#ifdef ARRAY_V2_ONLY 384136849Sscottl cap->SupportedRAIDTypes[2] = (AT_RAID1<<4)|AT_RAID0; /* RAID0/1 */ 385149871Sscottl#else 386136849Sscottl cap->SupportedRAIDTypes[2] = (AT_RAID0<<4)|AT_RAID1; /* RAID1/0 */ 387136849Sscottl#endif 388136849Sscottl cap->MaximumArrayMembers[2] = MAX_MEMBERS; 389136849Sscottl /* Jbod */ 390136849Sscottl cap->SupportedRAIDTypes[3] = AT_JBOD; 391136849Sscottl cap->MaximumArrayMembers[3] = MAX_MEMBERS; 392136849Sscottl /* RAID5 */ 393136849Sscottl#if SUPPORT_RAID5 394136849Sscottl cap->SupportedRAIDTypes[4] = AT_RAID5; 395136849Sscottl cap->MaximumArrayMembers[4] = MAX_MEMBERS; 396136849Sscottl#endif 397136849Sscottl#endif 398136849Sscottl return 0; 399136849Sscottl} 400136849Sscottl 401149871Sscottlint hpt_get_controller_count(void) 402136849Sscottl{ 403136849Sscottl IAL_ADAPTER_T *pAdapTemp = gIal_Adapter; 404136849Sscottl int iControllerCount = 0; 405136849Sscottl 406136849Sscottl while(pAdapTemp != 0) 407136849Sscottl { 408136849Sscottl iControllerCount++; 409136849Sscottl pAdapTemp = pAdapTemp->next; 410136849Sscottl } 411136849Sscottl 412136849Sscottl return iControllerCount; 413136849Sscottl} 414136849Sscottl 415149871Sscottlint hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo) 416136849Sscottl{ 417136849Sscottl IAL_ADAPTER_T *pAdapTemp; 418136849Sscottl int iControllerCount = 0; 419136849Sscottl 420136849Sscottl for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) { 421136849Sscottl if (iControllerCount++==id) { 422136849Sscottl pInfo->InterruptLevel = 0; 423136849Sscottl pInfo->ChipType = 0; 424136849Sscottl pInfo->ChipFlags = CHIP_SUPPORT_ULTRA_100; 425136849Sscottl strcpy( pInfo->szVendorID, "HighPoint Technologies, Inc."); 426136849Sscottl#ifdef GUI_CONTROLLER_NAME 427136849Sscottl#ifdef FORCE_ATA150_DISPLAY 428136849Sscottl /* show "Bus Type: ATA/150" in GUI for SATA controllers */ 429136849Sscottl pInfo->ChipFlags = CHIP_SUPPORT_ULTRA_150; 430136849Sscottl#endif 431136849Sscottl strcpy(pInfo->szProductID, GUI_CONTROLLER_NAME); 432136849Sscottl#define _set_product_id(x) 433149871Sscottl#else 434136849Sscottl#define _set_product_id(x) strcpy(pInfo->szProductID, x) 435136849Sscottl#endif 436190809Sdelphij _set_product_id("RocketRAID 18xx SATA Controller"); 437136849Sscottl pInfo->NumBuses = 8; 438136849Sscottl pInfo->ChipFlags |= CHIP_SUPPORT_ULTRA_133|CHIP_SUPPORT_ULTRA_150; 439136849Sscottl return 0; 440136849Sscottl } 441136849Sscottl } 442136849Sscottl return -1; 443136849Sscottl} 444136849Sscottl 445136849Sscottl 446149871Sscottlint hpt_get_channel_info(int id, int bus, PCHANNEL_INFO pInfo) 447136849Sscottl{ 448136849Sscottl IAL_ADAPTER_T *pAdapTemp = gIal_Adapter; 449136849Sscottl int i,iControllerCount = 0; 450136849Sscottl 451136849Sscottl while(pAdapTemp != 0) 452136849Sscottl { 453136849Sscottl if (iControllerCount++==id) 454136849Sscottl goto found; 455136849Sscottl pAdapTemp = pAdapTemp->next; 456136849Sscottl } 457136849Sscottl return -1; 458136849Sscottl 459136849Sscottlfound: 460136849Sscottl 461136849Sscottl pInfo->IoPort = 0; 462136849Sscottl pInfo->ControlPort = 0; 463136849Sscottl 464136849Sscottl for (i=0; i<2 ;i++) 465136849Sscottl { 466136849Sscottl pInfo->Devices[i] = (DEVICEID)INVALID_DEVICEID; 467136849Sscottl } 468136849Sscottl 469136849Sscottl if (pAdapTemp->mvChannel[bus].online == MV_TRUE) 470136849Sscottl pInfo->Devices[0] = VDEV_TO_ID(&pAdapTemp->VDevices[bus]); 471136849Sscottl else 472136849Sscottl pInfo->Devices[0] = (DEVICEID)INVALID_DEVICEID; 473136849Sscottl 474136849Sscottl return 0; 475136849Sscottl 476136849Sscottl 477136849Sscottl} 478136849Sscottl 479149871Sscottlint hpt_get_logical_devices(DEVICEID * pIds, int nMaxCount) 480136849Sscottl{ 481136849Sscottl int count = 0; 482136849Sscottl int i,j; 483136849Sscottl PVDevice pPhysical, pLogical; 484136849Sscottl IAL_ADAPTER_T *pAdapTemp; 485136849Sscottl 486136849Sscottl for(i = 0; i < nMaxCount; i++) 487136849Sscottl pIds[i] = INVALID_DEVICEID; 488136849Sscottl 489136849Sscottl /* append the arrays not registered on VBus */ 490136849Sscottl for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) { 491136849Sscottl for(i = 0; i < MV_SATA_CHANNELS_NUM; i++) 492136849Sscottl { 493136849Sscottl pPhysical = &pAdapTemp->VDevices[i]; 494136849Sscottl pLogical = pPhysical; 495136849Sscottl 496136849Sscottl while (pLogical->pParent) pLogical = pLogical->pParent; 497136849Sscottl if (pLogical->VDeviceType==VD_SPARE) 498136849Sscottl continue; 499136849Sscottl 500136849Sscottl for (j=0; j<count; j++) 501136849Sscottl if (pIds[j]==VDEV_TO_ID(pLogical)) goto next; 502136849Sscottl pIds[count++] = VDEV_TO_ID(pLogical); 503136849Sscottl if (count>=nMaxCount) goto done; 504136849Sscottl next:; 505136849Sscottl } 506136849Sscottl } 507136849Sscottl 508136849Sscottldone: 509136849Sscottl return count; 510136849Sscottl} 511136849Sscottl 512149871Sscottlint hpt_get_device_info(DEVICEID id, PLOGICAL_DEVICE_INFO pInfo) 513136849Sscottl{ 514136849Sscottl PVDevice pVDevice = ID_TO_VDEV(id); 515136849Sscottl 516149871Sscottl if((id == 0) || check_VDevice_valid(pVDevice)) 517136849Sscottl return -1; 518136849Sscottl 519136849Sscottl#ifdef SUPPORT_ARRAY 520190809Sdelphij if (mIsArray(pVDevice)) { 521190809Sdelphij pInfo->Type = LDT_ARRAY; 522190809Sdelphij pInfo->Capacity = pVDevice->VDeviceCapacity; 523190809Sdelphij pInfo->ParentArray = VDEV_TO_ID(pVDevice->pParent); 524190809Sdelphij get_array_info(pVDevice, &pInfo->u.array); 525190809Sdelphij return 0; 526190809Sdelphij } 527136849Sscottl#endif 528136849Sscottl 529190809Sdelphij pInfo->Type = LDT_DEVICE; 530190809Sdelphij pInfo->ParentArray = pVDevice->pParent? VDEV_TO_ID(pVDevice->pParent) : INVALID_DEVICEID; 531190809Sdelphij /* report real capacity to be compatible with old arrays */ 532190809Sdelphij pInfo->Capacity = pVDevice->u.disk.dDeRealCapacity; 533190809Sdelphij return get_disk_info(pVDevice, &pInfo->u.device); 534190809Sdelphij} 535190809Sdelphij 536190809Sdelphijint hpt_get_device_info_v2(DEVICEID id, PLOGICAL_DEVICE_INFO_V2 pInfo) 537190809Sdelphij{ 538190809Sdelphij PVDevice pVDevice = ID_TO_VDEV(id); 539190809Sdelphij 540190809Sdelphij if((id == 0) || check_VDevice_valid(pVDevice)) 541190809Sdelphij return -1; 542190809Sdelphij 543190809Sdelphij#ifdef SUPPORT_ARRAY 544190809Sdelphij if (mIsArray(pVDevice)) { 545190809Sdelphij pInfo->Type = LDT_ARRAY; 546190809Sdelphij pInfo->Capacity.lo32 = pVDevice->VDeviceCapacity; 547190809Sdelphij pInfo->Capacity.hi32 = sizeof(LBA_T)>4? (pVDevice->VDeviceCapacity>>32) : 0; 548190809Sdelphij pInfo->ParentArray = VDEV_TO_ID(pVDevice->pParent); 549190809Sdelphij get_array_info_v2(pVDevice, &pInfo->u.array); 550136849Sscottl return 0; 551136849Sscottl} 552190809Sdelphij#endif 553136849Sscottl 554190809Sdelphij pInfo->Type = LDT_DEVICE; 555190809Sdelphij pInfo->ParentArray = pVDevice->pParent? VDEV_TO_ID(pVDevice->pParent) : INVALID_DEVICEID; 556190809Sdelphij /* report real capacity to be compatible with old arrays */ 557190809Sdelphij pInfo->Capacity.lo32 = pVDevice->u.disk.dDeRealCapacity; 558190809Sdelphij pInfo->Capacity.hi32 = 0; 559190809Sdelphij return get_disk_info(pVDevice, &pInfo->u.device); 560190809Sdelphij} 561190809Sdelphij 562136849Sscottl#ifdef SUPPORT_ARRAY 563190809SdelphijDEVICEID hpt_create_array_v2(_VBUS_ARG PCREATE_ARRAY_PARAMS_V2 pParam) 564136849Sscottl{ 565136849Sscottl ULONG Stamp = GetStamp(); 566136849Sscottl int i,j; 567190809Sdelphij LBA_T capacity = MAX_LBA_T; 568136849Sscottl PVDevice pArray,pChild; 569136849Sscottl int Loca = -1; 570136849Sscottl 571190809Sdelphij if (pParam->nDisk > MAX_MEMBERS) 572190809Sdelphij return INVALID_DEVICEID; 573190809Sdelphij/* check in verify_vd 574136849Sscottl for(i = 0; i < pParam->nDisk; i++) 575136849Sscottl { 576136849Sscottl PVDevice pVDev = ID_TO_VDEV(pParam->Members[i]); 577136849Sscottl if (check_VDevice_valid(pVDev)) return INVALID_DEVICEID; 578136849Sscottl if (mIsArray(pVDev)) return INVALID_DEVICEID; 579136849Sscottl if (!pVDev->vf_online) return INVALID_DEVICEID; 580136849Sscottl if (!_vbus_p) 581136849Sscottl _vbus_p = pVDev->u.disk.pVBus; 582136849Sscottl else if (_vbus_p != pVDev->u.disk.pVBus) 583136849Sscottl return INVALID_DEVICEID; 584136849Sscottl } 585190809Sdelphij*/ 586190809Sdelphij _vbus_p = (ID_TO_VDEV(pParam->Members[0]))->u.disk.pVBus; 587136849Sscottl if (!_vbus_p) return INVALID_DEVICEID; 588136849Sscottl 589136849Sscottl mArGetArrayTable(pArray); 590136849Sscottl if(!pArray) return INVALID_DEVICEID; 591136849Sscottl 592136849Sscottl switch (pParam->ArrayType) 593136849Sscottl { 594136849Sscottl case AT_JBOD: 595136849Sscottl pArray->VDeviceType = VD_JBOD; 596136849Sscottl goto simple; 597136849Sscottl 598136849Sscottl case AT_RAID0: 599136849Sscottl if((pParam->BlockSizeShift < MinBlockSizeShift) || (pParam->BlockSizeShift > MaxBlockSizeShift)) 600136849Sscottl goto error; 601136849Sscottl pArray->VDeviceType = VD_RAID_0; 602136849Sscottl goto simple; 603136849Sscottl 604136849Sscottl case AT_RAID5: 605136849Sscottl if((pParam->BlockSizeShift < MinBlockSizeShift) || (pParam->BlockSizeShift > MaxBlockSizeShift)) 606136849Sscottl goto error; 607136849Sscottl pArray->VDeviceType = VD_RAID_5; 608136849Sscottl /* only "no build" R5 is not critical after creation. */ 609136849Sscottl if ((pParam->CreateFlags & CAF_CREATE_R5_NO_BUILD)==0) 610136849Sscottl pArray->u.array.rf_need_rebuild = 1; 611136849Sscottl goto simple; 612136849Sscottl 613136849Sscottl case AT_RAID1: 614136849Sscottl if(pParam->nDisk <= 2) 615136849Sscottl { 616136849Sscottl pArray->VDeviceType = VD_RAID_1; 617136849Sscottlsimple: 618136849Sscottl pArray->u.array.bArnMember = pParam->nDisk; 619136849Sscottl pArray->u.array.bArRealnMember = pParam->nDisk; 620136849Sscottl pArray->u.array.bArBlockSizeShift = pParam->BlockSizeShift; 621136849Sscottl pArray->u.array.bStripeWitch = (1 << pParam->BlockSizeShift); 622136849Sscottl pArray->u.array.dArStamp = Stamp; 623136849Sscottl 624136849Sscottl pArray->u.array.rf_need_sync = 1; 625136849Sscottl pArray->u.array.rf_newly_created = 1; 626136849Sscottl 627136849Sscottl if ((pParam->CreateFlags & CAF_CREATE_AND_DUPLICATE) && 628136849Sscottl (pArray->VDeviceType == VD_RAID_1)) 629136849Sscottl { 630136849Sscottl pArray->u.array.rf_newly_created = 0; /* R1 shall still be accessible */ 631136849Sscottl pArray->u.array.rf_need_rebuild = 1; 632136849Sscottl pArray->u.array.rf_auto_rebuild = 1; 633136849Sscottl pArray->u.array.rf_duplicate_and_create = 1; 634136849Sscottl 635136849Sscottl for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) 636136849Sscottl if (_vbus_p->pVDevice[i] == ID_TO_VDEV(pParam->Members[0])) 637136849Sscottl Loca = i; 638136849Sscottl } 639136849Sscottl 640136849Sscottl pArray->u.array.RebuildSectors = pArray->u.array.rf_need_rebuild? 0 : MAX_LBA_T; 641136849Sscottl 642136849Sscottl memcpy(pArray->u.array.ArrayName, pParam->ArrayName, MAX_ARRAY_NAME); 643136849Sscottl 644136849Sscottl for(i = 0; i < pParam->nDisk; i++) 645136849Sscottl { 646136849Sscottl pArray->u.array.pMember[i] = ID_TO_VDEV(pParam->Members[i]); 647136849Sscottl pArray->u.array.pMember[i]->bSerialNumber = i; 648136849Sscottl pArray->u.array.pMember[i]->pParent = pArray; 649136849Sscottl 650136849Sscottl /* don't unregister source disk for duplicate RAID1 */ 651136849Sscottl if (i || 652136849Sscottl pArray->VDeviceType!=VD_RAID_1 || 653136849Sscottl (pParam->CreateFlags & CAF_CREATE_AND_DUPLICATE)==0) 654136849Sscottl UnregisterVDevice(pArray->u.array.pMember[i]); 655136849Sscottl 656136849Sscottl if(pArray->VDeviceType == VD_RAID_5) 657136849Sscottl pArray->u.array.pMember[i]->vf_cache_disk = 1; 658136849Sscottl } 659136849Sscottl } 660136849Sscottl else 661136849Sscottl { 662136849Sscottl for(i = 0; i < (pParam->nDisk / 2); i++) 663136849Sscottl { 664136849Sscottl mArGetArrayTable(pChild); 665136849Sscottl pChild->VDeviceType = VD_RAID_1; 666136849Sscottl 667136849Sscottl pChild->u.array.bArnMember = 2; 668136849Sscottl pChild->u.array.bArRealnMember = 2; 669136849Sscottl pChild->u.array.bArBlockSizeShift = pParam->BlockSizeShift; 670136849Sscottl pChild->u.array.bStripeWitch = (1 << pParam->BlockSizeShift); 671136849Sscottl pChild->u.array.dArStamp = Stamp; 672136849Sscottl 673136849Sscottl pChild->u.array.rf_need_sync = 1; 674136849Sscottl pChild->u.array.rf_newly_created = 1; 675136849Sscottl 676136849Sscottl pChild->u.array.RebuildSectors = MAX_LBA_T; 677136849Sscottl 678136849Sscottl memcpy(pChild->u.array.ArrayName, pParam->ArrayName, MAX_ARRAY_NAME); 679136849Sscottl 680136849Sscottl for(j = 0; j < 2; j++) 681136849Sscottl { 682136849Sscottl pChild->u.array.pMember[j] = ID_TO_VDEV(pParam->Members[i*2 + j]); 683136849Sscottl pChild->u.array.pMember[j]->bSerialNumber = j; 684136849Sscottl pChild->u.array.pMember[j]->pParent = pChild; 685136849Sscottl pChild->u.array.pMember[j]->pfnDeviceFailed = pfnDeviceFailed[pChild->VDeviceType]; 686136849Sscottl UnregisterVDevice(pChild->u.array.pMember[j]); 687136849Sscottl } 688136849Sscottl 689136849Sscottl pArray->u.array.pMember[i] = pChild; 690136849Sscottl 691136849Sscottl pChild->vf_online = 1; 692136849Sscottl pChild->bSerialNumber = i; 693136849Sscottl pChild->pParent = pArray; 694136849Sscottl pChild->VDeviceCapacity = MIN(pChild->u.array.pMember[0]->VDeviceCapacity, 695136849Sscottl pChild->u.array.pMember[1]->VDeviceCapacity); 696136849Sscottl 697136849Sscottl pChild->pfnSendCommand = pfnSendCommand[pChild->VDeviceType]; 698136849Sscottl pChild->pfnDeviceFailed = pfnDeviceFailed[VD_RAID_0]; 699136849Sscottl } 700136849Sscottl 701136849Sscottl pArray->VDeviceType = VD_RAID_0; 702136849Sscottl 703136849Sscottl pArray->u.array.bArnMember = pParam->nDisk / 2; 704136849Sscottl pArray->u.array.bArRealnMember = pParam->nDisk / 2; 705136849Sscottl pArray->u.array.bArBlockSizeShift = pParam->BlockSizeShift; 706136849Sscottl pArray->u.array.bStripeWitch = (1 << pParam->BlockSizeShift); 707136849Sscottl pArray->u.array.dArStamp = Stamp; 708136849Sscottl 709136849Sscottl pArray->u.array.rf_need_sync = 1; 710136849Sscottl pArray->u.array.rf_newly_created = 1; 711136849Sscottl 712136849Sscottl memcpy(pArray->u.array.ArrayName, pParam->ArrayName, MAX_ARRAY_NAME); 713136849Sscottl } 714136849Sscottl break; 715136849Sscottl 716136849Sscottl default: 717136849Sscottl goto error; 718136849Sscottl } 719136849Sscottl 720136849Sscottl for(i = 0; i < pArray->u.array.bArnMember; i++) 721136849Sscottl pArray->u.array.pMember[i]->pfnDeviceFailed = pfnDeviceFailed[pArray->VDeviceType]; 722136849Sscottl 723136849Sscottl if ((pParam->CreateFlags & CAF_CREATE_AND_DUPLICATE) && 724136849Sscottl (pArray->VDeviceType == VD_RAID_1)) 725136849Sscottl { 726136849Sscottl pArray->vf_bootmark = pArray->u.array.pMember[0]->vf_bootmark; 727136849Sscottl pArray->vf_bootable = pArray->u.array.pMember[0]->vf_bootable; 728136849Sscottl pArray->u.array.pMember[0]->vf_bootable = 0; 729136849Sscottl pArray->u.array.pMember[0]->vf_bootmark = 0; 730136849Sscottl if (Loca>=0) { 731136849Sscottl _vbus_p->pVDevice[Loca] = pArray; 732136849Sscottl /* to comfort OS */ 733136849Sscottl pArray->u.array.rf_duplicate_and_created = 1; 734136849Sscottl pArray->pVBus = _vbus_p; 735136849Sscottl } 736136849Sscottl } 737136849Sscottl else { 738136849Sscottl UCHAR TempBuffer[512]; 739136849Sscottl ZeroMemory(TempBuffer, 512); 740136849Sscottl for(i = 0; i < pParam->nDisk; i++) 741136849Sscottl { 742136849Sscottl PVDevice pDisk = ID_TO_VDEV(pParam->Members[i]); 743136849Sscottl pDisk->vf_bootmark = pDisk->vf_bootable = 0; 744136849Sscottl fDeReadWrite(&pDisk->u.disk, 0, IDE_COMMAND_WRITE, TempBuffer); 745136849Sscottl } 746136849Sscottl } 747136849Sscottl 748136849Sscottl pArray->vf_online = 1; 749136849Sscottl pArray->pParent = NULL; 750136849Sscottl 751136849Sscottl switch(pArray->VDeviceType) 752136849Sscottl { 753136849Sscottl case VD_RAID_0: 754136849Sscottl for(i = 0; i < pArray->u.array.bArnMember; i++) 755136849Sscottl if(pArray->u.array.pMember[i]->VDeviceCapacity < capacity) 756136849Sscottl capacity = pArray->u.array.pMember[i]->VDeviceCapacity; 757136849Sscottl#ifdef ARRAY_V2_ONLY 758136849Sscottl capacity -= 10; 759136849Sscottl#endif 760136849Sscottl capacity &= ~(pArray->u.array.bStripeWitch - 1); 761136849Sscottl /* shrink member capacity for RAID 1/0 */ 762136849Sscottl for(i = 0; i < pArray->u.array.bArnMember; i++) 763136849Sscottl if (mIsArray(pArray->u.array.pMember[i])) 764136849Sscottl pArray->u.array.pMember[i]->VDeviceCapacity = capacity; 765136849Sscottl pArray->VDeviceCapacity = capacity * pArray->u.array.bArnMember; 766136849Sscottl break; 767136849Sscottl 768136849Sscottl case VD_RAID_1: 769136849Sscottl pArray->VDeviceCapacity = MIN(pArray->u.array.pMember[0]->VDeviceCapacity, 770136849Sscottl pArray->u.array.pMember[1]->VDeviceCapacity); 771136849Sscottl break; 772136849Sscottl 773136849Sscottl case VD_JBOD: 774136849Sscottl for(i = 0; i < pArray->u.array.bArnMember; i++) 775136849Sscottl pArray->VDeviceCapacity += pArray->u.array.pMember[i]->VDeviceCapacity 776136849Sscottl#ifdef ARRAY_V2_ONLY 777136849Sscottl -10 778136849Sscottl#endif 779136849Sscottl ; 780136849Sscottl break; 781136849Sscottl 782136849Sscottl case VD_RAID_5: 783136849Sscottl for(i = 0; i < pArray->u.array.bArnMember; i++) 784136849Sscottl if(pArray->u.array.pMember[i]->VDeviceCapacity < capacity) 785136849Sscottl capacity = pArray->u.array.pMember[i]->VDeviceCapacity; 786136849Sscottl pArray->VDeviceCapacity = (capacity & ~(pArray->u.array.bStripeWitch - 1)) 787136849Sscottl * (pArray->u.array.bArnMember - 1); 788136849Sscottl break; 789136849Sscottl 790136849Sscottl default: 791136849Sscottl goto error; 792136849Sscottl } 793136849Sscottl 794136849Sscottl pArray->pfnSendCommand = pfnSendCommand[pArray->VDeviceType]; 795136849Sscottl pArray->pfnDeviceFailed = fOsDiskFailed; 796136849Sscottl SyncArrayInfo(pArray); 797136849Sscottl 798136849Sscottl if (!pArray->u.array.rf_duplicate_and_created) 799136849Sscottl RegisterVDevice(pArray); 800136849Sscottl return VDEV_TO_ID(pArray); 801136849Sscottl 802136849Sscottlerror: 803136849Sscottl for(i = 0; i < pArray->u.array.bArnMember; i++) 804136849Sscottl { 805136849Sscottl pChild = pArray->u.array.pMember[i]; 806136849Sscottl if((pChild != NULL) && (pChild->VDeviceType != VD_SINGLE_DISK)) 807136849Sscottl mArFreeArrayTable(pChild); 808136849Sscottl } 809136849Sscottl mArFreeArrayTable(pArray); 810136849Sscottl return INVALID_DEVICEID; 811136849Sscottl} 812136849Sscottl 813190809SdelphijDEVICEID hpt_create_array(_VBUS_ARG PCREATE_ARRAY_PARAMS pParam) 814190809Sdelphij{ 815190809Sdelphij CREATE_ARRAY_PARAMS_V2 param2; 816190809Sdelphij param2.ArrayType = pParam->ArrayType; 817190809Sdelphij param2.nDisk = pParam->nDisk; 818190809Sdelphij param2.BlockSizeShift = pParam->BlockSizeShift; 819190809Sdelphij param2.CreateFlags = pParam->CreateFlags; 820190809Sdelphij param2.CreateTime = pParam->CreateTime; 821190809Sdelphij memcpy(param2.ArrayName, pParam->ArrayName, sizeof(param2.ArrayName)); 822190809Sdelphij memcpy(param2.Description, pParam->Description, sizeof(param2.Description)); 823190809Sdelphij memcpy(param2.CreateManager, pParam->CreateManager, sizeof(param2.CreateManager)); 824190809Sdelphij param2.Capacity.lo32 = param2.Capacity.hi32 = 0; 825190809Sdelphij memcpy(param2.Members, pParam->Members, sizeof(pParam->Members)); 826190809Sdelphij return hpt_create_array_v2(_VBUS_P ¶m2); 827190809Sdelphij} 828190809Sdelphij 829136849Sscottl#ifdef SUPPORT_OLD_ARRAY 830136849Sscottl/* this is only for old RAID 0/1 */ 831136849Sscottlint old_add_disk_to_raid01(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk) 832136849Sscottl{ 833136849Sscottl PVDevice pArray1 = ID_TO_VDEV(idArray); 834136849Sscottl PVDevice pArray2 = 0; 835136849Sscottl PVDevice pDisk = ID_TO_VDEV(idDisk); 836136849Sscottl int i; 837136849Sscottl IAL_ADAPTER_T *pAdapter = gIal_Adapter; 838136849Sscottl 839136849Sscottl if (pArray1->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;} 840136849Sscottl 841136849Sscottl if(pDisk->u.disk.dDeRealCapacity < (pArray1->VDeviceCapacity / 2)) 842136849Sscottl return -1; 843136849Sscottl 844136849Sscottl pArray2 = pArray1->u.array.pMember[1]; 845136849Sscottl if(pArray2 == NULL) { 846136849Sscottl /* create a Stripe */ 847136849Sscottl mArGetArrayTable(pArray2); 848136849Sscottl pArray2->VDeviceType = VD_RAID_0; 849136849Sscottl pArray2->u.array.dArStamp = GetStamp(); 850136849Sscottl pArray2->vf_format_v2 = 1; 851136849Sscottl pArray2->u.array.rf_broken = 1; 852136849Sscottl pArray2->u.array.bArBlockSizeShift = pArray1->u.array.bArBlockSizeShift; 853136849Sscottl pArray2->u.array.bStripeWitch = (1 << pArray2->u.array.bArBlockSizeShift); 854136849Sscottl pArray2->u.array.bArnMember = 2; 855136849Sscottl pArray2->VDeviceCapacity = pArray1->VDeviceCapacity; 856136849Sscottl pArray2->pfnSendCommand = pfnSendCommand[pArray2->VDeviceType]; 857136849Sscottl pArray2->pfnDeviceFailed = pfnDeviceFailed[pArray1->VDeviceType]; 858136849Sscottl memcpy(pArray2->u.array.ArrayName, pArray1->u.array.ArrayName, MAX_ARRAY_NAME); 859136849Sscottl pArray2->pParent = pArray1; 860136849Sscottl pArray2->bSerialNumber = 1; 861136849Sscottl pArray1->u.array.pMember[1] = pArray2; 862136849Sscottl pArray1->u.array.bArRealnMember++; 863136849Sscottl } 864136849Sscottl 865136849Sscottl for(i = 0; i < pArray2->u.array.bArnMember; i++) 866136849Sscottl if((pArray2->u.array.pMember[i] == NULL) || !pArray2->u.array.pMember[i]->vf_online) 867136849Sscottl { 868136849Sscottl if(pArray2->u.array.pMember[i] != NULL) 869136849Sscottl pArray2->u.array.pMember[i]->pParent = NULL; 870136849Sscottl pArray2->u.array.pMember[i] = pDisk; 871136849Sscottl goto find; 872136849Sscottl } 873136849Sscottl return -1; 874136849Sscottl 875136849Sscottlfind: 876136849Sscottl UnregisterVDevice(pDisk); 877136849Sscottl pDisk->VDeviceType = VD_SINGLE_DISK; 878136849Sscottl pDisk->bSerialNumber = i; 879136849Sscottl pDisk->pParent = pArray2; 880136849Sscottl pDisk->vf_format_v2 = 1; 881136849Sscottl pDisk->u.disk.dDeHiddenLba = i? 10 : 0; 882136849Sscottl pDisk->VDeviceCapacity = pDisk->u.disk.dDeRealCapacity; 883136849Sscottl pDisk->pfnDeviceFailed = pfnDeviceFailed[pArray2->VDeviceType]; 884136849Sscottl 885136849Sscottl pArray2->u.array.bArRealnMember++; 886136849Sscottl if(pArray2->u.array.bArnMember == pArray2->u.array.bArRealnMember){ 887136849Sscottl pArray2->vf_online = 1; 888136849Sscottl pArray2->u.array.rf_broken = 0; 889136849Sscottl } 890136849Sscottl 891136849Sscottl if(pArray1->u.array.pMember[0]->vf_online && pArray1->u.array.pMember[1]->vf_online){ 892136849Sscottl pArray1->u.array.bArRealnMember = pArray1->u.array.bArnMember; 893136849Sscottl pArray1->u.array.rf_broken = 0; 894136849Sscottl pArray1->u.array.rf_need_rebuild = 1; 895136849Sscottl pArray1->u.array.rf_auto_rebuild = 1; 896136849Sscottl 897136849Sscottl } 898136849Sscottl pArray1->u.array.RebuildSectors = 0; 899136849Sscottl pArray1->u.array.dArStamp = GetStamp(); 900136849Sscottl SyncArrayInfo(pArray1); 901136849Sscottl return 1; 902136849Sscottl} 903136849Sscottl#endif 904136849Sscottl 905136849Sscottlint hpt_add_disk_to_array(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk) 906136849Sscottl{ 907136849Sscottl int i; 908136849Sscottl 909190809Sdelphij LBA_T Capacity; 910136849Sscottl PVDevice pArray = ID_TO_VDEV(idArray); 911136849Sscottl PVDevice pDisk = ID_TO_VDEV(idDisk); 912136849Sscottl 913149871Sscottl if((idArray == 0) || (idDisk == 0)) return -1; 914136849Sscottl if(check_VDevice_valid(pArray) || check_VDevice_valid(pDisk)) return -1; 915136849Sscottl if(!pArray->u.array.rf_broken) return -1; 916136849Sscottl 917136849Sscottl if(pArray->VDeviceType != VD_RAID_1 && pArray->VDeviceType != VD_RAID_5) 918136849Sscottl return -1; 919136849Sscottl if((pDisk->VDeviceType != VD_SINGLE_DISK) && (pDisk->VDeviceType != VD_SPARE)) 920136849Sscottl return -1; 921136849Sscottl 922136849Sscottl#ifdef SUPPORT_OLD_ARRAY 923136849Sscottl /* RAID 0 + 1 */ 924136849Sscottl if (pArray->vf_format_v2 && pArray->VDeviceType==VD_RAID_1 && 925136849Sscottl pArray->u.array.pMember[0] && 926136849Sscottl mIsArray(pArray->u.array.pMember[0])) 927136849Sscottl { 928136849Sscottl if(old_add_disk_to_raid01(_VBUS_P idArray, idDisk)) 929136849Sscottl return 0; 930136849Sscottl else 931136849Sscottl return -1; 932136849Sscottl } 933136849Sscottl#endif 934136849Sscottl 935136849Sscottl Capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember - 1); 936136849Sscottl 937136849Sscottl if (pArray->vf_format_v2) { 938136849Sscottl if(pDisk->u.disk.dDeRealCapacity < Capacity) return -1; 939136849Sscottl } 940136849Sscottl else 941136849Sscottl if(pDisk->VDeviceCapacity < Capacity) return -1; 942136849Sscottl 943136849Sscottl if (pArray->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;} 944136849Sscottl 945136849Sscottl for(i = 0; i < pArray->u.array.bArnMember; i++) 946190809Sdelphij if((pArray->u.array.pMember[i] == 0) || !pArray->u.array.pMember[i]->vf_online) 947136849Sscottl { 948136849Sscottl if(pArray->u.array.pMember[i] != NULL) 949136849Sscottl pArray->u.array.pMember[i]->pParent = NULL; 950136849Sscottl pArray->u.array.pMember[i] = pDisk; 951136849Sscottl goto find; 952136849Sscottl } 953136849Sscottl return -1; 954136849Sscottl 955136849Sscottlfind: 956136849Sscottl UnregisterVDevice(pDisk); 957136849Sscottl pDisk->VDeviceType = VD_SINGLE_DISK; 958136849Sscottl pDisk->bSerialNumber = i; 959136849Sscottl pDisk->pParent = pArray; 960136849Sscottl if (pArray->VDeviceType==VD_RAID_5) pDisk->vf_cache_disk = 1; 961136849Sscottl pDisk->pfnDeviceFailed = pfnDeviceFailed[pArray->VDeviceType]; 962136849Sscottl if (pArray->vf_format_v2) { 963136849Sscottl pDisk->vf_format_v2 = 1; 964136849Sscottl pDisk->VDeviceCapacity = pDisk->u.disk.dDeRealCapacity; 965136849Sscottl } 966136849Sscottl 967136849Sscottl pArray->u.array.bArRealnMember++; 968136849Sscottl if(pArray->u.array.bArnMember == pArray->u.array.bArRealnMember) 969136849Sscottl { 970136849Sscottl pArray->u.array.rf_need_rebuild = 1; 971136849Sscottl pArray->u.array.RebuildSectors = 0; 972136849Sscottl pArray->u.array.rf_auto_rebuild = 1; 973136849Sscottl pArray->u.array.rf_broken = 0; 974136849Sscottl } 975136849Sscottl pArray->u.array.RebuildSectors = 0; 976136849Sscottl 977136849Sscottl /* sync the whole array */ 978136849Sscottl while (pArray->pParent) pArray = pArray->pParent; 979136849Sscottl pArray->u.array.dArStamp = GetStamp(); 980136849Sscottl SyncArrayInfo(pArray); 981136849Sscottl return 0; 982136849Sscottl} 983136849Sscottl 984149871Sscottlint hpt_add_spare_disk(_VBUS_ARG DEVICEID idDisk) 985136849Sscottl{ 986136849Sscottl PVDevice pVDevice = ID_TO_VDEV(idDisk); 987136849Sscottl DECLARE_BUFFER(PUCHAR, pbuffer); 988136849Sscottl 989149871Sscottl if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1; 990136849Sscottl if (pVDevice->VDeviceType != VD_SINGLE_DISK || pVDevice->pParent) 991136849Sscottl return -1; 992136849Sscottl 993136849Sscottl if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 994136849Sscottl 995136849Sscottl UnregisterVDevice(pVDevice); 996136849Sscottl pVDevice->VDeviceType = VD_SPARE; 997136849Sscottl pVDevice->vf_bootmark = 0; 998136849Sscottl 999136849Sscottl ZeroMemory((char *)pbuffer, 512); 1000136849Sscottl fDeReadWrite(&pVDevice->u.disk, 0, IDE_COMMAND_WRITE, pbuffer); 1001136849Sscottl SyncArrayInfo(pVDevice); 1002136849Sscottl return 0; 1003136849Sscottl} 1004136849Sscottl 1005149871Sscottlint hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk) 1006136849Sscottl{ 1007136849Sscottl PVDevice pVDevice = ID_TO_VDEV(idDisk); 1008136849Sscottl 1009136849Sscottl if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1; 1010136849Sscottl 1011136849Sscottl if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 1012136849Sscottl 1013136849Sscottl pVDevice->VDeviceType = VD_SINGLE_DISK; 1014136849Sscottl 1015136849Sscottl SyncArrayInfo(pVDevice); 1016136849Sscottl RegisterVDevice(pVDevice); 1017136849Sscottl return 0; 1018136849Sscottl} 1019136849Sscottl 1020149871Sscottlint hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO pInfo) 1021136849Sscottl{ 1022136849Sscottl PVDevice pVDevice = ID_TO_VDEV(idArray); 1023136849Sscottl 1024149871Sscottl if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1; 1025136849Sscottl if (!mIsArray(pVDevice)) return -1; 1026136849Sscottl 1027136849Sscottl /* if the pVDevice isn't a top level, return -1; */ 1028136849Sscottl if(pVDevice->pParent != NULL) return -1; 1029136849Sscottl 1030136849Sscottl if (pVDevice->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;} 1031136849Sscottl 1032136849Sscottl if (pInfo->ValidFields & AAIF_NAME) { 1033136849Sscottl memset(pVDevice->u.array.ArrayName, 0, MAX_ARRAY_NAME); 1034136849Sscottl memcpy(pVDevice->u.array.ArrayName, pInfo->Name, sizeof(pInfo->Name)); 1035136849Sscottl pVDevice->u.array.rf_need_sync = 1; 1036136849Sscottl } 1037136849Sscottl 1038136849Sscottl if (pInfo->ValidFields & AAIF_DESCRIPTION) { 1039136849Sscottl memcpy(pVDevice->u.array.Description, pInfo->Description, sizeof(pInfo->Description)); 1040136849Sscottl pVDevice->u.array.rf_need_sync = 1; 1041136849Sscottl } 1042136849Sscottl 1043136849Sscottl if (pVDevice->u.array.rf_need_sync) 1044136849Sscottl SyncArrayInfo(pVDevice); 1045136849Sscottl return 0; 1046136849Sscottl} 1047136849Sscottl 1048190809Sdelphijstatic int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO pInfo) 1049136849Sscottl{ 1050136849Sscottl PVDevice pVDevice = ID_TO_VDEV(idDisk); 1051136849Sscottl 1052190809Sdelphij if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1; 1053190809Sdelphij if (mIsArray(pVDevice)) 1054190809Sdelphij return -1; 1055190809Sdelphij 1056190809Sdelphij if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 1057190809Sdelphij 1058190809Sdelphij /* TODO */ 1059136849Sscottl return 0; 1060136849Sscottl } 1061136849Sscottl 1062190809Sdelphijstatic int hpt_set_device_info_v2(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO_V2 pInfo) 1063190809Sdelphij{ 1064190809Sdelphij PVDevice pVDevice = ID_TO_VDEV(idDisk); 1065190809Sdelphij int sync = 0; 1066190809Sdelphij 1067190809Sdelphij if(idDisk==0 || check_VDevice_valid(pVDevice)) return -1; 1068136849Sscottl if (mIsArray(pVDevice)) 1069136849Sscottl return -1; 1070136849Sscottl 1071136849Sscottl if (pVDevice->u.disk.pVBus!=_vbus_p) return -1; 1072136849Sscottl 1073190809Sdelphij if (pInfo->ValidFields & ADIF_MODE) { 1074136849Sscottl pVDevice->u.disk.bDeModeSetting = pInfo->DeviceModeSetting; 1075136849Sscottl pVDevice->u.disk.bDeUserSelectMode = pInfo->DeviceModeSetting; 1076136849Sscottl pVDevice->u.disk.df_user_mode_set = 1; 1077136849Sscottl fDeSelectMode((PDevice)&(pVDevice->u.disk), (UCHAR)pInfo->DeviceModeSetting); 1078190809Sdelphij sync = 1; 1079136849Sscottl} 1080136849Sscottl 1081190809Sdelphij if (pInfo->ValidFields & ADIF_TCQ) { 1082190809Sdelphij if (fDeSetTCQ(&pVDevice->u.disk, pInfo->TCQEnabled, 0)) { 1083190809Sdelphij pVDevice->u.disk.df_tcq_set = 1; 1084190809Sdelphij pVDevice->u.disk.df_tcq = pInfo->TCQEnabled!=0; 1085190809Sdelphij sync = 1; 1086136849Sscottl} 1087136849Sscottl } 1088136849Sscottl 1089190809Sdelphij if (pInfo->ValidFields & ADIF_NCQ) { 1090190809Sdelphij if (fDeSetNCQ(&pVDevice->u.disk, pInfo->NCQEnabled, 0)) { 1091190809Sdelphij pVDevice->u.disk.df_ncq_set = 1; 1092190809Sdelphij pVDevice->u.disk.df_ncq = pInfo->NCQEnabled!=0; 1093190809Sdelphij sync = 1; 1094136849Sscottl } 1095136849Sscottl } 1096136849Sscottl 1097190809Sdelphij if (pInfo->ValidFields & ADIF_WRITE_CACHE) { 1098190809Sdelphij if (fDeSetWriteCache(&pVDevice->u.disk, pInfo->WriteCacheEnabled)) { 1099190809Sdelphij pVDevice->u.disk.df_write_cache_set = 1; 1100190809Sdelphij pVDevice->u.disk.df_write_cache = pInfo->WriteCacheEnabled!=0; 1101190809Sdelphij sync = 1; 1102136849Sscottl } 1103136849Sscottl } 1104136849Sscottl 1105190809Sdelphij if (pInfo->ValidFields & ADIF_READ_AHEAD) { 1106190809Sdelphij if (fDeSetReadAhead(&pVDevice->u.disk, pInfo->ReadAheadEnabled)) { 1107190809Sdelphij pVDevice->u.disk.df_read_ahead_set = 1; 1108190809Sdelphij pVDevice->u.disk.df_read_ahead = pInfo->ReadAheadEnabled!=0; 1109190809Sdelphij sync = 1; 1110190809Sdelphij } 1111190809Sdelphij } 1112136849Sscottl 1113190809Sdelphij if (sync) 1114190809Sdelphij SyncArrayInfo(pVDevice); 1115136849Sscottl return 0; 1116136849Sscottl} 1117190809Sdelphij 1118136849Sscottl#endif 1119136849Sscottl 1120136849Sscottl/* hpt_default_ioctl() 1121136849Sscottl * This is a default implementation. The platform dependent part 1122136849Sscottl * may reuse this function and/or use it own implementation for 1123136849Sscottl * each ioctl function. 1124136849Sscottl */ 1125136849Sscottlint hpt_default_ioctl(_VBUS_ARG 1126136849Sscottl DWORD dwIoControlCode, /* operation control code */ 1127136849Sscottl PVOID lpInBuffer, /* input data buffer */ 1128136849Sscottl DWORD nInBufferSize, /* size of input data buffer */ 1129136849Sscottl PVOID lpOutBuffer, /* output data buffer */ 1130136849Sscottl DWORD nOutBufferSize, /* size of output data buffer */ 1131136849Sscottl PDWORD lpBytesReturned /* byte count */ 1132136849Sscottl ) 1133136849Sscottl{ 1134136849Sscottl switch(dwIoControlCode) { 1135136849Sscottl 1136136849Sscottl case HPT_IOCTL_GET_VERSION: 1137136849Sscottl 1138136849Sscottl if (nInBufferSize != 0) return -1; 1139136849Sscottl if (nOutBufferSize != sizeof(DWORD)) return -1; 1140136849Sscottl *((DWORD*)lpOutBuffer) = HPT_INTERFACE_VERSION; 1141136849Sscottl break; 1142136849Sscottl 1143136849Sscottl case HPT_IOCTL_GET_CONTROLLER_COUNT: 1144136849Sscottl 1145136849Sscottl if (nOutBufferSize!=sizeof(DWORD)) return -1; 1146136849Sscottl *(PDWORD)lpOutBuffer = hpt_get_controller_count(); 1147136849Sscottl break; 1148136849Sscottl 1149136849Sscottl case HPT_IOCTL_GET_CONTROLLER_INFO: 1150136849Sscottl { 1151136849Sscottl int id; 1152136849Sscottl PCONTROLLER_INFO pInfo; 1153136849Sscottl 1154136849Sscottl if (nInBufferSize!=sizeof(DWORD)) return -1; 1155136849Sscottl if (nOutBufferSize!=sizeof(CONTROLLER_INFO)) return -1; 1156136849Sscottl 1157136849Sscottl id = *(DWORD *)lpInBuffer; 1158136849Sscottl pInfo = (PCONTROLLER_INFO)lpOutBuffer; 1159136849Sscottl if (hpt_get_controller_info(id, pInfo)!=0) 1160136849Sscottl return -1; 1161136849Sscottl } 1162136849Sscottl break; 1163136849Sscottl 1164136849Sscottl case HPT_IOCTL_GET_CHANNEL_INFO: 1165136849Sscottl { 1166136849Sscottl int id, bus; 1167136849Sscottl PCHANNEL_INFO pInfo; 1168136849Sscottl 1169136849Sscottl if (nInBufferSize!=8) return -1; 1170136849Sscottl if (nOutBufferSize!=sizeof(CHANNEL_INFO)) return -1; 1171136849Sscottl 1172136849Sscottl id = *(DWORD *)lpInBuffer; 1173136849Sscottl bus = ((DWORD *)lpInBuffer)[1]; 1174136849Sscottl pInfo = (PCHANNEL_INFO)lpOutBuffer; 1175136849Sscottl 1176136849Sscottl if (hpt_get_channel_info(id, bus, pInfo)!=0) 1177136849Sscottl return -1; 1178136849Sscottl } 1179136849Sscottl break; 1180136849Sscottl 1181136849Sscottl case HPT_IOCTL_GET_LOGICAL_DEVICES: 1182136849Sscottl { 1183136849Sscottl DWORD nMax; 1184136849Sscottl DEVICEID *pIds; 1185136849Sscottl 1186136849Sscottl if (nInBufferSize!=sizeof(DWORD)) return -1; 1187136849Sscottl nMax = *(DWORD *)lpInBuffer; 1188136849Sscottl if (nOutBufferSize < sizeof(DWORD)+sizeof(DWORD)*nMax) return -1; 1189136849Sscottl 1190136849Sscottl pIds = ((DEVICEID *)lpOutBuffer)+1; 1191136849Sscottl *(DWORD*)lpOutBuffer = hpt_get_logical_devices(pIds, nMax); 1192136849Sscottl } 1193136849Sscottl break; 1194136849Sscottl 1195136849Sscottl case HPT_IOCTL_GET_DEVICE_INFO: 1196136849Sscottl { 1197136849Sscottl DEVICEID id; 1198136849Sscottl PLOGICAL_DEVICE_INFO pInfo; 1199136849Sscottl 1200136849Sscottl if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1201136849Sscottl if (nOutBufferSize!=sizeof(LOGICAL_DEVICE_INFO)) return -1; 1202136849Sscottl 1203136849Sscottl id = *(DWORD *)lpInBuffer; 1204136849Sscottl if (id == INVALID_DEVICEID) return -1; 1205136849Sscottl 1206136849Sscottl pInfo = (PLOGICAL_DEVICE_INFO)lpOutBuffer; 1207136849Sscottl memset(pInfo, 0, sizeof(LOGICAL_DEVICE_INFO)); 1208136849Sscottl 1209136849Sscottl if (hpt_get_device_info(id, pInfo)!=0) 1210136849Sscottl return -1; 1211136849Sscottl } 1212136849Sscottl break; 1213136849Sscottl 1214190809Sdelphij case HPT_IOCTL_GET_DEVICE_INFO_V2: 1215190809Sdelphij { 1216190809Sdelphij DEVICEID id; 1217190809Sdelphij PLOGICAL_DEVICE_INFO_V2 pInfo; 1218190809Sdelphij 1219190809Sdelphij if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1220190809Sdelphij if (nOutBufferSize!=sizeof(LOGICAL_DEVICE_INFO_V2)) return -1; 1221190809Sdelphij 1222190809Sdelphij id = *(DWORD *)lpInBuffer; 1223190809Sdelphij if (id == INVALID_DEVICEID) return -1; 1224190809Sdelphij 1225190809Sdelphij pInfo = (PLOGICAL_DEVICE_INFO_V2)lpOutBuffer; 1226190809Sdelphij memset(pInfo, 0, sizeof(LOGICAL_DEVICE_INFO_V2)); 1227190809Sdelphij 1228190809Sdelphij if (hpt_get_device_info_v2(id, pInfo)!=0) 1229190809Sdelphij return -1; 1230190809Sdelphij } 1231190809Sdelphij break; 1232190809Sdelphij 1233136849Sscottl#ifdef SUPPORT_ARRAY 1234136849Sscottl case HPT_IOCTL_CREATE_ARRAY: 1235136849Sscottl { 1236136849Sscottl if (nInBufferSize!=sizeof(CREATE_ARRAY_PARAMS)) return -1; 1237136849Sscottl if (nOutBufferSize!=sizeof(DEVICEID)) return -1; 1238136849Sscottl 1239190809Sdelphij *(DEVICEID *)lpOutBuffer = hpt_create_array(_VBUS_P (PCREATE_ARRAY_PARAMS)lpInBuffer); 1240136849Sscottl 1241190809Sdelphij if(*(DEVICEID *)lpOutBuffer == INVALID_DEVICEID) 1242190809Sdelphij return -1; 1243190809Sdelphij } 1244190809Sdelphij break; 1245136849Sscottl 1246190809Sdelphij case HPT_IOCTL_CREATE_ARRAY_V2: 1247190809Sdelphij { 1248190809Sdelphij if (nInBufferSize!=sizeof(CREATE_ARRAY_PARAMS_V2)) return -1; 1249190809Sdelphij if (nOutBufferSize!=sizeof(DEVICEID)) return -1; 1250190809Sdelphij 1251190809Sdelphij *(DEVICEID *)lpOutBuffer = hpt_create_array_v2(_VBUS_P (PCREATE_ARRAY_PARAMS_V2)lpInBuffer); 1252190809Sdelphij 1253190809Sdelphij if (*(DEVICEID *)lpOutBuffer == INVALID_DEVICEID) 1254136849Sscottl return -1; 1255136849Sscottl } 1256136849Sscottl break; 1257136849Sscottl 1258136849Sscottl case HPT_IOCTL_SET_ARRAY_INFO: 1259136849Sscottl { 1260136849Sscottl DEVICEID idArray; 1261136849Sscottl PALTERABLE_ARRAY_INFO pInfo; 1262136849Sscottl 1263136849Sscottl if (nInBufferSize!=sizeof(HPT_SET_ARRAY_INFO)) return -1; 1264136849Sscottl if (nOutBufferSize!=0) return -1; 1265136849Sscottl 1266136849Sscottl idArray = ((PHPT_SET_ARRAY_INFO)lpInBuffer)->idArray; 1267136849Sscottl pInfo = &((PHPT_SET_ARRAY_INFO)lpInBuffer)->Info; 1268136849Sscottl 1269136849Sscottl if(hpt_set_array_info(_VBUS_P idArray, pInfo)) 1270136849Sscottl return -1; 1271136849Sscottl } 1272136849Sscottl break; 1273136849Sscottl 1274136849Sscottl case HPT_IOCTL_SET_DEVICE_INFO: 1275136849Sscottl { 1276136849Sscottl DEVICEID idDisk; 1277136849Sscottl PALTERABLE_DEVICE_INFO pInfo; 1278136849Sscottl 1279136849Sscottl if (nInBufferSize!=sizeof(HPT_SET_DEVICE_INFO)) return -1; 1280136849Sscottl if (nOutBufferSize!=0) return -1; 1281136849Sscottl 1282136849Sscottl idDisk = ((PHPT_SET_DEVICE_INFO)lpInBuffer)->idDisk; 1283136849Sscottl pInfo = &((PHPT_SET_DEVICE_INFO)lpInBuffer)->Info; 1284136849Sscottl if(hpt_set_device_info(_VBUS_P idDisk, pInfo) != 0) 1285136849Sscottl return -1; 1286136849Sscottl } 1287136849Sscottl break; 1288136849Sscottl 1289190809Sdelphij case HPT_IOCTL_SET_DEVICE_INFO_V2: 1290190809Sdelphij { 1291190809Sdelphij DEVICEID idDisk; 1292190809Sdelphij PALTERABLE_DEVICE_INFO_V2 pInfo; 1293190809Sdelphij 1294190809Sdelphij if (nInBufferSize < sizeof(HPT_SET_DEVICE_INFO_V2)) return -1; 1295190809Sdelphij if (nOutBufferSize!=0) return -1; 1296190809Sdelphij 1297190809Sdelphij idDisk = ((PHPT_SET_DEVICE_INFO_V2)lpInBuffer)->idDisk; 1298190809Sdelphij pInfo = &((PHPT_SET_DEVICE_INFO_V2)lpInBuffer)->Info; 1299190809Sdelphij if(hpt_set_device_info_v2(_VBUS_P idDisk, pInfo) != 0) 1300190809Sdelphij return -1; 1301190809Sdelphij } 1302190809Sdelphij break; 1303190809Sdelphij 1304136849Sscottl case HPT_IOCTL_SET_BOOT_MARK: 1305136849Sscottl { 1306136849Sscottl DEVICEID id; 1307136849Sscottl PVDevice pTop; 1308136849Sscottl int i; 1309136849Sscottl IAL_ADAPTER_T *pAdapter = gIal_Adapter; 1310136849Sscottl PVBus pVBus; 1311136849Sscottl 1312136849Sscottl if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1313136849Sscottl id = *(DEVICEID *)lpInBuffer; 1314136849Sscottl while(pAdapter != 0) 1315136849Sscottl { 1316136849Sscottl pVBus = &pAdapter->VBus; 1317190809Sdelphij for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) 1318136849Sscottl { 1319136849Sscottl if(!(pTop = pVBus->pVDevice[i])) continue; 1320136849Sscottl if (pTop->pVBus!=_vbus_p) return -1; 1321136849Sscottl while (pTop->pParent) pTop = pTop->pParent; 1322136849Sscottl if (id==0 && pTop->vf_bootmark) 1323136849Sscottl pTop->vf_bootmark = 0; 1324136849Sscottl else if (pTop==ID_TO_VDEV(id) && !pTop->vf_bootmark) 1325136849Sscottl pTop->vf_bootmark = 1; 1326136849Sscottl else 1327136849Sscottl continue; 1328136849Sscottl SyncArrayInfo(pTop); 1329136849Sscottl break; 1330136849Sscottl } 1331136849Sscottl pAdapter = pAdapter->next; 1332136849Sscottl } 1333136849Sscottl } 1334136849Sscottl break; 1335136849Sscottl 1336136849Sscottl case HPT_IOCTL_ADD_SPARE_DISK: 1337136849Sscottl { 1338136849Sscottl DEVICEID id; 1339136849Sscottl 1340136849Sscottl if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1341136849Sscottl if (nOutBufferSize!=0) return -1; 1342136849Sscottl 1343136849Sscottl id = *(DEVICEID *)lpInBuffer; 1344136849Sscottl 1345136849Sscottl if(hpt_add_spare_disk(_VBUS_P id)) 1346136849Sscottl return -1; 1347136849Sscottl } 1348136849Sscottl break; 1349136849Sscottl 1350136849Sscottl case HPT_IOCTL_REMOVE_SPARE_DISK: 1351136849Sscottl { 1352136849Sscottl DEVICEID id; 1353136849Sscottl 1354136849Sscottl if (nInBufferSize!=sizeof(DEVICEID)) return -1; 1355136849Sscottl if (nOutBufferSize!=0) return -1; 1356136849Sscottl 1357136849Sscottl id = *(DEVICEID *)lpInBuffer; 1358136849Sscottl 1359136849Sscottl if(hpt_remove_spare_disk(_VBUS_P id)) 1360136849Sscottl return -1; 1361136849Sscottl } 1362136849Sscottl break; 1363136849Sscottl 1364136849Sscottl case HPT_IOCTL_ADD_DISK_TO_ARRAY: 1365136849Sscottl { 1366136849Sscottl DEVICEID id1,id2; 1367136849Sscottl id1 = ((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray; 1368136849Sscottl id2 = ((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idDisk; 1369136849Sscottl 1370136849Sscottl if (nInBufferSize != sizeof(HPT_ADD_DISK_TO_ARRAY)) return -1; 1371136849Sscottl if (nOutBufferSize != 0) return -1; 1372136849Sscottl 1373136849Sscottl if(hpt_add_disk_to_array(_VBUS_P id1, id2)) 1374136849Sscottl return -1; 1375136849Sscottl } 1376136849Sscottl break; 1377136849Sscottl#endif 1378136849Sscottl case HPT_IOCTL_GET_DRIVER_CAPABILITIES: 1379136849Sscottl { 1380136849Sscottl PDRIVER_CAPABILITIES cap; 1381136849Sscottl if (nOutBufferSize<sizeof(DRIVER_CAPABILITIES)) return -1; 1382136849Sscottl cap = (PDRIVER_CAPABILITIES)lpOutBuffer; 1383136849Sscottl 1384136849Sscottl if(hpt_get_driver_capabilities(cap)) 1385136849Sscottl return -1; 1386136849Sscottl } 1387136849Sscottl break; 1388136849Sscottl 1389190809Sdelphij case HPT_IOCTL_GET_CONTROLLER_VENID: 1390136849Sscottl { 1391190809Sdelphij DWORD id = ((DWORD*)lpInBuffer)[0]; 1392190809Sdelphij IAL_ADAPTER_T *pAdapTemp; 1393190809Sdelphij int iControllerCount = 0; 1394136849Sscottl 1395190809Sdelphij for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) 1396190809Sdelphij if (iControllerCount++==id) 1397190809Sdelphij break; 1398190809Sdelphij 1399190809Sdelphij if (!pAdapTemp) 1400136849Sscottl return -1; 1401190809Sdelphij 1402190809Sdelphij if (nOutBufferSize < 4) 1403190809Sdelphij return -1; 1404190809Sdelphij 1405190809Sdelphij *(DWORD*)lpOutBuffer = ((DWORD)pAdapTemp->mvSataAdapter.pciConfigDeviceId << 16) | 0x11AB; 1406190809Sdelphij return 0; 1407136849Sscottl } 1408136849Sscottl 1409190809Sdelphij case HPT_IOCTL_EPROM_IO: 1410136849Sscottl { 1411190809Sdelphij DWORD id = ((DWORD*)lpInBuffer)[0]; 1412190809Sdelphij DWORD offset = ((DWORD*)lpInBuffer)[1]; 1413190809Sdelphij DWORD direction = ((DWORD*)lpInBuffer)[2]; 1414190809Sdelphij DWORD length = ((DWORD*)lpInBuffer)[3]; 1415190809Sdelphij IAL_ADAPTER_T *pAdapTemp; 1416190809Sdelphij int iControllerCount = 0; 1417136849Sscottl 1418190809Sdelphij for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) 1419190809Sdelphij if (iControllerCount++==id) 1420190809Sdelphij break; 1421190809Sdelphij 1422190809Sdelphij if (!pAdapTemp) 1423190809Sdelphij return -1; 1424190809Sdelphij 1425190809Sdelphij if (nInBufferSize < sizeof(DWORD) * 4 + (direction? length : 0) || 1426190809Sdelphij nOutBufferSize < (direction? 0 : length)) 1427190809Sdelphij return -1; 1428136849Sscottl 1429190809Sdelphij if (direction == 0) /* read */ 1430190809Sdelphij sx508x_flash_access(&pAdapTemp->mvSataAdapter, 1431190809Sdelphij offset, lpOutBuffer, length, 1); 1432190809Sdelphij else 1433190809Sdelphij sx508x_flash_access(&pAdapTemp->mvSataAdapter, 1434190809Sdelphij offset, (char *)lpInBuffer + 16, length, 0); 1435190809Sdelphij 1436190809Sdelphij return 0; 1437136849Sscottl } 1438136849Sscottl break; 1439190809Sdelphij 1440136849Sscottl default: 1441136849Sscottl return -1; 1442136849Sscottl } 1443136849Sscottl 1444136849Sscottl if (lpBytesReturned) 1445136849Sscottl *lpBytesReturned = nOutBufferSize; 1446136849Sscottl return 0; 1447136849Sscottl} 1448