1331722Seadler/* 2149871Sscottl * Copyright (c) 2004-2005 HighPoint Technologies, Inc. 3136849Sscottl * All rights reserved. 4136849Sscottl * 5136849Sscottl * Redistribution and use in source and binary forms, with or without 6136849Sscottl * modification, are permitted provided that the following conditions 7136849Sscottl * are met: 8136849Sscottl * 1. Redistributions of source code must retain the above copyright 9136849Sscottl * notice, this list of conditions and the following disclaimer. 10136849Sscottl * 2. Redistributions in binary form must reproduce the above copyright 11136849Sscottl * notice, this list of conditions and the following disclaimer in the 12136849Sscottl * documentation and/or other materials provided with the distribution. 13136849Sscottl * 14136849Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15136849Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16136849Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17136849Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18136849Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19136849Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20136849Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21136849Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22136849Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23136849Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24136849Sscottl * SUCH DAMAGE. 25142988Sscottl * 26142988Sscottl * $FreeBSD: stable/11/sys/dev/hptmv/hptproc.c 315221 2017-03-14 02:06:03Z pfg $ 27136849Sscottl */ 28136849Sscottl/* 29136849Sscottl * hptproc.c sysctl support 30136849Sscottl */ 31136849Sscottl#include <sys/param.h> 32136849Sscottl#include <sys/systm.h> 33136849Sscottl#include <sys/kernel.h> 34136849Sscottl#include <sys/malloc.h> 35136849Sscottl#include <sys/sysctl.h> 36136849Sscottl#include <machine/stdarg.h> 37136849Sscottl 38149871Sscottl#ifndef __KERNEL__ 39149871Sscottl#define __KERNEL__ 40149871Sscottl#endif 41149871Sscottl 42136849Sscottl#include <dev/hptmv/global.h> 43136849Sscottl#include <dev/hptmv/hptintf.h> 44136849Sscottl#include <dev/hptmv/osbsd.h> 45143039Sscottl#include <dev/hptmv/access601.h> 46136849Sscottl 47136849Sscottlint hpt_rescan_all(void); 48136849Sscottl 49136849Sscottl/***************************************************************************/ 50136849Sscottl 51136849Sscottlstatic char hptproc_buffer[256]; 52149871Sscottlextern char DRIVER_VERSION[]; 53136849Sscottl 54136849Sscottltypedef struct sysctl_req HPT_GET_INFO; 55136849Sscottl 56149871Sscottlstatic int 57149871Sscottlhpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length) 58136849Sscottl{ 59136849Sscottl int orig_length = length+4; 60136849Sscottl PVBus _vbus_p = &pAdapter->VBus; 61136849Sscottl PVDevice pArray; 62136849Sscottl PVDevice pSubArray, pVDev; 63136849Sscottl UINT i, iarray, ichan; 64136849Sscottl struct cam_periph *periph = NULL; 65136849Sscottl 66269617Sjhb mtx_lock(&pAdapter->lock); 67136849Sscottl#ifdef SUPPORT_ARRAY 68136849Sscottl if (length>=8 && strncmp(buffer, "rebuild ", 8)==0) 69136849Sscottl { 70136849Sscottl buffer+=8; 71136849Sscottl length-=8; 72136849Sscottl if (length>=5 && strncmp(buffer, "start", 5)==0) 73136849Sscottl { 74136849Sscottl for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) 75136849Sscottl if ((pArray=ArrayTables(i))->u.array.dArStamp==0) 76136849Sscottl continue; 77136849Sscottl else{ 78136849Sscottl if (pArray->u.array.rf_need_rebuild && !pArray->u.array.rf_rebuilding) 79136849Sscottl hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, 80136849Sscottl (UCHAR)((pArray->u.array.CriticalMembers || pArray->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY)); 81136849Sscottl } 82269617Sjhb mtx_unlock(&pAdapter->lock); 83136849Sscottl return orig_length; 84136849Sscottl } 85136849Sscottl else if (length>=4 && strncmp(buffer, "stop", 4)==0) 86136849Sscottl { 87136849Sscottl for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) 88136849Sscottl if ((pArray=ArrayTables(i))->u.array.dArStamp==0) 89136849Sscottl continue; 90136849Sscottl else{ 91136849Sscottl if (pArray->u.array.rf_rebuilding) 92136849Sscottl pArray->u.array.rf_abort_rebuild = 1; 93136849Sscottl } 94269617Sjhb mtx_unlock(&pAdapter->lock); 95136849Sscottl return orig_length; 96136849Sscottl } 97136849Sscottl else if (length>=3 && buffer[1]==','&& buffer[0]>='1'&& buffer[2]>='1') 98136849Sscottl { 99136849Sscottl iarray = buffer[0]-'1'; 100136849Sscottl ichan = buffer[2]-'1'; 101136849Sscottl 102136849Sscottl if(iarray >= MAX_VDEVICE_PER_VBUS || ichan >= MV_SATA_CHANNELS_NUM) return -EINVAL; 103136849Sscottl 104136849Sscottl pArray = _vbus_p->pVDevice[iarray]; 105269617Sjhb if (!pArray || (pArray->vf_online == 0)) { 106269617Sjhb mtx_unlock(&pAdapter->lock); 107269617Sjhb return -EINVAL; 108269617Sjhb } 109136849Sscottl 110136849Sscottl for (i=0;i<MV_SATA_CHANNELS_NUM;i++) 111136849Sscottl if(i == ichan) 112136849Sscottl goto rebuild; 113136849Sscottl 114269617Sjhb mtx_unlock(&pAdapter->lock); 115136849Sscottl return -EINVAL; 116136849Sscottl 117136849Sscottlrebuild: 118136849Sscottl pVDev = &pAdapter->VDevices[ichan]; 119269617Sjhb if(!pVDev->u.disk.df_on_line || pVDev->pParent) { 120269617Sjhb mtx_unlock(&pAdapter->lock); 121269617Sjhb return -EINVAL; 122269617Sjhb } 123136849Sscottl 124136849Sscottl /* Not allow to use a mounted disk ??? test*/ 125136849Sscottl for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) 126136849Sscottl if(pVDev == _vbus_p->pVDevice[i]) 127136849Sscottl { 128136849Sscottl periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId,i); 129149871Sscottl if (periph != NULL && periph->refcount >= 1) 130136849Sscottl { 131136849Sscottl hpt_printk(("Can not use disk used by OS!\n")); 132269617Sjhb mtx_unlock(&pAdapter->lock); 133136849Sscottl return -EINVAL; 134136849Sscottl } 135136849Sscottl /* the Mounted Disk isn't delete */ 136136849Sscottl } 137136849Sscottl 138136849Sscottl switch(pArray->VDeviceType) 139136849Sscottl { 140136849Sscottl case VD_RAID_1: 141136849Sscottl case VD_RAID_5: 142136849Sscottl { 143136849Sscottl pSubArray = pArray; 144136849Sscottlloop: 145136849Sscottl if(hpt_add_disk_to_array(_VBUS_P VDEV_TO_ID(pSubArray), VDEV_TO_ID(pVDev)) == -1) { 146269617Sjhb mtx_unlock(&pAdapter->lock); 147136849Sscottl return -EINVAL; 148136849Sscottl } 149149871Sscottl pSubArray->u.array.rf_auto_rebuild = 0; 150149871Sscottl pSubArray->u.array.rf_abort_rebuild = 0; 151149871Sscottl hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pSubArray, DUPLICATE); 152136849Sscottl break; 153136849Sscottl } 154136849Sscottl case VD_RAID_0: 155136849Sscottl for (i = 0; (UCHAR)i < pArray->u.array.bArnMember; i++) 156136849Sscottl if(pArray->u.array.pMember[i] && mIsArray(pArray->u.array.pMember[i]) && 157136849Sscottl (pArray->u.array.pMember[i]->u.array.rf_broken == 1)) 158136849Sscottl { 159136849Sscottl pSubArray = pArray->u.array.pMember[i]; 160136849Sscottl goto loop; 161136849Sscottl } 162136849Sscottl default: 163269617Sjhb mtx_unlock(&pAdapter->lock); 164136849Sscottl return -EINVAL; 165136849Sscottl } 166269617Sjhb mtx_unlock(&pAdapter->lock); 167136849Sscottl return orig_length; 168136849Sscottl } 169136849Sscottl } 170136849Sscottl else if (length>=7 && strncmp(buffer, "verify ", 7)==0) 171136849Sscottl { 172136849Sscottl buffer+=7; 173136849Sscottl length-=7; 174136849Sscottl if (length>=6 && strncmp(buffer, "start ", 6)==0) 175136849Sscottl { 176136849Sscottl buffer+=6; 177136849Sscottl length-=6; 178136849Sscottl if (length>=1 && *buffer>='1') 179136849Sscottl { 180136849Sscottl iarray = *buffer-'1'; 181269617Sjhb if(iarray >= MAX_VDEVICE_PER_VBUS) { 182269617Sjhb mtx_unlock(&pAdapter->lock); 183269617Sjhb return -EINVAL; 184269617Sjhb } 185136849Sscottl 186136849Sscottl pArray = _vbus_p->pVDevice[iarray]; 187269617Sjhb if (!pArray || (pArray->vf_online == 0)) { 188269617Sjhb mtx_unlock(&pAdapter->lock); 189269617Sjhb return -EINVAL; 190269617Sjhb } 191136849Sscottl 192269617Sjhb if(pArray->VDeviceType != VD_RAID_1 && pArray->VDeviceType != VD_RAID_5) { 193269617Sjhb mtx_unlock(&pAdapter->lock); 194136849Sscottl return -EINVAL; 195269617Sjhb } 196136849Sscottl 197136849Sscottl if (!(pArray->u.array.rf_need_rebuild || 198136849Sscottl pArray->u.array.rf_rebuilding || 199136849Sscottl pArray->u.array.rf_verifying || 200136849Sscottl pArray->u.array.rf_initializing)) 201136849Sscottl { 202136849Sscottl pArray->u.array.RebuildSectors = 0; 203136849Sscottl hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, VERIFY); 204136849Sscottl } 205269617Sjhb mtx_unlock(&pAdapter->lock); 206136849Sscottl return orig_length; 207136849Sscottl } 208136849Sscottl } 209136849Sscottl else if (length>=5 && strncmp(buffer, "stop ", 5)==0) 210136849Sscottl { 211136849Sscottl buffer+=5; 212136849Sscottl length-=5; 213136849Sscottl if (length>=1 && *buffer>='1') 214136849Sscottl { 215136849Sscottl iarray = *buffer-'1'; 216269617Sjhb if(iarray >= MAX_VDEVICE_PER_VBUS) { 217269617Sjhb mtx_unlock(&pAdapter->lock); 218269617Sjhb return -EINVAL; 219269617Sjhb } 220136849Sscottl 221136849Sscottl pArray = _vbus_p->pVDevice[iarray]; 222269617Sjhb if (!pArray || (pArray->vf_online == 0)) { 223269617Sjhb mtx_unlock(&pAdapter->lock); 224269617Sjhb return -EINVAL; 225269617Sjhb } 226136849Sscottl if(pArray->u.array.rf_verifying) 227136849Sscottl { 228136849Sscottl pArray->u.array.rf_abort_rebuild = 1; 229136849Sscottl } 230269617Sjhb mtx_unlock(&pAdapter->lock); 231136849Sscottl return orig_length; 232136849Sscottl } 233136849Sscottl } 234136849Sscottl } 235136849Sscottl else 236136849Sscottl#ifdef _RAID5N_ 237136849Sscottl if (length>=10 && strncmp(buffer, "writeback ", 10)==0) { 238136849Sscottl buffer+=10; 239136849Sscottl length-=10; 240136849Sscottl if (length>=1 && *buffer>='0' && *buffer<='1') { 241136849Sscottl _vbus_(r5.enable_write_back) = *buffer-'0'; 242136849Sscottl if (_vbus_(r5.enable_write_back)) 243136849Sscottl hpt_printk(("RAID5 write back enabled")); 244269617Sjhb mtx_unlock(&pAdapter->lock); 245136849Sscottl return orig_length; 246136849Sscottl } 247136849Sscottl } 248136849Sscottl else 249136849Sscottl#endif 250149871Sscottl#endif 251136849Sscottl if (0) {} /* just to compile */ 252153072Sru#ifdef DEBUG 253136849Sscottl else if (length>=9 && strncmp(buffer, "dbglevel ", 9)==0) { 254136849Sscottl buffer+=9; 255136849Sscottl length-=9; 256136849Sscottl if (length>=1 && *buffer>='0' && *buffer<='3') { 257136849Sscottl hpt_dbg_level = *buffer-'0'; 258269617Sjhb mtx_unlock(&pAdapter->lock); 259136849Sscottl return orig_length; 260136849Sscottl } 261136849Sscottl } 262136849Sscottl else if (length>=8 && strncmp(buffer, "disable ", 8)==0) { 263136849Sscottl /* TO DO */ 264136849Sscottl } 265149871Sscottl#endif 266269617Sjhb mtx_unlock(&pAdapter->lock); 267136849Sscottl 268136849Sscottl return -EINVAL; 269136849Sscottl} 270136849Sscottl 271136849Sscottl/* 272136849Sscottl * Since we have only one sysctl node, add adapter ID in the command 273136849Sscottl * line string: e.g. "hpt 0 rebuild start" 274136849Sscottl */ 275149871Sscottlstatic int 276149871Sscottlhpt_set_info(int length) 277136849Sscottl{ 278136849Sscottl int retval; 279136849Sscottl 280136849Sscottl#ifdef SUPPORT_IOCTL 281136849Sscottl PUCHAR ke_area; 282136849Sscottl int err; 283136849Sscottl DWORD dwRet; 284149871Sscottl PHPT_IOCTL_PARAM piop; 285136849Sscottl#endif 286136849Sscottl char *buffer = hptproc_buffer; 287136849Sscottl if (length >= 6) { 288136849Sscottl if (strncmp(buffer,"hpt ",4) == 0) { 289136849Sscottl IAL_ADAPTER_T *pAdapter; 290136849Sscottl retval = buffer[4]-'0'; 291136849Sscottl for (pAdapter=gIal_Adapter; pAdapter; pAdapter=pAdapter->next) { 292136849Sscottl if (pAdapter->mvSataAdapter.adapterId==retval) 293136849Sscottl return (retval = hpt_set_asc_info(pAdapter, buffer+6, length-6)) >= 0? retval : -EINVAL; 294136849Sscottl } 295136849Sscottl return -EINVAL; 296136849Sscottl } 297136849Sscottl#ifdef SUPPORT_IOCTL 298149871Sscottl piop = (PHPT_IOCTL_PARAM)buffer; 299190809Sdelphij if (piop->Magic == HPT_IOCTL_MAGIC || 300190809Sdelphij piop->Magic == HPT_IOCTL_MAGIC32) { 301149871Sscottl KdPrintE(("ioctl=%d in=%p len=%d out=%p len=%d\n", 302136849Sscottl piop->dwIoControlCode, 303136849Sscottl piop->lpInBuffer, 304136849Sscottl piop->nInBufferSize, 305136849Sscottl piop->lpOutBuffer, 306149871Sscottl piop->nOutBufferSize)); 307136849Sscottl 308136849Sscottl /* 309136849Sscottl * map buffer to kernel. 310136849Sscottl */ 311298231Ssbruno if (piop->nInBufferSize > PAGE_SIZE || 312298231Ssbruno piop->nOutBufferSize > PAGE_SIZE || 313298231Ssbruno piop->nInBufferSize+piop->nOutBufferSize > PAGE_SIZE) { 314136849Sscottl KdPrintE(("User buffer too large\n")); 315136849Sscottl return -EINVAL; 316136849Sscottl } 317136849Sscottl 318136849Sscottl ke_area = malloc(piop->nInBufferSize+piop->nOutBufferSize, M_DEVBUF, M_NOWAIT); 319136849Sscottl if (ke_area == NULL) { 320136849Sscottl KdPrintE(("Couldn't allocate kernel mem.\n")); 321136849Sscottl return -EINVAL; 322136849Sscottl } 323136849Sscottl 324298231Ssbruno if (piop->nInBufferSize) { 325298231Ssbruno if (copyin((void*)(ULONG_PTR)piop->lpInBuffer, ke_area, piop->nInBufferSize) != 0) { 326298231Ssbruno KdPrintE(("Failed to copyin from lpInBuffer\n")); 327298231Ssbruno free(ke_area, M_DEVBUF); 328298231Ssbruno return -EFAULT; 329298231Ssbruno } 330298231Ssbruno } 331136849Sscottl 332136849Sscottl /* 333136849Sscottl * call kernel handler. 334136849Sscottl */ 335149871Sscottl err = Kernel_DeviceIoControl(&gIal_Adapter->VBus, 336149871Sscottl piop->dwIoControlCode, ke_area, piop->nInBufferSize, 337149871Sscottl ke_area + piop->nInBufferSize, piop->nOutBufferSize, &dwRet); 338136849Sscottl 339136849Sscottl if (err==0) { 340149871Sscottl if (piop->nOutBufferSize) 341149871Sscottl copyout(ke_area + piop->nInBufferSize, (void*)(ULONG_PTR)piop->lpOutBuffer, piop->nOutBufferSize); 342136849Sscottl 343149871Sscottl if (piop->lpBytesReturned) 344149871Sscottl copyout(&dwRet, (void*)(ULONG_PTR)piop->lpBytesReturned, sizeof(DWORD)); 345136849Sscottl 346136849Sscottl free(ke_area, M_DEVBUF); 347136849Sscottl return length; 348136849Sscottl } 349136849Sscottl else KdPrintW(("Kernel_ioctl(): return %d\n", err)); 350136849Sscottl 351136849Sscottl free(ke_area, M_DEVBUF); 352298231Ssbruno return -EINVAL; 353136849Sscottl } else { 354136849Sscottl KdPrintW(("Wrong signature: %x\n", piop->Magic)); 355136849Sscottl return -EINVAL; 356136849Sscottl } 357136849Sscottl#endif 358136849Sscottl } 359136849Sscottl 360136849Sscottl return -EINVAL; 361136849Sscottl} 362136849Sscottl 363136849Sscottl#define shortswap(w) ((WORD)((w)>>8 | ((w) & 0xFF)<<8)) 364136849Sscottl 365149871Sscottlstatic void 366149871Sscottlget_disk_name(char *name, PDevice pDev) 367136849Sscottl{ 368136849Sscottl int i; 369136849Sscottl MV_SATA_CHANNEL *pMvSataChannel = pDev->mv; 370136849Sscottl IDENTIFY_DATA2 *pIdentifyData = (IDENTIFY_DATA2 *)pMvSataChannel->identifyDevice; 371136849Sscottl 372136849Sscottl for (i = 0; i < 10; i++) 373136849Sscottl ((WORD*)name)[i] = shortswap(pIdentifyData->ModelNumber[i]); 374136849Sscottl name[20] = '\0'; 375136849Sscottl} 376136849Sscottl 377149871Sscottlstatic int 378149871Sscottlhpt_copy_info(HPT_GET_INFO *pinfo, char *fmt, ...) 379136849Sscottl{ 380136849Sscottl int printfretval; 381136849Sscottl va_list ap; 382136849Sscottl 383136849Sscottl if(fmt == NULL) { 384136849Sscottl *hptproc_buffer = 0; 385136849Sscottl return (SYSCTL_OUT(pinfo, hptproc_buffer, 1)); 386136849Sscottl } 387136849Sscottl else 388136849Sscottl { 389136849Sscottl va_start(ap, fmt); 390136849Sscottl printfretval = vsnprintf(hptproc_buffer, sizeof(hptproc_buffer), fmt, ap); 391136849Sscottl va_end(ap); 392136849Sscottl return(SYSCTL_OUT(pinfo, hptproc_buffer, strlen(hptproc_buffer))); 393136849Sscottl } 394136849Sscottl} 395136849Sscottl 396149871Sscottlstatic void 397149871Sscottlhpt_copy_disk_info(HPT_GET_INFO *pinfo, PVDevice pVDev, UINT iChan) 398136849Sscottl{ 399149871Sscottl char name[32], arrayname[16], *status; 400149871Sscottl 401149871Sscottl get_disk_name(name, &pVDev->u.disk); 402136849Sscottl 403149871Sscottl if (!pVDev->u.disk.df_on_line) 404149871Sscottl status = "Disabled"; 405149871Sscottl else if (pVDev->VDeviceType==VD_SPARE) 406149871Sscottl status = "Spare "; 407149871Sscottl else 408149871Sscottl status = "Normal "; 409136849Sscottl 410149871Sscottl#ifdef SUPPORT_ARRAY 411149871Sscottl if(pVDev->pParent) { 412136849Sscottl memcpy(arrayname, pVDev->pParent->u.array.ArrayName, MAX_ARRAY_NAME); 413149871Sscottl if (pVDev->pParent->u.array.CriticalMembers & (1<<pVDev->bSerialNumber)) 414149871Sscottl status = "Degraded"; 415149871Sscottl } 416136849Sscottl else 417136849Sscottl#endif 418149871Sscottl arrayname[0]=0; 419136849Sscottl 420136849Sscottl hpt_copy_info(pinfo, "Channel %d %s %5dMB %s %s\n", 421136849Sscottl iChan+1, 422149871Sscottl name, pVDev->VDeviceCapacity>>11, status, arrayname); 423136849Sscottl} 424136849Sscottl 425136849Sscottl#ifdef SUPPORT_ARRAY 426149871Sscottlstatic void 427149871Sscottlhpt_copy_array_info(HPT_GET_INFO *pinfo, int nld, PVDevice pArray) 428136849Sscottl{ 429136849Sscottl int i; 430315221Spfg char *sType = NULL, *sStatus = NULL; 431136849Sscottl char buf[32]; 432136849Sscottl PVDevice pTmpArray; 433136849Sscottl 434136849Sscottl switch (pArray->VDeviceType) { 435136849Sscottl case VD_RAID_0: 436136849Sscottl for (i = 0; (UCHAR)i < pArray->u.array.bArnMember; i++) 437136849Sscottl if(pArray->u.array.pMember[i]) { 438136849Sscottl if(mIsArray(pArray->u.array.pMember[i])) 439136849Sscottl sType = "RAID 1/0 "; 440136849Sscottl /* TO DO */ 441136849Sscottl else 442136849Sscottl sType = "RAID 0 "; 443136849Sscottl break; 444136849Sscottl } 445136849Sscottl break; 446136849Sscottl 447136849Sscottl case VD_RAID_1: 448136849Sscottl sType = "RAID 1 "; 449136849Sscottl break; 450136849Sscottl 451136849Sscottl case VD_JBOD: 452136849Sscottl sType = "JBOD "; 453136849Sscottl break; 454136849Sscottl 455136849Sscottl case VD_RAID_5: 456136849Sscottl sType = "RAID 5 "; 457136849Sscottl break; 458136849Sscottl 459136849Sscottl default: 460136849Sscottl sType = "N/A "; 461136849Sscottl break; 462136849Sscottl } 463136849Sscottl 464136849Sscottl if (pArray->vf_online == 0) 465136849Sscottl sStatus = "Disabled"; 466136849Sscottl else if (pArray->u.array.rf_broken) 467136849Sscottl sStatus = "Critical"; 468136849Sscottl for (i = 0; (UCHAR)i < pArray->u.array.bArnMember; i++) 469136849Sscottl { 470136849Sscottl if (!sStatus) 471136849Sscottl { 472136849Sscottl if(mIsArray(pArray->u.array.pMember[i])) 473136849Sscottl pTmpArray = pArray->u.array.pMember[i]; 474136849Sscottl else 475136849Sscottl pTmpArray = pArray; 476136849Sscottl 477136849Sscottl if (pTmpArray->u.array.rf_rebuilding) { 478136849Sscottl#ifdef DEBUG 479190809Sdelphij sprintf(buf, "Rebuilding %lldMB", (pTmpArray->u.array.RebuildSectors>>11)); 480149871Sscottl#else 481190809Sdelphij sprintf(buf, "Rebuilding %d%%", (UINT)((pTmpArray->u.array.RebuildSectors>>11)*100/((pTmpArray->VDeviceCapacity/(pTmpArray->u.array.bArnMember-1))>>11))); 482136849Sscottl#endif 483136849Sscottl sStatus = buf; 484136849Sscottl } 485136849Sscottl else if (pTmpArray->u.array.rf_verifying) { 486190809Sdelphij sprintf(buf, "Verifying %d%%", (UINT)((pTmpArray->u.array.RebuildSectors>>11)*100/((pTmpArray->VDeviceCapacity/(pTmpArray->u.array.bArnMember-1))>>11))); 487136849Sscottl sStatus = buf; 488136849Sscottl } 489136849Sscottl else if (pTmpArray->u.array.rf_need_rebuild) 490136849Sscottl sStatus = "Critical"; 491136849Sscottl else if (pTmpArray->u.array.rf_broken) 492136849Sscottl sStatus = "Critical"; 493136849Sscottl 494136849Sscottl if(pTmpArray == pArray) goto out; 495136849Sscottl } 496136849Sscottl else 497136849Sscottl goto out; 498136849Sscottl } 499136849Sscottlout: 500136849Sscottl if (!sStatus) sStatus = "Normal"; 501190809Sdelphij hpt_copy_info(pinfo, "%2d %11s %-20s %5lldMB %-16s", nld, sType, pArray->u.array.ArrayName, pArray->VDeviceCapacity>>11, sStatus); 502136849Sscottl} 503136849Sscottl#endif 504136849Sscottl 505149871Sscottlstatic int 506149871Sscottlhpt_get_info(IAL_ADAPTER_T *pAdapter, HPT_GET_INFO *pinfo) 507136849Sscottl{ 508136849Sscottl PVBus _vbus_p = &pAdapter->VBus; 509136849Sscottl struct cam_periph *periph = NULL; 510136849Sscottl UINT channel,j,i; 511136849Sscottl PVDevice pVDev; 512136849Sscottl 513136849Sscottl#ifndef FOR_DEMO 514269617Sjhb mtx_lock(&pAdapter->lock); 515136849Sscottl if (pAdapter->beeping) { 516136849Sscottl pAdapter->beeping = 0; 517136849Sscottl BeepOff(pAdapter->mvSataAdapter.adapterIoBaseAddress); 518136849Sscottl } 519269617Sjhb mtx_unlock(&pAdapter->lock); 520136849Sscottl#endif 521136849Sscottl 522136849Sscottl hpt_copy_info(pinfo, "Controller #%d:\n\n", pAdapter->mvSataAdapter.adapterId); 523136849Sscottl 524136849Sscottl hpt_copy_info(pinfo, "Physical device list\n"); 525136849Sscottl hpt_copy_info(pinfo, "Channel Model Capacity Status Array\n"); 526136849Sscottl hpt_copy_info(pinfo, "-------------------------------------------------------------------\n"); 527136849Sscottl 528136849Sscottl for (channel = 0; channel < MV_SATA_CHANNELS_NUM; channel++) 529136849Sscottl { 530136849Sscottl pVDev = &(pAdapter->VDevices[channel]); 531136849Sscottl if(pVDev->u.disk.df_on_line) 532136849Sscottl hpt_copy_disk_info(pinfo, pVDev, channel); 533136849Sscottl } 534136849Sscottl 535136849Sscottl hpt_copy_info(pinfo, "\nLogical device list\n"); 536136849Sscottl hpt_copy_info(pinfo, "No. Type Name Capacity Status OsDisk\n"); 537136849Sscottl hpt_copy_info(pinfo, "--------------------------------------------------------------------------\n"); 538136849Sscottl 539136849Sscottl j=1; 540136849Sscottl for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++){ 541136849Sscottl pVDev = _vbus_p->pVDevice[i]; 542136849Sscottl if(pVDev){ 543136849Sscottl j=i+1; 544136849Sscottl#ifdef SUPPORT_ARRAY 545136849Sscottl if (mIsArray(pVDev)) 546136849Sscottl { 547136849Sscottl is_array: 548136849Sscottl hpt_copy_array_info(pinfo, j, pVDev); 549136849Sscottl } 550136849Sscottl else 551136849Sscottl#endif 552136849Sscottl { 553136849Sscottl char name[32]; 554136849Sscottl /* it may be add to an array after driver loaded, check it */ 555136849Sscottl#ifdef SUPPORT_ARRAY 556136849Sscottl if (pVDev->pParent) 557136849Sscottl /* in this case, pVDev can only be a RAID 1 source disk. */ 558136849Sscottl if (pVDev->pParent->VDeviceType==VD_RAID_1 && pVDev==pVDev->pParent->u.array.pMember[0]) 559136849Sscottl goto is_array; 560136849Sscottl#endif 561136849Sscottl get_disk_name(name, &pVDev->u.disk); 562136849Sscottl 563136849Sscottl hpt_copy_info(pinfo, "%2d %s %s %5dMB %-16s", 564136849Sscottl j, "Single disk", name, pVDev->VDeviceCapacity>>11, 565136849Sscottl /* gmm 2001-6-19: Check if pDev has been added to an array. */ 566136849Sscottl ((pVDev->pParent) ? "Unavailable" : "Normal")); 567136849Sscottl } 568136849Sscottl periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId, i); 569136849Sscottl if (periph == NULL) 570136849Sscottl hpt_copy_info(pinfo," %s\n","not registered"); 571136849Sscottl else 572136849Sscottl hpt_copy_info(pinfo," %s%d\n", periph->periph_name, periph->unit_number); 573136849Sscottl } 574136849Sscottl } 575136849Sscottl return 0; 576136849Sscottl} 577136849Sscottl 578149871Sscottlstatic __inline int 579290519Scemhpt_proc_in(SYSCTL_HANDLER_ARGS, int *len) 580136849Sscottl{ 581136849Sscottl int i, error=0; 582136849Sscottl 583136849Sscottl *len = 0; 584136849Sscottl if ((req->newlen - req->newidx) >= sizeof(hptproc_buffer)) { 585136849Sscottl error = EINVAL; 586136849Sscottl } else { 587136849Sscottl i = (req->newlen - req->newidx); 588136849Sscottl error = SYSCTL_IN(req, hptproc_buffer, i); 589136849Sscottl if (!error) 590136849Sscottl *len = i; 591136849Sscottl (hptproc_buffer)[i] = '\0'; 592136849Sscottl } 593136849Sscottl return (error); 594136849Sscottl} 595136849Sscottl 596149871Sscottlstatic int 597290519Scemhpt_status(SYSCTL_HANDLER_ARGS) 598136849Sscottl{ 599136849Sscottl int length, error=0, retval=0; 600136849Sscottl IAL_ADAPTER_T *pAdapter; 601136849Sscottl 602290519Scem error = hpt_proc_in(oidp, arg1, arg2, req, &length); 603136849Sscottl 604136849Sscottl if (req->newptr != NULL) 605136849Sscottl { 606136849Sscottl if (error || length == 0) 607136849Sscottl { 608136849Sscottl KdPrint(("error!\n")); 609136849Sscottl retval = EINVAL; 610136849Sscottl goto out; 611136849Sscottl } 612136849Sscottl 613136849Sscottl if (hpt_set_info(length) >= 0) 614136849Sscottl retval = 0; 615136849Sscottl else 616136849Sscottl retval = EINVAL; 617136849Sscottl goto out; 618136849Sscottl } 619136849Sscottl 620136849Sscottl hpt_copy_info(req, "%s Version %s\n", DRIVER_NAME, DRIVER_VERSION); 621136849Sscottl for (pAdapter=gIal_Adapter; pAdapter; pAdapter=pAdapter->next) { 622136849Sscottl if (hpt_get_info(pAdapter, req) < 0) { 623136849Sscottl retval = EINVAL; 624136849Sscottl break; 625136849Sscottl } 626136849Sscottl } 627136849Sscottl 628136849Sscottl hpt_copy_info(req, NULL); 629136849Sscottl goto out; 630136849Sscottl 631136849Sscottlout: 632136849Sscottl return (retval); 633136849Sscottl} 634136849Sscottl 635136849Sscottl 636136849Sscottl#define xhptregister_node(name) hptregister_node(name) 637136849Sscottl 638269617Sjhb#if __FreeBSD_version >= 1100024 639136849Sscottl#define hptregister_node(name) \ 640269617Sjhb SYSCTL_ROOT_NODE(OID_AUTO, name, CTLFLAG_RW, 0, "Get/Set " #name " state root node"); \ 641136849Sscottl SYSCTL_OID(_ ## name, OID_AUTO, status, CTLTYPE_STRING|CTLFLAG_RW, \ 642136849Sscottl NULL, 0, hpt_status, "A", "Get/Set " #name " state") 643269617Sjhb#else 644136849Sscottl#define hptregister_node(name) \ 645269617Sjhb SYSCTL_NODE(, OID_AUTO, name, CTLFLAG_RW, 0, "Get/Set " #name " state root node"); \ 646136849Sscottl SYSCTL_OID(_ ## name, OID_AUTO, status, CTLTYPE_STRING|CTLFLAG_RW, \ 647269617Sjhb NULL, 0, hpt_status, "A", "Get/Set " #name " state") 648136849Sscottl#endif 649136849Sscottl 650136849Sscottlxhptregister_node(PROC_DIR_NAME); 651