AdiDeviceResult AdiDevice::Read(ADI_DEV_BUFFER_TYPE bufferType, ADI_DEV_BUFFER *pBuffer) { ESS_ASSERT(IsOpened()); return adi_dev_Read(m_deviceHandle, bufferType, pBuffer); }
static void Callback( void *AppHandle, u32 Event, void *pArg) { ADI_DEV_1D_BUFFER *pBuffer; // pointer to the buffer that was processed // CASEOF (event type) switch (Event) { // CASE (buffer processed) case ADI_DEV_EVENT_BUFFER_PROCESSED: // identify which buffer is generating the callback // we're setup to only get callbacks on inbound buffers so we know this // is an inbound buffer pBuffer = (ADI_DEV_1D_BUFFER *)pArg; if (pArg == &InboundBuffer) { InputBuffer[InputBufferhead] = InboundData; InputBufferhead = (InputBufferhead +1) % INBUFLEN; if ((InputBufferhead +1) % INBUFLEN != InputBuffertail) // requeue the inbound buffer ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer)); } else if (pArg == &OutboundBuffer) { sending_done = 1; } break; // CASE (an error) case ADI_UART_EVENT_BREAK_INTERRUPT: ezErrorCheck(ADI_UART_EVENT_BREAK_INTERRUPT); break; case ADI_UART_EVENT_FRAMING_ERROR: ezErrorCheck(ADI_UART_EVENT_FRAMING_ERROR); break; case ADI_UART_EVENT_PARITY_ERROR: ezErrorCheck(ADI_UART_EVENT_PARITY_ERROR); break; case ADI_UART_EVENT_OVERRUN_ERROR: ezErrorCheck(ADI_UART_EVENT_OVERRUN_ERROR); break; // ENDCASE } // return }
void UARTinit( u32 baudrate ) { ADI_DCB_HANDLE DCBManagerHandle = 0; // handle to the callback service u32 cclk, sclk, vco; // frequencies (note these are in MHz) u32 i; //loop variable ADI_DEV_CMD_VALUE_PAIR ConfigurationTable [] = { // configuration table for the UART driver { ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED }, { ADI_UART_CMD_SET_DATA_BITS, (void *)8 }, { ADI_UART_CMD_ENABLE_PARITY, (void *)FALSE }, { ADI_UART_CMD_SET_STOP_BITS, (void *)1 }, { ADI_UART_CMD_SET_BAUD_RATE, (void *)baudrate }, { ADI_UART_CMD_SET_LINE_STATUS_EVENTS, (void *)TRUE }, { ADI_DEV_CMD_END, NULL }, }; InputBufferhead = 0; InputBuffertail = 0; // create two buffers that will be initially be placed on the inbound queue // only the inbound buffer will have a callback InboundBuffer.Data = &InboundData; InboundBuffer.ElementCount = 1; InboundBuffer.ElementWidth = 1; InboundBuffer.CallbackParameter = (void*)&InboundBuffer; InboundBuffer.ProcessedFlag = FALSE; InboundBuffer.pNext = NULL; sending_done = 1; OutboundBuffer.Data = OutboundData; OutboundBuffer.ElementCount = 1; OutboundBuffer.ElementWidth = 1; OutboundBuffer.CallbackParameter = (void*)&OutboundBuffer; OutboundBuffer.ProcessedFlag = TRUE; OutboundBuffer.pNext = NULL; // open the UART driver for bidirectional data flow ezErrorCheck(adi_dev_Open(DeviceManagerHandle, &ADIUARTEntryPoint, 0, NULL, &DriverHandle, ADI_DEV_DIRECTION_BIDIRECTIONAL, NULL, DCBManagerHandle, Callback)); // configure the UART driver with the values from the configuration table ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_TABLE, ConfigurationTable)); // give the device the inbound buffer ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer)); // enable data flow ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void *)TRUE)); }
static u32 adi_pdd_Read( // Reads data or queues an inbound buffer to a device ADI_DEV_PDD_HANDLE PDDHandle, // PDD handle ADI_DEV_BUFFER_TYPE BufferType, // buffer type ADI_DEV_BUFFER *pBuffer // pointer to buffer ){ // check for errors if required u32 Result = ADI_DEV_RESULT_SUCCESS; #if defined(ADI_DEV_DEBUG) if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result); #endif // Simply pass the request on ADI_AD7477A *pAD7477A = (ADI_AD7477A *)PDDHandle; Result = adi_dev_Read(pAD7477A->spiHandle,BufferType,pBuffer); return(Result); }
static u32 adi_pdd_Read( // Reads data or queues an inbound buffer to a device ADI_DEV_PDD_HANDLE PDDHandle, // PDD handle ADI_DEV_BUFFER_TYPE BufferType, // buffer type ADI_DEV_BUFFER *pBuffer // pointer to buffer ) { // Pointer to ADAV801 device driver instance ADI_ADAV801 *pADAV801 = (ADI_ADAV801 *)PDDHandle; #ifdef ADI_DEV_DEBUG // check for errors if required u32 Result = ADI_DEV_RESULT_SUCCESS; if ((Result = ValidatePDDHandle(PDDHandle)) != ADI_DEV_RESULT_SUCCESS) return (Result); #endif // pass read operation to SPORT return(adi_dev_Read(pADAV801->sportHandle,BufferType,pBuffer)); }
u8 UARTread() { u8 data; while (!UARThit()); data = InputBuffer[InputBuffertail]; InputBuffertail = (InputBuffertail +1) % INBUFLEN; if (InboundBuffer.ProcessedFlag == 1) { InboundBuffer.ProcessedFlag = 0; // requeue the inbound buffer ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer)); } return data; }
/********************************************************************* Function: adi_ad1980_SportConfig Opens and Configures SPORT device allocated to AD1980 Audio Codec Parameters: poDevice - Pointer to AD1980 device instance to work on Returns: ADI_DEV_RESULT_SUCCESS - Successfully opened and configured SPORT device Error code returned from SPORT driver *********************************************************************/ static u32 adi_ad1980_SportConfig( ADI_AD1980_DEF *poDevice ) { /* default return code */ u32 nResult = ADI_DEV_RESULT_SUCCESS; /* SPORT Configuration Table */ ADI_DEV_CMD_VALUE_PAIR aoSportConfigTable[] = { /* clear any previous Tx errors */ { ADI_SPORT_CMD_CLEAR_TX_ERRORS, (void *)NULL }, /* clear any previous Rx errors */ { ADI_SPORT_CMD_CLEAR_RX_ERRORS, (void *)NULL }, /* SPORT in Circular mode */ { ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CIRCULAR }, /* Enable Streaming mode */ { ADI_DEV_CMD_SET_STREAMING, (void *)true }, /* External Frame sync, MSB first, No TFS required */ { ADI_SPORT_CMD_SET_TCR1, (void *)0 }, /* Secondary disabled */ { ADI_SPORT_CMD_SET_TCR2, (void *)0 }, /* Tx Wordlength = 16 bits */ { ADI_SPORT_CMD_SET_TX_WORD_LENGTH, (void *)15 }, /* Internal RFS, Require RFS for every data */ { ADI_SPORT_CMD_SET_RCR1, (void *)0x0600 }, /* Secondary disabled */ { ADI_SPORT_CMD_SET_RCR2, (void *)0 }, /* Rx Wordlength = 16 bits */ { ADI_SPORT_CMD_SET_RX_WORD_LENGTH, (void *)15 }, /* sets RFS to 48kHz (BIT_CLK for AC'97 = 12.288MHz) */ { ADI_SPORT_CMD_SET_RFSDIV, (void *)0xFF }, /* MFD = 1, Enable Multi Channel, Enable Tx/Rx DMA packing */ { ADI_SPORT_CMD_SET_MCMC2, (void *)0x101C }, /* 16 Channels */ { ADI_SPORT_CMD_SET_MTCS0, (void *)0xFFFF }, /* 16 Channels */ { ADI_SPORT_CMD_SET_MRCS0, (void *)0xFFFF }, /* Window Size = ((16 Channels/8) - 1) = 1 */ { ADI_SPORT_CMD_SET_MCMC1, (void *)0x1000 }, /* Enable error reporting */ { ADI_DEV_CMD_SET_ERROR_REPORTING, (void *)true }, /* End of Configuration table */ { ADI_DEV_CMD_END, (void *)NULL }, }; /* IF (Reset Flag ID is valid) */ if (poDevice->eResetFlag != ADI_FLAG_UNDEFINED) { /* Issue a Hardware reset to AD1980 */ nResult = adi_ac97_HwReset(poDevice->pAC97, poDevice->eResetFlag); } /* ELSE (Invalid reset flag) */ else { /* Report failure (Invalid Reset Flag) */ nResult = ADI_AD1980_RESULT_RESET_FLAG_ID_INVALID; } /* IF (Successfully Reset AD1980) */ if (nResult == ADI_DEV_RESULT_SUCCESS) { /* Open SPORT Device connected to AD1980 */ nResult = adi_dev_Open(poDevice->hDeviceManager, &ADISPORTEntryPoint, poDevice->nSportDevNumber, poDevice, &poDevice->hSport, ADI_DEV_DIRECTION_BIDIRECTIONAL, poDevice->hDmaManager, NULL, adi_ad1980_SportCallback); } /* IF (Successfully opened SPORT device) */ if (nResult == ADI_DEV_RESULT_SUCCESS) { /* Configure SPORT Device */ nResult = adi_dev_Control(poDevice->hSport, ADI_DEV_CMD_TABLE, (void *)&aoSportConfigTable[0]); } /* IF (Successfully Configured the SPORT driver) */ if (nResult == ADI_DEV_RESULT_SUCCESS) { /* Submit outbound buffer */ nResult = adi_dev_Write (poDevice->hSport, ADI_DEV_CIRC, (ADI_DEV_BUFFER *)(&poDevice->pAC97->DacCircBuf)); } /* IF (Successfully Submitted outbound buffer) */ if (nResult == ADI_DEV_RESULT_SUCCESS) { /* Submit inbound buffer */ nResult = adi_dev_Read (poDevice->hSport, ADI_DEV_CIRC, (ADI_DEV_BUFFER *)(&poDevice->pAC97->AdcCircBuf)); } /* IF (Successfully Opened and Configured SPORT Device) */ if (nResult == ADI_DEV_RESULT_SUCCESS) { /* Enable SPORT dataflow - this enables AC-Link to AD1980 */ nResult = adi_dev_Control(poDevice->hSport, ADI_DEV_CMD_SET_DATAFLOW, (void *)true); } return (nResult); }
/*########################################################################## * * low_level_init * *#########################################################################*/ static void low_level_init(struct netif *netif) { ADI_ETHER_BUFFER* p; struct nifce_info* nip = (struct nifce_info*)netif->state; struct buffer_info* bip; int rx_len, tx_len, count; int i; ADI_ETHER_BUFFER* rx_head = NULL; ADI_ETHER_BUFFER* tx_head = NULL; unsigned int *mangle_ptr; struct tcpip_msg* msg; LWIP_ASSERT("low_level_init: nfice info supply failed", nip != NULL); LWIP_ASSERT("low_level_init: buffer area supply failed", nip->buff_area != NULL && nip->buff_area_size > 0); // copy individual (MAC) address into netif struct for (i = 0; i < 6; i += 1) netif->hwaddr[i] = nip->ia[i]; netif->hwaddr_len = 6; // calculate total requirement for each rx and tx buffer rx_len = sizeof(ADI_ETHER_BUFFER) + sizeof(struct buffer_info); tx_len = rx_len; rx_len += nip->rx_buff_datalen + nip->buff_overhead; tx_len += nip->tx_buff_datalen + nip->buff_overhead; rx_len = ((rx_len + 3) / 4) * 4; tx_len = ((tx_len + 3) / 4) * 4; rx_len = (rx_len + 31) & ~31; tx_len = (tx_len + 31) & ~31; nip->buff_area = (char*)(((unsigned int)nip->buff_area + 31) & ~31); // allocate buffers in required ratio from supplied memory area while (nip->buff_area_size > rx_len || nip->buff_area_size > tx_len) { int n; for (n = 0; n < nip->rx_buffs; n += 1) { if (nip->buff_area_size < rx_len) break; p = (ADI_ETHER_BUFFER*)nip->buff_area; nip->buff_area += rx_len; nip->buff_area_size -= rx_len; p->pNext = rx_head; rx_head = p; } for (n = 0; n < nip->tx_buffs; n += 1) { if (nip->buff_area_size < tx_len) break; p = (ADI_ETHER_BUFFER*)nip->buff_area; nip->buff_area += tx_len; nip->buff_area_size -= tx_len; p->pNext = tx_head; tx_head = p; } } // initialise each buffer's ADI_ETHER_BUFFER descriptor p = rx_head; count = 0; while (p) { p->Data = (char*)p + sizeof(ADI_ETHER_BUFFER) + nip->buff_overhead; #if defined(__ADSPBF537__) if(p->Data >0) LWIP_ASSERT("Rx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)p->Data)); #elif (defined(__ADSPBF533__) || defined(__ADSPBF561__)) // first two bytes in the data buffer are used to store the length. if((p->Data >0) && (nip->buff_overhead > 0)) LWIP_ASSERT("Rx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)((char*)p->Data+ 2))); #endif /* __ADSPBF537__ */ p->ElementCount = nip->rx_buff_datalen; p->ElementWidth = 1; p->CallbackParameter =p; p->ProcessedElementCount=0; p->ProcessedFlag =0; p->PayLoad = 0; p->x = netif; mangle_ptr = ((unsigned int*)&p->Reserved)+4; *((unsigned int*)mangle_ptr)= (unsigned int)((char*)p->Data + p->ElementCount - nip->buff_overhead); bip = (struct buffer_info*)(*(unsigned int*)mangle_ptr); bip->netif = netif; bip->max_buf_len = nip->rx_buff_datalen; count += 1; p = p->pNext; } nip->rx_buffs = count; p = tx_head; count = 0; while (p) { p->Data = (char*)p + sizeof(ADI_ETHER_BUFFER) + nip->buff_overhead; #if defined(__ADSPBF537__) if(p->Data >0) LWIP_ASSERT("Tx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)p->Data)); #elif (defined(__ADSPBF533__) || defined(__ADSPBF561__)) // first two bytes in the data buffer are used to store the length. if((p->Data >0) && (nip->buff_overhead > 0)) LWIP_ASSERT("Tx data buffers are not aligned properly",CHECK_ALIGNMENT((unsigned int)((char*)p->Data +2))); #endif /* __ADSPBF537__ */ p->ElementCount = nip->tx_buff_datalen; p->ElementWidth = 1; p->CallbackParameter =p; p->x = netif; p->PayLoad = 0; mangle_ptr = ((unsigned int*)&p->Reserved)+4; *((unsigned int*)mangle_ptr)= (unsigned int)((char*)p->Data + p->ElementCount - nip->buff_overhead); bip = (struct buffer_info*)(*(unsigned int*)mangle_ptr); bip->netif = netif; bip->max_buf_len = nip->tx_buff_datalen; count += 1; p = p->pNext; } nip->tx_buffs = count; // set up this interface's TCPIP callback messages msg = &nip->txmsg; msg->type = TCPIP_MSG_CALLBACK; msg->flags = TCPIP_MSG_FLAG_STATIC; msg->msg.cb.function = process_xmtd_packets; msg->msg.cb.ctx = netif; msg = &nip->rxmsg; msg->type = TCPIP_MSG_CALLBACK; msg->flags = TCPIP_MSG_FLAG_STATIC; msg->msg.cb.function = process_rcvd_packets; msg->msg.cb.ctx = netif; // give all the rx buffers to the Ethernet device driver adi_dev_Read(nip->handle,ADI_DEV_1D,(ADI_DEV_BUFFER*)rx_head); // save the list of tx buffers until they are needed nip->x = tx_head; }
static void process_rcvd_packets(void *arg_nif) { struct netif* netif = (struct netif*)arg_nif; struct nifce_info* nip = (struct nifce_info*)netif->state; unsigned int *mangle_ptr; void *handle = nip->handle; int int_sts; ADI_ETHER_BUFFER* buffers_to_reuse; ADI_ETHER_BUFFER* buffers_to_process; ADI_ETHER_BUFFER* recycle_list = 0; ADI_ETHER_BUFFER* bp; ADI_ETHER_BUFFER* nbp; ADI_ETHER_BUFFER* lbp; // now check for received buffers int_sts = ker_disable_interrupts(ker_kPriorityLevelAll); buffers_to_process = nip->rcv_list; nip->rcv_list = NULL; nip->rxmsg_processed =0; ker_enable_interrupts(int_sts); // create a pbuf for each received buffer and call eth_input to process it bp = buffers_to_process; while (bp != 0) { struct hw_eth_hdr* ethhdr = (struct hw_eth_hdr*)((char*)bp->Data+2); u16_t length = bp->ProcessedElementCount - 6; // 2 + 4crc byte to store length struct pbuf* p; int unpack_arp = 0; nbp = bp->pNext; bp->pNext = 0; // (char*)bp->Data + 2 contrain the actual data. if (Trace_Function) Trace_Function('R',length,((unsigned char *)bp->Data+2)); // see whether we need two extra u16_t fields for alignment if (length >= (sizeof(struct etharp_hdr) - 6) && htons(ethhdr->type) == ETHTYPE_ARP) { length += 4; // need fields unused2 and unused3 in struct etharp_hdr unpack_arp = 1; } length += 2;// for field unused1 in struct eth_hdr p = pbuf_alloc(PBUF_RAW, length, PBUF_RAM); if (p != NULL) { //u8_t* psrc = (u8_t*)bp->Data; u8_t* psrc = (u8_t*)bp->Data+2; u8_t* pdst = (u8_t*)p->payload; // set field unused1 to 0 *(u16_t*)pdst = 0; pdst += 2; // copy in eth_hdr data memcpy(pdst, psrc, 14); pdst += 14; psrc += 14; if (unpack_arp) { // copy etharp frame into pbuf up to field unused2 memcpy(pdst, psrc, 14); pdst += 14; psrc += 14; // set field unused2 to 0 *(u16_t*)pdst = 0; pdst += 2; // copy more of frame up to field unused3 memcpy(pdst, psrc, 10); pdst += 10; psrc += 10; // set field unused3 to 0 *(u16_t*)pdst = 0; pdst += 2; // copy remainder of frame memcpy(pdst, psrc, 4); } else { // just copy the rest of the frame into the pbuf in one go memcpy(pdst, psrc, length - 16); } #ifdef LINK_STATS lwip_stats.link.recv++; #endif mangle_ptr = ((unsigned int*)&bp->Reserved)+4; // TODO: get-rid of Reserved. eth_input(p, ((struct buffer_info*)(*((unsigned int*)mangle_ptr)))->netif); } // p!=NULL else { #ifdef LINK_STATS lwip_stats.link.memerr++; // had to drop frame - no memory for pbuf #endif } mangle_ptr = ((unsigned int*)&bp->Reserved)+4; bp->ElementCount = ((struct buffer_info*)(*((unsigned int*)mangle_ptr)))->max_buf_len; bp->CallbackParameter = bp; bp->PayLoad =0; bp->StatusWord =0; bp->ProcessedElementCount=0; bp->ProcessedFlag =0; bp->pNext = recycle_list; recycle_list = bp; bp = nbp; } // while // return the buffers to the driver if (recycle_list != 0) adi_dev_Read(nip->handle,ADI_DEV_1D,(ADI_DEV_BUFFER*)recycle_list); }
static u32 adi_pdd_Read( ADI_DEV_PDD_HANDLE PDDHandle, /* PDD handle */ ADI_DEV_BUFFER_TYPE BufferType, /* buffer type */ ADI_DEV_BUFFER *pBuffer /* pointer to buffer */ ) { u32 Result; /* Expose the Device Definition structure */ ADI_USB_DEF *pDevice = (ADI_USB_DEF *)PDDHandle; /* Expose the FSS super buffer structure */ ADI_FSS_SUPER_BUFFER *pSuperBuffer = (ADI_FSS_SUPER_BUFFER *)pBuffer; /* Assign callback function and handle to Super Buffer */ pSuperBuffer->PIDCallbackFunction = CallbackFromFSS; pSuperBuffer->PIDCallbackHandle = (void*)pDevice; #if defined(_BF527_SDRAM_ISSUE_WORKAROUND) /* tranfser 'gEndPointMaxPacketSize' bytes at at time & copy to request buffer */ ADI_DEV_1D_BUFFER TempBuffer, *pClientBuffer; u32 BytesRemaining = pBuffer->OneD.ElementCount*pBuffer->OneD.ElementWidth; u32 *pClientData = (u32*)pBuffer->OneD.Data; u32 *pTempData; u32 i; u32 SectorNumber = pSuperBuffer->LBARequest.StartSector; u32 BufferSize; u32 SectorIncrement; if (BytesRemaining< TEMP_BUF_SIZE) { BufferSize = BytesRemaining; } else { BufferSize = TEMP_BUF_SIZE; } SectorIncrement = BufferSize/512; /* change LBA request to 1 sector */ pSuperBuffer->LBARequest.SectorCount = SectorIncrement; /* get max end point buffer size from MSH class driver */ //adi_dev_Control( pDevice->ClassDriverHandle, ADI_USB_MSD_CMD_GET_MAX_EP_PACKET_SIZE, (void*)&TempBuffer.ElementCount ); TempBuffer.Data = (void*)&TempBufferData[0]; TempBuffer.ElementCount = BufferSize; TempBuffer.ElementWidth = sizeof(u8); TempBuffer.ProcessedElementCount = 0; TempBuffer.ProcessedFlag = FALSE; TempBuffer.CallbackParameter = &TempBuffer; TempBuffer.pNext = NULL; pClientBuffer = &pSuperBuffer->Buffer; while (pClientBuffer) { while (BytesRemaining) { pDevice->ClassCommandComplete = FALSE; /* Pass LBA request to the Class Driver */ SendLbaRequest(pDevice,&pSuperBuffer->LBARequest); /* Queue the buffer */ Result = adi_dev_Read( pDevice->ClassDriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER*)&TempBuffer ); if (Result!=ADI_DEV_RESULT_SUCCESS) { return Result; } /* and wait for completion */ WaitOnCommandCompletion(pDevice); pTempData = (u32*)&TempBufferData[0]; /* If a Memory DMA stream has been registered with the driver then it is used for the * transfer between the L1 temporary buffer and the client buffer */ if (pDevice->MemDMAStreamHandle) { adi_dma_MemoryCopy( pDevice->MemDMAStreamHandle, /* Stream Handle */ pClientData, /* Destination buffer */ pTempData, /* Source buffer */ sizeof(u32), /* Element Width */ (TempBuffer.ElementCount)/sizeof(u32), /* Number of elements */ MemDmaCallback /* Callback function */ ); /* pend on completion */ adi_sem_Pend(MemDmaSemaphoreHandle,ADI_SEM_TIMEOUT_FOREVER); pClientData += (TempBuffer.ElementCount)/sizeof(u32); } /* Otherwise a core copy is used */ else { for(i=0;i<(TempBuffer.ElementCount)/sizeof(u32);i++,pClientData++,pTempData++) { *pClientData = *pTempData; } } BytesRemaining -= TempBuffer.ElementCount; pSuperBuffer->LBARequest.StartSector += SectorIncrement; } pClientBuffer = pClientBuffer->pNext; } (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_DEV_EVENT_BUFFER_PROCESSED, (void *)pBuffer ); (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_PID_EVENT_DEVICE_INTERRUPT, (void *)pBuffer); #else #if defined(_USE_BACKG_XFER) /* save aside the next buffer in the chain */ pNextBufferInChain = (ADI_FSS_SUPER_BUFFER *)pBuffer->OneD.pNext; /* and clear it so that the USB driver only deals with a single buffer */ pBuffer->OneD.pNext = NULL; #endif #if defined(_USE_BACKG_XFER) /* Pass LBA request to the Class Driver */ SendLbaRequest(pDevice,&pSuperBuffer->LBARequest); #endif /* Pass on the request to the Class Driver */ Result = adi_dev_Read( pDevice->ClassDriverHandle, BufferType, pBuffer ); #endif return(Result); }
/********************************************************************* Function: CallbackFromFSS Description: This is the callback to be taken from the Class Driver. *********************************************************************/ static void ClassDriverCallback(void *pHandle, u32 Event, void *pArg) { ADI_USB_DEF *pDevice = (ADI_USB_DEF *)pHandle; void *pExitCriticalArg; u32 Result; switch (Event) { /* CASE (USB DEVICE INSERTED) */ case ADI_USB_EVENT_CONNECT: /* Callback FSS with ADI_FSS_EVENT_MEDIA_DETECTED event, which may pass the event on to * the application which can take action to Poll for Media. */ #if 0 if (FSSDirectCallbackFunction) { (FSSDirectCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_DETECTED, 0 ); } else { (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_DETECTED, 0 ); } #endif if (MediaDetectionCallbackFunction) { (MediaDetectionCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_DETECTED, 0 ); } break; /* CASE (USB DEVICE REMOVED) */ case ADI_USB_EVENT_DISCONNECT: /* simply flag as not present. Next ADI_PID_CMD_POLL_MEDIA_CHANGE command will * result in the ADI_FSS_EVENT_MEDIA_REMOVED event being sent to FSS. */ if (pDevice->MediaPresent) { pDevice->MediaPresent = FALSE; } if (MediaDetectionCallbackFunction) { (MediaDetectionCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, 0 ); } break; /* CASE (USB DATA TRANSFER COMPLETE) */ case ADI_DEV_EVENT_BUFFER_PROCESSED: /* pass on event to FSS via DM callback */ #if !defined(_BF527_SDRAM_ISSUE_WORKAROUND) (pDevice->DMCallback)( pDevice->DeviceHandle, Event, pArg); #endif /* If there is another buffer in the chain, send the next LBA request and * queue the next buffer with the class driver */ #if defined(_USE_BACKG_XFER) if (pNextBufferInChain) { ADI_FSS_SUPER_BUFFER *pSuperBuffer = pNextBufferInChain; /* The next buffer may not have an LBA Request associated with it, as * it may have been combimed with the previous buffer. In which case * we do not need to send the LBA request */ if (pSuperBuffer->LBARequest.SectorCount) { SendLbaRequest(pDevice, &pSuperBuffer->LBARequest); } pNextBufferInChain = (ADI_FSS_SUPER_BUFFER *)pSuperBuffer->Buffer.pNext; pSuperBuffer->Buffer.pNext = NULL; /* Queue the data buffer with the class driver */ if (pSuperBuffer->LBARequest.ReadFlag) { adi_dev_Read( pDevice->ClassDriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)pSuperBuffer); } else { adi_dev_Write( pDevice->ClassDriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)pSuperBuffer ); } } else #endif { /* At the end of the chain we issue the Device Interrupt event to signal * total completion */ #if defined(_BF527_SDRAM_ISSUE_WORKAROUND) pExitCriticalArg = adi_int_EnterCriticalRegion( pDevice->pEnterCriticalArg ); pDevice->ClassCommandComplete = TRUE; adi_int_ExitCriticalRegion(pExitCriticalArg); #else (pDevice->DMCallback)( pDevice->DeviceHandle, ADI_PID_EVENT_DEVICE_INTERRUPT, pArg); #endif } break; case ADI_USB_MSD_EVENT_SCSI_CMD_COMPLETE: /* post the semaphore upon which the DevicePollMedia function is pending */ pExitCriticalArg = adi_int_EnterCriticalRegion( pDevice->pEnterCriticalArg ); pDevice->ClassCommandComplete = TRUE; adi_int_ExitCriticalRegion(pExitCriticalArg); break; case ADI_USB_MSD_EVENT_SCSI_CMD_ERROR: pExitCriticalArg = adi_int_EnterCriticalRegion( pDevice->pEnterCriticalArg ); pDevice->SCSICommandError = TRUE; adi_int_ExitCriticalRegion(pExitCriticalArg); break; case ADI_FSS_EVENT_MEDIA_ERROR: { if (FSSDirectCallbackFunction) { (FSSDirectCallbackFunction)( &pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, 0 ); } else { (pDevice->DMCallback) ( pDevice->DeviceHandle, ADI_FSS_EVENT_MEDIA_REMOVED, 0 ); } } break; } }