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