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