mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (29 commits) ide-tape: bump minor driver version ide-tape: cleanup the remaining codestyle issues ide-tape: fix syntax error in idetape_identify_device() ide-tape: remove leftover OnStream support warning ide-tape: collect module-related macro calls at the end ide-tape: include proper headers ide-tape: remove unused "length" arg from idetape_create_read_buffer_cmd() ide-tape: remove struct idetape_id_gcw ide-tape: cleanup and fix comments ide-tape: shorten some function names ide-tape: remove idetape_increase_max_pipeline_stages() ide-tape: struct idetape_tape_t: shorten member names v2 ide-tape: struct idetape_tape_t: remove unused members ide-tape: remove typedef idetape_chrdev_direction_t ide-tape: simplify code branching in the interrupt handler ide-tape: remove unreachable code chunk ide-tape: remove struct idetape_read_position_result_t ide-tape: refactor the debug logging facility ide: add ide_read_error() inline helper ide: add ide_read_[alt]status() inline helpers ...
This commit is contained in:
commit
551e4fb246
32 changed files with 1825 additions and 1593 deletions
|
@ -780,6 +780,9 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
|
loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
|
||||||
as idle=poll.
|
as idle=poll.
|
||||||
|
|
||||||
|
ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
|
||||||
|
Claim all unknown PCI IDE storage controllers.
|
||||||
|
|
||||||
ignore_loglevel [KNL]
|
ignore_loglevel [KNL]
|
||||||
Ignore loglevel setting - this will print /all/
|
Ignore loglevel setting - this will print /all/
|
||||||
kernel messages to the console. Useful for debugging.
|
kernel messages to the console. Useful for debugging.
|
||||||
|
|
|
@ -1009,6 +1009,15 @@ config BLK_DEV_Q40IDE
|
||||||
normally be on; disable it only if you are running a custom hard
|
normally be on; disable it only if you are running a custom hard
|
||||||
drive subsystem through an expansion card.
|
drive subsystem through an expansion card.
|
||||||
|
|
||||||
|
config BLK_DEV_PALMCHIP_BK3710
|
||||||
|
tristate "Palmchip bk3710 IDE controller support"
|
||||||
|
depends on ARCH_DAVINCI
|
||||||
|
select BLK_DEV_IDEDMA_PCI
|
||||||
|
help
|
||||||
|
Say Y here if you want to support the onchip IDE controller on the
|
||||||
|
TI DaVinci SoC
|
||||||
|
|
||||||
|
|
||||||
config BLK_DEV_MPC8xx_IDE
|
config BLK_DEV_MPC8xx_IDE
|
||||||
tristate "MPC8xx IDE support"
|
tristate "MPC8xx IDE support"
|
||||||
depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE
|
depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
|
obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
|
||||||
obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
|
obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
|
||||||
obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o
|
obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o
|
||||||
|
obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_IDE_ARM), m)
|
ifeq ($(CONFIG_IDE_ARM), m)
|
||||||
obj-m += ide_arm.o
|
obj-m += ide_arm.o
|
||||||
|
|
|
@ -365,7 +365,7 @@ static void icside_dma_timeout(ide_drive_t *drive)
|
||||||
if (icside_dma_test_irq(drive))
|
if (icside_dma_test_irq(drive))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ide_dump_status(drive, "DMA timeout", HWIF(drive)->INB(IDE_STATUS_REG));
|
ide_dump_status(drive, "DMA timeout", ide_read_status(drive));
|
||||||
|
|
||||||
icside_dma_end(drive);
|
icside_dma_end(drive);
|
||||||
}
|
}
|
||||||
|
|
395
drivers/ide/arm/palm_bk3710.c
Normal file
395
drivers/ide/arm/palm_bk3710.c
Normal file
|
@ -0,0 +1,395 @@
|
||||||
|
/*
|
||||||
|
* Palmchip bk3710 IDE controller
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Texas Instruments.
|
||||||
|
* Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com>
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/hdreg.h>
|
||||||
|
#include <linux/ide.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
/* Offset of the primary interface registers */
|
||||||
|
#define IDE_PALM_ATA_PRI_REG_OFFSET 0x1F0
|
||||||
|
|
||||||
|
/* Primary Control Offset */
|
||||||
|
#define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PalmChip 3710 IDE Controller UDMA timing structure Definition
|
||||||
|
*/
|
||||||
|
struct palm_bk3710_udmatiming {
|
||||||
|
unsigned int rptime; /* Ready to pause time */
|
||||||
|
unsigned int cycletime; /* Cycle Time */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BK3710_BMICP 0x00
|
||||||
|
#define BK3710_BMISP 0x02
|
||||||
|
#define BK3710_BMIDTP 0x04
|
||||||
|
#define BK3710_BMICS 0x08
|
||||||
|
#define BK3710_BMISS 0x0A
|
||||||
|
#define BK3710_BMIDTS 0x0C
|
||||||
|
#define BK3710_IDETIMP 0x40
|
||||||
|
#define BK3710_IDETIMS 0x42
|
||||||
|
#define BK3710_SIDETIM 0x44
|
||||||
|
#define BK3710_SLEWCTL 0x45
|
||||||
|
#define BK3710_IDESTATUS 0x47
|
||||||
|
#define BK3710_UDMACTL 0x48
|
||||||
|
#define BK3710_UDMATIM 0x4A
|
||||||
|
#define BK3710_MISCCTL 0x50
|
||||||
|
#define BK3710_REGSTB 0x54
|
||||||
|
#define BK3710_REGRCVR 0x58
|
||||||
|
#define BK3710_DATSTB 0x5C
|
||||||
|
#define BK3710_DATRCVR 0x60
|
||||||
|
#define BK3710_DMASTB 0x64
|
||||||
|
#define BK3710_DMARCVR 0x68
|
||||||
|
#define BK3710_UDMASTB 0x6C
|
||||||
|
#define BK3710_UDMATRP 0x70
|
||||||
|
#define BK3710_UDMAENV 0x74
|
||||||
|
#define BK3710_IORDYTMP 0x78
|
||||||
|
#define BK3710_IORDYTMS 0x7C
|
||||||
|
|
||||||
|
#include "../ide-timing.h"
|
||||||
|
|
||||||
|
static long ide_palm_clk;
|
||||||
|
|
||||||
|
static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
|
||||||
|
{160, 240}, /* UDMA Mode 0 */
|
||||||
|
{125, 160}, /* UDMA Mode 1 */
|
||||||
|
{100, 120}, /* UDMA Mode 2 */
|
||||||
|
{100, 90}, /* UDMA Mode 3 */
|
||||||
|
{85, 60}, /* UDMA Mode 4 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk *ideclkp;
|
||||||
|
|
||||||
|
static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
|
||||||
|
unsigned int mode)
|
||||||
|
{
|
||||||
|
u8 tenv, trp, t0;
|
||||||
|
u32 val32;
|
||||||
|
u16 val16;
|
||||||
|
|
||||||
|
/* DMA Data Setup */
|
||||||
|
t0 = (palm_bk3710_udmatimings[mode].cycletime + ide_palm_clk - 1)
|
||||||
|
/ ide_palm_clk - 1;
|
||||||
|
tenv = (20 + ide_palm_clk - 1) / ide_palm_clk - 1;
|
||||||
|
trp = (palm_bk3710_udmatimings[mode].rptime + ide_palm_clk - 1)
|
||||||
|
/ ide_palm_clk - 1;
|
||||||
|
|
||||||
|
/* udmatim Register */
|
||||||
|
val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
|
||||||
|
val16 |= (mode << (dev ? 4 : 0));
|
||||||
|
writew(val16, base + BK3710_UDMATIM);
|
||||||
|
|
||||||
|
/* udmastb Ultra DMA Access Strobe Width */
|
||||||
|
val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (t0 << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_UDMASTB);
|
||||||
|
|
||||||
|
/* udmatrp Ultra DMA Ready to Pause Time */
|
||||||
|
val32 = readl(base + BK3710_UDMATRP) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (trp << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_UDMATRP);
|
||||||
|
|
||||||
|
/* udmaenv Ultra DMA envelop Time */
|
||||||
|
val32 = readl(base + BK3710_UDMAENV) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (tenv << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_UDMAENV);
|
||||||
|
|
||||||
|
/* Enable UDMA for Device */
|
||||||
|
val16 = readw(base + BK3710_UDMACTL) | (1 << dev);
|
||||||
|
writew(val16, base + BK3710_UDMACTL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev,
|
||||||
|
unsigned short min_cycle,
|
||||||
|
unsigned int mode)
|
||||||
|
{
|
||||||
|
u8 td, tkw, t0;
|
||||||
|
u32 val32;
|
||||||
|
u16 val16;
|
||||||
|
struct ide_timing *t;
|
||||||
|
int cycletime;
|
||||||
|
|
||||||
|
t = ide_timing_find_mode(mode);
|
||||||
|
cycletime = max_t(int, t->cycle, min_cycle);
|
||||||
|
|
||||||
|
/* DMA Data Setup */
|
||||||
|
t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk;
|
||||||
|
td = (t->active + ide_palm_clk - 1) / ide_palm_clk;
|
||||||
|
tkw = t0 - td - 1;
|
||||||
|
td -= 1;
|
||||||
|
|
||||||
|
val32 = readl(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (td << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_DMASTB);
|
||||||
|
|
||||||
|
val32 = readl(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (tkw << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_DMARCVR);
|
||||||
|
|
||||||
|
/* Disable UDMA for Device */
|
||||||
|
val16 = readw(base + BK3710_UDMACTL) & ~(1 << dev);
|
||||||
|
writew(val16, base + BK3710_UDMACTL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
|
||||||
|
unsigned int dev, unsigned int cycletime,
|
||||||
|
unsigned int mode)
|
||||||
|
{
|
||||||
|
u8 t2, t2i, t0;
|
||||||
|
u32 val32;
|
||||||
|
struct ide_timing *t;
|
||||||
|
|
||||||
|
/* PIO Data Setup */
|
||||||
|
t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk;
|
||||||
|
t2 = (ide_timing_find_mode(XFER_PIO_0 + mode)->active +
|
||||||
|
ide_palm_clk - 1) / ide_palm_clk;
|
||||||
|
|
||||||
|
t2i = t0 - t2 - 1;
|
||||||
|
t2 -= 1;
|
||||||
|
|
||||||
|
val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (t2 << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_DATSTB);
|
||||||
|
|
||||||
|
val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (t2i << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_DATRCVR);
|
||||||
|
|
||||||
|
if (mate && mate->present) {
|
||||||
|
u8 mode2 = ide_get_best_pio_mode(mate, 255, 4);
|
||||||
|
|
||||||
|
if (mode2 < mode)
|
||||||
|
mode = mode2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TASKFILE Setup */
|
||||||
|
t = ide_timing_find_mode(XFER_PIO_0 + mode);
|
||||||
|
t0 = (t->cyc8b + ide_palm_clk - 1) / ide_palm_clk;
|
||||||
|
t2 = (t->act8b + ide_palm_clk - 1) / ide_palm_clk;
|
||||||
|
|
||||||
|
t2i = t0 - t2 - 1;
|
||||||
|
t2 -= 1;
|
||||||
|
|
||||||
|
val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (t2 << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_REGSTB);
|
||||||
|
|
||||||
|
val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8));
|
||||||
|
val32 |= (t2i << (dev ? 8 : 0));
|
||||||
|
writel(val32, base + BK3710_REGRCVR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
|
||||||
|
{
|
||||||
|
int is_slave = drive->dn & 1;
|
||||||
|
void __iomem *base = (void *)drive->hwif->dma_base;
|
||||||
|
|
||||||
|
if (xferspeed >= XFER_UDMA_0) {
|
||||||
|
palm_bk3710_setudmamode(base, is_slave,
|
||||||
|
xferspeed - XFER_UDMA_0);
|
||||||
|
} else {
|
||||||
|
palm_bk3710_setdmamode(base, is_slave, drive->id->eide_dma_min,
|
||||||
|
xferspeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
|
||||||
|
{
|
||||||
|
unsigned int cycle_time;
|
||||||
|
int is_slave = drive->dn & 1;
|
||||||
|
ide_drive_t *mate;
|
||||||
|
void __iomem *base = (void *)drive->hwif->dma_base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain the drive PIO data for tuning the Palm Chip registers
|
||||||
|
*/
|
||||||
|
cycle_time = ide_pio_cycle_time(drive, pio);
|
||||||
|
mate = ide_get_paired_drive(drive);
|
||||||
|
palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __devinit palm_bk3710_chipinit(void __iomem *base)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* enable the reset_en of ATA controller so that when ata signals
|
||||||
|
* are brought out, by writing into device config. at that
|
||||||
|
* time por_n signal should not be 'Z' and have a stable value.
|
||||||
|
*/
|
||||||
|
writel(0x0300, base + BK3710_MISCCTL);
|
||||||
|
|
||||||
|
/* wait for some time and deassert the reset of ATA Device. */
|
||||||
|
mdelay(100);
|
||||||
|
|
||||||
|
/* Deassert the Reset */
|
||||||
|
writel(0x0200, base + BK3710_MISCCTL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Program the IDETIMP Register Value based on the following assumptions
|
||||||
|
*
|
||||||
|
* (ATA_IDETIMP_IDEEN , ENABLE ) |
|
||||||
|
* (ATA_IDETIMP_SLVTIMEN , DISABLE) |
|
||||||
|
* (ATA_IDETIMP_RDYSMPL , 70NS) |
|
||||||
|
* (ATA_IDETIMP_RDYRCVRY , 50NS) |
|
||||||
|
* (ATA_IDETIMP_DMAFTIM1 , PIOCOMP) |
|
||||||
|
* (ATA_IDETIMP_PREPOST1 , DISABLE) |
|
||||||
|
* (ATA_IDETIMP_RDYSEN1 , DISABLE) |
|
||||||
|
* (ATA_IDETIMP_PIOFTIM1 , DISABLE) |
|
||||||
|
* (ATA_IDETIMP_DMAFTIM0 , PIOCOMP) |
|
||||||
|
* (ATA_IDETIMP_PREPOST0 , DISABLE) |
|
||||||
|
* (ATA_IDETIMP_RDYSEN0 , DISABLE) |
|
||||||
|
* (ATA_IDETIMP_PIOFTIM0 , DISABLE)
|
||||||
|
*/
|
||||||
|
writew(0xB388, base + BK3710_IDETIMP);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure SIDETIM Register
|
||||||
|
* (ATA_SIDETIM_RDYSMPS1 ,120NS ) |
|
||||||
|
* (ATA_SIDETIM_RDYRCYS1 ,120NS )
|
||||||
|
*/
|
||||||
|
writeb(0, base + BK3710_SIDETIM);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UDMACTL Ultra-ATA DMA Control
|
||||||
|
* (ATA_UDMACTL_UDMAP1 , 0 ) |
|
||||||
|
* (ATA_UDMACTL_UDMAP0 , 0 )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
writew(0, base + BK3710_UDMACTL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MISCCTL Miscellaneous Conrol Register
|
||||||
|
* (ATA_MISCCTL_RSTMODEP , 1) |
|
||||||
|
* (ATA_MISCCTL_RESETP , 0) |
|
||||||
|
* (ATA_MISCCTL_TIMORIDE , 1)
|
||||||
|
*/
|
||||||
|
writel(0x201, base + BK3710_MISCCTL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IORDYTMP IORDY Timer for Primary Register
|
||||||
|
* (ATA_IORDYTMP_IORDYTMP , 0xffff )
|
||||||
|
*/
|
||||||
|
writel(0xFFFF, base + BK3710_IORDYTMP);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure BMISP Register
|
||||||
|
* (ATA_BMISP_DMAEN1 , DISABLE ) |
|
||||||
|
* (ATA_BMISP_DMAEN0 , DISABLE ) |
|
||||||
|
* (ATA_BMISP_IORDYINT , CLEAR) |
|
||||||
|
* (ATA_BMISP_INTRSTAT , CLEAR) |
|
||||||
|
* (ATA_BMISP_DMAERROR , CLEAR)
|
||||||
|
*/
|
||||||
|
writew(0, base + BK3710_BMISP);
|
||||||
|
|
||||||
|
palm_bk3710_setpiomode(base, NULL, 0, 600, 0);
|
||||||
|
palm_bk3710_setpiomode(base, NULL, 1, 600, 0);
|
||||||
|
}
|
||||||
|
static int __devinit palm_bk3710_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
hw_regs_t ide_ctlr_info;
|
||||||
|
int index = 0;
|
||||||
|
int pribase;
|
||||||
|
struct clk *clkp;
|
||||||
|
struct resource *mem, *irq;
|
||||||
|
ide_hwif_t *hwif;
|
||||||
|
void __iomem *base;
|
||||||
|
|
||||||
|
clkp = clk_get(NULL, "IDECLK");
|
||||||
|
if (IS_ERR(clkp))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
ideclkp = clkp;
|
||||||
|
clk_enable(ideclkp);
|
||||||
|
ide_palm_clk = clk_get_rate(ideclkp)/100000;
|
||||||
|
ide_palm_clk = (10000/ide_palm_clk) + 1;
|
||||||
|
/* Register the IDE interface with Linux ATA Interface */
|
||||||
|
memset(&ide_ctlr_info, 0, sizeof(ide_ctlr_info));
|
||||||
|
|
||||||
|
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
if (mem == NULL) {
|
||||||
|
printk(KERN_ERR "failed to get memory region resource\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||||
|
if (irq == NULL) {
|
||||||
|
printk(KERN_ERR "failed to get IRQ resource\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
base = (void *)mem->start;
|
||||||
|
|
||||||
|
/* Configure the Palm Chip controller */
|
||||||
|
palm_bk3710_chipinit(base);
|
||||||
|
|
||||||
|
pribase = mem->start + IDE_PALM_ATA_PRI_REG_OFFSET;
|
||||||
|
for (index = 0; index < IDE_NR_PORTS - 2; index++)
|
||||||
|
ide_ctlr_info.io_ports[index] = pribase + index;
|
||||||
|
ide_ctlr_info.io_ports[IDE_CONTROL_OFFSET] = mem->start +
|
||||||
|
IDE_PALM_ATA_PRI_CTL_OFFSET;
|
||||||
|
ide_ctlr_info.irq = irq->start;
|
||||||
|
ide_ctlr_info.chipset = ide_palm3710;
|
||||||
|
|
||||||
|
if (ide_register_hw(&ide_ctlr_info, NULL, &hwif) < 0) {
|
||||||
|
printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
hwif->set_pio_mode = &palm_bk3710_set_pio_mode;
|
||||||
|
hwif->set_dma_mode = &palm_bk3710_set_dma_mode;
|
||||||
|
hwif->mmio = 1;
|
||||||
|
default_hwif_mmiops(hwif);
|
||||||
|
hwif->cbl = ATA_CBL_PATA80;
|
||||||
|
hwif->ultra_mask = 0x1f; /* Ultra DMA Mode 4 Max
|
||||||
|
(input clk 99MHz) */
|
||||||
|
hwif->mwdma_mask = 0x7;
|
||||||
|
hwif->drives[0].autotune = 1;
|
||||||
|
hwif->drives[1].autotune = 1;
|
||||||
|
|
||||||
|
ide_setup_dma(hwif, mem->start);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver platform_bk_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "palm_bk3710",
|
||||||
|
},
|
||||||
|
.probe = palm_bk3710_probe,
|
||||||
|
.remove = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init palm_bk3710_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&platform_bk_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(palm_bk3710_init);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -753,6 +753,25 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
|
||||||
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
|
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init cris_setup_ports(hw_regs_t *hw, unsigned long base)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(hw, 0, sizeof(*hw));
|
||||||
|
|
||||||
|
for (i = 0; i <= 7; i++)
|
||||||
|
hw->io_ports[i] = base + cris_ide_reg_addr(i, 0, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the IDE control register is at ATA address 6,
|
||||||
|
* with CS1 active instead of CS0
|
||||||
|
*/
|
||||||
|
hw->io_ports[IDE_CONTROL_OFFSET] = base + cris_ide_reg_addr(6, 1, 0);
|
||||||
|
|
||||||
|
hw->irq = ide_default_irq(0);
|
||||||
|
hw->ack_intr = cris_ide_ack_intr;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ide_port_info cris_port_info __initdata = {
|
static const struct ide_port_info cris_port_info __initdata = {
|
||||||
.chipset = ide_etrax100,
|
.chipset = ide_etrax100,
|
||||||
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
|
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
|
||||||
|
@ -765,24 +784,16 @@ static const struct ide_port_info cris_port_info __initdata = {
|
||||||
static int __init init_e100_ide(void)
|
static int __init init_e100_ide(void)
|
||||||
{
|
{
|
||||||
hw_regs_t hw;
|
hw_regs_t hw;
|
||||||
int ide_offsets[IDE_NR_PORTS], h, i;
|
int h;
|
||||||
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
|
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
printk("ide: ETRAX FS built-in ATA DMA controller\n");
|
printk("ide: ETRAX FS built-in ATA DMA controller\n");
|
||||||
|
|
||||||
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
|
|
||||||
ide_offsets[i] = cris_ide_reg_addr(i, 0, 1);
|
|
||||||
|
|
||||||
/* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */
|
|
||||||
ide_offsets[IDE_CONTROL_OFFSET] = cris_ide_reg_addr(6, 1, 0);
|
|
||||||
|
|
||||||
for (h = 0; h < 4; h++) {
|
for (h = 0; h < 4; h++) {
|
||||||
ide_hwif_t *hwif = NULL;
|
ide_hwif_t *hwif = NULL;
|
||||||
|
|
||||||
ide_setup_ports(&hw, cris_ide_base_address(h),
|
cris_setup_ports(&hw, cris_ide_base_address(h));
|
||||||
ide_offsets,
|
|
||||||
0, 0, cris_ide_ack_intr,
|
|
||||||
ide_default_irq(0));
|
|
||||||
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
||||||
if (hwif == NULL)
|
if (hwif == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -171,7 +171,7 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
|
||||||
static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
|
static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
|
||||||
{
|
{
|
||||||
struct device *dev = hwif->gendev.parent;
|
struct device *dev = hwif->gendev.parent;
|
||||||
acpi_handle dev_handle;
|
acpi_handle uninitialized_var(dev_handle);
|
||||||
acpi_integer pcidevfn;
|
acpi_integer pcidevfn;
|
||||||
acpi_handle chan_handle;
|
acpi_handle chan_handle;
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -295,7 +295,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
|
||||||
int stat, err, sense_key;
|
int stat, err, sense_key;
|
||||||
|
|
||||||
/* Check for errors. */
|
/* Check for errors. */
|
||||||
stat = HWIF(drive)->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (stat_ret)
|
if (stat_ret)
|
||||||
*stat_ret = stat;
|
*stat_ret = stat;
|
||||||
|
|
||||||
|
@ -303,7 +304,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Get the IDE error register. */
|
/* Get the IDE error register. */
|
||||||
err = HWIF(drive)->INB(IDE_ERROR_REG);
|
err = ide_read_error(drive);
|
||||||
sense_key = err >> 4;
|
sense_key = err >> 4;
|
||||||
|
|
||||||
if (rq == NULL) {
|
if (rq == NULL) {
|
||||||
|
@ -692,7 +693,7 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw)
|
||||||
/* Some drives (ASUS) seem to tell us that status
|
/* Some drives (ASUS) seem to tell us that status
|
||||||
* info is available. just get it and ignore.
|
* info is available. just get it and ignore.
|
||||||
*/
|
*/
|
||||||
(void) HWIF(drive)->INB(IDE_STATUS_REG);
|
(void)ide_read_status(drive);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
/* Drive wants a command packet, or invalid ireason... */
|
/* Drive wants a command packet, or invalid ireason... */
|
||||||
|
@ -1326,7 +1327,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
|
||||||
if (blk_fs_request(rq)) {
|
if (blk_fs_request(rq)) {
|
||||||
if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
|
if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
|
||||||
unsigned long elapsed = jiffies - info->start_seek;
|
unsigned long elapsed = jiffies - info->start_seek;
|
||||||
int stat = HWIF(drive)->INB(IDE_STATUS_REG);
|
int stat = ide_read_status(drive);
|
||||||
|
|
||||||
if ((stat & SEEK_STAT) != SEEK_STAT) {
|
if ((stat & SEEK_STAT) != SEEK_STAT) {
|
||||||
if (elapsed < IDECD_SEEK_TIMEOUT) {
|
if (elapsed < IDECD_SEEK_TIMEOUT) {
|
||||||
|
|
|
@ -147,7 +147,8 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
|
||||||
u8 stat = 0, dma_stat = 0;
|
u8 stat = 0, dma_stat = 0;
|
||||||
|
|
||||||
dma_stat = HWIF(drive)->ide_dma_end(drive);
|
dma_stat = HWIF(drive)->ide_dma_end(drive);
|
||||||
stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
|
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
|
||||||
if (!dma_stat) {
|
if (!dma_stat) {
|
||||||
struct request *rq = HWGROUP(drive)->rq;
|
struct request *rq = HWGROUP(drive)->rq;
|
||||||
|
|
|
@ -465,7 +465,7 @@ static void idefloppy_retry_pc(ide_drive_t *drive)
|
||||||
idefloppy_pc_t *pc;
|
idefloppy_pc_t *pc;
|
||||||
struct request *rq;
|
struct request *rq;
|
||||||
|
|
||||||
(void)drive->hwif->INB(IDE_ERROR_REG);
|
(void)ide_read_error(drive);
|
||||||
pc = idefloppy_next_pc_storage(drive);
|
pc = idefloppy_next_pc_storage(drive);
|
||||||
rq = idefloppy_next_rq_storage(drive);
|
rq = idefloppy_next_rq_storage(drive);
|
||||||
idefloppy_create_request_sense_cmd(pc);
|
idefloppy_create_request_sense_cmd(pc);
|
||||||
|
@ -501,7 +501,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the interrupt */
|
/* Clear the interrupt */
|
||||||
stat = drive->hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
/* No more interrupts */
|
/* No more interrupts */
|
||||||
if ((stat & DRQ_STAT) == 0) {
|
if ((stat & DRQ_STAT) == 0) {
|
||||||
|
@ -1246,7 +1246,7 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
stat = drive->hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000;
|
progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000;
|
||||||
|
|
|
@ -20,8 +20,14 @@ static int __init ide_generic_init(void)
|
||||||
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
|
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
|
||||||
ide_get_lock(NULL, NULL); /* for atari only */
|
ide_get_lock(NULL, NULL); /* for atari only */
|
||||||
|
|
||||||
for (i = 0; i < MAX_HWIFS; i++)
|
for (i = 0; i < MAX_HWIFS; i++) {
|
||||||
idx[i] = ide_hwifs[i].present ? 0xff : i;
|
ide_hwif_t *hwif = &ide_hwifs[i];
|
||||||
|
|
||||||
|
if (hwif->io_ports[IDE_DATA_OFFSET] && !hwif->present)
|
||||||
|
idx[i] = i;
|
||||||
|
else
|
||||||
|
idx[i] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
ide_device_add_all(idx, NULL);
|
ide_device_add_all(idx, NULL);
|
||||||
|
|
||||||
|
|
|
@ -466,7 +466,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
|
||||||
return ide_stopped;
|
return ide_stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
|
if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
|
||||||
rq->errors |= ERROR_RESET;
|
rq->errors |= ERROR_RESET;
|
||||||
|
|
||||||
if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
|
if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
|
||||||
|
@ -493,7 +493,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
|
||||||
/* add decoding error stuff */
|
/* add decoding error stuff */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
|
if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
|
||||||
/* force an abort */
|
/* force an abort */
|
||||||
hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
|
hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
|
||||||
|
|
||||||
|
@ -821,9 +821,8 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printk("%s: DRIVE_CMD (null)\n", drive->name);
|
printk("%s: DRIVE_CMD (null)\n", drive->name);
|
||||||
#endif
|
#endif
|
||||||
ide_end_drive_cmd(drive,
|
ide_end_drive_cmd(drive, ide_read_status(drive), ide_read_error(drive));
|
||||||
hwif->INB(IDE_STATUS_REG),
|
|
||||||
hwif->INB(IDE_ERROR_REG));
|
|
||||||
return ide_stopped;
|
return ide_stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1231,7 +1230,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
|
||||||
printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
|
printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
|
||||||
(void)HWIF(drive)->ide_dma_end(drive);
|
(void)HWIF(drive)->ide_dma_end(drive);
|
||||||
ret = ide_error(drive, "dma timeout error",
|
ret = ide_error(drive, "dma timeout error",
|
||||||
hwif->INB(IDE_STATUS_REG));
|
ide_read_status(drive));
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
|
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
|
||||||
hwif->dma_timeout(drive);
|
hwif->dma_timeout(drive);
|
||||||
|
@ -1355,7 +1354,8 @@ void ide_timer_expiry (unsigned long data)
|
||||||
startstop = ide_dma_timeout_retry(drive, wait);
|
startstop = ide_dma_timeout_retry(drive, wait);
|
||||||
} else
|
} else
|
||||||
startstop =
|
startstop =
|
||||||
ide_error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
|
ide_error(drive, "irq timeout",
|
||||||
|
ide_read_status(drive));
|
||||||
}
|
}
|
||||||
drive->service_time = jiffies - drive->service_start;
|
drive->service_time = jiffies - drive->service_start;
|
||||||
spin_lock_irq(&ide_lock);
|
spin_lock_irq(&ide_lock);
|
||||||
|
|
|
@ -430,10 +430,10 @@ int drive_is_ready (ide_drive_t *drive)
|
||||||
* about possible isa-pnp and pci-pnp issues yet.
|
* about possible isa-pnp and pci-pnp issues yet.
|
||||||
*/
|
*/
|
||||||
if (IDE_CONTROL_REG)
|
if (IDE_CONTROL_REG)
|
||||||
stat = hwif->INB(IDE_ALTSTATUS_REG);
|
stat = ide_read_altstatus(drive);
|
||||||
else
|
else
|
||||||
/* Note: this may clear a pending IRQ!! */
|
/* Note: this may clear a pending IRQ!! */
|
||||||
stat = hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (stat & BUSY_STAT)
|
if (stat & BUSY_STAT)
|
||||||
/* drive busy: definitely not interrupting */
|
/* drive busy: definitely not interrupting */
|
||||||
|
@ -458,23 +458,24 @@ EXPORT_SYMBOL(drive_is_ready);
|
||||||
*/
|
*/
|
||||||
static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
|
static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = drive->hwif;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int i;
|
int i;
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
|
||||||
udelay(1); /* spec allows drive 400ns to assert "BUSY" */
|
udelay(1); /* spec allows drive 400ns to assert "BUSY" */
|
||||||
if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) {
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (stat & BUSY_STAT) {
|
||||||
local_irq_set(flags);
|
local_irq_set(flags);
|
||||||
timeout += jiffies;
|
timeout += jiffies;
|
||||||
while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) {
|
while ((stat = ide_read_status(drive)) & BUSY_STAT) {
|
||||||
if (time_after(jiffies, timeout)) {
|
if (time_after(jiffies, timeout)) {
|
||||||
/*
|
/*
|
||||||
* One last read after the timeout in case
|
* One last read after the timeout in case
|
||||||
* heavy interrupt load made us not make any
|
* heavy interrupt load made us not make any
|
||||||
* progress during the timeout..
|
* progress during the timeout..
|
||||||
*/
|
*/
|
||||||
stat = hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
if (!(stat & BUSY_STAT))
|
if (!(stat & BUSY_STAT))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -494,7 +495,9 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
udelay(1);
|
udelay(1);
|
||||||
if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) {
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (OK_STAT(stat, good, bad)) {
|
||||||
*rstat = stat;
|
*rstat = stat;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -617,6 +620,7 @@ int ide_driveid_update(ide_drive_t *drive)
|
||||||
ide_hwif_t *hwif = drive->hwif;
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
struct hd_driveid *id;
|
struct hd_driveid *id;
|
||||||
unsigned long timeout, flags;
|
unsigned long timeout, flags;
|
||||||
|
u8 stat;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Re-read drive->id for possible DMA mode
|
* Re-read drive->id for possible DMA mode
|
||||||
|
@ -633,10 +637,15 @@ int ide_driveid_update(ide_drive_t *drive)
|
||||||
SELECT_MASK(drive, 0);
|
SELECT_MASK(drive, 0);
|
||||||
return 0; /* drive timed-out */
|
return 0; /* drive timed-out */
|
||||||
}
|
}
|
||||||
|
|
||||||
msleep(50); /* give drive a breather */
|
msleep(50); /* give drive a breather */
|
||||||
} while (hwif->INB(IDE_ALTSTATUS_REG) & BUSY_STAT);
|
stat = ide_read_altstatus(drive);
|
||||||
|
} while (stat & BUSY_STAT);
|
||||||
|
|
||||||
msleep(50); /* wait for IRQ and DRQ_STAT */
|
msleep(50); /* wait for IRQ and DRQ_STAT */
|
||||||
if (!OK_STAT(hwif->INB(IDE_STATUS_REG),DRQ_STAT,BAD_R_STAT)) {
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
|
||||||
SELECT_MASK(drive, 0);
|
SELECT_MASK(drive, 0);
|
||||||
printk("%s: CHECK for good STATUS\n", drive->name);
|
printk("%s: CHECK for good STATUS\n", drive->name);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -649,7 +658,7 @@ int ide_driveid_update(ide_drive_t *drive)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ata_input_data(drive, id, SECTOR_WORDS);
|
ata_input_data(drive, id, SECTOR_WORDS);
|
||||||
(void) hwif->INB(IDE_STATUS_REG); /* clear drive IRQ */
|
(void)ide_read_status(drive); /* clear drive IRQ */
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
ide_fix_driveid(id);
|
ide_fix_driveid(id);
|
||||||
|
@ -850,17 +859,16 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int);
|
||||||
static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
|
static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_hwgroup_t *hwgroup = HWGROUP(drive);
|
ide_hwgroup_t *hwgroup = HWGROUP(drive);
|
||||||
ide_hwif_t *hwif = HWIF(drive);
|
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
|
||||||
SELECT_DRIVE(drive);
|
SELECT_DRIVE(drive);
|
||||||
udelay (10);
|
udelay (10);
|
||||||
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) {
|
if (OK_STAT(stat, 0, BUSY_STAT))
|
||||||
printk("%s: ATAPI reset complete\n", drive->name);
|
printk("%s: ATAPI reset complete\n", drive->name);
|
||||||
} else {
|
else {
|
||||||
if (time_before(jiffies, hwgroup->poll_timeout)) {
|
if (time_before(jiffies, hwgroup->poll_timeout)) {
|
||||||
BUG_ON(HWGROUP(drive)->handler != NULL);
|
|
||||||
ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
|
ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
|
||||||
/* continue polling */
|
/* continue polling */
|
||||||
return ide_started;
|
return ide_started;
|
||||||
|
@ -898,9 +906,10 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!OK_STAT(tmp = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) {
|
tmp = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (!OK_STAT(tmp, 0, BUSY_STAT)) {
|
||||||
if (time_before(jiffies, hwgroup->poll_timeout)) {
|
if (time_before(jiffies, hwgroup->poll_timeout)) {
|
||||||
BUG_ON(HWGROUP(drive)->handler != NULL);
|
|
||||||
ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
|
ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
|
||||||
/* continue polling */
|
/* continue polling */
|
||||||
return ide_started;
|
return ide_started;
|
||||||
|
@ -909,7 +918,9 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
|
||||||
drive->failures++;
|
drive->failures++;
|
||||||
} else {
|
} else {
|
||||||
printk("%s: reset: ", hwif->name);
|
printk("%s: reset: ", hwif->name);
|
||||||
if ((tmp = hwif->INB(IDE_ERROR_REG)) == 1) {
|
tmp = ide_read_error(drive);
|
||||||
|
|
||||||
|
if (tmp == 1) {
|
||||||
printk("success\n");
|
printk("success\n");
|
||||||
drive->failures = 0;
|
drive->failures = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -578,7 +578,7 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
|
||||||
}
|
}
|
||||||
printk("}\n");
|
printk("}\n");
|
||||||
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
|
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
|
||||||
err = drive->hwif->INB(IDE_ERROR_REG);
|
err = ide_read_error(drive);
|
||||||
printk("%s: %s: error=0x%02x ", drive->name, msg, err);
|
printk("%s: %s: error=0x%02x ", drive->name, msg, err);
|
||||||
if (drive->media == ide_disk)
|
if (drive->media == ide_disk)
|
||||||
ide_dump_ata_error(drive, err);
|
ide_dump_ata_error(drive, err);
|
||||||
|
|
|
@ -264,8 +264,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
|
||||||
static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
|
static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = HWIF(drive);
|
ide_hwif_t *hwif = HWIF(drive);
|
||||||
int rc;
|
int use_altstatus = 0, rc;
|
||||||
unsigned long hd_status;
|
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
u8 s = 0, a = 0;
|
u8 s = 0, a = 0;
|
||||||
|
|
||||||
|
@ -273,19 +272,17 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
|
||||||
msleep(50);
|
msleep(50);
|
||||||
|
|
||||||
if (IDE_CONTROL_REG) {
|
if (IDE_CONTROL_REG) {
|
||||||
a = hwif->INB(IDE_ALTSTATUS_REG);
|
a = ide_read_altstatus(drive);
|
||||||
s = hwif->INB(IDE_STATUS_REG);
|
s = ide_read_status(drive);
|
||||||
if ((a ^ s) & ~INDEX_STAT) {
|
if ((a ^ s) & ~INDEX_STAT)
|
||||||
printk(KERN_INFO "%s: probing with STATUS(0x%02x) instead of "
|
|
||||||
"ALTSTATUS(0x%02x)\n", drive->name, s, a);
|
|
||||||
/* ancient Seagate drives, broken interfaces */
|
/* ancient Seagate drives, broken interfaces */
|
||||||
hd_status = IDE_STATUS_REG;
|
printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
|
||||||
} else {
|
"instead of ALTSTATUS(0x%02x)\n",
|
||||||
|
drive->name, s, a);
|
||||||
|
else
|
||||||
/* use non-intrusive polling */
|
/* use non-intrusive polling */
|
||||||
hd_status = IDE_ALTSTATUS_REG;
|
use_altstatus = 1;
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
hd_status = IDE_STATUS_REG;
|
|
||||||
|
|
||||||
/* set features register for atapi
|
/* set features register for atapi
|
||||||
* identify command to be sure of reply
|
* identify command to be sure of reply
|
||||||
|
@ -306,11 +303,15 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
|
||||||
}
|
}
|
||||||
/* give drive a breather */
|
/* give drive a breather */
|
||||||
msleep(50);
|
msleep(50);
|
||||||
} while ((hwif->INB(hd_status)) & BUSY_STAT);
|
s = use_altstatus ? ide_read_altstatus(drive)
|
||||||
|
: ide_read_status(drive);
|
||||||
|
} while (s & BUSY_STAT);
|
||||||
|
|
||||||
/* wait for IRQ and DRQ_STAT */
|
/* wait for IRQ and DRQ_STAT */
|
||||||
msleep(50);
|
msleep(50);
|
||||||
if (OK_STAT((hwif->INB(IDE_STATUS_REG)), DRQ_STAT, BAD_R_STAT)) {
|
s = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/* local CPU only; some systems need this */
|
/* local CPU only; some systems need this */
|
||||||
|
@ -320,7 +321,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
|
||||||
/* drive responded with ID */
|
/* drive responded with ID */
|
||||||
rc = 0;
|
rc = 0;
|
||||||
/* clear drive IRQ */
|
/* clear drive IRQ */
|
||||||
(void) hwif->INB(IDE_STATUS_REG);
|
(void)ide_read_status(drive);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
} else {
|
} else {
|
||||||
/* drive refused ID */
|
/* drive refused ID */
|
||||||
|
@ -367,7 +368,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
|
||||||
|
|
||||||
ide_set_irq(drive, 0);
|
ide_set_irq(drive, 0);
|
||||||
/* clear drive IRQ */
|
/* clear drive IRQ */
|
||||||
(void) hwif->INB(IDE_STATUS_REG);
|
(void)ide_read_status(drive);
|
||||||
udelay(5);
|
udelay(5);
|
||||||
irq = probe_irq_off(cookie);
|
irq = probe_irq_off(cookie);
|
||||||
if (!hwif->irq) {
|
if (!hwif->irq) {
|
||||||
|
@ -455,7 +456,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OK_STAT((hwif->INB(IDE_STATUS_REG)), READY_STAT, BUSY_STAT) ||
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (OK_STAT(stat, READY_STAT, BUSY_STAT) ||
|
||||||
drive->present || cmd == WIN_PIDENTIFY) {
|
drive->present || cmd == WIN_PIDENTIFY) {
|
||||||
/* send cmd and wait */
|
/* send cmd and wait */
|
||||||
if ((rc = try_to_identify(drive, cmd))) {
|
if ((rc = try_to_identify(drive, cmd))) {
|
||||||
|
@ -463,7 +466,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
|
||||||
rc = try_to_identify(drive,cmd);
|
rc = try_to_identify(drive,cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
stat = hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (stat == (BUSY_STAT | READY_STAT))
|
if (stat == (BUSY_STAT | READY_STAT))
|
||||||
return 4;
|
return 4;
|
||||||
|
@ -482,7 +485,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure drive IRQ is clear */
|
/* ensure drive IRQ is clear */
|
||||||
stat = hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (rc == 1)
|
if (rc == 1)
|
||||||
printk(KERN_ERR "%s: no response (status = 0x%02x)\n",
|
printk(KERN_ERR "%s: no response (status = 0x%02x)\n",
|
||||||
|
@ -496,7 +499,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
|
||||||
SELECT_DRIVE(&hwif->drives[0]);
|
SELECT_DRIVE(&hwif->drives[0]);
|
||||||
msleep(50);
|
msleep(50);
|
||||||
/* ensure drive irq is clear */
|
/* ensure drive irq is clear */
|
||||||
(void) hwif->INB(IDE_STATUS_REG);
|
(void)ide_read_status(drive);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -521,7 +524,7 @@ static void enable_nest (ide_drive_t *drive)
|
||||||
|
|
||||||
msleep(50);
|
msleep(50);
|
||||||
|
|
||||||
stat = hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (!OK_STAT(stat, 0, BAD_STAT))
|
if (!OK_STAT(stat, 0, BAD_STAT))
|
||||||
printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
|
printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
|
||||||
|
|
|
@ -65,6 +65,7 @@ static int proc_ide_read_imodel
|
||||||
case ide_4drives: name = "4drives"; break;
|
case ide_4drives: name = "4drives"; break;
|
||||||
case ide_pmac: name = "mac-io"; break;
|
case ide_pmac: name = "mac-io"; break;
|
||||||
case ide_au1xxx: name = "au1xxx"; break;
|
case ide_au1xxx: name = "au1xxx"; break;
|
||||||
|
case ide_palm3710: name = "palm3710"; break;
|
||||||
case ide_etrax100: name = "etrax100"; break;
|
case ide_etrax100: name = "etrax100"; break;
|
||||||
case ide_acorn: name = "acorn"; break;
|
case ide_acorn: name = "acorn"; break;
|
||||||
default: name = "(unknown)"; break;
|
default: name = "(unknown)"; break;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -189,12 +189,11 @@ EXPORT_SYMBOL_GPL(do_rw_taskfile);
|
||||||
*/
|
*/
|
||||||
static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
|
static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = HWIF(drive);
|
u8 stat = ide_read_status(drive);
|
||||||
u8 stat;
|
|
||||||
|
|
||||||
if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
|
if (OK_STAT(stat, READY_STAT, BAD_STAT))
|
||||||
drive->mult_count = drive->mult_req;
|
drive->mult_count = drive->mult_req;
|
||||||
} else {
|
else {
|
||||||
drive->mult_req = drive->mult_count = 0;
|
drive->mult_req = drive->mult_count = 0;
|
||||||
drive->special.b.recalibrate = 1;
|
drive->special.b.recalibrate = 1;
|
||||||
(void) ide_dump_status(drive, "set_multmode", stat);
|
(void) ide_dump_status(drive, "set_multmode", stat);
|
||||||
|
@ -207,11 +206,10 @@ static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
|
||||||
*/
|
*/
|
||||||
static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
|
static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = HWIF(drive);
|
|
||||||
int retries = 5;
|
int retries = 5;
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
|
||||||
while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
|
while (((stat = ide_read_status(drive)) & BUSY_STAT) && retries--)
|
||||||
udelay(10);
|
udelay(10);
|
||||||
|
|
||||||
if (OK_STAT(stat, READY_STAT, BAD_STAT))
|
if (OK_STAT(stat, READY_STAT, BAD_STAT))
|
||||||
|
@ -230,10 +228,9 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
|
||||||
*/
|
*/
|
||||||
static ide_startstop_t recal_intr(ide_drive_t *drive)
|
static ide_startstop_t recal_intr(ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = HWIF(drive);
|
u8 stat = ide_read_status(drive);
|
||||||
u8 stat;
|
|
||||||
|
|
||||||
if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), READY_STAT, BAD_STAT))
|
if (!OK_STAT(stat, READY_STAT, BAD_STAT))
|
||||||
return ide_error(drive, "recal_intr", stat);
|
return ide_error(drive, "recal_intr", stat);
|
||||||
return ide_stopped;
|
return ide_stopped;
|
||||||
}
|
}
|
||||||
|
@ -244,23 +241,23 @@ static ide_startstop_t recal_intr(ide_drive_t *drive)
|
||||||
static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
|
static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_task_t *args = HWGROUP(drive)->rq->special;
|
ide_task_t *args = HWGROUP(drive)->rq->special;
|
||||||
ide_hwif_t *hwif = HWIF(drive);
|
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
|
||||||
local_irq_enable_in_hardirq();
|
local_irq_enable_in_hardirq();
|
||||||
if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (!OK_STAT(stat, READY_STAT, BAD_STAT))
|
||||||
return ide_error(drive, "task_no_data_intr", stat);
|
return ide_error(drive, "task_no_data_intr", stat);
|
||||||
/* calls ide_end_drive_cmd */
|
/* calls ide_end_drive_cmd */
|
||||||
}
|
|
||||||
if (args)
|
if (args)
|
||||||
ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
|
ide_end_drive_cmd(drive, stat, ide_read_error(drive));
|
||||||
|
|
||||||
return ide_stopped;
|
return ide_stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 wait_drive_not_busy(ide_drive_t *drive)
|
static u8 wait_drive_not_busy(ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = HWIF(drive);
|
|
||||||
int retries;
|
int retries;
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
|
||||||
|
@ -269,7 +266,9 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
|
||||||
* This can take up to 10 usec, but we will wait max 1 ms.
|
* This can take up to 10 usec, but we will wait max 1 ms.
|
||||||
*/
|
*/
|
||||||
for (retries = 0; retries < 100; retries++) {
|
for (retries = 0; retries < 100; retries++) {
|
||||||
if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT)
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
|
if (stat & BUSY_STAT)
|
||||||
udelay(10);
|
udelay(10);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -408,7 +407,7 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
|
||||||
void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
|
void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
|
||||||
{
|
{
|
||||||
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
|
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
|
||||||
u8 err = drive->hwif->INB(IDE_ERROR_REG);
|
u8 err = ide_read_error(drive);
|
||||||
|
|
||||||
ide_end_drive_cmd(drive, stat, err);
|
ide_end_drive_cmd(drive, stat, err);
|
||||||
return;
|
return;
|
||||||
|
@ -430,7 +429,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = drive->hwif;
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
struct request *rq = HWGROUP(drive)->rq;
|
struct request *rq = HWGROUP(drive)->rq;
|
||||||
u8 stat = hwif->INB(IDE_STATUS_REG);
|
u8 stat = ide_read_status(drive);
|
||||||
|
|
||||||
/* new way for dealing with premature shared PCI interrupts */
|
/* new way for dealing with premature shared PCI interrupts */
|
||||||
if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
|
if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
|
||||||
|
@ -465,7 +464,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = drive->hwif;
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
struct request *rq = HWGROUP(drive)->rq;
|
struct request *rq = HWGROUP(drive)->rq;
|
||||||
u8 stat = hwif->INB(IDE_STATUS_REG);
|
u8 stat = ide_read_status(drive);
|
||||||
|
|
||||||
if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
|
if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
|
||||||
return task_error(drive, rq, __FUNCTION__, stat);
|
return task_error(drive, rq, __FUNCTION__, stat);
|
||||||
|
|
|
@ -618,60 +618,6 @@ void ide_unregister(unsigned int index, int init_default, int restore)
|
||||||
|
|
||||||
EXPORT_SYMBOL(ide_unregister);
|
EXPORT_SYMBOL(ide_unregister);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ide_setup_ports - set up IDE interface ports
|
|
||||||
* @hw: register descriptions
|
|
||||||
* @base: base register
|
|
||||||
* @offsets: table of register offsets
|
|
||||||
* @ctrl: control register
|
|
||||||
* @ack_irq: IRQ ack
|
|
||||||
* @irq: interrupt lie
|
|
||||||
*
|
|
||||||
* Setup hw_regs_t structure described by parameters. You
|
|
||||||
* may set up the hw structure yourself OR use this routine to
|
|
||||||
* do it for you. This is basically a helper
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ide_setup_ports ( hw_regs_t *hw,
|
|
||||||
unsigned long base, int *offsets,
|
|
||||||
unsigned long ctrl, unsigned long intr,
|
|
||||||
ide_ack_intr_t *ack_intr,
|
|
||||||
/*
|
|
||||||
* ide_io_ops_t *iops,
|
|
||||||
*/
|
|
||||||
int irq)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(hw, 0, sizeof(hw_regs_t));
|
|
||||||
for (i = 0; i < IDE_NR_PORTS; i++) {
|
|
||||||
if (offsets[i] == -1) {
|
|
||||||
switch(i) {
|
|
||||||
case IDE_CONTROL_OFFSET:
|
|
||||||
hw->io_ports[i] = ctrl;
|
|
||||||
break;
|
|
||||||
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
|
|
||||||
case IDE_IRQ_OFFSET:
|
|
||||||
hw->io_ports[i] = intr;
|
|
||||||
break;
|
|
||||||
#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
|
|
||||||
default:
|
|
||||||
hw->io_ports[i] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hw->io_ports[i] = base + offsets[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hw->irq = irq;
|
|
||||||
hw->ack_intr = ack_intr;
|
|
||||||
/*
|
|
||||||
* hw->iops = iops;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
|
void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
|
||||||
{
|
{
|
||||||
memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
|
memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
|
||||||
|
|
|
@ -56,31 +56,11 @@ static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = {
|
||||||
XSURF_BASE1, XSURF_BASE2
|
XSURF_BASE1, XSURF_BASE2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Offsets from one of the above bases
|
* Offsets from one of the above bases
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BUDDHA_DATA 0x00
|
|
||||||
#define BUDDHA_ERROR 0x06 /* see err-bits */
|
|
||||||
#define BUDDHA_NSECTOR 0x0a /* nr of sectors to read/write */
|
|
||||||
#define BUDDHA_SECTOR 0x0e /* starting sector */
|
|
||||||
#define BUDDHA_LCYL 0x12 /* starting cylinder */
|
|
||||||
#define BUDDHA_HCYL 0x16 /* high byte of starting cyl */
|
|
||||||
#define BUDDHA_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */
|
|
||||||
#define BUDDHA_STATUS 0x1e /* see status-bits */
|
|
||||||
#define BUDDHA_CONTROL 0x11a
|
#define BUDDHA_CONTROL 0x11a
|
||||||
#define XSURF_CONTROL -1 /* X-Surf has no CS1* (Control/AltStat) */
|
|
||||||
|
|
||||||
static int buddha_offsets[IDE_NR_PORTS] __initdata = {
|
|
||||||
BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL,
|
|
||||||
BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL, -1
|
|
||||||
};
|
|
||||||
|
|
||||||
static int xsurf_offsets[IDE_NR_PORTS] __initdata = {
|
|
||||||
BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL,
|
|
||||||
BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, XSURF_CONTROL, -1
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other registers
|
* Other registers
|
||||||
|
@ -140,6 +120,26 @@ static int xsurf_ack_intr(ide_hwif_t *hwif)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
|
||||||
|
unsigned long ctl, unsigned long irq_port,
|
||||||
|
ide_ack_intr_t *ack_intr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(hw, 0, sizeof(*hw));
|
||||||
|
|
||||||
|
hw->io_ports[IDE_DATA_OFFSET] = base;
|
||||||
|
|
||||||
|
for (i = 1; i < 8; i++)
|
||||||
|
hw->io_ports[i] = base + 2 + i * 4;
|
||||||
|
|
||||||
|
hw->io_ports[IDE_CONTROL_OFFSET] = ctl;
|
||||||
|
hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
|
||||||
|
|
||||||
|
hw->irq = IRQ_AMIGA_PORTS;
|
||||||
|
hw->ack_intr = ack_intr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Probe for a Buddha or Catweasel IDE interface
|
* Probe for a Buddha or Catweasel IDE interface
|
||||||
*/
|
*/
|
||||||
|
@ -202,23 +202,25 @@ static int __init buddha_init(void)
|
||||||
printk(KERN_INFO "ide: %s IDE controller\n",
|
printk(KERN_INFO "ide: %s IDE controller\n",
|
||||||
buddha_board_name[type]);
|
buddha_board_name[type]);
|
||||||
|
|
||||||
for(i=0;i<buddha_num_hwifs;i++) {
|
for (i = 0; i < buddha_num_hwifs; i++) {
|
||||||
if(type != BOARD_XSURF) {
|
unsigned long base, ctl, irq_port;
|
||||||
ide_setup_ports(&hw, (buddha_board+buddha_bases[i]),
|
ide_ack_intr_t *ack_intr;
|
||||||
buddha_offsets, 0,
|
|
||||||
(buddha_board+buddha_irqports[i]),
|
if (type != BOARD_XSURF) {
|
||||||
buddha_ack_intr,
|
base = buddha_board + buddha_bases[i];
|
||||||
// budda_iops,
|
ctl = base + BUDDHA_CONTROL;
|
||||||
IRQ_AMIGA_PORTS);
|
irq_port = buddha_board + buddha_irqports[i];
|
||||||
|
ack_intr = buddha_ack_intr;
|
||||||
} else {
|
} else {
|
||||||
ide_setup_ports(&hw, (buddha_board+xsurf_bases[i]),
|
base = buddha_board + xsurf_bases[i];
|
||||||
xsurf_offsets, 0,
|
/* X-Surf has no CS1* (Control/AltStat) */
|
||||||
(buddha_board+xsurf_irqports[i]),
|
ctl = 0;
|
||||||
xsurf_ack_intr,
|
irq_port = buddha_board + xsurf_irqports[i];
|
||||||
// xsurf_iops,
|
ack_intr = xsurf_ack_intr;
|
||||||
IRQ_AMIGA_PORTS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr);
|
||||||
|
|
||||||
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
||||||
if (hwif) {
|
if (hwif) {
|
||||||
u8 index = hwif->index;
|
u8 index = hwif->index;
|
||||||
|
|
|
@ -33,22 +33,8 @@
|
||||||
* Offsets from the above base
|
* Offsets from the above base
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ATA_HD_DATA 0x00
|
|
||||||
#define ATA_HD_ERROR 0x05 /* see err-bits */
|
|
||||||
#define ATA_HD_NSECTOR 0x09 /* nr of sectors to read/write */
|
|
||||||
#define ATA_HD_SECTOR 0x0d /* starting sector */
|
|
||||||
#define ATA_HD_LCYL 0x11 /* starting cylinder */
|
|
||||||
#define ATA_HD_HCYL 0x15 /* high byte of starting cyl */
|
|
||||||
#define ATA_HD_SELECT 0x19 /* 101dhhhh , d=drive, hhhh=head */
|
|
||||||
#define ATA_HD_STATUS 0x1d /* see status-bits */
|
|
||||||
#define ATA_HD_CONTROL 0x39
|
#define ATA_HD_CONTROL 0x39
|
||||||
|
|
||||||
static int falconide_offsets[IDE_NR_PORTS] __initdata = {
|
|
||||||
ATA_HD_DATA, ATA_HD_ERROR, ATA_HD_NSECTOR, ATA_HD_SECTOR, ATA_HD_LCYL,
|
|
||||||
ATA_HD_HCYL, ATA_HD_SELECT, ATA_HD_STATUS, ATA_HD_CONTROL, -1
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* falconide_intr_lock is used to obtain access to the IDE interrupt,
|
* falconide_intr_lock is used to obtain access to the IDE interrupt,
|
||||||
* which is shared between several drivers.
|
* which is shared between several drivers.
|
||||||
|
@ -57,6 +43,22 @@ static int falconide_offsets[IDE_NR_PORTS] __initdata = {
|
||||||
int falconide_intr_lock;
|
int falconide_intr_lock;
|
||||||
EXPORT_SYMBOL(falconide_intr_lock);
|
EXPORT_SYMBOL(falconide_intr_lock);
|
||||||
|
|
||||||
|
static void __init falconide_setup_ports(hw_regs_t *hw)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(hw, 0, sizeof(*hw));
|
||||||
|
|
||||||
|
hw->io_ports[IDE_DATA_OFFSET] = ATA_HD_BASE;
|
||||||
|
|
||||||
|
for (i = 1; i < 8; i++)
|
||||||
|
hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4;
|
||||||
|
|
||||||
|
hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_CONTROL;
|
||||||
|
|
||||||
|
hw->irq = IRQ_MFP_IDE;
|
||||||
|
hw->ack_intr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Probe for a Falcon IDE interface
|
* Probe for a Falcon IDE interface
|
||||||
|
@ -64,16 +66,15 @@ EXPORT_SYMBOL(falconide_intr_lock);
|
||||||
|
|
||||||
static int __init falconide_init(void)
|
static int __init falconide_init(void)
|
||||||
{
|
{
|
||||||
if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) {
|
|
||||||
hw_regs_t hw;
|
hw_regs_t hw;
|
||||||
ide_hwif_t *hwif;
|
ide_hwif_t *hwif;
|
||||||
|
|
||||||
|
if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
|
||||||
|
return 0;
|
||||||
|
|
||||||
printk(KERN_INFO "ide: Falcon IDE controller\n");
|
printk(KERN_INFO "ide: Falcon IDE controller\n");
|
||||||
|
|
||||||
ide_setup_ports(&hw, ATA_HD_BASE, falconide_offsets,
|
falconide_setup_ports(&hw);
|
||||||
0, 0, NULL,
|
|
||||||
// falconide_iops,
|
|
||||||
IRQ_MFP_IDE);
|
|
||||||
|
|
||||||
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
||||||
if (hwif) {
|
if (hwif) {
|
||||||
|
@ -85,9 +86,8 @@ static int __init falconide_init(void)
|
||||||
|
|
||||||
ide_device_add(idx, NULL);
|
ide_device_add(idx, NULL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(falconide_init);
|
module_init(falconide_init);
|
||||||
|
|
|
@ -34,22 +34,8 @@
|
||||||
* Offsets from one of the above bases
|
* Offsets from one of the above bases
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GAYLE_DATA 0x00
|
|
||||||
#define GAYLE_ERROR 0x06 /* see err-bits */
|
|
||||||
#define GAYLE_NSECTOR 0x0a /* nr of sectors to read/write */
|
|
||||||
#define GAYLE_SECTOR 0x0e /* starting sector */
|
|
||||||
#define GAYLE_LCYL 0x12 /* starting cylinder */
|
|
||||||
#define GAYLE_HCYL 0x16 /* high byte of starting cyl */
|
|
||||||
#define GAYLE_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */
|
|
||||||
#define GAYLE_STATUS 0x1e /* see status-bits */
|
|
||||||
#define GAYLE_CONTROL 0x101a
|
#define GAYLE_CONTROL 0x101a
|
||||||
|
|
||||||
static int gayle_offsets[IDE_NR_PORTS] __initdata = {
|
|
||||||
GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL,
|
|
||||||
GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are at different offsets from the base
|
* These are at different offsets from the base
|
||||||
*/
|
*/
|
||||||
|
@ -106,6 +92,26 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
|
||||||
|
unsigned long ctl, unsigned long irq_port,
|
||||||
|
ide_ack_intr_t *ack_intr);
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(hw, 0, sizeof(*hw));
|
||||||
|
|
||||||
|
hw->io_ports[IDE_DATA_OFFSET] = base;
|
||||||
|
|
||||||
|
for (i = 1; i < 8; i++)
|
||||||
|
hw->io_ports[i] = base + 2 + i * 4;
|
||||||
|
|
||||||
|
hw->io_ports[IDE_CONTROL_OFFSET] = ctl;
|
||||||
|
hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
|
||||||
|
|
||||||
|
hw->irq = IRQ_AMIGA_PORTS;
|
||||||
|
hw->ack_intr = ack_intr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Probe for a Gayle IDE interface (and optionally for an IDE doubler)
|
* Probe for a Gayle IDE interface (and optionally for an IDE doubler)
|
||||||
*/
|
*/
|
||||||
|
@ -167,10 +173,7 @@ static int __init gayle_init(void)
|
||||||
base = (unsigned long)ZTWO_VADDR(phys_base);
|
base = (unsigned long)ZTWO_VADDR(phys_base);
|
||||||
ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
|
ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
|
||||||
|
|
||||||
ide_setup_ports(&hw, base, gayle_offsets,
|
gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr);
|
||||||
ctrlport, irqport, ack_intr,
|
|
||||||
// &gayle_iops,
|
|
||||||
IRQ_AMIGA_PORTS);
|
|
||||||
|
|
||||||
hwif = ide_find_port(base);
|
hwif = ide_find_port(base);
|
||||||
if (hwif) {
|
if (hwif) {
|
||||||
|
|
|
@ -421,11 +421,14 @@ static void bad_rw_intr(void)
|
||||||
|
|
||||||
static inline int wait_DRQ(void)
|
static inline int wait_DRQ(void)
|
||||||
{
|
{
|
||||||
int retries = 100000, stat;
|
int retries;
|
||||||
|
int stat;
|
||||||
|
|
||||||
while (--retries > 0)
|
for (retries = 0; retries < 100000; retries++) {
|
||||||
if ((stat = inb_p(HD_STATUS)) & DRQ_STAT)
|
stat = inb_p(HD_STATUS);
|
||||||
|
if (stat & DRQ_STAT)
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
dump_status("wait_DRQ", stat);
|
dump_status("wait_DRQ", stat);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,14 +31,6 @@
|
||||||
* These match MkLinux so they should be correct.
|
* These match MkLinux so they should be correct.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define IDE_DATA 0x00
|
|
||||||
#define IDE_ERROR 0x04 /* see err-bits */
|
|
||||||
#define IDE_NSECTOR 0x08 /* nr of sectors to read/write */
|
|
||||||
#define IDE_SECTOR 0x0c /* starting sector */
|
|
||||||
#define IDE_LCYL 0x10 /* starting cylinder */
|
|
||||||
#define IDE_HCYL 0x14 /* high byte of starting cyl */
|
|
||||||
#define IDE_SELECT 0x18 /* 101dhhhh , d=drive, hhhh=head */
|
|
||||||
#define IDE_STATUS 0x1c /* see status-bits */
|
|
||||||
#define IDE_CONTROL 0x38 /* control/altstatus */
|
#define IDE_CONTROL 0x38 /* control/altstatus */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -63,11 +55,6 @@
|
||||||
|
|
||||||
volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR);
|
volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR);
|
||||||
|
|
||||||
static int macide_offsets[IDE_NR_PORTS] = {
|
|
||||||
IDE_DATA, IDE_ERROR, IDE_NSECTOR, IDE_SECTOR, IDE_LCYL,
|
|
||||||
IDE_HCYL, IDE_SELECT, IDE_STATUS, IDE_CONTROL
|
|
||||||
};
|
|
||||||
|
|
||||||
int macide_ack_intr(ide_hwif_t* hwif)
|
int macide_ack_intr(ide_hwif_t* hwif)
|
||||||
{
|
{
|
||||||
if (*ide_ifr & 0x20) {
|
if (*ide_ifr & 0x20) {
|
||||||
|
@ -77,6 +64,22 @@ int macide_ack_intr(ide_hwif_t* hwif)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
|
||||||
|
int irq, ide_ack_intr_t *ack_intr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(hw, 0, sizeof(*hw));
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
hw->io_ports[i] = base + i * 4;
|
||||||
|
|
||||||
|
hw->io_ports[IDE_CONTROL_OFFSET] = IDE_CONTROL;
|
||||||
|
|
||||||
|
hw->irq = irq;
|
||||||
|
hw->ack_intr = ack_intr;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *mac_ide_name[] =
|
static const char *mac_ide_name[] =
|
||||||
{ "Quadra", "Powerbook", "Powerbook Baboon" };
|
{ "Quadra", "Powerbook", "Powerbook Baboon" };
|
||||||
|
|
||||||
|
@ -86,27 +89,27 @@ static const char *mac_ide_name[] =
|
||||||
|
|
||||||
static int __init macide_init(void)
|
static int __init macide_init(void)
|
||||||
{
|
{
|
||||||
hw_regs_t hw;
|
|
||||||
ide_hwif_t *hwif;
|
ide_hwif_t *hwif;
|
||||||
|
ide_ack_intr_t *ack_intr;
|
||||||
|
unsigned long base;
|
||||||
|
int irq;
|
||||||
|
hw_regs_t hw;
|
||||||
|
|
||||||
switch (macintosh_config->ide_type) {
|
switch (macintosh_config->ide_type) {
|
||||||
case MAC_IDE_QUADRA:
|
case MAC_IDE_QUADRA:
|
||||||
ide_setup_ports(&hw, IDE_BASE, macide_offsets,
|
base = IDE_BASE;
|
||||||
0, 0, macide_ack_intr,
|
ack_intr = macide_ack_intr;
|
||||||
// quadra_ide_iops,
|
irq = IRQ_NUBUS_F;
|
||||||
IRQ_NUBUS_F);
|
|
||||||
break;
|
break;
|
||||||
case MAC_IDE_PB:
|
case MAC_IDE_PB:
|
||||||
ide_setup_ports(&hw, IDE_BASE, macide_offsets,
|
base = IDE_BASE;
|
||||||
0, 0, macide_ack_intr,
|
ack_intr = macide_ack_intr;
|
||||||
// macide_pb_iops,
|
irq = IRQ_NUBUS_C;
|
||||||
IRQ_NUBUS_C);
|
|
||||||
break;
|
break;
|
||||||
case MAC_IDE_BABOON:
|
case MAC_IDE_BABOON:
|
||||||
ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
|
base = BABOON_BASE;
|
||||||
0, 0, NULL,
|
ack_intr = NULL;
|
||||||
// macide_baboon_iops,
|
irq = IRQ_BABOON_1;
|
||||||
IRQ_BABOON_1);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -115,6 +118,8 @@ static int __init macide_init(void)
|
||||||
printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
|
printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
|
||||||
mac_ide_name[macintosh_config->ide_type - 1]);
|
mac_ide_name[macintosh_config->ide_type - 1]);
|
||||||
|
|
||||||
|
macide_setup_ports(&hw, base, irq, ack_intr);
|
||||||
|
|
||||||
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
|
||||||
if (hwif) {
|
if (hwif) {
|
||||||
u8 index = hwif->index;
|
u8 index = hwif->index;
|
||||||
|
|
|
@ -66,16 +66,12 @@ static int q40ide_default_irq(unsigned long base)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is very similar to ide_setup_ports except that addresses
|
* Addresses are pretranslated for Q40 ISA access.
|
||||||
* are pretranslated for q40 ISA access
|
|
||||||
*/
|
*/
|
||||||
void q40_ide_setup_ports ( hw_regs_t *hw,
|
void q40_ide_setup_ports ( hw_regs_t *hw,
|
||||||
unsigned long base, int *offsets,
|
unsigned long base, int *offsets,
|
||||||
unsigned long ctrl, unsigned long intr,
|
unsigned long ctrl, unsigned long intr,
|
||||||
ide_ack_intr_t *ack_intr,
|
ide_ack_intr_t *ack_intr,
|
||||||
/*
|
|
||||||
* ide_io_ops_t *iops,
|
|
||||||
*/
|
|
||||||
int irq)
|
int irq)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -92,9 +88,6 @@ void q40_ide_setup_ports ( hw_regs_t *hw,
|
||||||
|
|
||||||
hw->irq = irq;
|
hw->irq = irq;
|
||||||
hw->ack_intr = ack_intr;
|
hw->ack_intr = ack_intr;
|
||||||
/*
|
|
||||||
* hw->iops = iops;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o
|
||||||
obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
|
obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
|
||||||
|
|
||||||
# Must appear at the end of the block
|
# Must appear at the end of the block
|
||||||
obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o
|
obj-$(CONFIG_BLK_DEV_GENERIC) += ide-pci-generic.o
|
||||||
|
ide-pci-generic-y += generic.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_BLK_DEV_CMD640), m)
|
ifeq ($(CONFIG_BLK_DEV_CMD640), m)
|
||||||
obj-m += cmd640.o
|
obj-m += cmd640.o
|
||||||
|
|
|
@ -29,19 +29,6 @@
|
||||||
|
|
||||||
static int ide_generic_all; /* Set to claim all devices */
|
static int ide_generic_all; /* Set to claim all devices */
|
||||||
|
|
||||||
/*
|
|
||||||
* the module_param_named() was added for the modular case
|
|
||||||
* the __setup() is left as compatibility for existing setups
|
|
||||||
*/
|
|
||||||
#ifndef MODULE
|
|
||||||
static int __init ide_generic_all_on(char *unused)
|
|
||||||
{
|
|
||||||
ide_generic_all = 1;
|
|
||||||
printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
const __setup("all-generic-ide", ide_generic_all_on);
|
|
||||||
#endif
|
|
||||||
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
|
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
|
||||||
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
|
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
|
||||||
|
|
||||||
|
|
|
@ -704,9 +704,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
|
||||||
hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104;
|
hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104;
|
||||||
hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108;
|
hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108;
|
||||||
hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100;
|
hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100;
|
||||||
hwif->sata_misc[SATA_MISC_OFFSET] = base + 0x140;
|
|
||||||
hwif->sata_misc[SATA_PHY_OFFSET] = base + 0x144;
|
|
||||||
hwif->sata_misc[SATA_IEN_OFFSET] = base + 0x148;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
|
memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
|
||||||
|
|
|
@ -78,12 +78,14 @@ struct media_bay_info {
|
||||||
int cached_gpio;
|
int cached_gpio;
|
||||||
int sleeping;
|
int sleeping;
|
||||||
struct semaphore lock;
|
struct semaphore lock;
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
void __iomem *cd_base;
|
void __iomem *cd_base;
|
||||||
int cd_index;
|
|
||||||
int cd_irq;
|
int cd_irq;
|
||||||
int cd_retry;
|
int cd_retry;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(CONFIG_BLK_DEV_IDE_PMAC) || defined(CONFIG_MAC_FLOPPY)
|
||||||
|
int cd_index;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_BAYS 2
|
#define MAX_BAYS 2
|
||||||
|
@ -91,7 +93,7 @@ struct media_bay_info {
|
||||||
static struct media_bay_info media_bays[MAX_BAYS];
|
static struct media_bay_info media_bays[MAX_BAYS];
|
||||||
int media_bay_count = 0;
|
int media_bay_count = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
/* check the busy bit in the media-bay ide interface
|
/* check the busy bit in the media-bay ide interface
|
||||||
(assumes the media-bay contains an ide device) */
|
(assumes the media-bay contains an ide device) */
|
||||||
#define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
|
#define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
|
||||||
|
@ -401,7 +403,7 @@ static void poll_media_bay(struct media_bay_info* bay)
|
||||||
set_mb_power(bay, id != MB_NO);
|
set_mb_power(bay, id != MB_NO);
|
||||||
bay->content_id = id;
|
bay->content_id = id;
|
||||||
if (id == MB_NO) {
|
if (id == MB_NO) {
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
bay->cd_retry = 0;
|
bay->cd_retry = 0;
|
||||||
#endif
|
#endif
|
||||||
printk(KERN_INFO "media bay %d is empty\n", bay->index);
|
printk(KERN_INFO "media bay %d is empty\n", bay->index);
|
||||||
|
@ -414,9 +416,9 @@ static void poll_media_bay(struct media_bay_info* bay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MAC_FLOPPY
|
||||||
int check_media_bay(struct device_node *which_bay, int what)
|
int check_media_bay(struct device_node *which_bay, int what)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<media_bay_count; i++)
|
for (i=0; i<media_bay_count; i++)
|
||||||
|
@ -426,14 +428,14 @@ int check_media_bay(struct device_node *which_bay, int what)
|
||||||
media_bays[i].cd_index = -1;
|
media_bays[i].cd_index = -1;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLK_DEV_IDE */
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(check_media_bay);
|
EXPORT_SYMBOL(check_media_bay);
|
||||||
|
#endif /* CONFIG_MAC_FLOPPY */
|
||||||
|
|
||||||
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
int check_media_bay_by_base(unsigned long base, int what)
|
int check_media_bay_by_base(unsigned long base, int what)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<media_bay_count; i++)
|
for (i=0; i<media_bay_count; i++)
|
||||||
|
@ -443,15 +445,13 @@ int check_media_bay_by_base(unsigned long base, int what)
|
||||||
media_bays[i].cd_index = -1;
|
media_bays[i].cd_index = -1;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
|
int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
|
||||||
int irq, int index)
|
int irq, int index)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<media_bay_count; i++) {
|
for (i=0; i<media_bay_count; i++) {
|
||||||
|
@ -483,10 +483,10 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLK_DEV_IDE */
|
|
||||||
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
|
||||||
|
|
||||||
static void media_bay_step(int i)
|
static void media_bay_step(int i)
|
||||||
{
|
{
|
||||||
|
@ -521,14 +521,13 @@ static void media_bay_step(int i)
|
||||||
bay->state = mb_resetting;
|
bay->state = mb_resetting;
|
||||||
MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id);
|
MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mb_resetting:
|
case mb_resetting:
|
||||||
if (bay->content_id != MB_CD) {
|
if (bay->content_id != MB_CD) {
|
||||||
MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
|
MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
|
||||||
bay->state = mb_up;
|
bay->state = mb_up;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
|
MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
|
||||||
bay->ops->un_reset_ide(bay);
|
bay->ops->un_reset_ide(bay);
|
||||||
bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
|
bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
|
||||||
|
@ -536,16 +535,14 @@ static void media_bay_step(int i)
|
||||||
#else
|
#else
|
||||||
printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
|
printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
|
||||||
set_mb_power(bay, 0);
|
set_mb_power(bay, 0);
|
||||||
#endif /* CONFIG_BLK_DEV_IDE */
|
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
|
||||||
case mb_ide_resetting:
|
case mb_ide_resetting:
|
||||||
bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT);
|
bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT);
|
||||||
bay->state = mb_ide_waiting;
|
bay->state = mb_ide_waiting;
|
||||||
MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id);
|
MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mb_ide_waiting:
|
case mb_ide_waiting:
|
||||||
if (bay->cd_base == NULL) {
|
if (bay->cd_base == NULL) {
|
||||||
bay->timer = 0;
|
bay->timer = 0;
|
||||||
|
@ -587,11 +584,10 @@ static void media_bay_step(int i)
|
||||||
bay->timer = 0;
|
bay->timer = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BLK_DEV_IDE */
|
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
|
||||||
|
|
||||||
case mb_powering_down:
|
case mb_powering_down:
|
||||||
bay->state = mb_empty;
|
bay->state = mb_empty;
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
if (bay->cd_index >= 0) {
|
if (bay->cd_index >= 0) {
|
||||||
printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
|
printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
|
||||||
bay->cd_index);
|
bay->cd_index);
|
||||||
|
@ -607,7 +603,7 @@ static void media_bay_step(int i)
|
||||||
bay->content_id = MB_NO;
|
bay->content_id = MB_NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLK_DEV_IDE */
|
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
|
||||||
MBDBG("mediabay%d: end of power down\n", i);
|
MBDBG("mediabay%d: end of power down\n", i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -739,7 +735,7 @@ static int media_bay_resume(struct macio_dev *mdev)
|
||||||
bay->last_value = bay->content_id;
|
bay->last_value = bay->content_id;
|
||||||
bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
|
bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
|
||||||
bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
|
bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
bay->cd_retry = 0;
|
bay->cd_retry = 0;
|
||||||
#endif
|
#endif
|
||||||
do {
|
do {
|
||||||
|
@ -829,7 +825,7 @@ static int __init media_bay_init(void)
|
||||||
for (i=0; i<MAX_BAYS; i++) {
|
for (i=0; i<MAX_BAYS; i++) {
|
||||||
memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
|
memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
|
||||||
media_bays[i].content_id = -1;
|
media_bays[i].content_id = -1;
|
||||||
#ifdef CONFIG_BLK_DEV_IDE
|
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||||
media_bays[i].cd_index = -1;
|
media_bays[i].cd_index = -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,7 +287,7 @@ static int idescsi_end_request(ide_drive_t *, int, int);
|
||||||
static ide_startstop_t
|
static ide_startstop_t
|
||||||
idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
|
idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
|
||||||
{
|
{
|
||||||
if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
|
if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
|
||||||
/* force an abort */
|
/* force an abort */
|
||||||
HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
|
HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the interrupt */
|
/* Clear the interrupt */
|
||||||
stat = drive->hwif->INB(IDE_STATUS_REG);
|
stat = ide_read_status(drive);
|
||||||
|
|
||||||
if ((stat & DRQ_STAT) == 0) {
|
if ((stat & DRQ_STAT) == 0) {
|
||||||
/* No more interrupts */
|
/* No more interrupts */
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
#define MB_NO 7 /* media bay contains nothing */
|
#define MB_NO 7 /* media bay contains nothing */
|
||||||
|
|
||||||
int check_media_bay(struct device_node *which_bay, int what);
|
int check_media_bay(struct device_node *which_bay, int what);
|
||||||
int check_media_bay_by_base(unsigned long base, int what);
|
|
||||||
|
|
||||||
/* Number of bays in the machine or 0 */
|
/* Number of bays in the machine or 0 */
|
||||||
extern int media_bay_count;
|
extern int media_bay_count;
|
||||||
|
|
||||||
/* called by pmac-ide.c to register IDE controller for media bay */
|
int check_media_bay_by_base(unsigned long base, int what);
|
||||||
extern int media_bay_set_ide_infos(struct device_node* which_bay,
|
/* called by IDE PMAC host driver to register IDE controller for media bay */
|
||||||
unsigned long base, int irq, int index);
|
int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base,
|
||||||
|
int irq, int index);
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _PPC_MEDIABAY_H */
|
#endif /* _PPC_MEDIABAY_H */
|
||||||
|
|
|
@ -115,10 +115,6 @@ typedef unsigned char byte; /* used everywhere */
|
||||||
#define SATA_ERROR_OFFSET (1)
|
#define SATA_ERROR_OFFSET (1)
|
||||||
#define SATA_CONTROL_OFFSET (2)
|
#define SATA_CONTROL_OFFSET (2)
|
||||||
|
|
||||||
#define SATA_MISC_OFFSET (0)
|
|
||||||
#define SATA_PHY_OFFSET (1)
|
|
||||||
#define SATA_IEN_OFFSET (2)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our Physical Region Descriptor (PRD) table should be large enough
|
* Our Physical Region Descriptor (PRD) table should be large enough
|
||||||
* to handle the biggest I/O request we are likely to see. Since requests
|
* to handle the biggest I/O request we are likely to see. Since requests
|
||||||
|
@ -173,7 +169,7 @@ enum { ide_unknown, ide_generic, ide_pci,
|
||||||
ide_rz1000, ide_trm290,
|
ide_rz1000, ide_trm290,
|
||||||
ide_cmd646, ide_cy82c693, ide_4drives,
|
ide_cmd646, ide_cy82c693, ide_4drives,
|
||||||
ide_pmac, ide_etrax100, ide_acorn,
|
ide_pmac, ide_etrax100, ide_acorn,
|
||||||
ide_au1xxx, ide_forced
|
ide_au1xxx, ide_palm3710, ide_forced
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef u8 hwif_chipset_t;
|
typedef u8 hwif_chipset_t;
|
||||||
|
@ -198,17 +194,6 @@ struct ide_drive_s;
|
||||||
int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *),
|
int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *),
|
||||||
struct hwif_s **);
|
struct hwif_s **);
|
||||||
|
|
||||||
void ide_setup_ports( hw_regs_t *hw,
|
|
||||||
unsigned long base,
|
|
||||||
int *offsets,
|
|
||||||
unsigned long ctrl,
|
|
||||||
unsigned long intr,
|
|
||||||
ide_ack_intr_t *ack_intr,
|
|
||||||
#if 0
|
|
||||||
ide_io_ops_t *iops,
|
|
||||||
#endif
|
|
||||||
int irq);
|
|
||||||
|
|
||||||
static inline void ide_std_init_ports(hw_regs_t *hw,
|
static inline void ide_std_init_ports(hw_regs_t *hw,
|
||||||
unsigned long io_addr,
|
unsigned long io_addr,
|
||||||
unsigned long ctl_addr)
|
unsigned long ctl_addr)
|
||||||
|
@ -473,7 +458,6 @@ typedef struct hwif_s {
|
||||||
/* task file registers for pata and sata */
|
/* task file registers for pata and sata */
|
||||||
unsigned long io_ports[IDE_NR_PORTS];
|
unsigned long io_ports[IDE_NR_PORTS];
|
||||||
unsigned long sata_scr[SATA_NR_PORTS];
|
unsigned long sata_scr[SATA_NR_PORTS];
|
||||||
unsigned long sata_misc[SATA_NR_PORTS];
|
|
||||||
|
|
||||||
ide_drive_t drives[MAX_DRIVES]; /* drive info */
|
ide_drive_t drives[MAX_DRIVES]; /* drive info */
|
||||||
|
|
||||||
|
@ -1014,7 +998,8 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o
|
||||||
void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *);
|
void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *);
|
||||||
void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
|
void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
|
/* FIXME: palm_bk3710 uses BLK_DEV_IDEDMA_PCI without BLK_DEV_IDEPCI! */
|
||||||
|
#if defined(CONFIG_BLK_DEV_IDEPCI) && defined(CONFIG_BLK_DEV_IDEDMA_PCI)
|
||||||
void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *);
|
void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *);
|
||||||
#else
|
#else
|
||||||
static inline void ide_hwif_setup_dma(ide_hwif_t *hwif,
|
static inline void ide_hwif_setup_dma(ide_hwif_t *hwif,
|
||||||
|
@ -1324,4 +1309,25 @@ static inline void ide_set_irq(ide_drive_t *drive, int on)
|
||||||
drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG);
|
drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u8 ide_read_status(ide_drive_t *drive)
|
||||||
|
{
|
||||||
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
|
|
||||||
|
return hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u8 ide_read_altstatus(ide_drive_t *drive)
|
||||||
|
{
|
||||||
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
|
|
||||||
|
return hwif->INB(hwif->io_ports[IDE_CONTROL_OFFSET]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u8 ide_read_error(ide_drive_t *drive)
|
||||||
|
{
|
||||||
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
|
|
||||||
|
return hwif->INB(hwif->io_ports[IDE_ERROR_OFFSET]);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _IDE_H */
|
#endif /* _IDE_H */
|
||||||
|
|
Loading…
Reference in a new issue