Esempio n. 1
0
/* This function checks if parameters are appropriate for DMA,
   and if they are, it sets up for DMA.

   If return value is false, caller may use PIO for this transfer.

   If return value is true, caller must issue a DMA ATA command
   and then call ata_dma_finish().
 */
bool ata_dma_setup(void *addr, unsigned long bytes, bool write) {
    /* Require cacheline alignment for reads to prevent interference. */
    if (!write && ((unsigned long)addr & 15))
        return false;

    /* Writes only need to be word-aligned, but by default DMA
     * is not used for writing as it appears to be slower.
     */
#ifdef ATA_DMA_WRITES
    if (write && ((unsigned long)addr & 3))
        return false;
#else
    if (write)
        return false;
#endif

#if ATA_MAX_UDMA > 2
    if (dma_needs_boost && !dma_boosted) {
        cpu_boost(true);
        dma_boosted = true;
    }
#endif

    if (write) {
        /* If unflushed, old data may be written to disk */
        commit_dcache();
    }
    else {
        /* Invalidate cache because new data may be present in RAM */
        commit_discard_dcache();
    }

    /* Clear pending interrupts so ata_dma_finish() can wait for an
       interrupt from this transfer
     */
    IDE0_CFG |= IDE_CFG_INTRQ;

    IDE_DMA_CONTROL |= 2;
    IDE_DMA_LENGTH = bytes - 4;

#if !defined(BOOTLOADER) || defined (HAVE_BOOTLOADER_USB_MODE)
    if ((unsigned long)addr < DRAM_START)
        /* Rockbox remaps DRAM to start at 0 */
        IDE_DMA_ADDR = (unsigned long)addr + DRAM_START;
    else
#endif
        IDE_DMA_ADDR = (unsigned long)addr;

    if (write)
        IDE_DMA_CONTROL &= ~IDE_DMA_CONTROL_READ;
    else
        IDE_DMA_CONTROL |= IDE_DMA_CONTROL_READ;

    IDE0_CFG |= 0x8000;

    return true;
}
Esempio n. 2
0
void usb_storage_init_connection(void)
{
    logf("ums: set config");
    /* prime rx endpoint. We only need room for commands */
    state = WAITING_FOR_COMMAND;

#if (CONFIG_CPU == IMX31L || defined(CPU_TCC77X) || defined(CPU_TCC780X) || \
     defined(BOOTLOADER) || CONFIG_CPU == DM320) && !defined(CPU_PP502x)
    static unsigned char _cbw_buffer[MAX_CBW_SIZE]
        USB_DEVBSS_ATTR __attribute__((aligned(32)));
    cbw_buffer = (void *)_cbw_buffer;

    static unsigned char _transfer_buffer[ALLOCATE_BUFFER_SIZE]
        USB_DEVBSS_ATTR __attribute__((aligned(32)));
    tb.transfer_buffer = (void *)_transfer_buffer;
#ifdef USB_USE_RAMDISK
    static unsigned char _ramdisk_buffer[RAMDISK_SIZE*SECTOR_SIZE];
    ramdisk_buffer = _ramdisk_buffer;
#endif
#else
    /* TODO : check if bufsize is at least 32K ? */
    size_t bufsize;
    unsigned char * audio_buffer;

    audio_buffer = audio_get_buffer(false,&bufsize);
#if defined(UNCACHED_ADDR) && CONFIG_CPU != AS3525
    cbw_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer+31) & 0xffffffe0);
#else
    cbw_buffer = (void *)((unsigned int)(audio_buffer+31) & 0xffffffe0);
#endif
    tb.transfer_buffer = cbw_buffer + MAX_CBW_SIZE;
    commit_discard_dcache();
#ifdef USB_USE_RAMDISK
    ramdisk_buffer = tb.transfer_buffer + ALLOCATE_BUFFER_SIZE;
#endif
#endif
    usb_drv_recv(ep_out, cbw_buffer, MAX_CBW_SIZE);

    int i;
    for(i=0;i<storage_num_drives();i++) {
        locked[i] = false;
        ejected[i] = !check_disk_present(IF_MD(i));
        queue_broadcast(SYS_USB_LUN_LOCKED, (i<<16)+0);
    }
}
Esempio n. 3
0
static int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long timeout)
{
    mmc_discard_irq();
    uint32_t responsetype;
    uint32_t cmdtype;
    uint32_t direction;
    if (write)
    {
        cmdtype = SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_CMD_RD_WR;
        responsetype = SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_BUSY;
        direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_WRITE;
    }
    else
    {
        cmdtype = SDCI_CMD_CMD_TYPE_ADTC;
        responsetype = SDCI_CMD_RES_TYPE_R1;
        direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_READ;
    }
    SDCI_DMASIZE = 0x200;
    SDCI_DMAADDR = buf;
    SDCI_DMACOUNT = count;
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
    commit_discard_dcache();
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_BLOCK)
                           | SDCI_CMD_CMD_TYPE_ADTC | cmdtype | responsetype
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count),
                             NULL, CEATA_COMMAND_TIMEOUT), 4, 0);
    if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
    if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
    {
        PASS_RC(ceata_cancel_command(), 4, 1);
        RET_ERR(2);
    }
    PASS_RC(mmc_dsta_check_data_success(), 4, 3);
    if (semaphore_wait(&mmc_comp_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
    {
        PASS_RC(ceata_cancel_command(), 4, 4);
        RET_ERR(4);
    }
    PASS_RC(ceata_check_error(), 4, 5);
    return 0;
}
Esempio n. 4
0
static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size)
{
    if (size > 0x10) RET_ERR(0);
    mmc_discard_irq();
    SDCI_DMASIZE = size;
    SDCI_DMACOUNT = 1;
    SDCI_DMAADDR = dest;
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
    commit_discard_dcache();
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG)
                           | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_RES_TYPE_R1
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_READ
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
                             NULL, CEATA_COMMAND_TIMEOUT), 2, 1);
    if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000)
        == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
    PASS_RC(mmc_dsta_check_data_success(), 2, 3);
    return 0;
}
Esempio n. 5
0
static inline void discard_dma_buffer_cache(void) { commit_discard_dcache(); }