/*--------------------------------------------------------------------------- * * Subclasses should take necessary action to create DMA channel programs, * for the current memory descriptor in _currentCommand and activate the * the DMA hardware ---------------------------------------------------------------------------*/ IOReturn AppleKiwiATA::startDMA( void ) { IOReturn err = kATANoErr; // first make sure the engine is stopped. stopDMA(); // reality check the memory descriptor in the current command // state flag _dmaState = kATADMAStarting; // create the channel commands err = createChannelCommands(); if( err ) { DLOG("IOPCIATA error createChannelCmds err = %ld\n", (long int)err); stopDMA(); return err; } // fire the engine //activateDMAEngine(); // Promise DMA engines prefer the host activate the DMA channel *after* the command is written to the drive. This is actually // backwards from the ATA standard, but what is implied in the intel data from several years ago. return err; }
/*--------------------------------------------------------------------------- * * If there's a timeout, read the drive's status reg to clear any pending * interrupt, then clear the interrupt bit and enable inta# propogation in the * controller. * ---------------------------------------------------------------------------*/ void AppleKiwiATA::handleTimeout( void ) { if( isBusOnline == false) { return; } getLock(true); stopDMA(); volatile UInt8 statusByte = *_tfStatusCmdReg; OSSynchronizeIO(); statusByte++; // make sure the compiler doesn't drop this. super::handleTimeout(); getLock( false); }
IOReturn AppleKiwiATA::message (UInt32 type, IOService* provider, void* argument) { switch( type ) { case kATARemovedEvent: DLOG( "AppleKiwiATA got remove event.\n"); // mark the bus as dead. if(isBusOnline == true) { isBusOnline = false; // lock the queue, don't dispatch immediates or anything else. _queueState = IOATAController::kQueueLocked; // disable the interrupt source(s) and timers _devIntSrc->disable(); stopTimer(); _workLoop->removeEventSource(_devIntSrc); _workLoop->removeEventSource(_timer); getLock(true); stopDMA(); // disable the controller pins *globalControlReg |= 0x00000800; // LE format OSSynchronizeIO(); // flush any commands in the queue handleQueueFlush(); // if there's a command active then call through the command gate // and clean it up from inside the workloop. // if( _currentCommand != 0) { DLOG( "AppleKiwiATA Calling cleanup bus.\n"); _cmdGate->runAction( (IOCommandGate::Action) &AppleKiwiATA::cleanUpAction, 0, // arg 0 0, // arg 1 0, 0); // arg2 arg 3 } _workLoop->removeEventSource(_cmdGate); getLock(false); DLOG( "AppleKiwiATA notify the clients.\n"); terminate( ); getProvider()->message( 'ofln', 0 ); } break; default: DLOG( "AppleKiwiATA got some other event = %d\n", (int) type); return super::message(type, provider, argument); break; } return kATANoErr; }
int main(int argc, char **argv) { unsigned int *data_samples; int i; int size; pd_device_t dev; void *memr, *mems; float throughput; struct timeval tv1,tv2; int mintime, curtime; printf("====================================\n"); printf("= DMA Throughput Test =\n"); printf("====================================\n\n"); if(argc != 2){ printf("Usage: %s [buffer size]\n",argv[0]); return -1; } size = atoi(argv[1]); if(size > 524288){ printf("Wohaa, easy there. Maximum buffer size is 262144\n"); return -1; } if(size % 4 != 0){ printf("Buffer size must be divisible by 4 bytes\n"); return -1; } printf("Buffer size: %d\n\n",size); if(pd_open(0,&dev) != 0){ printf("Failed to open file \n"); return -1; } printf("Device file opened successfuly\n"); // Allocate send and receive buffers posix_memalign( (void**)&memr, 16, size); posix_memalign( (void**)&mems, 16, size); //for(i=0;i<size/4;i++) // ((unsigned int*)mems)[i] = i; //for(i=0;i<size/4;i++) // ((unsigned int*)memr)[i] = 9; //-------------------------- if(initDMA(&dev) < 0) printf("Init DMA failed\n"); /* gettimeofday(&tv1,NULL); if(setupSend(&dev, (void*)mems, size) < 0) printf("Setup Send failed\n"); gettimeofday(&tv2,NULL); printf(">> Time taken to setup send transfer:%d\n", tv2.tv_usec - tv1.tv_usec); //-------------------------- gettimeofday(&tv1,NULL); if(setupRecv(&dev, memr, size) < 0) printf("Setup Recv failed\n"); gettimeofday(&tv2,NULL); printf(">> Time taken to setup receive transfer:%d\n", tv2.tv_usec - tv1.tv_usec); //-------------------------- gettimeofday(&tv1,NULL); if(startSend(&dev, 0) < 0) printf("DMA Send failed\n"); if(checkSend() < 0) printf("Check DMA send failed\n"); gettimeofday(&tv2,NULL); printf(">> Time taken to complete and check send transfer:%d\n", tv2.tv_usec - tv1.tv_usec); printf(">> Throughput: %f MB/s\n",(float)size/((float)(tv2.tv_usec - tv1.tv_usec))); //-------------------------- gettimeofday(&tv1,NULL); if(startRecv() < 0) printf("DMA Recv failed\n"); if(checkRecv() < 0) printf("Check DMA recv failed\n"); gettimeofday(&tv2,NULL); printf(">> Time taken to complete and check recv transfer:%d\n", tv2.tv_usec - tv1.tv_usec); printf(">> Throughput: %f MB/s\n",(float)size/((float)(tv2.tv_usec - tv1.tv_usec))); */ //-------------------------- // Send and receive in simultaneous mintime = 9999; for(i=0;i<NRUNS;i++){ gettimeofday(&tv1,NULL); if(setupSend(&dev, (void*)mems, size,1) < 0) printf("Setup Send failed\n"); if(setupRecv(&dev, (void*)memr, size) < 0) printf("Setup Recv failed\n"); gettimeofday(&tv2,NULL); printf("Time taken to setup receive AND send transfer:%d\n", tv2.tv_usec - tv1.tv_usec); //-------------------------- gettimeofday(&tv1,NULL); if(startRecv(&dev, 0) < 0) printf("DMA Recv failed\n"); if(startSend(&dev, 0) < 0) printf("DMA Send failed\n"); if(checkRecv() < 0) printf("Check DMA recv failed\n"); if(checkSend() < 0) printf("Check DMA send failed\n"); gettimeofday(&tv2,NULL); curtime = tv2.tv_usec - tv1.tv_usec; printf("Time taken to complete and check send AND receive transfer:%d\n", curtime); printf("Throughput: %f MB/s\n",(float)2*size/((float)(curtime))); freeSend(&dev); freeRecv(&dev); if(curtime < mintime) mintime = curtime; } stopDMA(&dev); //for(i=0;i<size/4;i++) // printf("%d ",((unsigned int*)memr)[i]); free(memr); free(mems); printf("Maximum throughput for %d points: %f MB/s\n",size,(float)2*size/((float)(mintime))); return 0; }
int main(int argc, char **argv) { unsigned int *data_samples; int i,val,j; int size, new_size; pd_device_t dev; void *memr, *mems, *mem_new; float throughput; struct timeval tv1,tv2; int mintime, curtime, vsize; printf("====================================\n"); printf("= Pattern Tests =\n"); printf("====================================\n\n"); if(pd_open(0,&dev) != 0){ printf("Failed to open file \n"); return -1; } printf("Device file opened successfuly\n"); // Allocate send and receive buffers size = 4*1024*1024; // 32x32 matrix with 4 byte entries posix_memalign( (void**)&memr, 16, size); posix_memalign( (void**)&mems, 16, size); //for(i=0;i < size/4; i++){ // ((int*)mems)[i] = i; // printf("%d ",((int*)mems)[i]); //} /* vsize = 1; for(i=1; i < 16; i++) { mintime = 99999; for(j=0; j < 500; j++) { gettimeofday(&tv1,NULL); compressData(mems, &mem_new, &new_size, 0, 4, 120, vsize); gettimeofday(&tv2,NULL); curtime = tv2.tv_usec - tv1.tv_usec; if (curtime < mintime) mintime = curtime; free(mem_new); } printf("Total Size: %d, Time elapsed: %d\n", new_size, mintime); vsize *= 2; } return; */ // Each 5x5 subblock will hold the same value val = 0; for(i=0; i < size/4; i++){ if (i % 16 == 0 && i!=0) val ++; val = val % 2; ((int *)mems)[i] = val; } // Test matrix for(i=0; i < size/4; i++){ if (i%32 == 0 && i!=0) printf("\n"); printf("%d ", ((int*)mems)[i]); } //-------------------------- if(initDMA(&dev) < 0) printf("Init DMA failed\n"); // Send and receive in simultaneous gettimeofday(&tv1,NULL); #ifdef SEND if(setupSend(&dev, (void*)mems, size,1) < 0) printf("Setup Send failed\n"); if(applyBlocking_send(16, 32, 4) < 0) printf("Apply Blocking send failed\n"); #endif if(setupRecv(&dev, (void*)memr, size) < 0) printf("Setup Recv failed\n"); //int applyLinear_recv(int offset, int hsize, int stride, int total_size); // if(applyBlocking_recv(16, 32, 4) < 0) if(applyLinear_recv(0,128,128,4096) < 0) printf("Apply Blocking recv failed\n"); gettimeofday(&tv2,NULL); printf("Time taken to setup receive AND send transfer:%d\n", tv2.tv_usec - tv1.tv_usec); //-------------------------- gettimeofday(&tv1,NULL); #ifdef SEND //if(startSend(&dev, 0) < 0) // printf("DMA Send failed\n"); #endif // printf("Press any key to continue ;)\n"); // getchar(); if(startRecv(&dev, 0) < 0) printf("DMA Recv failed\n"); if(startSend(&dev, 0) < 0) printf("DMA Send failed\n"); if(checkRecv() < 0) printf("Check DMA recv failed\n"); #ifdef SEND if(checkSend() < 0) printf("Check DMA send failed\n"); #endif gettimeofday(&tv2,NULL); curtime = tv2.tv_usec - tv1.tv_usec; printf("Time taken to complete and check send AND receive transfer:%d\n", curtime); printf("Throughput: %f MB/s\n",(float)2*size/((float)(curtime))); // Test matrix for(i=0; i < size/4; i++){ if (i%32 == 0 && i!=0) printf("\n"); printf("%d ", ((int*)memr)[i]); } freeSend(&dev); freeRecv(&dev); stopDMA(&dev); //for(i=0;i<size/4;i++) // printf("%d ",((unsigned int*)memr)[i]); free(memr); free(mems); return 0; }