/**************************************************************** * Name: Pci2000_QueueCommand * * Description: Process a queued command from the SCSI manager. * * Parameters: SCpnt - Pointer to SCSI command structure. * done - Pointer to done function to call. * * Returns: Status code. * ****************************************************************/ int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB PADAPTER2000 padapter = HOSTDATA(SCpnt->host); // Pointer to adapter control structure int rc = -1; // command return code UCHAR bus = SCpnt->channel; UCHAR pun = SCpnt->target; UCHAR lun = SCpnt->lun; UCHAR cmd; PDEV2000 pdev = &padapter->dev[bus][pun]; if ( !done ) { printk("pci2000_queuecommand: %02X: done can't be NULL\n", *cdb); return 0; } SCpnt->scsi_done = done; SCpnt->SCp.have_data_in = 0; pdev->SCpnt = SCpnt; // Save this command data if ( WaitReady (padapter) ) { rc = DID_ERROR; goto finished; } outw_p (pun | (lun << 8), padapter->mb0); if ( bus ) { DEB (if(*cdb) printk ("\nCDB: %X- %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9])); DEB (if(*cdb) printk ("\ntimeout_per_command: %d, timeout_total: %d, timeout: %d, internal_timout: %d", SCpnt->timeout_per_command, SCpnt->timeout_total, SCpnt->timeout, SCpnt->internal_timeout)); outl (SCpnt->timeout_per_command, padapter->mb1); outb_p (CMD_SCSI_TIMEOUT, padapter->cmd); if ( WaitReady (padapter) ) { rc = DID_ERROR; goto finished; } outw_p (pun | (lun << 8), padapter->mb0); outw_p (SCpnt->cmd_len << 8, padapter->mb0 + 2); memcpy (pdev->cdb, cdb, MAX_COMMAND_SIZE); outl (pdev->cdbDma, padapter->mb1); if ( BuildSgList (SCpnt, padapter, pdev) ) cmd = CMD_SCSI_THRU; else cmd = CMD_SCSI_THRU_SG; if ( (pdev->tag = Command (padapter, cmd)) == 0 ) rc = DID_TIME_OUT; goto finished; } else { if ( lun )
bool Wiimote::Connect() { m_thread_ready = false; StartThread(); WaitReady(); return IsConnected(); }
// *** DATAFLASH PUBLIC FUNCTIONS *** void DataFlash_Block::StartWrite(uint16_t PageAdr) { df_BufferIdx = 0; df_BufferNum = 0; df_PageAdr = PageAdr; WaitReady(); }
void rf_SendByte(uchar data) { uchar cmd = 0xB800 | data; WaitReady();//while(RFM12_IRQ==1); WriteCMD(cmd); }
void DataFlash_Block::ReadBlock(void *pBuffer, uint16_t size) { while (size > 0) { uint16_t n = df_PageSize - df_Read_BufferIdx; if (n > size) { n = size; } WaitReady(); BlockRead(df_Read_BufferNum, df_Read_BufferIdx, pBuffer, n); size -= n; pBuffer = (void *)(n + (uintptr_t)pBuffer); df_Read_BufferIdx += n; if (df_Read_BufferIdx == df_PageSize) { df_Read_PageAdr++; if (df_Read_PageAdr > df_NumPages) { df_Read_PageAdr = 1; } PageToBuffer(df_Read_BufferNum, df_Read_PageAdr); // We are starting a new page - read FileNumber and FilePage struct PageHeader ph; BlockRead(df_Read_BufferNum, 0, &ph, sizeof(ph)); df_FileNumber = ph.FileNumber; df_FilePage = ph.FilePage; df_Read_BufferIdx = sizeof(ph); } } }
/*------------------------------------------------------------------------------ * Erase block * row = Block address * *cfg = Pointer to configuration structure * * Return: RTV_NOERR - Block erase successful * ERR_NAND_ERASE - Block erase failed * ERR_NAND_HW_TOUT - Hardware transfer timeout *----------------------------------------------------------------------------*/ static U32 BlockErase (U32 row, NAND_DRV_CFG *cfg) { /* Write command 1 */ WrCmd (NAND_CMD_ERASE1ST); /* Set address */ SetBlAddr (cfg->AddrCycles, row, cfg->PageSize); /* Write command 2 */ WrCmd (NAND_CMD_ERASE2ND); /* Wait until NAND ready */ if (WaitReady() == NAND_BUSY) { return ERR_NAND_HW_TOUT; } /* Check status */ switch (ChkStatus (NAND_STAT_FAIL)) { case NAND_FLAG_TOUT: return ERR_NAND_HW_TOUT; case NAND_FLAG_SET: return ERR_NAND_ERASE; default: return RTV_NOERR; } }
int MICROSD_BlockTx(const uint8_t *buff, uint8_t token) { uint8_t resp; uint32_t bc = 512; if (WaitReady() != 0xFF) return 0; MICROSD_XferSpi(token); /* Xmit a token */ if (token != 0xFD) { /* Not StopTran token */ do { /* Xmit the 512 byte data block to the MMC */ MICROSD_XferSpi(*buff++); MICROSD_XferSpi(*buff++); MICROSD_XferSpi(*buff++); MICROSD_XferSpi(*buff++); bc -= 4; } while (bc); MICROSD_XferSpi(0xFF); /* CRC (Dummy) */ MICROSD_XferSpi(0xFF); resp = MICROSD_XferSpi(0xff); /* Receive a data response */ if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */ return 0; } return 1; }
/*------------------------------------------------------------------------------ * Read page * row = Page address * *buf = Pointer to data buffer * *cfg = Pointer to configuration structure * * Return: RTV_NOERR - Page read successful * ERR_NAND_HW_TOUT - Hardware transfer timeout * ERR_NAND_DMA_TOUT - DMA transfer timeout * ERR_ECC_COR - ECC corrected the data within page * ERR_ECC_UNCOR - ECC was not able to correct the data *----------------------------------------------------------------------------*/ static U32 PageRead (U32 row, U8 *buf, NAND_DRV_CFG *cfg) { U32 i, sz; /* Write command 1 */ WrCmd (NAND_CMD_READ1ST); /* Set address */ SetPgAddr (cfg->AddrCycles, row, cfg->PageSize); /* Write command 2 */ WrCmd (NAND_CMD_READ2ND); /* Wait until NAND ready */ if (WaitReady() == NAND_BUSY) { return ERR_NAND_HW_TOUT; } /* Read page from NAND chip */ sz = cfg->PageSize; for (i = 0; i < sz; i += 8) { buf[i] = EMC_DATA8; buf[i+1] = EMC_DATA8; buf[i+2] = EMC_DATA8; buf[i+3] = EMC_DATA8; buf[i+4] = EMC_DATA8; buf[i+5] = EMC_DATA8; buf[i+6] = EMC_DATA8; buf[i+7] = EMC_DATA8; } return RTV_NOERR; }
/********************************************************************* * Name: PsiRaidCmd * * Description: Execute a simple command. * * Parameters: padapter - Pointer to adapter control structure. * cmd - Roy command byte. * * Returns: Return error status. * ********************************************************************/ static int PsiRaidCmd (PADAPTER2000 padapter, char cmd) { if ( WaitReady (padapter) ) // test for command register ready return DID_TIME_OUT; outb_p (cmd, padapter->cmd); // issue command if ( WaitReadyLong (padapter) ) // wait for adapter ready return DID_TIME_OUT; return DID_OK; }
/**************************************************************************//** * @brief Select the micro SD card and wait for the card to become ready. * @return 1:Successful, 0:Timeout. *****************************************************************************/ int MICROSD_Select(void) { GPIO->P[ MICROSD_GPIOPORT ].DOUTCLR = 1 << MICROSD_CSPIN; /* CS pin low. */ if (WaitReady() != 0xFF) { MICROSD_Deselect(); return 0; } return 1; }
bool Wiimote::Connect() { if (!m_run_thread.load()) { m_thread_ready.store(false); StartThread(); WaitReady(); } return IsConnected(); }
/**************************************************************** * Name: Command :LOCAL * * Description: Issue queued command to the PCI-2000. * * Parameters: padapter - Pointer to adapter information structure. * cmd - PCI-2000 command byte. * * Returns: Non-zero command tag if operation is accepted. * ****************************************************************/ static UCHAR Command (PADAPTER2000 padapter, UCHAR cmd) { outb_p (cmd, padapter->cmd); if ( WaitReady (padapter) ) return 0; if ( inw_p (padapter->mb0) ) return 0; return inb_p (padapter->mb1); }
bool Wiimote::Connect(int index) { m_index = index; m_need_prepare.store(true); if (!m_run_thread.load()) { m_thread_ready.store(false); StartThread(); WaitReady(); } return IsConnected(); }
// *** DATAFLASH PUBLIC FUNCTIONS *** void DataFlash_APM1::StartWrite(int16_t PageAdr) { df_BufferNum=1; df_BufferIdx=4; df_PageAdr=PageAdr; df_Stop_Write=0; WaitReady(); // We are starting a new page - write FileNumber and FilePage BufferWrite(df_BufferNum,0,df_FileNumber>>8); // High byte BufferWrite(df_BufferNum,1,df_FileNumber&0xFF); // Low byte BufferWrite(df_BufferNum,2,df_FilePage>>8); // High byte BufferWrite(df_BufferNum,3,df_FilePage&0xFF); // Low byte }
void DataFlash_Block::StartRead(uint16_t PageAdr) { df_Read_BufferNum = 0; df_Read_PageAdr = PageAdr; WaitReady(); // copy flash page to buffer PageToBuffer(df_Read_BufferNum, df_Read_PageAdr); // We are starting a new page - read FileNumber and FilePage struct PageHeader ph; BlockRead(df_Read_BufferNum, 0, &ph, sizeof(ph)); df_FileNumber = ph.FileNumber; df_FilePage = ph.FilePage; df_Read_BufferIdx = sizeof(ph); }
/*------------------------------------------------------------------------------ * Write page * row = Page address * *buf = Pointer to data buffer * *cfg = Pointer to configuration structure * * Return: RTV_NOERR - Page write successful * ERR_NAND_PROG - Page write failed * ERR_NAND_HW_TOUT - Hardware transfer timeout * ERR_NAND_DMA_TOUT - DMA transfer timeout *----------------------------------------------------------------------------*/ static U32 PageWrite (U32 row, U8 *buf, NAND_DRV_CFG *cfg) { U32 i, sz; /* Write command 1 */ WrCmd (NAND_CMD_PROG1ST); /* Set address */ SetPgAddr (cfg->AddrCycles, row, cfg->PageSize); /* Write data to NAND chip */ sz = cfg->PageSize; for (i = 0; i < sz; i += 8) { EMC_DATA8 = buf[i]; EMC_DATA8 = buf[i+1]; EMC_DATA8 = buf[i+2]; EMC_DATA8 = buf[i+3]; EMC_DATA8 = buf[i+4]; EMC_DATA8 = buf[i+5]; EMC_DATA8 = buf[i+6]; EMC_DATA8 = buf[i+7]; } /* Write command 2 */ WrCmd (NAND_CMD_PROG2ND); /* Wait until NAND ready */ if (WaitReady() == NAND_BUSY) { return ERR_NAND_HW_TOUT; } /* Check status */ switch (ChkStatus (NAND_STAT_FAIL)) { case NAND_FLAG_TOUT: return ERR_NAND_HW_TOUT; case NAND_FLAG_SET: return ERR_NAND_PROG; default: return RTV_NOERR; } }
void DataFlash_Block::Erase_Sectors(uint8_t start, uint8_t end) { static uint16_t _erase_led = 0; LED_GRN = 0; LED_RED = 1; // Erase XX sectors * 256 bytes for (uint16_t sector = start; sector < end; sector++) { Flash_Jedec_EraseSector(sector << 16); WaitReady(); if (_erase_led == 1){ LED_RED=0; LED_GRN = 1; _erase_led=0; } else{ LED_RED=1; LED_GRN = 0; _erase_led=1; } } LED_RED = 1; LED_GRN = 1; }
void DataFlash_Block::FinishWrite(void) { WaitReady(); BufferToPage (df_PageAdr << 8); // Save 256 bytes from buffer to Page df_PageAdr++; if (df_PageAdr > df_NumPages){ Flash_Jedec_EraseSector(0); // Erase Sector 0 df_PageAdr = 1; } // check if new sector is erased if (df_PageAdr % 256 == 0){ uint16_t data = 0; BlockRead((df_PageAdr << 8), &data, sizeof(data)); if (data != 0xFFFF){ Flash_Jedec_EraseSector(df_PageAdr << 8); // Erase Sector } } df_BufferIdx = 0; }
/*------------------------------------------------------------------------------ * Initialise NAND flash driver * * *cfg = Pointer to configuration structure * * Return: RTV_NOERR - NAND Flash Initialisation successful * ERR_NAND_HW_TOUT - NAND Flash Reset Command failed * ERR_NAND_DMA_TOUT - DMA Configuration failed *----------------------------------------------------------------------------*/ static U32 Init (NAND_DRV_CFG *cfg) { /* Power On External Memory Controler */ PCONP |= (1 << 11); /* Init NAND peripheral lines */ /* Data Lines: P3.0 .. P3.7 - D0 .. D7 */ PINSEL6 = (PINSEL6 & ~0xFFFF) | 0x5555; /* Address latch: P4.19 - A19 [ALE] */ /* Command latch: P4.20 - A20 [CLE] */ /* Read enable: P4.24 - OE [nRE] */ /* Write enable: P4.25 - WE [nWE] */ PINSEL9 = (PINSEL9 & ~0x000F03C0) | 0x00050140; /* Ready/Busy pin */ PINSEL4 &= ~(3UL << 24); /* MCB2400: P2.12 is GPIO */ FIO2DIR &= ~PIN_RB; /* Ready/Busy pin is input */ #if NAND0_HW_CS == EMC_NAND_CS0 /* Chip enable 0: P4.30 - CS0 [nCE] */ PINSEL9 = (PINSEL9 & ~(3UL << 28)) | (1UL << 28); #elif NAND0_HW_CS == EMC_NAND_CS1 /* Chip enable 1: P4.31 - CS1 [nCE] */ PINSEL9 = (PINSEL9 & ~(3UL << 30)) | (1UL << 30); #elif NAND0_HW_CS == EMC_NAND_CS2 /* Chip enable 2: P2.14 - CS2 [nCE] */ PINSEL4 = (PINSEL4 & ~(3UL << 28)) | (1UL << 28); #elif NAND0_HW_CS == EMC_NAND_CS3 /* Chip enable 3: P2.15 - CS3 [nCE] */ PINSEL4 = (PINSEL4 & ~(3UL << 30)) | (1UL << 30); #endif /* Init External Memory Controller peripheral */ /* Enable EMC, Normal memory map */ EMC_CTRL = 1; /* Delays are configured for CPU clock 72 MHz */ EMC_STA_CFG (NAND0_HW_CS) = (1 << 7); /* BLSn[3:0] are Low for Read/Write */ EMC_STA_WAITWEN (NAND0_HW_CS) = 2; /* Delay from CS to WE */ EMC_STA_WAITOEN (NAND0_HW_CS) = 2; /* Delay from CS or addr change to RE */ EMC_STA_WAITRD (NAND0_HW_CS) = 6; /* Delay from CS to read access */ EMC_STA_WAITPAGE(NAND0_HW_CS) = 2; /* Page Mode Read Delay */ EMC_STA_WAITWR (NAND0_HW_CS) = 6; /* Delay from CS to write access */ EMC_STA_WAITTURN(NAND0_HW_CS) = 2; /* Turn Round Delay */ /* Reset NAND chip */ WrCmd (NAND_CMD_RESET); if (WaitReady() == NAND_BUSY) { /* Reset failed */ return ERR_NAND_HW_TOUT; } /* Check status */ if (ChkStatus (NAND_STAT_RDY) != NAND_FLAG_SET) { return ERR_NAND_HW_TOUT; } /* NAND is ready */ return RTV_NOERR; }
size_t LoaderBase::GetLength() { WaitReady(); return len; };
char* LoaderBase::GetData() { WaitReady(); return data; };
bool LoaderBase::Sync() { WaitReady(); return data; };
// ***** class: LoaderBase ***** LoaderBase::~LoaderBase() { WaitReady(); delete[] data; };
/**************************************************************** * Name: Irq_Handler :LOCAL * * Description: Interrupt handler. * * Parameters: irq - Hardware IRQ number. * dev_id - * regs - * * Returns: TRUE if drive is not ready in time. * ****************************************************************/ static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *shost = NULL; // Pointer to host data block PADAPTER2000 padapter; // Pointer to adapter control structure PDEV2000 pdev; Scsi_Cmnd *SCpnt; UCHAR tag = 0; UCHAR tag0; ULONG error; int pun; int bus; int z; unsigned long flags; /* * Disable interrupts, if they aren't already disabled and acquire * the I/O spinlock. */ spin_lock_irqsave (&io_request_lock, flags); DEB(printk ("\npci2000 received interrupt ")); for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process { if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) ) { tag = inb_p (HOSTDATA(PsiHost[z])->tag); if ( tag ) { shost = PsiHost[z]; break; } } } if ( !shost ) { DEB (printk ("\npci2000: not my interrupt")); goto irq_return; } padapter = HOSTDATA(shost); tag0 = tag & 0x7F; // mask off the error bit for ( bus = 0; bus < MAX_BUS; bus++ ) // scan the busses { for ( pun = 0; pun < MAX_UNITS; pun++ ) // scan the targets { pdev = &padapter->dev[bus][pun]; if ( !pdev->tag ) continue; if ( pdev->tag == tag0 ) // is this it? { pdev->tag = 0; SCpnt = pdev->SCpnt; goto unmapProceed; } } } outb_p (0xFF, padapter->tag); // clear the op interrupt outb_p (CMD_DONE, padapter->cmd); // complete the op goto irq_return;; // done, but, with what? unmapProceed:; if ( !bus ) { switch ( SCpnt->cmnd[0] ) { case SCSIOP_TEST_UNIT_READY: pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE); goto irqProceed; case SCSIOP_READ_CAPACITY: pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 8, PCI_DMA_FROMDEVICE); goto irqProceed; case SCSIOP_VERIFY: case SCSIOP_START_STOP_UNIT: case SCSIOP_MEDIUM_REMOVAL: goto irqProceed; } } if ( SCpnt->SCp.have_data_in ) pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, SCpnt->request_bufflen, scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); else { if ( SCpnt->use_sg ) pci_unmap_sg (padapter->pdev, (struct scatterlist *)SCpnt->request_buffer, SCpnt->use_sg, scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); } irqProceed:; if ( tag & ERR08_TAGGED ) // is there an error here? { if ( WaitReady (padapter) ) { OpDone (SCpnt, DID_TIME_OUT << 16); goto irq_return;; } outb_p (tag0, padapter->mb0); // get real error code outb_p (CMD_ERROR, padapter->cmd); if ( WaitReady (padapter) ) // wait for controller to suck up the op { OpDone (SCpnt, DID_TIME_OUT << 16); goto irq_return;; } error = inl (padapter->mb0); // get error data outb_p (0xFF, padapter->tag); // clear the op interrupt outb_p (CMD_DONE, padapter->cmd); // complete the op DEB (printk ("status: %lX ", error)); if ( error == 0x00020002 ) // is this error a check condition? { if ( bus ) // are we doint SCSI commands? { OpDone (SCpnt, (DID_OK << 16) | 2); goto irq_return;; } if ( *SCpnt->cmnd == SCSIOP_TEST_UNIT_READY ) OpDone (SCpnt, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2); // test caller we have sense data too else OpDone (SCpnt, DID_ERROR << 16); goto irq_return;; } OpDone (SCpnt, DID_ERROR << 16); goto irq_return;; } outb_p (0xFF, padapter->tag); // clear the op interrupt outb_p (CMD_DONE, padapter->cmd); // complete the op OpDone (SCpnt, DID_OK << 16); irq_return:; /* * Release the I/O spinlock and restore the original flags * which will enable interrupts if and only if they were * enabled on entry. */ spin_unlock_irqrestore (&io_request_lock, flags); }
uchar ReadFifo(void) { WaitReady(); return (WriteCMD(0xB000) & 0xFF); }