/* Power up the card */
r592_write_reg(dev, R592_POWER, R592_POWER_0 | R592_POWER_1);
/* Perform a reset */
r592_set_reg_mask(dev, R592_IO, R592_IO_RESET);
msleep(100);
} else /* Power down the card */
r592_write_reg(dev, R592_POWER, 0);
return 0;
}
/* Set serial/parallel mode */ staticint r592_set_mode(struct r592_device *dev, bool parallel_mode)
{ if (!parallel_mode) {
dbg("switching to serial mode");
/* Set serial mode */
r592_write_reg(dev, R592_IO_MODE, R592_IO_MODE_SERIAL);
/* Tests if there is an CRC error */ staticint r592_test_io_error(struct r592_device *dev)
{ if (!(r592_read_reg(dev, R592_STATUS) &
(R592_STATUS_SEND_ERR | R592_STATUS_RECV_ERR))) return 0;
return -EIO;
}
/* Ensure that FIFO is ready for use */ staticint r592_test_fifo_empty(struct r592_device *dev)
{ if (r592_read_reg(dev, R592_REG_MSC) & R592_REG_MSC_FIFO_EMPTY) return 0;
dbg("FIFO not ready, trying to reset the device");
r592_host_reset(dev);
if (r592_read_reg(dev, R592_REG_MSC) & R592_REG_MSC_FIFO_EMPTY) return 0;
message("FIFO still not ready, giving up"); return -EIO;
}
/* Activates the DMA transfer from to FIFO */ staticvoid r592_start_dma(struct r592_device *dev, bool is_write)
{ unsignedlong flags;
u32 reg;
spin_lock_irqsave(&dev->irq_lock, flags);
/* Ack interrupts (just in case) + enable them */
r592_clear_reg_mask(dev, R592_REG_MSC, DMA_IRQ_ACK_MASK);
r592_set_reg_mask(dev, R592_REG_MSC, DMA_IRQ_EN_MASK);
/* Set DMA address */
r592_write_reg(dev, R592_FIFO_DMA, sg_dma_address(&dev->req->sg));
/* * Writes the FIFO in 4 byte chunks. * If length isn't 4 byte aligned, rest of the data if put to a fifo * to be written later * Use r592_flush_fifo_write to flush that fifo when writing for the * last time
*/ staticvoid r592_write_fifo_pio(struct r592_device *dev, unsignedchar *buffer, int len)
{ /* flush spill from former write */ if (!kfifo_is_empty(&dev->pio_fifo)) {
u8 tmp[4] = {0}; int copy_len = kfifo_in(&dev->pio_fifo, buffer, len);
if (!kfifo_is_full(&dev->pio_fifo)) return;
len -= copy_len;
buffer += copy_len;
/* write full dwords */ while (len >= 4) {
r592_write_reg_raw_be(dev, R592_FIFO_PIO, *(u32 *)buffer);
buffer += 4;
len -= 4;
}
/* put remaining bytes to the spill */ if (len)
kfifo_in(&dev->pio_fifo, buffer, len);
}
/* Flushes the temporary FIFO used to make aligned DWORD writes */ staticvoid r592_flush_fifo_write(struct r592_device *dev)
{ int ret;
u8 buffer[4] = { 0 };
/* * Read a fifo in 4 bytes chunks. * If input doesn't fit the buffer, it places bytes of last dword in spill * buffer, so that they don't get lost on last read, just throw these away.
*/ staticvoid r592_read_fifo_pio(struct r592_device *dev, unsignedchar *buffer, int len)
{
u8 tmp[4];
/* Read from last spill */ if (!kfifo_is_empty(&dev->pio_fifo)) { int bytes_copied =
kfifo_out(&dev->pio_fifo, buffer, min(4, len));
buffer += bytes_copied;
len -= bytes_copied;
if (!kfifo_is_empty(&dev->pio_fifo)) return;
}
/* Reads dwords from FIFO */ while (len >= 4) {
*(u32 *)buffer = r592_read_reg_raw_be(dev, R592_FIFO_PIO);
buffer += 4;
len -= 4;
}
if (len) {
*(u32 *)tmp = r592_read_reg_raw_be(dev, R592_FIFO_PIO);
kfifo_in(&dev->pio_fifo, tmp, 4);
len -= kfifo_out(&dev->pio_fifo, buffer, len);
}
WARN_ON(len); return;
}
/* Transfers actual data using PIO. */ staticint r592_transfer_fifo_pio(struct r592_device *dev)
{ unsignedlong flags;
/* Do the transfer fifo<->memory*/ while (sg_miter_next(&miter)) if (is_write)
r592_write_fifo_pio(dev, miter.addr, miter.length); else
r592_read_fifo_pio(dev, miter.addr, miter.length);
/* Write last few non aligned bytes*/ if (is_write)
r592_flush_fifo_write(dev);
/* Executes one TPC (data is read/written from small or large fifo) */ staticvoid r592_execute_tpc(struct r592_device *dev)
{ bool is_write; int len, error;
u32 status, reg;
if (!dev->req) {
message("BUG: tpc execution without request!"); return;
}
/* Ensure that FIFO can hold the input data */ if (len > R592_LFIFO_SIZE) {
message("IO: hardware doesn't support TPCs longer that 512");
error = -ENOSYS; goto out;
}
if (!(r592_read_reg(dev, R592_REG_MSC) & R592_REG_MSC_PRSNT)) {
dbg("IO: refusing to send TPC because card is absent");
error = -ENODEV; goto out;
}
/* Reprogram chip to detect change in card state */ /* eg, if card is detected, arm it to detect removal, and vice versa */ staticvoid r592_update_card_detect(struct r592_device *dev)
{
u32 reg = r592_read_reg(dev, R592_REG_MSC); bool card_detected = reg & R592_REG_MSC_PRSNT;
/* Get the IRQ status minus bits that aren't enabled */
irq_status &= (irq_enable);
/* Due to limitation of memstick core, we don't look at bits that
indicate that card was removed/inserted and/or present */ if (irq_status & (R592_REG_MSC_IRQ_INSERT | R592_REG_MSC_IRQ_REMOVE)) {
bool card_was_added = irq_status & R592_REG_MSC_IRQ_INSERT;
ret = IRQ_HANDLED;
spin_lock_irqsave(&dev->io_thread_lock, flags); if (wake_up_process(dev->io_thread))
dbg_verbose("IO thread woken to process requests");
spin_unlock_irqrestore(&dev->io_thread_lock, flags);
}
/* This is just a precation, so don't fail */
dev->dummy_dma_page = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
&dev->dummy_dma_page_physical_address, GFP_KERNEL);
r592_stop_dma(dev , 0);
/* Stop the processing thread.
That ensures that we won't take any more requests */
kthread_stop(dev->io_thread);
timer_delete_sync(&dev->detect_timer);
r592_enable_device(dev, false);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.