int Selftest(ubsec_DeviceContext_t pContext,struct pci_dev* pDev) { unsigned long delay_total_us; CallbackStatus=0; /* inc'd on callback */ Status=ubsec_TestCryptoDevice(pContext,CryptoCallback,(unsigned long)pDev); if (Status != UBSEC_STATUS_SUCCESS) { printk("Selftest Device failed %lx\n",Status); /* RJT call ubsec_PollDevice() here? Chip seems lost after failing */ goto Return; } for (delay_total_us=1 ; !CallbackStatus ; delay_total_us++) { #ifdef POLL /* We need to poll the device if we are operating in POLL mode. */ ubsec_PollDevice(pContext); #endif if (delay_total_us >= 3000000) { Status=UBSEC_STATUS_TIMEOUT; break; } udelay(1); } if (Status != UBSEC_STATUS_SUCCESS) goto Return; if(UBSEC_IS_CRYPTO_DEVICEID(pDev->device)) { goto Return; } CallbackStatus=0; /* inc'd on callback */ Status=ubsec_TestKeyDevice(pContext,KeyCallback,(unsigned long)pDev); if (Status != UBSEC_STATUS_SUCCESS) { printk("Key Selftest Device failed %lx\n",Status); /* RJT call ubsec_PollDevice() here? Chip seems lost after failing */ goto Return; } for (delay_total_us=1 ; !CallbackStatus ; delay_total_us++) { #ifdef POLL /* We need to poll the device if we are operating in POLL mode. */ ubsec_PollDevice(pContext); #endif if (delay_total_us >= 3000000) { Status=UBSEC_STATUS_TIMEOUT; break; } udelay(1); } Return: ubsec_ResetDevice(pContext); return(Status); }
int ubsec_rng(ubsec_DeviceContext_t *ubsecContext, ubsec_rng_io_t *pIOInfo) { ubsec_RNGCommandInfo_pt kcmd; ubsec_RNGCommandParams_pt pRngparams=NULL, pIOparams = NULL; unsigned long delay_total_us; unsigned char *RngLoc; unsigned int num_commands=1; ubsec_rng_io_t RngCommand; ubsec_rng_io_pt pRngIOInfo=&RngCommand; int error = 0; CommandContext_pt pCommandContext; unsigned char *prng_buf = NULL; /* int i; */ prng_buf = (char *) kmalloc((MAX_RNG_BYTE_SIZE ),GFP_KERNEL|GFP_ATOMIC); if( prng_buf == NULL ) { PRINTK("no memory for rng buffer\n"); return -ENOMEM; } memset(prng_buf,0,MAX_RNG_BYTE_SIZE); pCommandContext = (CommandContext_pt)prng_buf; kcmd = (ubsec_RNGCommandInfo_pt)&pCommandContext[1]; RngLoc=(unsigned char *)&kcmd[1]; pRngparams=&(kcmd->Parameters); if (copy_from_user( pRngIOInfo, pIOInfo, sizeof(*pRngIOInfo))) return -EFAULT; pIOparams=&pRngIOInfo->Rng; #ifndef LINUX2dot2 init_waitqueue_head(&pCommandContext->WaitQ); #else pCommandContext->WaitQ = 0; #endif /* * Now we need to format the command for the SRL. * This depends on the type of the key command. */ switch ((kcmd->Command=pRngIOInfo->command)) { case UBSEC_RNG_DIRECT: case UBSEC_RNG_SHA1: if (ubsec_rngsetup(pRngIOInfo->command,&pRngIOInfo->Rng, pRngparams, RngLoc) < 0){ error = -EINVAL; goto Free_Return; } break; default: PRINTK("Invalid Rng Command %lx\n",kcmd->Command); error = -EINVAL; goto Free_Return; } kcmd->CompletionCallback = CmdCompleteCallback; kcmd->CommandContext=(unsigned long)prng_buf; /* * Let the system do anything it may want/need to do before we begin * timing. */ do_gettimeofday(&pCommandContext->tv_start); pCommandContext->CallBackStatus=0; /* inc'd on callback */ switch ((pRngIOInfo->result_status=ubsec_RNGCommand(ubsecContext, kcmd, &num_commands))) { case UBSEC_STATUS_SUCCESS: break; case UBSEC_STATUS_TIMEOUT: PRINTK("ubsec_Command() Timeout\n"); error = -ETIMEDOUT; goto Return; break; case UBSEC_STATUS_INVALID_PARAMETER: PRINTK("ubsec_Command() Invalid parameter\n"); error = -EINVAL; goto Return; break; case UBSEC_STATUS_NO_RESOURCE: PRINTK("ubsec_Command() No rng resource. Num Done %d\n",num_commands); error = -ENOBUFS; goto Return; break; default: error = -EIO; goto Return; break; } #ifndef GOTOSLEEP for (delay_total_us=1 ; !(pCommandContext->CallBackStatus); delay_total_us++) { ubsec_PollDevice(ubsecContext); if (delay_total_us >= 3000000) { pCommandContext->Status=-ETIMEDOUT; error = -ETIMEDOUT; ubsec_ResetDevice(ubsecContext); goto Return; } udelay(1); } #else if (!pCommandContext->CallBackStatus) { /* Just in case completed on same thread. */ Gotosleep(&pCommandContext->WaitQ); if (!pCommandContext->CallBackStatus) { /* timed out, never got the interrupt */ ubsec_PollDevice(ubsecContext); /* Manually poll just in case */ if (!pCommandContext->CallBackStatus) { /* The command truly timed out, return error status */ pCommandContext->Status=UBSEC_STATUS_TIMEOUT; error = -ETIMEDOUT; ubsec_ResetDevice(ubsecContext); goto Return; } } } #endif pRngIOInfo->result_status = pCommandContext->Status; pRngIOInfo->time_us = pCommandContext->tv_start.tv_sec * 1000000 + pCommandContext->tv_start.tv_usec; /* * Status gets set above to timeout or in callback to success indicator. */ if (pRngIOInfo->result_status == UBSEC_STATUS_SUCCESS) { /* * Now we need to copy out those parameters that were changed */ pIOparams->Result.KeyLength = pRngparams->Result.KeyLength; if (copy_to_user(pIOparams->Result.KeyValue, RngLoc, ROUNDUP_TO_32_BIT(pIOparams->Result.KeyLength)/8)) { error = -EFAULT; goto Free_Return; } } else { #if 1 PRINTK("rng FAILURE %lx\n", (unsigned long)pCommandContext->Status); #endif error = -ENOMSG; } Return: /* * Copyback the result */ if (copy_to_user(pIOInfo, pRngIOInfo, sizeof(*pRngIOInfo)) && !error) error = -EFAULT; Free_Return: if (prng_buf != NULL) kfree(prng_buf); return error; }