The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/raid/hptmv/gui_lib.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b2d98af0b300d71e4d9057bbfb88e2d4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.