void HPTLIBAPI ioctl_ReportEvent(UCHAR event, PVOID param) { HPT_EVENT e; ZeroMemory(&e, sizeof(e)); e.EventType = event; switch(event) { case ET_INITIALIZE_ABORTED: case ET_INITIALIZE_FAILED: memcpy(e.Data, ((PVDevice)param)->u.array.ArrayName, MAX_ARRAY_NAME); case ET_INITIALIZE_STARTED: case ET_INITIALIZE_FINISHED: case ET_REBUILD_STARTED: case ET_REBUILD_ABORTED: case ET_REBUILD_FAILED: case ET_REBUILD_FINISHED: case ET_VERIFY_STARTED: case ET_VERIFY_ABORTED: case ET_VERIFY_FAILED: case ET_VERIFY_FINISHED: case ET_VERIFY_DATA_ERROR: case ET_SPARE_TOOK_OVER: case ET_DEVICE_REMOVED: case ET_DEVICE_PLUGGED: case ET_DEVICE_ERROR: e.DeviceID = VDEV_TO_ID((PVDevice)param); break; default: break; } event_queue_add(&e); if (event==ET_DEVICE_REMOVED) { int controller, channel; get_disk_location(&((PVDevice)param)->u.disk, &controller, &channel); hpt_printk(("Device removed: controller %d channel %d\n", controller, channel)); } wakeup(param); }
static int hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length) { int orig_length = length+4; PVBus _vbus_p = &pAdapter->VBus; PVDevice pArray; PVDevice pSubArray, pVDev; UINT i, iarray, ichan; struct cam_periph *periph = NULL; intrmask_t oldspl; #ifdef SUPPORT_ARRAY if (length>=8 && strncmp(buffer, "rebuild ", 8)==0) { buffer+=8; length-=8; if (length>=5 && strncmp(buffer, "start", 5)==0) { oldspl = lock_driver(); for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) if ((pArray=ArrayTables(i))->u.array.dArStamp==0) continue; else{ if (pArray->u.array.rf_need_rebuild && !pArray->u.array.rf_rebuilding) hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, (UCHAR)((pArray->u.array.CriticalMembers || pArray->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY)); } unlock_driver(oldspl); return orig_length; } else if (length>=4 && strncmp(buffer, "stop", 4)==0) { oldspl = lock_driver(); for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) if ((pArray=ArrayTables(i))->u.array.dArStamp==0) continue; else{ if (pArray->u.array.rf_rebuilding) pArray->u.array.rf_abort_rebuild = 1; } unlock_driver(oldspl); return orig_length; } else if (length>=3 && buffer[1]==','&& buffer[0]>='1'&& buffer[2]>='1') { iarray = buffer[0]-'1'; ichan = buffer[2]-'1'; if(iarray >= MAX_VDEVICE_PER_VBUS || ichan >= MV_SATA_CHANNELS_NUM) return -EINVAL; pArray = _vbus_p->pVDevice[iarray]; if (!pArray || (pArray->vf_online == 0)) return -EINVAL; for (i=0;i<MV_SATA_CHANNELS_NUM;i++) if(i == ichan) goto rebuild; return -EINVAL; rebuild: pVDev = &pAdapter->VDevices[ichan]; if(!pVDev->u.disk.df_on_line || pVDev->pParent) return -EINVAL; /* Not allow to use a mounted disk ??? test*/ for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) if(pVDev == _vbus_p->pVDevice[i]) { periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId,i); if (periph != NULL && periph->refcount >= 1) { hpt_printk(("Can not use disk used by OS!\n")); return -EINVAL; } /* the Mounted Disk isn't delete */ } switch(pArray->VDeviceType) { case VD_RAID_1: case VD_RAID_5: { pSubArray = pArray; loop: oldspl = lock_driver(); if(hpt_add_disk_to_array(_VBUS_P VDEV_TO_ID(pSubArray), VDEV_TO_ID(pVDev)) == -1) { unlock_driver(oldspl); return -EINVAL; } pSubArray->u.array.rf_auto_rebuild = 0; pSubArray->u.array.rf_abort_rebuild = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pSubArray, DUPLICATE); unlock_driver(oldspl); break; } case VD_RAID_0: for (i = 0; (UCHAR)i < pArray->u.array.bArnMember; i++) if(pArray->u.array.pMember[i] && mIsArray(pArray->u.array.pMember[i]) && (pArray->u.array.pMember[i]->u.array.rf_broken == 1)) { pSubArray = pArray->u.array.pMember[i]; goto loop; } default: return -EINVAL; } return orig_length; } } else if (length>=7 && strncmp(buffer, "verify ", 7)==0) { buffer+=7; length-=7; if (length>=6 && strncmp(buffer, "start ", 6)==0) { buffer+=6; length-=6; if (length>=1 && *buffer>='1') { iarray = *buffer-'1'; if(iarray >= MAX_VDEVICE_PER_VBUS) return -EINVAL; pArray = _vbus_p->pVDevice[iarray]; if (!pArray || (pArray->vf_online == 0)) return -EINVAL; if(pArray->VDeviceType != VD_RAID_1 && pArray->VDeviceType != VD_RAID_5) return -EINVAL; if (!(pArray->u.array.rf_need_rebuild || pArray->u.array.rf_rebuilding || pArray->u.array.rf_verifying || pArray->u.array.rf_initializing)) { oldspl = lock_driver(); pArray->u.array.RebuildSectors = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, VERIFY); unlock_driver(oldspl); } return orig_length; } } else if (length>=5 && strncmp(buffer, "stop ", 5)==0) { buffer+=5; length-=5; if (length>=1 && *buffer>='1') { iarray = *buffer-'1'; if(iarray >= MAX_VDEVICE_PER_VBUS) return -EINVAL; pArray = _vbus_p->pVDevice[iarray]; if (!pArray || (pArray->vf_online == 0)) return -EINVAL; if(pArray->u.array.rf_verifying) { oldspl = lock_driver(); pArray->u.array.rf_abort_rebuild = 1; unlock_driver(oldspl); } return orig_length; } } } else #ifdef _RAID5N_ if (length>=10 && strncmp(buffer, "writeback ", 10)==0) { buffer+=10; length-=10; if (length>=1 && *buffer>='0' && *buffer<='1') { _vbus_(r5.enable_write_back) = *buffer-'0'; if (_vbus_(r5.enable_write_back)) hpt_printk(("RAID5 write back enabled")); return orig_length; } } else #endif #endif if (0) {} /* just to compile */ #ifdef DEBUG else if (length>=9 && strncmp(buffer, "dbglevel ", 9)==0) { buffer+=9; length-=9; if (length>=1 && *buffer>='0' && *buffer<='3') { hpt_dbg_level = *buffer-'0'; return orig_length; } } else if (length>=8 && strncmp(buffer, "disable ", 8)==0) { /* TO DO */ } #endif return -EINVAL; }
static int hpt_set_array_state(DEVICEID idArray, DWORD state) { IAL_ADAPTER_T *pAdapter; PVDevice pVDevice = ID_TO_VDEV(idArray); int i; if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1; if(!mIsArray(pVDevice)) return -1; if(!pVDevice->vf_online || pVDevice->u.array.rf_broken) return -1; pAdapter=(IAL_ADAPTER_T *)pVDevice->pVBus->OsExt; switch(state) { case MIRROR_REBUILD_START: { mtx_lock(&pAdapter->lock); if (pVDevice->u.array.rf_rebuilding || pVDevice->u.array.rf_verifying || pVDevice->u.array.rf_initializing) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_auto_rebuild = 0; pVDevice->u.array.rf_abort_rebuild = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, (UCHAR)((pVDevice->u.array.CriticalMembers || pVDevice->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY)); while (!pVDevice->u.array.rf_rebuilding) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptwait", hz * 20) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case MIRROR_REBUILD_ABORT: { for(i = 0; i < pVDevice->u.array.bArnMember; i++) { if(pVDevice->u.array.pMember[i] != 0 && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1) hpt_set_array_state(VDEV_TO_ID(pVDevice->u.array.pMember[i]), state); } mtx_lock(&pAdapter->lock); if(pVDevice->u.array.rf_rebuilding != 1) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_abort_rebuild = 1; while (pVDevice->u.array.rf_abort_rebuild) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptabrt", hz * 20) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_VERIFY_START: { /*if(pVDevice->u.array.rf_verifying) return -1;*/ mtx_lock(&pAdapter->lock); if (pVDevice->u.array.rf_rebuilding || pVDevice->u.array.rf_verifying || pVDevice->u.array.rf_initializing) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.RebuildSectors = 0; hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY); while (!pVDevice->u.array.rf_verifying) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptvrfy", hz * 20) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_VERIFY_ABORT: { mtx_lock(&pAdapter->lock); if(pVDevice->u.array.rf_verifying != 1) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_abort_rebuild = 1; while (pVDevice->u.array.rf_abort_rebuild) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptvrfy", hz * 80) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_INITIALIZE_START: { mtx_lock(&pAdapter->lock); if (pVDevice->u.array.rf_rebuilding || pVDevice->u.array.rf_verifying || pVDevice->u.array.rf_initializing) { mtx_unlock(&pAdapter->lock); return -1; } hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY); while (!pVDevice->u.array.rf_initializing) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptinit", hz * 80) != 0) break; } mtx_unlock(&pAdapter->lock); } break; case AS_INITIALIZE_ABORT: { mtx_lock(&pAdapter->lock); if(pVDevice->u.array.rf_initializing != 1) { mtx_unlock(&pAdapter->lock); return -1; } pVDevice->u.array.rf_abort_rebuild = 1; while (pVDevice->u.array.rf_abort_rebuild) { if (mtx_sleep(pVDevice, &pAdapter->lock, 0, "hptinit", hz * 80) != 0) break; } mtx_unlock(&pAdapter->lock); } break; default: return -1; } return 0; }