|
AquilaOS documentation
How it works, and its code
|
The ATA driver: hard disks on the IDE controller, as block device 3 (/dev/hda and up). More...
#include <core/system.h>#include <core/module.h>#include <core/kargs.h>#include <cpu/io.h>#include <dev/dev.h>#include <fs/vfs.h>#include <fs/devfs.h>#include <fs/posix.h>#include <fs/mbr.h>#include <aquila/errno.h>#include <dev/pci.h>#include <dev/blkcache.h>#include <dev/irq.h>#include <sys/sched.h>#include <ata.h>Go to the source code of this file.
Macros | |
| #define | BLOCK_SIZE 512UL |
Functions | |
| static void | channel_acquire (struct ata_channel *ch) |
| Takes a channel for one command, waiting while another runs (a DMA request sleeps). | |
| static void | channel_release (struct ata_channel *ch) |
| Gives a channel back, and wakes up the requests waiting for it. | |
| static ssize_t | drive_read (void *_drive, uint64_t lba, size_t count, void *buf) |
| Reads sectors from a drive, for the block cache: the channel is held for the command only, and the buffer is the cache's. | |
| static ssize_t | drive_write (void *_drive, uint64_t lba, size_t count, void *buf) |
| Writes sectors to a drive, for the block cache. | |
| static void | ata_irq (void *channel) |
| Handles a channel's interrupt. | |
| void | ata_reset (struct ata_drive *drive) |
| Resets both drives on a drive's channel, and waits until they are done. | |
| void | ata_select_drive (struct ata_drive *drive, uint32_t mode) |
| Selects a drive on its channel, for an addressing mode, if it isn't selected so already, and waits for the drive to take it. | |
| 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. | |
| static int | ata_partition (struct ata_drive *drive, size_t part, uint64_t *start, uint64_t *nsectors) |
| Finds partition part of a drive (1 to 4; 0 is the whole disk): its first sector and how many sectors it has, from the MBR, which is read once. | |
| static int | ata_locate (struct devid *dd, int write, struct ata_drive **ref, uint64_t *start, uint64_t *nsectors) |
| Finds the drive of a device number, and where its partition is on it. | |
| static ssize_t | ata_read (struct devid *dd, off_t offset, size_t size, void *buf) |
| Reads sectors of a partition, from sector offset on, through the block cache. | |
| static ssize_t | ata_write (struct devid *dd, off_t offset, size_t size, void *buf) |
| Writes sectors of a partition, from sector offset on, through the block cache. | |
| static int | ata_drive_present (struct ata_drive *drive) |
| Returns whether the selected drive is there. | |
| static uint8_t | ata_detect_drive (struct ata_drive *drive) |
| Detects what a drive is (ATADEV_*). | |
| static int | ata_sync (void) |
| Has every drive write what its cache holds to the disk, for sync(). | |
| static size_t | ata_getbs (struct devid *dd) |
| Returns the block size: one sector, 512 bytes. | |
| static int | ata_probe () |
| Finds the IDE controller, detects its drives, sets them up, and registers the disks as block device 3. | |
Variables | |
| static struct ata_drive | drives [4] |
| static struct ata_channel | channels [2] |
| static struct ata_drive * | last_selected_drive = NULL |
| static uint32_t | last_selected_mode = -1 |
| struct dev | atadev |
The ATA driver: hard disks on the IDE controller, as block device 3 (/dev/hda and up).
The driver finds the IDE controller on the PCI bus, detects the four drives its two channels may have, and moves their sectors by PIO (pio.c) or bus master DMA (dma.c). Minor numbers are 64 per drive: 0 is the whole disk, 1 to 4 its primary partitions, from the MBR. Reads and writes go through the block cache (blkcache.c). One command at a time runs on a channel. Only ATA hard disks are supported: not ATAPI (CD-ROMs), and not SATA's own interface.
Definition in file ata.c.
| #define BLOCK_SIZE 512UL |
Definition at line 33 of file ata.c.
Referenced by ata_getbs(), and ata_partition().
Detects what a drive is (ATADEV_*).
An ATA disk's IDENTIFY reply gives its size, its capabilities and its model.
Definition at line 328 of file ata.c.
References ATA_CMD_IDENTIFY, ATA_CMD_IDENTIFY_PACKET, ata_detect_drive(), ata_drive_present(), ATA_IDENT_CAPABILITIES, ATA_IDENT_COMMANDSETS, ATA_IDENT_DEVICETYPE, ATA_IDENT_MAX_LBA, ATA_IDENT_MAX_LBA_EXT, ATA_IDENT_MODEL, ATA_MODE_LBA28, ATA_MODE_LBA48, ATA_REG_CMD, ATA_REG_DATA, ATA_REG_LBA1, ATA_REG_LBA2, ATA_REG_STATUS, ata_reset(), ata_select_drive(), ATADEV_NOTFOUND, ATADEV_PATA, ATADEV_PATAPI, ATADEV_SATA, ATADEV_SATAPI, ATADEV_UNKNOWN, ata_drive::base, ata_drive::capabilities, ata_drive::command_sets, ata_drive::id, io_in16(), io_in8(), io_out8(), ata_drive::max_lba, memset(), ata_drive::mode, ata_drive::model, printk(), ata_drive::signature, ata_drive::slave, and ata_drive::type.
Referenced by ata_detect_drive(), and ata_probe().
|
static |
Returns whether the selected drive is there.
It must be called once the channel's reset is done. A floating bus (no drive on the channel) reads 0xFF, and a missing drive next to a present one reads 0.
Definition at line 308 of file ata.c.
References ata_drive_present(), ATA_REG_LBA1, ATA_REG_LBA2, ATA_REG_STATUS, ATA_STATUS_BSY, ATA_STATUS_DRDY, ata_drive::base, and io_in8().
Referenced by ata_detect_drive(), and ata_drive_present().
Returns the block size: one sector, 512 bytes.
Definition at line 446 of file ata.c.
References ata_getbs(), and BLOCK_SIZE.
Referenced by ata_getbs().
|
static |
Handles a channel's interrupt.
Definition at line 82 of file ata.c.
References ata_irq(), ata_drive::channel, and dma_irq().
Referenced by ata_irq(), and ata_probe().
|
static |
Finds the drive of a device number, and where its partition is on it.
Returns 0 or a negative errno (-ENXIO if there is no such drive or partition).
Definition at line 240 of file ata.c.
References ata_locate(), ata_partition(), ata_drive::channel, channel_acquire(), channel_release(), drives, devid::minor, ata_drive::read, and ata_drive::write.
Referenced by ata_locate(), ata_read(), and ata_write().
|
static |
Finds partition part of a drive (1 to 4; 0 is the whole disk): its first sector and how many sectors it has, from the MBR, which is read once.
Returns 0, -ENXIO if the MBR has no partition there (no signature, an empty entry, or one past the disk's end), -EIO if the MBR can't be read, or -ENOMEM.
The MBR is read into a buffer of its own: lookups on the two channels may run at once, each sleeping while its read is done.
Definition at line 192 of file ata.c.
References ata_partition(), BLOCK_SIZE, mbr::boot_signature, kfree(), kmalloc(), ata_drive::max_lba, ata_drive::poff, ata_drive::psize, mbr::ptab, ata_drive::read, mbr_part::sectors_count, mbr_part::start_lba, and mbr_part::type.
Referenced by ata_locate(), and ata_partition().
|
static |
Finds the IDE controller, detects its drives, sets them up, and registers the disks as block device 3.
Definition at line 453 of file ata.c.
References ioaddr::addr, ata_detect_drive(), ata_irq(), ATA_PIO_PRI_PORT_BASE, ATA_PIO_PRI_PORT_CONTROL, ATA_PIO_SEC_PORT_BASE, ATA_PIO_SEC_PORT_CONTROL, ata_probe(), atadev, ATADEV_NOTFOUND, ATADEV_PATA, ATADEV_PATAPI, ATADEV_SATA, ATADEV_SATAPI, ata_channel::base, ata_drive::base, ata_channel::bm, pci_dev::bus, channels, ata_drive::ctrl, pci_dev::dev, dma_init(), drives, pci_dev::func, ata_drive::id, IOADDR_PORT, ata_channel::irq, irq_install(), kargs_get(), kdev_blkdev_register(), NULL, pci_irq(), pci_read_bar(), pci_reg16_read(), pci_reg16_write(), pci_scan_device(), pio_init(), printk(), ata_drive::slave, and ioaddr::type.
Referenced by ata_probe().
Reads sectors of a partition, from sector offset on, through the block cache.
Returns how many were read (none past the partition's end), or a negative errno.
Definition at line 266 of file ata.c.
References ata_locate(), ata_read(), blkcache_read(), drive_read(), ata_drive::max_lba, and MIN.
Referenced by ata_read().
| void ata_reset | ( | struct ata_drive * | drive | ) |
Resets both drives on a drive's channel, and waits until they are done.
| drive | a drive on the channel |
Definition at line 97 of file ata.c.
References ATA_CMD_RESET, ATA_REG_HDDEVSEL, ata_reset(), ATA_STATUS_BSY, ATA_TIMEOUT, ata_drive::base, ata_drive::ctrl, io_in8(), io_out8(), last_selected_drive, last_selected_mode, and NULL.
Referenced by ata_detect_drive(), ata_reset(), and pio_init().
Selects a drive on its channel, for an addressing mode, if it isn't selected so already, and waits for the drive to take it.
| drive | the drive |
| mode | the addressing mode (ATA_MODE_*), or 0 to detect it |
Definition at line 126 of file ata.c.
References ATA_MODE_LBA28, ATA_MODE_LBA48, ATA_REG_HDDEVSEL, ata_select_drive(), ata_drive::base, io_out8(), last_selected_drive, last_selected_mode, ata_drive::mode, and ata_drive::slave.
Referenced by ata_detect_drive(), ata_select_drive(), ata_setup(), and pio_flush().
Writes the registers of a command on count sectors from lba: the drive, the address and the count.
The command itself is sent after.
| drive | the drive |
| lba | the first sector |
| count | how many sectors |
Definition at line 155 of file ata.c.
References ATA_MODE_LBA48, ATA_REG_ERROR, ATA_REG_HDDEVSEL, ATA_REG_LBA0, ATA_REG_LBA1, ATA_REG_LBA2, ATA_REG_SECCOUNT0, ata_select_drive(), ata_setup(), ata_drive::base, io_out8(), ata_drive::mode, and ata_drive::slave.
Referenced by ata_setup(), dma_transfer(), pio_read_sectors(), and pio_write_sectors().
|
static |
Has every drive write what its cache holds to the disk, for sync().
Returns 0, or -EIO if a drive failed.
Definition at line 428 of file ata.c.
References ata_sync(), ata_drive::channel, channel_acquire(), channel_release(), drives, and flush().
Referenced by ata_sync().
Writes sectors of a partition, from sector offset on, through the block cache.
Returns how many were written (none past the partition's end: -ENOSPC), or a negative errno.
Definition at line 287 of file ata.c.
References ata_locate(), ata_write(), blkcache_write(), drive_write(), and MIN.
Referenced by ata_write().
|
static |
Takes a channel for one command, waiting while another runs (a DMA request sleeps).
Before there are processes, nothing else runs. A signal doesn't end the wait: a transfer is never left halfway.
Definition at line 41 of file ata.c.
References ata_channel::busy, channel_acquire(), curthread, sched_running, ata_channel::wait, and waitq_sleep_unint().
Referenced by ata_locate(), ata_sync(), channel_acquire(), drive_read(), and drive_write().
|
static |
Gives a channel back, and wakes up the requests waiting for it.
Definition at line 50 of file ata.c.
References ata_channel::busy, channel_release(), ata_channel::wait, and waitq_wakeup_nopoll().
Referenced by ata_locate(), ata_sync(), channel_release(), drive_read(), and drive_write().
Reads sectors from a drive, for the block cache: the channel is held for the command only, and the buffer is the cache's.
Definition at line 58 of file ata.c.
References ata_drive::channel, channel_acquire(), channel_release(), drive_read(), and ata_drive::read.
Referenced by ata_read(), and drive_read().
Writes sectors to a drive, for the block cache.
Definition at line 70 of file ata.c.
References ata_drive::channel, channel_acquire(), channel_release(), drive_write(), and ata_drive::write.
Referenced by ata_write(), and drive_write().
| struct dev atadev |
Definition at line 592 of file ata.c.
Referenced by ata_probe().
|
static |
Definition at line 36 of file ata.c.
Referenced by ata_probe().
|
static |
Definition at line 35 of file ata.c.
Referenced by ata_locate(), ata_probe(), and ata_sync().
Definition at line 89 of file ata.c.
Referenced by ata_reset(), and ata_select_drive().
|
static |
Definition at line 90 of file ata.c.
Referenced by ata_reset(), and ata_select_drive().