diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pc80/ide/ide.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/src/pc80/ide/ide.c b/src/pc80/ide/ide.c index d9ef69d34c..99225a2a47 100644 --- a/src/pc80/ide/ide.c +++ b/src/pc80/ide/ide.c @@ -29,8 +29,14 @@ #include <pc80/ide.h> #include <arch/io.h> +#ifndef CONFIG_IDE_MAXBUS +#define CONFIG_IDE_MAXBUS 2 +#endif + struct controller controller; struct harddisk_info harddisk_info[NUM_HD]; +extern uint32_t ide_base[CONFIG_IDE_MAXBUS]; + static int await_ide(int (*done)(struct controller *ctrl), struct controller *ctrl, unsigned long timeout) @@ -226,12 +232,16 @@ static inline int ide_read_sector_lba48( return pio_data_in(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE); } -int ide_read_sector(int driveno, void * buf, unsigned int sector, - int byte_offset, int n_bytes) +int ide_read(int driveno, unsigned int sector, void *buf) { - struct harddisk_info *info = &harddisk_info[driveno]; + struct harddisk_info *info; int result; + if (driveno > NUM_HD-1) + return -1; + + info = &harddisk_info[driveno]; + /* Report the buffer is empty */ if (sector > info->sectors) { return -1; @@ -251,7 +261,7 @@ int ide_read_sector(int driveno, void * buf, unsigned int sector, return result; } -static int init_drive(struct harddisk_info *info, struct controller *ctrl, int slave, int basedrive) +static int init_drive(struct harddisk_info *info, struct controller *ctrl, int slave, int drive) { uint16_t* drive_info; struct ide_pio_command cmd; @@ -267,9 +277,9 @@ static int init_drive(struct harddisk_info *info, struct controller *ctrl, int s info->drive_exists = 0; info->slave_absent = 0; info->slave = slave?IDE_DH_SLAVE: IDE_DH_MASTER; - info->basedrive = basedrive; + info->basedrive = drive & 1; - printk_info("Testing for disk %d\n", info->basedrive); + printk_info("Testing for disk %d\n", drive); /* Select the drive that we are testing */ outb(IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave, @@ -296,7 +306,7 @@ static int init_drive(struct harddisk_info *info, struct controller *ctrl, int s } } - printk_info("Probing for disk %d\n", info->basedrive); + printk_info("Probing for disk %d\n", drive); memset(&cmd, 0, sizeof(cmd)); cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave; @@ -404,8 +414,9 @@ static int init_drive(struct harddisk_info *info, struct controller *ctrl, int s return 0; } -static int init_controller(struct controller *ctrl, int basedrive) +static int init_controller(struct controller *ctrl, int num) { + int drive; struct harddisk_info *info; /* Put the drives ide channel in a know state and wait @@ -454,15 +465,16 @@ static int init_controller(struct controller *ctrl, int basedrive) */ /* Now initialize the individual drives */ - info = &harddisk_info[basedrive]; - init_drive(info, ctrl, 0, basedrive & 1); + drive = num * 2; /* 2 drives per controller */ + info = &harddisk_info[drive]; + init_drive(info, ctrl, 0, drive); /* at the moment this only works for the first drive */ #if 0 if (info->drive_exists && !info->slave_absent) { - basedrive++; + drive++; info++; - init_drive(info, ctrl, 1, basedrive & 1); + init_drive(info, ctrl, 1, drive); } #endif @@ -477,36 +489,26 @@ int ide_init(void) /* Intialize the harddisk_info structures */ memset(harddisk_info, 0, sizeof(harddisk_info)); - for(index = 0; index < 1; index++) { -#if 0 + for(index = 0; index < CONFIG_IDE_MAXBUS; index++) { /* IDE normal pci mode */ - unsigned cmd_reg, ctrl_reg; uint32_t cmd_base, ctrl_base; - if (index < 2) { - cmd_reg = PCI_BASE_ADDRESS_0; - ctrl_reg = PCI_BASE_ADDRESS_1; - } else { - cmd_reg = PCI_BASE_ADDRESS_2; - ctrl_reg = PCI_BASE_ADDRESS_3; - } - pcibios_read_config_dword(0, 0, cmd_reg, &cmd_base); - pcibios_read_config_dword(0, 0, ctrl_reg, &ctrl_base); - controller.cmd_base = cmd_base & ~3; - controller.ctrl_base = ctrl_base & ~3; - -#endif - uint16_t base; - base = (index < 1)?IDE_BASE0:IDE_BASE1; - controller.cmd_base = base; - controller.ctrl_base = base + IDE_REG_EXTENDED_OFFSET; + cmd_base = ide_base[index]; + ctrl_base = cmd_base + IDE_REG_EXTENDED_OFFSET; + controller.cmd_base = (cmd_base & ~3); + controller.ctrl_base = (ctrl_base & ~3); printk_info("init_controller %d at (%x, %x)\n", index, controller.cmd_base, controller.ctrl_base); - if (init_controller(&controller, index << 1) < 0) { + if (init_controller(&controller, index) < 0) { /* nothing behind the controller */ continue; } drives++; + /* + * break here to avoid lengthy timeout probing for + * disks on second controller + */ + break; } return drives > 0 ? 0 : -1; |