#include "devices/ide.h"
#include <ctype.h>
#include <debug.h>
#include <stdbool.h>
#include <stdio.h>
#include "devices/block.h"
#include "devices/partition.h"
#include "devices/timer.h"
#include "threads/io.h"
#include "threads/interrupt.h"
#include "threads/synch.h"
Go to the source code of this file.
Data Structures | |
struct | ata_disk |
struct | channel |
Defines | |
#define | reg_data(CHANNEL) ((CHANNEL)->reg_base + 0) |
#define | reg_error(CHANNEL) ((CHANNEL)->reg_base + 1) |
#define | reg_nsect(CHANNEL) ((CHANNEL)->reg_base + 2) |
#define | reg_lbal(CHANNEL) ((CHANNEL)->reg_base + 3) |
#define | reg_lbam(CHANNEL) ((CHANNEL)->reg_base + 4) |
#define | reg_lbah(CHANNEL) ((CHANNEL)->reg_base + 5) |
#define | reg_device(CHANNEL) ((CHANNEL)->reg_base + 6) |
#define | reg_status(CHANNEL) ((CHANNEL)->reg_base + 7) |
#define | reg_command(CHANNEL) reg_status (CHANNEL) |
#define | reg_ctl(CHANNEL) ((CHANNEL)->reg_base + 0x206) |
#define | reg_alt_status(CHANNEL) reg_ctl (CHANNEL) |
#define | STA_BSY 0x80 |
#define | STA_DRDY 0x40 |
#define | STA_DRQ 0x08 |
#define | CTL_SRST 0x04 |
#define | DEV_MBS 0xa0 |
#define | DEV_LBA 0x40 |
#define | DEV_DEV 0x10 |
#define | CMD_IDENTIFY_DEVICE 0xec |
#define | CMD_READ_SECTOR_RETRY 0x20 |
#define | CMD_WRITE_SECTOR_RETRY 0x30 |
#define | CHANNEL_CNT 2 |
Functions | |
static void | reset_channel (struct channel *) |
static bool | check_device_type (struct ata_disk *) |
static void | identify_ata_device (struct ata_disk *) |
static void | select_sector (struct ata_disk *, block_sector_t) |
static void | issue_pio_command (struct channel *, uint8_t command) |
static void | input_sector (struct channel *, void *) |
static void | output_sector (struct channel *, const void *) |
static void | wait_until_idle (const struct ata_disk *) |
static bool | wait_while_busy (const struct ata_disk *) |
static void | select_device (const struct ata_disk *) |
static void | select_device_wait (const struct ata_disk *) |
static void | interrupt_handler (struct intr_frame *) |
void | ide_init (void) |
static char * | descramble_ata_string (char *, int size) |
static void | ide_read (void *d_, block_sector_t sec_no, void *buffer) |
static void | ide_write (void *d_, block_sector_t sec_no, const void *buffer) |
Variables | |
static struct channel | channels [CHANNEL_CNT] |
static struct block_operations | ide_operations |
#define CHANNEL_CNT 2 |
#define CMD_IDENTIFY_DEVICE 0xec |
#define CMD_READ_SECTOR_RETRY 0x20 |
#define CMD_WRITE_SECTOR_RETRY 0x30 |
#define CTL_SRST 0x04 |
#define DEV_DEV 0x10 |
#define DEV_LBA 0x40 |
#define DEV_MBS 0xa0 |
#define reg_alt_status | ( | CHANNEL | ) | reg_ctl (CHANNEL) |
#define reg_command | ( | CHANNEL | ) | reg_status (CHANNEL) |
#define reg_ctl | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 0x206) |
#define reg_data | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 0) |
#define reg_device | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 6) |
#define reg_error | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 1) |
#define reg_lbah | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 5) |
#define reg_lbal | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 3) |
#define reg_lbam | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 4) |
#define reg_nsect | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 2) |
#define reg_status | ( | CHANNEL | ) | ((CHANNEL)->reg_base + 7) |
Definition at line 25 of file ide.c.
Referenced by check_device_type(), interrupt_handler(), and wait_until_idle().
#define STA_BSY 0x80 |
Definition at line 35 of file ide.c.
Referenced by check_device_type(), wait_until_idle(), and wait_while_busy().
#define STA_DRDY 0x40 |
#define STA_DRQ 0x08 |
static bool check_device_type | ( | struct ata_disk * | d | ) | [static] |
Definition at line 231 of file ide.c.
References ata_disk::channel, ata_disk::dev_no, inb(), ata_disk::is_ata, reg_error, reg_lbah, reg_lbam, reg_status, select_device(), STA_BSY, and STA_DRDY.
Referenced by ide_init().
static char * descramble_ata_string | ( | char * | string, | |
int | size | |||
) | [static] |
void ide_init | ( | void | ) |
Definition at line 103 of file ide.c.
References ata_disk::channel, CHANNEL_CNT, channels, check_device_type(), channel::completion_wait, ata_disk::dev_no, channel::devices, channel::expecting_interrupt, identify_ata_device(), interrupt_handler(), intr_register_ext(), channel::irq, ata_disk::is_ata, channel::lock, lock_init(), ata_disk::name, channel::name, NOT_REACHED, channel::reg_base, reset_channel(), sema_init(), and snprintf().
Referenced by main().
static void ide_read | ( | void * | d_, | |
block_sector_t | sec_no, | |||
void * | buffer | |||
) | [static] |
Definition at line 346 of file ide.c.
References ata_disk::channel, CMD_READ_SECTOR_RETRY, channel::completion_wait, input_sector(), issue_pio_command(), channel::lock, lock_acquire(), lock_release(), ata_disk::name, PANIC, PRDSNu, select_sector(), sema_down(), and wait_while_busy().
static void ide_write | ( | void * | d_, | |
block_sector_t | sec_no, | |||
const void * | buffer | |||
) | [static] |
Definition at line 366 of file ide.c.
References ata_disk::channel, CMD_WRITE_SECTOR_RETRY, channel::completion_wait, issue_pio_command(), channel::lock, lock_acquire(), lock_release(), ata_disk::name, output_sector(), PANIC, PRDSNu, select_sector(), sema_down(), and wait_while_busy().
static void identify_ata_device | ( | struct ata_disk * | d | ) | [static] |
Definition at line 261 of file ide.c.
References ASSERT, BLOCK_RAW, block_register(), BLOCK_SECTOR_SIZE, ata_disk::channel, CMD_IDENTIFY_DEVICE, channel::completion_wait, descramble_ata_string(), ide_operations, input_sector(), ata_disk::is_ata, issue_pio_command(), ata_disk::name, partition_scan(), print_human_readable_size(), printf(), select_device_wait(), sema_down(), snprintf(), and wait_while_busy().
Referenced by ide_init().
static void input_sector | ( | struct channel * | c, | |
void * | sector | |||
) | [static] |
Definition at line 421 of file ide.c.
References BLOCK_SECTOR_SIZE, insw(), and reg_data.
Referenced by ide_read(), and identify_ata_device().
static void interrupt_handler | ( | struct intr_frame * | f | ) | [static] |
Definition at line 508 of file ide.c.
References CHANNEL_CNT, channels, channel::completion_wait, channel::expecting_interrupt, inb(), channel::irq, channel::name, NOT_REACHED, printf(), reg_status, sema_up(), and intr_frame::vec_no.
Referenced by ide_init().
Definition at line 408 of file ide.c.
References ASSERT, channel::expecting_interrupt, intr_get_level(), INTR_ON, outb(), and reg_command.
Referenced by ide_read(), ide_write(), and identify_ata_device().
static void output_sector | ( | struct channel * | c, | |
const void * | sector | |||
) | [static] |
Definition at line 429 of file ide.c.
References BLOCK_SECTOR_SIZE, outsw(), and reg_data.
Referenced by ide_write().
static void reset_channel | ( | struct channel * | c | ) | [static] |
Definition at line 166 of file ide.c.
References CTL_SRST, ata_disk::dev_no, channel::devices, inb(), outb(), reg_ctl, reg_lbal, reg_nsect, select_device(), timer_msleep(), timer_usleep(), and wait_while_busy().
Referenced by ide_init().
static void select_device | ( | const struct ata_disk * | d | ) | [static] |
Definition at line 485 of file ide.c.
References ata_disk::channel, DEV_DEV, DEV_MBS, ata_disk::dev_no, inb(), outb(), reg_alt_status, reg_device, and timer_nsleep().
Referenced by check_device_type(), reset_channel(), and select_device_wait().
static void select_device_wait | ( | const struct ata_disk * | d | ) | [static] |
Definition at line 499 of file ide.c.
References select_device(), and wait_until_idle().
Referenced by identify_ata_device(), and select_sector().
static void select_sector | ( | struct ata_disk * | d, | |
block_sector_t | sec_no | |||
) | [static] |
Definition at line 390 of file ide.c.
References ASSERT, ata_disk::channel, DEV_DEV, DEV_LBA, DEV_MBS, ata_disk::dev_no, outb(), reg_device, reg_lbah, reg_lbal, reg_lbam, reg_nsect, and select_device_wait().
Referenced by ide_read(), and ide_write().
static void wait_until_idle | ( | const struct ata_disk * | d | ) | [static] |
Definition at line 442 of file ide.c.
References ata_disk::channel, inb(), ata_disk::name, printf(), reg_status, STA_BSY, STA_DRQ, and timer_usleep().
Referenced by select_device_wait().
static bool wait_while_busy | ( | const struct ata_disk * | d | ) | [static] |
Definition at line 461 of file ide.c.
References ata_disk::channel, inb(), ata_disk::name, printf(), reg_alt_status, STA_BSY, STA_DRQ, and timer_msleep().
Referenced by ide_read(), ide_write(), identify_ata_device(), and reset_channel().
static struct block_operations ide_operations [static, read] |