提交 551e4fb2 编写于 作者: L Linus Torvalds

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
  ...
......@@ -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
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 setting - this will print /all/
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
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
tristate "MPC8xx IDE support"
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_RAPIDE) += rapide.o
obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o
obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o
ifeq ($(CONFIG_IDE_ARM), m)
obj-m += ide_arm.o
......
......@@ -365,7 +365,7 @@ static void icside_dma_timeout(ide_drive_t *drive)
if (icside_dma_test_irq(drive))
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);
}
......
/*
* 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);
}
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 = {
.chipset = ide_etrax100,
.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)
{
hw_regs_t hw;
int ide_offsets[IDE_NR_PORTS], h, i;
int h;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
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++) {
ide_hwif_t *hwif = NULL;
ide_setup_ports(&hw, cris_ide_base_address(h),
ide_offsets,
0, 0, cris_ide_ack_intr,
ide_default_irq(0));
cris_setup_ports(&hw, cris_ide_base_address(h));
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif == NULL)
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)
{
struct device *dev = hwif->gendev.parent;
acpi_handle dev_handle;
acpi_handle uninitialized_var(dev_handle);
acpi_integer pcidevfn;
acpi_handle chan_handle;
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;
/* Check for errors. */
stat = HWIF(drive)->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
if (stat_ret)
*stat_ret = stat;
......@@ -303,7 +304,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
return 0;
/* Get the IDE error register. */
err = HWIF(drive)->INB(IDE_ERROR_REG);
err = ide_read_error(drive);
sense_key = err >> 4;
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
* info is available. just get it and ignore.
*/
(void) HWIF(drive)->INB(IDE_STATUS_REG);
(void)ide_read_status(drive);
return 0;
} else {
/* 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 (info->cd_flags & IDE_CD_FLAG_SEEKING) {
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 (elapsed < IDECD_SEEK_TIMEOUT) {
......
......@@ -147,7 +147,8 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
u8 stat = 0, dma_stat = 0;
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 (!dma_stat) {
struct request *rq = HWGROUP(drive)->rq;
......
......@@ -465,7 +465,7 @@ static void idefloppy_retry_pc(ide_drive_t *drive)
idefloppy_pc_t *pc;
struct request *rq;
(void)drive->hwif->INB(IDE_ERROR_REG);
(void)ide_read_error(drive);
pc = idefloppy_next_pc_storage(drive);
rq = idefloppy_next_rq_storage(drive);
idefloppy_create_request_sense_cmd(pc);
......@@ -501,7 +501,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
}
/* Clear the interrupt */
stat = drive->hwif->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
/* No more interrupts */
if ((stat & DRQ_STAT) == 0) {
......@@ -1246,7 +1246,7 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
u8 stat;
local_irq_save(flags);
stat = drive->hwif->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
local_irq_restore(flags);
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])
ide_get_lock(NULL, NULL); /* for atari only */
for (i = 0; i < MAX_HWIFS; i++)
idx[i] = ide_hwifs[i].present ? 0xff : i;
for (i = 0; i < MAX_HWIFS; 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);
......
......@@ -466,7 +466,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
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;
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 */
}
if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
/* force an abort */
hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
......@@ -821,9 +821,8 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
#ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
ide_end_drive_cmd(drive,
hwif->INB(IDE_STATUS_REG),
hwif->INB(IDE_ERROR_REG));
ide_end_drive_cmd(drive, ide_read_status(drive), ide_read_error(drive));
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);
(void)HWIF(drive)->ide_dma_end(drive);
ret = ide_error(drive, "dma timeout error",
hwif->INB(IDE_STATUS_REG));
ide_read_status(drive));
} else {
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
hwif->dma_timeout(drive);
......@@ -1355,7 +1354,8 @@ void ide_timer_expiry (unsigned long data)
startstop = ide_dma_timeout_retry(drive, wait);
} else
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;
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.
*/
if (IDE_CONTROL_REG)
stat = hwif->INB(IDE_ALTSTATUS_REG);
stat = ide_read_altstatus(drive);
else
/* Note: this may clear a pending IRQ!! */
stat = hwif->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
if (stat & BUSY_STAT)
/* 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)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
int i;
u8 stat;
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);
timeout += jiffies;
while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) {
while ((stat = ide_read_status(drive)) & BUSY_STAT) {
if (time_after(jiffies, timeout)) {
/*
* One last read after the timeout in case
* heavy interrupt load made us not make any
* progress during the timeout..
*/
stat = hwif->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
if (!(stat & BUSY_STAT))
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++) {
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;
return 0;
}
......@@ -617,6 +620,7 @@ int ide_driveid_update(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct hd_driveid *id;
unsigned long timeout, flags;
u8 stat;
/*
* Re-read drive->id for possible DMA mode
......@@ -633,10 +637,15 @@ int ide_driveid_update(ide_drive_t *drive)
SELECT_MASK(drive, 0);
return 0; /* drive timed-out */
}
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 */
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);
printk("%s: CHECK for good STATUS\n", drive->name);
return 0;
......@@ -649,7 +658,7 @@ int ide_driveid_update(ide_drive_t *drive)
return 0;
}
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_restore(flags);
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)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive);
u8 stat;
SELECT_DRIVE(drive);
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);
} else {
else {
if (time_before(jiffies, hwgroup->poll_timeout)) {
BUG_ON(HWGROUP(drive)->handler != NULL);
ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
/* continue polling */
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)) {
BUG_ON(HWGROUP(drive)->handler != NULL);
ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
/* continue polling */
return ide_started;
......@@ -909,7 +918,9 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
drive->failures++;
} else {
printk("%s: reset: ", hwif->name);
if ((tmp = hwif->INB(IDE_ERROR_REG)) == 1) {
tmp = ide_read_error(drive);
if (tmp == 1) {
printk("success\n");
drive->failures = 0;
} else {
......
......@@ -578,7 +578,7 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
}
printk("}\n");
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);
if (drive->media == ide_disk)
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)
{
ide_hwif_t *hwif = HWIF(drive);
int rc;
unsigned long hd_status;
int use_altstatus = 0, rc;
unsigned long timeout;
u8 s = 0, a = 0;
......@@ -273,19 +272,17 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
msleep(50);
if (IDE_CONTROL_REG) {
a = hwif->INB(IDE_ALTSTATUS_REG);
s = hwif->INB(IDE_STATUS_REG);
if ((a ^ s) & ~INDEX_STAT) {
printk(KERN_INFO "%s: probing with STATUS(0x%02x) instead of "
"ALTSTATUS(0x%02x)\n", drive->name, s, a);
a = ide_read_altstatus(drive);
s = ide_read_status(drive);
if ((a ^ s) & ~INDEX_STAT)
/* ancient Seagate drives, broken interfaces */
hd_status = IDE_STATUS_REG;
} else {
printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
"instead of ALTSTATUS(0x%02x)\n",
drive->name, s, a);
else
/* use non-intrusive polling */
hd_status = IDE_ALTSTATUS_REG;
use_altstatus = 1;
}
} else
hd_status = IDE_STATUS_REG;
/* set features register for atapi
* 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 */
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 */
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;
/* 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 */
rc = 0;
/* clear drive IRQ */
(void) hwif->INB(IDE_STATUS_REG);
(void)ide_read_status(drive);
local_irq_restore(flags);
} else {
/* drive refused ID */
......@@ -367,7 +368,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
ide_set_irq(drive, 0);
/* clear drive IRQ */
(void) hwif->INB(IDE_STATUS_REG);
(void)ide_read_status(drive);
udelay(5);
irq = probe_irq_off(cookie);
if (!hwif->irq) {
......@@ -455,7 +456,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
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) {
/* send cmd and wait */
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);
}
stat = hwif->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
if (stat == (BUSY_STAT | READY_STAT))
return 4;
......@@ -482,7 +485,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
}
/* ensure drive IRQ is clear */
stat = hwif->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
if (rc == 1)
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]);
msleep(50);
/* ensure drive irq is clear */
(void) hwif->INB(IDE_STATUS_REG);
(void)ide_read_status(drive);
}
return rc;
}
......@@ -521,7 +524,7 @@ static void enable_nest (ide_drive_t *drive)
msleep(50);
stat = hwif->INB(IDE_STATUS_REG);
stat = ide_read_status(drive);
if (!OK_STAT(stat, 0, BAD_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_pmac: name = "mac-io"; break;
case ide_au1xxx: name = "au1xxx"; break;
case ide_palm3710: name = "palm3710"; break;
case ide_etrax100: name = "etrax100"; break;
case ide_acorn: name = "acorn"; break;
default: name = "(unknown)"; break;
......
此差异已折叠。
......@@ -189,12 +189,11 @@ EXPORT_SYMBOL_GPL(do_rw_taskfile);
*/
static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 stat;
u8 stat = ide_read_status(drive);
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;
} else {
else {
drive->mult_req = drive->mult_count = 0;
drive->special.b.recalibrate = 1;
(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)
{
ide_hwif_t *hwif = HWIF(drive);
int retries = 5;
u8 stat;
while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
while (((stat = ide_read_status(drive)) & BUSY_STAT) && retries--)
udelay(10);
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)
{
ide_hwif_t *hwif = HWIF(drive);
u8 stat;
u8 stat = ide_read_status(drive);
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_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)
{
ide_task_t *args = HWGROUP(drive)->rq->special;
ide_hwif_t *hwif = HWIF(drive);
u8 stat;
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);
/* calls ide_end_drive_cmd */
}
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;
}
static u8 wait_drive_not_busy(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
int retries;
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.
*/
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);
else
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)
{
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);
return;
......@@ -430,7 +429,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
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 */
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;
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))
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);
/**
* 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)
{
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
};
/*
* 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 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
......@@ -140,6 +120,26 @@ static int xsurf_ack_intr(ide_hwif_t *hwif)
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
*/
......@@ -202,23 +202,25 @@ static int __init buddha_init(void)
printk(KERN_INFO "ide: %s IDE controller\n",
buddha_board_name[type]);
for(i=0;i<buddha_num_hwifs;i++) {
if(type != BOARD_XSURF) {
ide_setup_ports(&hw, (buddha_board+buddha_bases[i]),
buddha_offsets, 0,
(buddha_board+buddha_irqports[i]),
buddha_ack_intr,
// budda_iops,
IRQ_AMIGA_PORTS);
for (i = 0; i < buddha_num_hwifs; i++) {
unsigned long base, ctl, irq_port;
ide_ack_intr_t *ack_intr;
if (type != BOARD_XSURF) {
base = buddha_board + buddha_bases[i];
ctl = base + BUDDHA_CONTROL;
irq_port = buddha_board + buddha_irqports[i];
ack_intr = buddha_ack_intr;
} else {
ide_setup_ports(&hw, (buddha_board+xsurf_bases[i]),
xsurf_offsets, 0,
(buddha_board+xsurf_irqports[i]),
xsurf_ack_intr,
// xsurf_iops,
IRQ_AMIGA_PORTS);
base = buddha_board + xsurf_bases[i];
/* X-Surf has no CS1* (Control/AltStat) */
ctl = 0;
irq_port = buddha_board + xsurf_irqports[i];
ack_intr = xsurf_ack_intr;
}
buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr);
hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif) {
u8 index = hwif->index;
......
此差异已折叠。
此差异已折叠。
......@@ -421,11 +421,14 @@ static void bad_rw_intr(void)
static inline int wait_DRQ(void)
{
int retries = 100000, stat;
int retries;
int stat;
while (--retries > 0)
if ((stat = inb_p(HD_STATUS)) & DRQ_STAT)
for (retries = 0; retries < 100000; retries++) {
stat = inb_p(HD_STATUS);
if (stat & DRQ_STAT)
return 0;
}
dump_status("wait_DRQ", stat);
return -1;
}
......
此差异已折叠。
此差异已折叠。
......@@ -34,7 +34,8 @@ obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o
obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
# 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)
obj-m += cmd640.o
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册