20#include <aquila/errno.h>
29#define BM_CMD_START 0x01
30#define BM_CMD_READ 0x08
32#define BM_ST_ACTIVE 0x01
33#define BM_ST_ERROR 0x02
36#define DMA_BUF_SIZE (64 * 1024)
37#define DMA_MAX_SECTORS (DMA_BUF_SIZE / 512)
99 prdt[c].
size = (count * 512) & 0xFFFF;
134 printk(
"ata%d: DMA %s error, status 0x%x, bus master 0x%x\n", drive->
id,
static void io_out32(struct ioaddr *io, uintptr_t off, uint32_t val)
static uint8_t io_in8(struct ioaddr *io, uintptr_t off)
Reads an 8-, 16- or 32-bit register.
static void io_out8(struct ioaddr *io, uintptr_t off, uint8_t val)
Writes an 8-, 16- or 32-bit register.
void ata_setup(struct ata_drive *drive, uint64_t lba, size_t count)
Writes the registers of a command on count sectors from lba: the drive, the address and the count.
void dma_irq(struct ata_channel *channel)
Handles a channel's interrupt.
#define ATA_CMD_WRITE_DMA_EXT
#define ATA_CMD_WRITE_DMA
#define ATA_CMD_READ_DMA_EXT
int dma_init(struct ata_drive *drive)
Sets a drive up for DMA, if both the drive and its channel's controller can do it.
static int channel_index(struct ata_drive *drive)
Returns which channel a drive is on: 0 (primary) or 1 (secondary).
static int dma_transfer(struct ata_drive *drive, uint64_t lba, size_t count, int write)
Transfers up to DMA_MAX_SECTORS sectors between the drive and the channel's buffer,...
static ssize_t dma_read(struct ata_drive *drive, uint64_t lba, size_t count, void *buf)
Reads count sectors from lba on, through the channel's buffer.
static char dma_buf[2][DMA_BUF_SIZE]
static struct prd prdt[2]
static ssize_t dma_write(struct ata_drive *drive, uint64_t lba, size_t count, void *buf)
Writes count sectors from lba on, through the channel's buffer.
static void dma_complete(struct ata_channel *ch, uint8_t bm_status)
Ends a transfer: keeps what the controller and the drive say about it, which also acknowledges the in...
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
unsigned long long int uint64_t
unsigned short int uint16_t
An IDE channel, with the master and slave drives on it.
struct ioaddr base
the command block's registers, and the bus master's for DMA (whose address is 0 if the controller has...
struct waitq irq_wait
the DMA transfer waiting for the interrupt, and what it found
ssize_t(*) read(struct ata_drive *drive, uint64_t lba, size_t count, void *buf)
struct ata_channel * channel
ssize_t(*) write(struct ata_drive *drive, uint64_t lba, size_t count, void *buf)
A physical region descriptor: one piece of memory to transfer.
void waitq_wakeup_nopoll(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, but not the threads polling it.
void waitq_sleep_unint(struct waitq *waitq)
Puts the current thread to sleep on a wait queue until it is woken up, whatever signals come meanwhil...