Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6: (49 commits)
  drivers/ide: Fix continuation line formats
  ide: fixed section mismatch warning in cmd640.c
  ide: ide_timing_compute() fixup
  ide: make ide_get_best_pio_mode() static
  via82cxxx: use ->pio_mode value to determine pair device speed
  tx493xide: use ->pio_mode value to determine pair device speed
  siimage: use ->pio_mode value to determine pair device speed
  palm_bk3710: use ->pio_mode value to determine pair device speed
  it821x: use ->pio_mode value to determine pair device speed
  cs5536: use ->pio_mode value to determine pair device speed
  cs5535: use ->pio_mode value to determine pair device speed
  cmd64x: fix handling of address setup timings
  amd74xx: use ->pio_mode value to determine pair device speed
  alim15x3: fix handling of UDMA enable bit
  alim15x3: fix handling of DMA timings
  alim15x3: fix handling of command timings
  alim15x3: fix handling of address setup timings
  ide-timings: use ->pio_mode value to determine fastest PIO speed
  ide: change ->set_dma_mode method parameters
  ide: change ->set_pio_mode method parameters
  ...
This commit is contained in:
Linus Torvalds 2010-03-04 08:24:06 -08:00
Родитель 9bb676966a 950f564b70
Коммит 4c10c937cc
52 изменённых файлов: 615 добавлений и 676 удалений

Просмотреть файл

@ -159,42 +159,7 @@ two arguments: the CDROM device, and the slot number to which you wish
to change. If the slot number is -1, the drive is unloaded.
4. Compilation options
----------------------
There are a few additional options which can be set when compiling the
driver. Most people should not need to mess with any of these; they
are listed here simply for completeness. A compilation option can be
enabled by adding a line of the form `#define <option> 1' to the top
of ide-cd.c. All these options are disabled by default.
VERBOSE_IDE_CD_ERRORS
If this is set, ATAPI error codes will be translated into textual
descriptions. In addition, a dump is made of the command which
provoked the error. This is off by default to save the memory used
by the (somewhat long) table of error descriptions.
STANDARD_ATAPI
If this is set, the code needed to deal with certain drives which do
not properly implement the ATAPI spec will be disabled. If you know
your drive implements ATAPI properly, you can turn this on to get a
slightly smaller kernel.
NO_DOOR_LOCKING
If this is set, the driver will never attempt to lock the door of
the drive.
CDROM_NBLOCKS_BUFFER
This sets the size of the buffer to be used for a CDROMREADAUDIO
ioctl. The default is 8.
TEST
This currently enables an additional ioctl which enables a user-mode
program to execute an arbitrary packet command. See the source for
details. This should be left off unless you know what you're doing.
5. Common problems
4. Common problems
------------------
This section discusses some common problems encountered when trying to
@ -371,7 +336,7 @@ f. Data corruption.
expense of low system performance.
6. cdchange.c
5. cdchange.c
-------------
/*

Просмотреть файл

@ -81,15 +81,15 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
return chipset_table->ultra_settings;
}
static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
static void aec6210_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
u16 d_conf = 0;
u8 ultra = 0, ultra_conf = 0;
u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
const u8 speed = drive->dma_mode;
unsigned long flags;
local_irq_save(flags);
@ -109,15 +109,15 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
local_irq_restore(flags);
}
static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
static void aec6260_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
u8 unit = drive->dn & 1;
u8 tmp1 = 0, tmp2 = 0;
u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
const u8 speed = drive->dma_mode;
unsigned long flags;
local_irq_save(flags);
@ -134,9 +134,10 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
local_irq_restore(flags);
}
static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void aec_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
drive->dma_mode = drive->pio_mode;
hwif->port_ops->set_dma_mode(hwif, drive);
}
static int init_chipset_aec62xx(struct pci_dev *dev)

Просмотреть файл

@ -109,13 +109,14 @@ static DEFINE_SPINLOCK(ali14xx_lock);
* This function computes timing parameters
* and sets controller registers accordingly.
*/
static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void ali14xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int driveNum;
int time1, time2;
u8 param1, param2, param3, param4;
unsigned long flags;
int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
const u8 pio = drive->pio_mode - XFER_PIO_0;
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
/* calculate timing, according to PIO mode */

Просмотреть файл

@ -8,7 +8,7 @@
* Copyright (C) 2002 Alan Cox
* ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw>
* Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
* Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* (U)DMA capable version of ali 1533/1543(C), 1535(D)
*
@ -48,61 +48,84 @@ static u8 m5229_revision;
static u8 chip_is_1543c_e;
static struct pci_dev *isa_dev;
static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
int pio_fifo = 0x54 + hwif->channel;
u8 fifo;
int shift = 4 * (drive->dn & 1);
pci_read_config_byte(pdev, pio_fifo, &fifo);
fifo &= ~(0x0F << shift);
fifo |= (on << shift);
pci_write_config_byte(pdev, pio_fifo, fifo);
}
static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive,
struct ide_timing *t, u8 ultra)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
int port = hwif->channel ? 0x5c : 0x58;
int udmat = 0x56 + hwif->channel;
u8 unit = drive->dn & 1, udma;
int shift = 4 * unit;
/* Set up the UDMA */
pci_read_config_byte(dev, udmat, &udma);
udma &= ~(0x0F << shift);
udma |= ultra << shift;
pci_write_config_byte(dev, udmat, udma);
if (t == NULL)
return;
t->setup = clamp_val(t->setup, 1, 8) & 7;
t->act8b = clamp_val(t->act8b, 1, 8) & 7;
t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
t->active = clamp_val(t->active, 1, 8) & 7;
t->recover = clamp_val(t->recover, 1, 16) & 15;
pci_write_config_byte(dev, port, t->setup);
pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b);
pci_write_config_byte(dev, port + unit + 2,
(t->active << 4) | t->recover);
}
/**
* ali_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* Program the controller for the given PIO mode.
*/
static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
int s_time = t->setup, a_time = t->active, c_time = t->cycle;
u8 s_clc, a_clc, r_clc;
unsigned long flags;
ide_drive_t *pair = ide_get_pair_dev(drive);
int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
int port = hwif->channel ? 0x5c : 0x58;
int portFIFO = hwif->channel ? 0x55 : 0x54;
u8 cd_dma_fifo = 0, unit = drive->dn & 1;
unsigned long T = 1000000 / bus_speed; /* PCI clock based */
struct ide_timing t;
if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
s_clc = 0;
if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
a_clc = 0;
ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
if (pair) {
struct ide_timing p;
if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
r_clc = 1;
} else {
if (r_clc >= 16)
r_clc = 0;
ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
ide_timing_merge(&p, &t, &t,
IDE_TIMING_SETUP | IDE_TIMING_8BIT);
if (pair->dma_mode) {
ide_timing_compute(pair, pair->dma_mode, &p, T, 1);
ide_timing_merge(&p, &t, &t,
IDE_TIMING_SETUP | IDE_TIMING_8BIT);
}
}
local_irq_save(flags);
/*
* PIO mode => ATA FIFO on, ATAPI FIFO off
*/
pci_read_config_byte(dev, portFIFO, &cd_dma_fifo);
if (drive->media==ide_disk) {
if (unit) {
pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50);
} else {
pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05);
}
} else {
if (unit) {
pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F);
} else {
pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0);
}
}
pci_write_config_byte(dev, port, s_clc);
pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc);
local_irq_restore(flags);
ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00);
ali_program_timings(hwif, drive, &t, 0);
}
/**
@ -132,44 +155,42 @@ static u8 ali_udma_filter(ide_drive_t *drive)
/**
* ali_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Configure the hardware for the desired IDE transfer mode.
*/
static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD };
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 speed1 = speed;
u8 unit = drive->dn & 1;
ide_drive_t *pair = ide_get_pair_dev(drive);
int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
unsigned long T = 1000000 / bus_speed; /* PCI clock based */
const u8 speed = drive->dma_mode;
u8 tmpbyte = 0x00;
int m5229_udma = (hwif->channel) ? 0x57 : 0x56;
if (speed == XFER_UDMA_6)
speed1 = 0x47;
struct ide_timing t;
if (speed < XFER_UDMA_0) {
u8 ultra_enable = (unit) ? 0x7f : 0xf7;
/*
* clear "ultra enable" bit
*/
pci_read_config_byte(dev, m5229_udma, &tmpbyte);
tmpbyte &= ultra_enable;
pci_write_config_byte(dev, m5229_udma, tmpbyte);
ide_timing_compute(drive, drive->dma_mode, &t, T, 1);
if (pair) {
struct ide_timing p;
/*
* FIXME: Oh, my... DMA timings are never set.
*/
ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
ide_timing_merge(&p, &t, &t,
IDE_TIMING_SETUP | IDE_TIMING_8BIT);
if (pair->dma_mode) {
ide_timing_compute(pair, pair->dma_mode,
&p, T, 1);
ide_timing_merge(&p, &t, &t,
IDE_TIMING_SETUP | IDE_TIMING_8BIT);
}
}
ali_program_timings(hwif, drive, &t, 0);
} else {
pci_read_config_byte(dev, m5229_udma, &tmpbyte);
tmpbyte &= (0x0f << ((1-unit) << 2));
/*
* enable ultra dma and set timing
*/
tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2));
pci_write_config_byte(dev, m5229_udma, tmpbyte);
ali_program_timings(hwif, drive, NULL,
udma_timing[speed - XFER_UDMA_0]);
if (speed >= XFER_UDMA_3) {
pci_read_config_byte(dev, 0x4b, &tmpbyte);
tmpbyte |= 1;
@ -355,19 +376,13 @@ static int ali_cable_override(struct pci_dev *pdev)
*
* This checks if the controller and the cable are capable
* of UDMA66 transfers. It doesn't check the drives.
* But see note 2 below!
*
* FIXME: frobs bits that are not defined on newer ALi devicea
*/
static u8 ali_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
u8 cbl = ATA_CBL_PATA40, tmpbyte;
local_irq_save(flags);
if (m5229_revision >= 0xC2) {
/*
* m5229 80-pin cable detection (from Host View)
@ -387,8 +402,6 @@ static u8 ali_cable_detect(ide_hwif_t *hwif)
}
}
local_irq_restore(flags);
return cbl;
}
@ -584,6 +597,6 @@ static void __exit ali15x3_ide_exit(void)
module_init(ali15x3_ide_init);
module_exit(ali15x3_ide_exit);
MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox");
MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -3,7 +3,7 @@
* IDE driver for Linux.
*
* Copyright (c) 2000-2002 Vojtech Pavlik
* Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz
* Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
*
* Based on the work of:
* Andre Hedrick
@ -70,7 +70,8 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask,
default: return;
}
pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + (3 - dn), t);
if (timing->udma)
pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + 3 - dn, t);
}
/*
@ -78,14 +79,14 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask,
* to a desired transfer mode. It also can be called by upper layers.
*/
static void amd_set_drive(ide_drive_t *drive, const u8 speed)
static void amd_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
ide_drive_t *peer = ide_get_pair_dev(drive);
struct ide_timing t, p;
int T, UT;
u8 udma_mask = hwif->ultra_mask;
const u8 speed = drive->dma_mode;
T = 1000000000 / amd_clock;
UT = (udma_mask == ATA_UDMA2) ? T : (T / 2);
@ -93,7 +94,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
ide_timing_compute(drive, speed, &t, T, UT);
if (peer) {
ide_timing_compute(peer, peer->current_speed, &p, T, UT);
ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
@ -107,9 +108,10 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
* amd_set_pio_mode() is a callback from upper layers for PIO-only tuning.
*/
static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void amd_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
amd_set_drive(drive, XFER_PIO_0 + pio);
drive->dma_mode = drive->pio_mode;
amd_set_drive(hwif, drive);
}
static void amd7409_cable_detect(struct pci_dev *dev)
@ -340,6 +342,6 @@ static void __exit amd74xx_ide_exit(void)
module_init(amd74xx_ide_init);
module_exit(amd74xx_ide_exit);
MODULE_AUTHOR("Vojtech Pavlik");
MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("AMD PCI IDE driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -172,11 +172,12 @@ static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
leave_16bit(chipselect, mode);
}
static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void at91_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct ide_timing *timing;
u8 chipselect = drive->hwif->select_data;
u8 chipselect = hwif->select_data;
int use_iordy = 0;
const u8 pio = drive->pio_mode - XFER_PIO_0;
pdbg("chipselect %u pio %u\n", chipselect, pio);

Просмотреть файл

@ -42,19 +42,20 @@ static DEFINE_SPINLOCK(atiixp_lock);
/**
* atiixp_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* Set the interface PIO mode.
*/
static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void atiixp_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn ^ 1) * 8;
u32 pio_timing_data;
u16 pio_mode_data;
const u8 pio = drive->pio_mode - XFER_PIO_0;
spin_lock_irqsave(&atiixp_lock, flags);
@ -74,21 +75,22 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* atiixp_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Set a ATIIXP host controller to the desired DMA mode. This involves
* programming the right timing data into the PCI configuration space.
*/
static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void atiixp_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn ^ 1) * 8;
u32 tmp32;
u16 tmp16;
u16 udma_ctl = 0;
const u8 speed = drive->dma_mode;
spin_lock_irqsave(&atiixp_lock, flags);

Просмотреть файл

@ -99,12 +99,11 @@ static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
}
#endif
static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void au1xxx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
/* set pio mode! */
switch(pio) {
switch (drive->pio_mode - XFER_PIO_0) {
case 0:
mem_sttime = SBC_IDE_TIMING(PIO0);
@ -161,11 +160,11 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
au_writel(mem_stcfg,MEM_STCFG2);
}
static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void auide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
switch(speed) {
switch (drive->dma_mode) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
case XFER_MW_DMA_2:
mem_sttime = SBC_IDE_TIMING(MDMA2);
@ -297,8 +296,8 @@ static int auide_dma_test_irq(ide_drive_t *drive)
*/
drive->waiting_for_dma++;
if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
printk(KERN_WARNING "%s: timeout waiting for ddma to \
complete\n", drive->name);
printk(KERN_WARNING "%s: timeout waiting for ddma to complete\n",
drive->name);
return 1;
}
udelay(10);

Просмотреть файл

@ -572,9 +572,10 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
program_drive_counts(drive, index);
}
static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cmd640_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned int index = 0, cycle_time;
const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 b;
switch (pio) {
@ -605,7 +606,7 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
static void cmd640_init_dev(ide_drive_t *drive)
static void __init cmd640_init_dev(ide_drive_t *drive)
{
unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1);

Просмотреть файл

@ -7,6 +7,7 @@
* Copyright (C) 1998 David S. Miller (davem@redhat.com)
*
* Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
* Copyright (C) 2007,2009 MontaVista Software, Inc. <source@mvista.com>
*/
@ -50,72 +51,42 @@
#define UDIDETCR1 0x7B
#define DTPR1 0x7C
static u8 quantize_timing(int timing, int quant)
{
return (timing + quant - 1) / quant;
}
/*
* This routine calculates active/recovery counts and then writes them into
* the chipset registers.
*/
static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time)
static void cmd64x_program_timings(ide_drive_t *drive, u8 mode)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33);
u8 cycle_count, active_count, recovery_count, drwtim;
int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
const unsigned long T = 1000000 / bus_speed;
static const u8 recovery_values[] =
{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3};
struct ide_timing t;
u8 arttim = 0;
cycle_count = quantize_timing( cycle_time, clock_time);
active_count = quantize_timing(active_time, clock_time);
recovery_count = cycle_count - active_count;
ide_timing_compute(drive, mode, &t, T, 0);
/*
* In case we've got too long recovery phase, try to lengthen
* the active phase
*/
if (recovery_count > 16) {
active_count += recovery_count - 16;
recovery_count = 16;
if (t.recover > 16) {
t.active += t.recover - 16;
t.recover = 16;
}
if (active_count > 16) /* shouldn't actually happen... */
active_count = 16;
if (t.active > 16) /* shouldn't actually happen... */
t.active = 16;
/*
* Convert values to internal chipset representation
*/
recovery_count = recovery_values[recovery_count];
active_count &= 0x0f;
t.recover = recovery_values[t.recover];
t.active &= 0x0f;
/* Program the active/recovery counts into the DRWTIM register */
drwtim = (active_count << 4) | recovery_count;
(void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim);
}
/*
* This routine writes into the chipset registers
* PIO setup/active/recovery timings.
*/
static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
unsigned long setup_count;
unsigned int cycle_time;
u8 arttim = 0;
static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
cycle_time = ide_pio_cycle_time(drive, pio);
program_cycle_times(drive, cycle_time, t->active);
setup_count = quantize_timing(t->setup,
1000 / (ide_pci_clk ? ide_pci_clk : 33));
pci_write_config_byte(dev, drwtim_regs[drive->dn],
(t.active << 4) | t.recover);
/*
* The primary channel has individual address setup timing registers
@ -126,15 +97,21 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
if (hwif->channel) {
ide_drive_t *pair = ide_get_pair_dev(drive);
ide_set_drivedata(drive, (void *)setup_count);
if (pair) {
struct ide_timing tp;
if (pair)
setup_count = max_t(u8, setup_count,
(unsigned long)ide_get_drivedata(pair));
ide_timing_compute(pair, pair->pio_mode, &tp, T, 0);
ide_timing_merge(&t, &tp, &t, IDE_TIMING_SETUP);
if (pair->dma_mode) {
ide_timing_compute(pair, pair->dma_mode,
&tp, T, 0);
ide_timing_merge(&tp, &t, &t, IDE_TIMING_SETUP);
}
}
}
if (setup_count > 5) /* shouldn't actually happen... */
setup_count = 5;
if (t.setup > 5) /* shouldn't actually happen... */
t.setup = 5;
/*
* Program the address setup clocks into the ARTTIM registers.
@ -144,7 +121,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
if (hwif->channel)
arttim &= ~ARTTIM23_INTR_CH1;
arttim &= ~0xc0;
arttim |= setup_values[setup_count];
arttim |= setup_values[t.setup];
(void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
}
@ -153,8 +130,10 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
* Special cases are 8: prefetch off, 9: prefetch on (both never worked)
*/
static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cmd64x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* Filter out the prefetch control values
* to prevent PIO5 from being programmed
@ -162,20 +141,18 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
if (pio == 8 || pio == 9)
return;
cmd64x_tune_pio(drive, pio);
cmd64x_program_timings(drive, XFER_PIO_0 + pio);
}
static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void cmd64x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 unit = drive->dn & 0x01;
u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0;
const u8 speed = drive->dma_mode;
if (speed >= XFER_SW_DMA_0) {
(void) pci_read_config_byte(dev, pciU, &regU);
regU &= ~(unit ? 0xCA : 0x35);
}
pci_read_config_byte(dev, pciU, &regU);
regU &= ~(unit ? 0xCA : 0x35);
switch(speed) {
case XFER_UDMA_5:
@ -197,18 +174,13 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
regU |= unit ? 0xC2 : 0x31;
break;
case XFER_MW_DMA_2:
program_cycle_times(drive, 120, 70);
break;
case XFER_MW_DMA_1:
program_cycle_times(drive, 150, 80);
break;
case XFER_MW_DMA_0:
program_cycle_times(drive, 480, 215);
cmd64x_program_timings(drive, speed);
break;
}
if (speed >= XFER_SW_DMA_0)
(void) pci_write_config_byte(dev, pciU, regU);
pci_write_config_byte(dev, pciU, regU);
}
static void cmd648_clear_irq(ide_drive_t *drive)
@ -471,6 +443,6 @@ static void __exit cmd64x_ide_exit(void)
module_init(cmd64x_ide_init);
module_exit(cmd64x_ide_exit);
MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick");
MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for CMD64x IDE");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -57,11 +57,11 @@ static struct pio_clocks cs5520_pio_clocks[]={
{1, 2, 1}
};
static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cs5520_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *pdev = to_pci_dev(hwif->dev);
int controller = drive->dn > 1 ? 1 : 0;
const u8 pio = drive->pio_mode - XFER_PIO_0;
/* 8bit CAT/CRT - 8bit command timing for channel */
pci_write_config_byte(pdev, 0x62 + controller,
@ -81,11 +81,12 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
(cs5520_pio_clocks[pio].assert));
}
static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void cs5520_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
printk(KERN_ERR "cs55x0: bad ide timing.\n");
cs5520_set_pio_mode(drive, 0);
drive->pio_mode = XFER_PIO_0 + 0;
cs5520_set_pio_mode(hwif, drive);
}
static const struct ide_port_ops cs5520_port_ops = {

Просмотреть файл

@ -41,8 +41,8 @@ static unsigned int cs5530_pio_timings[2][5] = {
/**
* cs5530_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* Handles setting of PIO mode for the chipset.
*
@ -50,10 +50,11 @@ static unsigned int cs5530_pio_timings[2][5] = {
* will have valid default PIO timings set up before we get here.
*/
static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cs5530_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned long basereg = CS5530_BASEREG(drive->hwif);
unsigned long basereg = CS5530_BASEREG(hwif);
unsigned int format = (inl(basereg + 4) >> 31) & 1;
const u8 pio = drive->pio_mode - XFER_PIO_0;
outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
}
@ -99,12 +100,12 @@ out:
return mask;
}
static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void cs5530_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned long basereg;
unsigned int reg, timings = 0;
switch (mode) {
switch (drive->dma_mode) {
case XFER_UDMA_0: timings = 0x00921250; break;
case XFER_UDMA_1: timings = 0x00911140; break;
case XFER_UDMA_2: timings = 0x00911030; break;
@ -112,7 +113,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
case XFER_MW_DMA_1: timings = 0x00012121; break;
case XFER_MW_DMA_2: timings = 0x00002020; break;
}
basereg = CS5530_BASEREG(drive->hwif);
basereg = CS5530_BASEREG(hwif);
reg = inl(basereg + 4); /* get drive0 config register */
timings |= reg & 0x80000000; /* preserve PIO format bit */
if ((drive-> dn & 1) == 0) { /* are we configuring drive0? */

Просмотреть файл

@ -86,7 +86,7 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
cmd = pioa = speed - XFER_PIO_0;
if (pair) {
u8 piob = ide_get_best_pio_mode(pair, 255, 4);
u8 piob = pair->pio_mode - XFER_PIO_0;
if (piob < cmd)
cmd = piob;
@ -129,28 +129,28 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
/**
* cs5535_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Programs the chipset for DMA mode.
*/
static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void cs5535_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
cs5535_set_speed(drive, speed);
cs5535_set_speed(drive, drive->dma_mode);
}
/**
* cs5535_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* A callback from the upper layers for PIO-only tuning.
*/
static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cs5535_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
cs5535_set_speed(drive, XFER_PIO_0 + pio);
cs5535_set_speed(drive, drive->pio_mode);
}
static u8 cs5535_cable_detect(ide_hwif_t *hwif)

Просмотреть файл

@ -125,11 +125,11 @@ static u8 cs5536_cable_detect(ide_hwif_t *hwif)
/**
* cs5536_set_pio_mode - PIO timing setup
* @hwif: ATA port
* @drive: ATA device
* @pio: PIO mode number
*/
static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cs5536_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 drv_timings[5] = {
0x98, 0x55, 0x32, 0x21, 0x20,
@ -143,15 +143,16 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
0x99, 0x92, 0x90, 0x22, 0x20,
};
struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
struct pci_dev *pdev = to_pci_dev(hwif->dev);
ide_drive_t *pair = ide_get_pair_dev(drive);
int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
unsigned long timings = (unsigned long)ide_get_drivedata(drive);
u32 cast;
const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 cmd_pio = pio;
if (pair)
cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));
cmd_pio = min_t(u8, pio, pair->pio_mode - XFER_PIO_0);
timings &= (IDE_DRV_MASK << 8);
timings |= drv_timings[pio];
@ -172,11 +173,11 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* cs5536_set_dma_mode - DMA timing setup
* @hwif: ATA port
* @drive: ATA device
* @mode: DMA mode
*/
static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void cs5536_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 udma_timings[6] = {
0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
@ -186,10 +187,11 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
0x67, 0x21, 0x20,
};
struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
struct pci_dev *pdev = to_pci_dev(hwif->dev);
int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
unsigned long timings = (unsigned long)ide_get_drivedata(drive);
u32 etc;
const u8 mode = drive->dma_mode;
cs5536_read(pdev, ETC, &etc);

Просмотреть файл

@ -1,43 +1,11 @@
/*
* Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
* Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* CYPRESS CY82C693 chipset IDE controller
*
* The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
* Writing the driver was quite simple, since most of the job is
* done by the generic pci-ide support.
* The hard part was finding the CY82C693's datasheet on Cypress's
* web page :-(. But Altavista solved this problem :-).
*
*
* Notes:
* - I recently got a 16.8G IBM DTTA, so I was able to test it with
* a large and fast disk - the results look great, so I'd say the
* driver is working fine :-)
* hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
* - this is my first linux driver, so there's probably a lot of room
* for optimizations and bug fixing, so feel free to do it.
* - if using PIO mode it's a good idea to set the PIO mode and
* 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
* - I had some problems with my IBM DHEA with PIO modes < 2
* (lost interrupts) ?????
* - first tests with DMA look okay, they seem to work, but there is a
* problem with sound - the BusMaster IDE TimeOut should fixed this
*
* Ancient History:
* AMH@1999-08-24: v0.34 init_cy82c693_chip moved to pci_init_cy82c693
* ASK@1999-01-23: v0.33 made a few minor code clean ups
* removed DMA clock speed setting by default
* added boot message
* ASK@1998-11-01: v0.32 added support to set BusMaster IDE TimeOut
* added support to set DMA Controller Clock Speed
* ASK@1998-10-31: v0.31 fixed problem with setting to high DMA modes
* on some drives.
* ASK@1998-10-29: v0.3 added support to set DMA modes
* ASK@1998-10-28: v0.2 added support to set PIO modes
* ASK@1998-10-27: v0.1 first version - chipset detection
*
*/
#include <linux/module.h>
@ -81,87 +49,13 @@
#define CY82_INDEX_CHANNEL1 0x31
#define CY82_INDEX_TIMEOUT 0x32
/* the min and max PCI bus speed in MHz - from datasheet */
#define CY82C963_MIN_BUS_SPEED 25
#define CY82C963_MAX_BUS_SPEED 33
/* the struct for the PIO mode timings */
typedef struct pio_clocks_s {
u8 address_time; /* Address setup (clocks) */
u8 time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
u8 time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
u8 time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
} pio_clocks_t;
/*
* calc clocks using bus_speed
* returns (rounded up) time in bus clocks for time in ns
*/
static int calc_clk(int time, int bus_speed)
{
int clocks;
clocks = (time*bus_speed+999)/1000 - 1;
if (clocks < 0)
clocks = 0;
if (clocks > 0x0F)
clocks = 0x0F;
return clocks;
}
/*
* compute the values for the clock registers for PIO
* mode and pci_clk [MHz] speed
*
* NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used
* for mode 3 and 4 drives 8 and 16-bit timings are the same
*
*/
static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
{
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
int clk1, clk2;
int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
/* we don't check against CY82C693's min and max speed,
* so you can play with the idebus=xx parameter
*/
/* let's calc the address setup time clocks */
p_pclk->address_time = (u8)calc_clk(t->setup, bus_speed);
/* let's calc the active and recovery time clocks */
clk1 = calc_clk(t->active, bus_speed);
/* calc recovery timing */
clk2 = t->cycle - t->active - t->setup;
clk2 = calc_clk(clk2, bus_speed);
clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */
/* note: we use the same values for 16bit IOR and IOW
* those are all the same, since I don't have other
* timings than those from ide-lib.c
*/
p_pclk->time_16r = (u8)clk1;
p_pclk->time_16w = (u8)clk1;
/* what are good values for 8bit ?? */
p_pclk->time_8 = (u8)clk1;
}
/*
* set DMA mode a specific channel for CY82C693
*/
static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void cy82c693_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const u8 mode = drive->dma_mode;
u8 single = (mode & 0x10) >> 4, index = 0, data = 0;
index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0;
@ -186,12 +80,14 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
outb(data, CY82_DATA_PORT);
}
static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
pio_clocks_t pclk;
int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
const unsigned long T = 1000000 / bus_speed;
unsigned int addrCtrl;
struct ide_timing t;
u8 time_16, time_8;
/* select primary or secondary channel */
if (hwif->index > 0) { /* drive is on the secondary channel */
@ -204,8 +100,12 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
}
/* let's calc the values for this PIO mode */
compute_clocks(pio, &pclk);
ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
time_16 = clamp_val(t.recover - 1, 0, 15) |
(clamp_val(t.active - 1, 0, 15) << 4);
time_8 = clamp_val(t.act8b - 1, 0, 15) |
(clamp_val(t.rec8b - 1, 0, 15) << 4);
/* now let's write the clocks registers */
if ((drive->dn & 1) == 0) {
@ -217,13 +117,13 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF);
addrCtrl |= (unsigned int)pclk.address_time;
addrCtrl |= clamp_val(t.setup - 1, 0, 15);
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
/* now let's set the remaining registers */
pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, time_16);
pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, time_16);
pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, time_8);
} else {
/*
* set slave drive
@ -233,13 +133,13 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF0);
addrCtrl |= ((unsigned int)pclk.address_time<<4);
addrCtrl |= (clamp_val(t.setup - 1, 0, 15) << 4);
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
/* now let's set the remaining registers */
pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, time_16);
pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16);
pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8);
}
}
@ -325,6 +225,6 @@ static void __exit cy82c693_ide_exit(void)
module_init(cy82c693_ide_init);
module_exit(cy82c693_ide_exit);
MODULE_AUTHOR("Andreas Krebs, Andre Hedrick");
MODULE_AUTHOR("Andreas Krebs, Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for the Cypress CY82C693 IDE");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -68,11 +68,11 @@ static void sub22 (char b, char c)
static DEFINE_SPINLOCK(dtc2278_lock);
static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void dtc2278_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned long flags;
if (pio >= 3) {
if (drive->pio_mode >= XFER_PIO_3) {
spin_lock_irqsave(&dtc2278_lock, flags);
/*
* This enables PIO mode4 (3?) on the first interface

Просмотреть файл

@ -627,14 +627,14 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
return info->timings->clock_table[info->clock][i];
}
static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
static void hpt3xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
struct hpt_timings *t = info->timings;
u8 itr_addr = 0x40 + (drive->dn * 4);
u32 old_itr = 0;
const u8 speed = drive->dma_mode;
u32 new_itr = get_speed_setting(speed, info);
u32 itr_mask = speed < XFER_MW_DMA_0 ? t->pio_mask :
(speed < XFER_UDMA_0 ? t->dma_mask :
@ -651,9 +651,10 @@ static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_dword(dev, itr_addr, new_itr);
}
static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void hpt3xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
drive->dma_mode = drive->pio_mode;
hpt3xx_set_mode(hwif, drive);
}
static void hpt3xx_maskproc(ide_drive_t *drive, int mask)

Просмотреть файл

@ -279,9 +279,10 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
#endif
}
static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void ht6560b_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned long flags, config;
const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 timing;
switch (pio) {

Просмотреть файл

@ -65,6 +65,8 @@ static struct cardinfo icside_cardinfo_v6_2 = {
};
struct icside_state {
unsigned int channel;
unsigned int enabled;
void __iomem *irq_port;
void __iomem *ioc_base;
unsigned int sel;
@ -114,11 +116,18 @@ static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
struct icside_state *state = ec->irq_data;
void __iomem *base = state->irq_port;
writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
readb(base + ICS_ARCIN_V6_INTROFFSET_2);
state->enabled = 1;
writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
readb(base + ICS_ARCIN_V6_INTROFFSET_1);
switch (state->channel) {
case 0:
writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
readb(base + ICS_ARCIN_V6_INTROFFSET_2);
break;
case 1:
writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
readb(base + ICS_ARCIN_V6_INTROFFSET_1);
break;
}
}
/* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
@ -128,6 +137,8 @@ static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
{
struct icside_state *state = ec->irq_data;
state->enabled = 0;
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
}
@ -149,6 +160,44 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = {
.irqpending = icside_irqpending_arcin_v6,
};
/*
* Handle routing of interrupts. This is called before
* we write the command to the drive.
*/
static void icside_maskproc(ide_drive_t *drive, int mask)
{
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
unsigned long flags;
local_irq_save(flags);
state->channel = hwif->channel;
if (state->enabled && !mask) {
switch (hwif->channel) {
case 0:
writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
break;
case 1:
writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
break;
}
} else {
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
}
local_irq_restore(flags);
}
static const struct ide_port_ops icside_v6_no_dma_port_ops = {
.maskproc = icside_maskproc,
};
#ifdef CONFIG_BLK_DEV_IDEDMA_ICS
/*
* SG-DMA support.
@ -185,10 +234,11 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = {
* MW1 80 50 50 150 C
* MW2 70 25 25 120 C
*/
static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned long cycle_time;
int use_dma_info = 0;
const u8 xfer_mode = drive->dma_mode;
switch (xfer_mode) {
case XFER_MW_DMA_2:
@ -228,6 +278,7 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
static const struct ide_port_ops icside_v6_port_ops = {
.set_dma_mode = icside_set_dma_mode,
.maskproc = icside_maskproc,
};
static void icside_dma_host_set(ide_drive_t *drive, int on)
@ -271,6 +322,11 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
*/
BUG_ON(dma_channel_active(ec->dma));
/*
* Ensure that we have the right interrupt routed.
*/
icside_maskproc(drive, 0);
/*
* Route the DMA signals to the correct interface.
*/
@ -399,6 +455,7 @@ err_free:
static const struct ide_port_info icside_v6_port_info __initdata = {
.init_dma = icside_dma_off_init,
.port_ops = &icside_v6_no_dma_port_ops,
.dma_ops = &icside_v6_dma_ops,
.host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO,
.mwdma_mask = ATA_MWDMA2,

Просмотреть файл

@ -121,19 +121,11 @@ static int ide_probe(struct pcmcia_device *link)
static void ide_detach(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
ide_hwif_t *hwif = info->host->ports[0];
unsigned long data_addr, ctl_addr;
dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
data_addr = hwif->io_ports.data_addr;
ctl_addr = hwif->io_ports.ctl_addr;
ide_release(link);
release_region(ctl_addr, 1);
release_region(data_addr, 8);
kfree(info);
} /* ide_detach */
@ -354,12 +346,19 @@ static void ide_release(struct pcmcia_device *link)
dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
if (info->ndev)
/* FIXME: if this fails we need to queue the cleanup somehow
-- need to investigate the required PCMCIA magic */
ide_host_remove(host);
if (info->ndev) {
ide_hwif_t *hwif = host->ports[0];
unsigned long data_addr, ctl_addr;
info->ndev = 0;
data_addr = hwif->io_ports.data_addr;
ctl_addr = hwif->io_ports.ctl_addr;
ide_host_remove(host);
info->ndev = 0;
release_region(ctl_addr, 1);
release_region(data_addr, 8);
}
pcmcia_disable_device(link);
} /* ide_release */

Просмотреть файл

@ -105,15 +105,17 @@ static int set_pio_mode(ide_drive_t *drive, int arg)
return -ENOSYS;
if (set_pio_mode_abuse(drive->hwif, arg)) {
drive->pio_mode = arg + XFER_PIO_0;
if (arg == 8 || arg == 9) {
unsigned long flags;
/* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
spin_lock_irqsave(&hwif->lock, flags);
port_ops->set_pio_mode(drive, arg);
port_ops->set_pio_mode(hwif, drive);
spin_unlock_irqrestore(&hwif->lock, flags);
} else
port_ops->set_pio_mode(drive, arg);
port_ops->set_pio_mode(hwif, drive);
} else {
int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);

Просмотреть файл

@ -231,7 +231,7 @@ u8 eighty_ninty_three(ide_drive_t *drive)
u16 *id = drive->id;
int ivb = ide_in_drive_list(id, ivb_list);
if (hwif->cbl == ATA_CBL_PATA40_SHORT)
if (hwif->cbl == ATA_CBL_SATA || hwif->cbl == ATA_CBL_PATA40_SHORT)
return 1;
if (ivb)

Просмотреть файл

@ -1042,6 +1042,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
drive->pio_mode = XFER_PIO_0;
if (port_ops && port_ops->init_dev)
port_ops->init_dev(drive);
}

Просмотреть файл

@ -1365,7 +1365,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
* supported here, and not in the corresponding block interface. Our own
* ide-tape ioctls are supported on both interfaces.
*/
static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
static long do_idetape_chrdev_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct ide_tape_obj *tape = file->private_data;
@ -1420,6 +1420,16 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
}
}
static long idetape_chrdev_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
long ret;
lock_kernel();
ret = do_idetape_chrdev_ioctl(file, cmd, arg);
unlock_kernel();
return ret;
}
/*
* Do a mode sense page 0 with block descriptor and if it succeeds set the tape
* block size with the reported value.
@ -1888,7 +1898,7 @@ static const struct file_operations idetape_fops = {
.owner = THIS_MODULE,
.read = idetape_chrdev_read,
.write = idetape_chrdev_write,
.ioctl = idetape_chrdev_ioctl,
.unlocked_ioctl = idetape_chrdev_ioctl,
.open = idetape_chrdev_open,
.release = idetape_chrdev_release,
};

Просмотреть файл

@ -166,12 +166,13 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */
memset(&p, 0, sizeof(p));
if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
else if ((speed <= XFER_PIO_4) ||
(speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) {
if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
else if ((speed <= XFER_PIO_4) ||
(speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
} else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
p.cycle = id[ATA_ID_EIDE_DMA_MIN];
ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
@ -185,11 +186,10 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
/*
* Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
* S.M.A.R.T and some other commands. We have to ensure that the
* DMA cycle timing is slower/equal than the fastest PIO timing.
* DMA cycle timing is slower/equal than the current PIO timing.
*/
if (speed >= XFER_SW_DMA_0) {
u8 pio = ide_get_best_pio_mode(drive, 255, 5);
ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT);
ide_timing_compute(drive, drive->pio_mode, &p, T, UT);
ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
}

Просмотреть файл

@ -58,7 +58,7 @@ EXPORT_SYMBOL(ide_xfer_verbose);
* This is used by most chipset support modules when "auto-tuning".
*/
u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
static u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
{
u16 *id = drive->id;
int pio_mode = -1, overridden = 0;
@ -105,7 +105,6 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
return pio_mode;
}
EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio)
{
@ -135,17 +134,20 @@ int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
* set transfer mode on the device in ->set_pio_mode method...
*/
if (port_ops->set_dma_mode == NULL) {
port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
drive->pio_mode = mode;
port_ops->set_pio_mode(hwif, drive);
return 0;
}
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
drive->pio_mode = mode;
port_ops->set_pio_mode(hwif, drive);
return 0;
} else {
port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
drive->pio_mode = mode;
port_ops->set_pio_mode(hwif, drive);
return ide_config_drive_speed(drive, mode);
}
}
@ -164,10 +166,12 @@ int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
port_ops->set_dma_mode(drive, mode);
drive->dma_mode = mode;
port_ops->set_dma_mode(hwif, drive);
return 0;
} else {
port_ops->set_dma_mode(drive, mode);
drive->dma_mode = mode;
port_ops->set_dma_mode(hwif, drive);
return ide_config_drive_speed(drive, mode);
}
}

Просмотреть файл

@ -37,12 +37,12 @@
#define DRV_NAME "IT8172"
static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void it8172_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u16 drive_enables;
u32 drive_timing;
const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* The highest value of DIOR/DIOW pulse width and recovery time
@ -77,14 +77,14 @@ static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_write_config_dword(dev, 0x44, drive_timing);
}
static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void it8172_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int a_speed = 3 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int u_speed = 0;
u8 reg48, reg4a;
const u8 speed = drive->dma_mode;
pci_read_config_byte(dev, 0x48, &reg48);
pci_read_config_byte(dev, 0x4a, &reg4a);
@ -98,14 +98,14 @@ static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
u8 pio;
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
drive->pio_mode =
mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
it8172_set_pio_mode(drive, pio);
it8172_set_pio_mode(hwif, drive);
}
}

Просмотреть файл

@ -17,15 +17,14 @@
/**
* it8213_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* Set the interface PIO mode.
*/
static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void it8213_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int is_slave = drive->dn & 1;
int master_port = 0x40;
@ -35,6 +34,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
u8 slave_data;
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
const u8 pio = drive->pio_mode - XFER_PIO_0;
static const u8 timings[][2] = {
{ 0, 0 },
@ -74,15 +74,14 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* it8213_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Tune the ITE chipset for the DMA mode.
*/
static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void it8213_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 maslave = 0x40;
int a_speed = 3 << (drive->dn * 4);
@ -92,6 +91,7 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
int u_speed = 0;
u16 reg4042, reg4a;
u8 reg48, reg54, reg55;
const u8 speed = drive->dma_mode;
pci_read_config_word(dev, maslave, &reg4042);
pci_read_config_byte(dev, 0x48, &reg48);
@ -120,7 +120,6 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
u8 pio;
if (reg48 & u_flag)
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
@ -132,11 +131,12 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
if (speed >= XFER_MW_DMA_0)
pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
drive->pio_mode =
mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
else
pio = 2; /* only SWDMA2 is allowed */
drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
it8213_set_pio_mode(drive, pio);
it8213_set_pio_mode(hwif, drive);
}
}

Просмотреть файл

@ -228,18 +228,18 @@ static void it821x_clock_strategy(ide_drive_t *drive)
/**
* it821x_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* Tune the host to the desired PIO mode taking into the consideration
* the maximum PIO mode supported by the other device on the cable.
*/
static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void it821x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct it821x_dev *itdev = ide_get_hwifdata(hwif);
ide_drive_t *pair = ide_get_pair_dev(drive);
const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 unit = drive->dn & 1, set_pio = pio;
/* Spec says 89 ref driver uses 88 */
@ -252,7 +252,7 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
* on the cable.
*/
if (pair) {
u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
u8 pair_pio = pair->pio_mode - XFER_PIO_0;
/* trim PIO to the slowest of the master/slave */
if (pair_pio < set_pio)
set_pio = pair_pio;
@ -393,14 +393,16 @@ static int it821x_dma_end(ide_drive_t *drive)
/**
* it821x_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Tune the ITE chipset for the desired DMA mode.
*/
static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void it821x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
const u8 speed = drive->dma_mode;
/*
* MWDMA tuning is really hard because our MWDMA and PIO
* timings are kept in the same place. We can switch in the

Просмотреть файл

@ -80,19 +80,19 @@ static u8 jmicron_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void jmicron_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
}
/**
* jmicron_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @mode: DMA mode
*
* As the JMicron snoops for timings we don't need to do anything here.
*/
static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void jmicron_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
}

Просмотреть файл

@ -8,77 +8,6 @@
* Jan Harkes <jaharkes@cwi.nl>,
* Mark Lord <mlord@pobox.com>
* Some parts of code are from ali14xx.c and from rz1000.c.
*
* OPTi is trademark of OPTi, Octek is trademark of Octek.
*
* I used docs from OPTi databook, from ftp.opti.com, file 9123-0002.ps
* and disassembled/traced setupvic.exe (DOS program).
* It increases kernel code about 2 kB.
* I don't have this card no more, but I hope I can get some in case
* of needed development.
* My card is Octek PIDE 1.01 (on card) or OPTiViC (program).
* It has a place for a secondary connector in circuit, but nothing
* is there. Also BIOS says no address for
* secondary controller (see bellow in ide_init_opti621).
* I've only tested this on my system, which only has one disk.
* It's Western Digital WDAC2850, with PIO mode 3. The PCI bus
* is at 20 MHz (I have DX2/80, I tried PCI at 40, but I got random
* lockups). I tried the OCTEK double speed CD-ROM and
* it does not work! But I can't boot DOS also, so it's probably
* hardware fault. I have connected Conner 80MB, the Seagate 850MB (no
* problems) and Seagate 1GB (as slave, WD as master). My experiences
* with the third, 1GB drive: I got 3MB/s (hdparm), but sometimes
* it slows to about 100kB/s! I don't know why and I have
* not this drive now, so I can't try it again.
* I write this driver because I lost the paper ("manual") with
* settings of jumpers on the card and I have to boot Linux with
* Loadlin except LILO, cause I have to run the setupvic.exe program
* already or I get disk errors (my test: rpm -Vf
* /usr/X11R6/bin/XF86_SVGA - or any big file).
* Some numbers from hdparm -t /dev/hda:
* Timing buffer-cache reads: 32 MB in 3.02 seconds =10.60 MB/sec
* Timing buffered disk reads: 16 MB in 5.52 seconds = 2.90 MB/sec
* I have 4 Megs/s before, but I don't know why (maybe changes
* in hdparm test).
* After release of 0.1, I got some successful reports, so it might work.
*
* The main problem with OPTi is that some timings for master
* and slave must be the same. For example, if you have master
* PIO 3 and slave PIO 0, driver have to set some timings of
* master for PIO 0. Second problem is that opti621_set_pio_mode
* got only one drive to set, but have to set both drives.
* This is solved in compute_pios. If you don't set
* the second drive, compute_pios use ide_get_best_pio_mode
* for autoselect mode (you can change it to PIO 0, if you want).
* If you then set the second drive to another PIO, the old value
* (automatically selected) will be overrided by yours.
* There is a 25/33MHz switch in configuration
* register, but driver is written for use at any frequency.
*
* Version 0.1, Nov 8, 1996
* by Jaromir Koutek, for 2.1.8.
* Initial version of driver.
*
* Version 0.2
* Number 0.2 skipped.
*
* Version 0.3, Nov 29, 1997
* by Mark Lord (probably), for 2.1.68
* Updates for use with new IDE block driver.
*
* Version 0.4, Dec 14, 1997
* by Jan Harkes
* Fixed some errors and cleaned the code.
*
* Version 0.5, Jan 2, 1998
* by Jaromir Koutek
* Updates for use with (again) new IDE block driver.
* Update of documentation.
*
* Version 0.6, Jan 2, 1999
* by Jaromir Koutek
* Reversed to version 0.3 of the driver, because
* 0.5 doesn't work.
*/
#include <linux/types.h>
@ -133,12 +62,12 @@ static u8 read_reg(int reg)
return ret;
}
static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void opti621_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
ide_drive_t *pair = ide_get_pair_dev(drive);
unsigned long flags;
unsigned long mode = XFER_PIO_0 + pio, pair_mode;
unsigned long mode = drive->pio_mode, pair_mode;
const u8 pio = mode - XFER_PIO_0;
u8 tim, misc, addr_pio = pio, clk;
/* DRDY is default 2 (by OPTi Databook) */

Просмотреть файл

@ -166,7 +166,7 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
writel(val32, base + BK3710_DATRCVR);
if (mate) {
u8 mode2 = ide_get_best_pio_mode(mate, 255, 4);
u8 mode2 = mate->pio_mode - XFER_PIO_0;
if (mode2 < mode)
mode = mode2;
@ -188,10 +188,11 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
writel(val32, base + BK3710_REGRCVR);
}
static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
static void palm_bk3710_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int is_slave = drive->dn & 1;
void __iomem *base = (void *)drive->hwif->dma_base;
void __iomem *base = (void *)hwif->dma_base;
const u8 xferspeed = drive->dma_mode;
if (xferspeed >= XFER_UDMA_0) {
palm_bk3710_setudmamode(base, is_slave,
@ -203,12 +204,13 @@ static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
}
}
static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
static void palm_bk3710_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned int cycle_time;
int is_slave = drive->dn & 1;
ide_drive_t *mate;
void __iomem *base = (void *)drive->hwif->dma_base;
void __iomem *base = (void *)hwif->dma_base;
const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* Obtain the drive PIO data for tuning the Palm Chip registers

Просмотреть файл

@ -129,11 +129,11 @@ static struct udma_timing {
{ 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */
};
static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void pdcnew_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
const u8 speed = drive->dma_mode;
/*
* IDE core issues SETFEATURES_XFER to the drive first (thanks to
@ -167,11 +167,11 @@ static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
}
static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void pdcnew_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
const u8 pio = drive->pio_mode - XFER_PIO_0;
if (max_dma_rate(dev) == 4) {
set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c);

Просмотреть файл

@ -1,7 +1,7 @@
/*
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007, 2009 MontaVista Software, Inc.
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
* Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* Portions Copyright (C) 1999 Promise Technology, Inc.
* Author: Frank Tiernan (frankt@promise.com)
@ -21,23 +21,15 @@
#define DRV_NAME "pdc202xx_old"
static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
static void pdc202xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 drive_pci = 0x60 + (drive->dn << 2);
const u8 speed = drive->dma_mode;
u8 AP = 0, BP = 0, CP = 0;
u8 TA = 0, TB = 0, TC = 0;
/*
* TODO: do this once per channel
*/
if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
pdc_old_disable_66MHz_clock(hwif);
pci_read_config_byte(dev, drive_pci, &AP);
pci_read_config_byte(dev, drive_pci + 1, &BP);
pci_read_config_byte(dev, drive_pci + 2, &CP);
@ -84,9 +76,10 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
}
}
static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void pdc202xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
drive->dma_mode = drive->pio_mode;
pdc202xx_set_mode(hwif, drive);
}
static int pdc202xx_test_irq(ide_hwif_t *hwif)
@ -100,13 +93,13 @@ static int pdc202xx_test_irq(ide_hwif_t *hwif)
* bit 7: error, bit 6: interrupting,
* bit 5: FIFO full, bit 4: FIFO empty
*/
return ((sc1d & 0x50) == 0x40) ? 1 : 0;
return ((sc1d & 0x50) == 0x50) ? 1 : 0;
} else {
/*
* bit 3: error, bit 2: interrupting,
* bit 1: FIFO full, bit 0: FIFO empty
*/
return ((sc1d & 0x05) == 0x04) ? 1 : 0;
return ((sc1d & 0x05) == 0x05) ? 1 : 0;
}
}
@ -145,6 +138,11 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
}
static void pdc2026x_init_hwif(ide_hwif_t *hwif)
{
pdc_old_disable_66MHz_clock(hwif);
}
static void pdc202xx_dma_start(ide_drive_t *drive)
{
if (drive->current_speed > XFER_UDMA_2)
@ -261,6 +259,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_pdc202xx, \
.init_hwif = pdc2026x_init_hwif, \
.port_ops = &pdc2026x_port_ops, \
.dma_ops = &pdc2026x_dma_ops, \
.host_flags = IDE_HFLAGS_PDC202XX, \
@ -356,6 +355,6 @@ static void __exit pdc202xx_ide_exit(void)
module_init(pdc202xx_ide_init);
module_exit(pdc202xx_ide_exit);
MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for older Promise IDE");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -59,15 +59,14 @@ static int no_piix_dma;
/**
* piix_set_pio_mode - set host controller for PIO mode
* @port: port
* @drive: drive
* @pio: PIO mode number
*
* Set the interface PIO mode based upon the settings done by AMI BIOS.
*/
static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void piix_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int is_slave = drive->dn & 1;
int master_port = hwif->channel ? 0x42 : 0x40;
@ -77,6 +76,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
u8 slave_data;
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
const u8 pio = drive->pio_mode - XFER_PIO_0;
/* ISP RTC */
static const u8 timings[][2]= {
@ -127,16 +127,15 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* piix_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Set a PIIX host controller to the desired DMA mode. This involves
* programming the right timing data into the PCI configuration space.
*/
static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void piix_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 maslave = hwif->channel ? 0x42 : 0x40;
int a_speed = 3 << (drive->dn * 4);
@ -147,6 +146,7 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
int sitre;
u16 reg4042, reg4a;
u8 reg48, reg54, reg55;
const u8 speed = drive->dma_mode;
pci_read_config_word(dev, maslave, &reg4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
@ -176,7 +176,6 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
u8 pio;
if (reg48 & u_flag)
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
@ -188,11 +187,12 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
if (speed >= XFER_MW_DMA_0)
pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
drive->pio_mode =
mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
else
pio = 2; /* only SWDMA2 is allowed */
drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
piix_set_pio_mode(drive, pio);
piix_set_pio_mode(hwif, drive);
}
}

Просмотреть файл

@ -496,12 +496,11 @@ static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
/*
* Old tuning functions (called on hdparm -p), sets up drive PIO timings
*/
static void
pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void pmac_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
const u8 pio = drive->pio_mode - XFER_PIO_0;
struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
u32 *timings, t;
unsigned accessTicks, recTicks;
@ -778,14 +777,14 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
#endif
}
static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void pmac_ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
int ret = 0;
u32 *timings, *timings2, tl[2];
u8 unit = drive->dn & 1;
const u8 speed = drive->dma_mode;
timings = &pmif->timings[unit];
timings2 = &pmif->timings[unit+2];
@ -1651,8 +1650,8 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
if ((status & FLUSH) == 0)
break;
if (++timeout > 100) {
printk(KERN_WARNING "ide%d, ide_dma_test_irq \
timeout flushing channel\n", hwif->index);
printk(KERN_WARNING "ide%d, ide_dma_test_irq timeout flushing channel\n",
hwif->index);
break;
}
}

Просмотреть файл

@ -189,15 +189,13 @@ static void qd_set_timing (ide_drive_t *drive, u8 timing)
printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
}
static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void qd6500_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
u16 *id = drive->id;
int active_time = 175;
int recovery_time = 415; /* worst case values from the dos driver */
/*
* FIXME: use "pio" value
*/
/* FIXME: use drive->pio_mode value */
if (!qd_find_disk_type(drive, &active_time, &recovery_time) &&
(id[ATA_ID_OLD_PIO_MODES] & 0xff) && (id[ATA_ID_FIELD_VALID] & 2) &&
id[ATA_ID_EIDE_PIO] >= 240) {
@ -211,9 +209,9 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
active_time, recovery_time));
}
static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void qd6580_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const u8 pio = drive->pio_mode - XFER_PIO_0;
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
unsigned int cycle_time;
int active_time = 175;

Просмотреть файл

@ -122,13 +122,13 @@ out:
return mask;
}
static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void sc1200_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned int reg, timings;
unsigned short pci_clock;
unsigned int basereg = hwif->channel ? 0x50 : 0x40;
const u8 mode = drive->dma_mode;
static const u32 udma_timing[3][3] = {
{ 0x00921250, 0x00911140, 0x00911030 },
@ -193,10 +193,10 @@ static int sc1200_dma_end(ide_drive_t *drive)
* will have valid default PIO timings set up before we get here.
*/
static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void sc1200_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
int mode = -1;
const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* bad abuse of ->set_pio_mode interface

Просмотреть файл

@ -199,16 +199,15 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
/**
* scc_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* Load the timing settings for this device mode into the
* controller.
*/
static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct scc_ports *ports = ide_get_hwifdata(hwif);
unsigned long ctl_base = ports->ctl;
unsigned long cckctrl_port = ctl_base + 0xff0;
@ -216,6 +215,7 @@ static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
unsigned long pioct_port = ctl_base + 0x004;
unsigned long reg;
int offset;
const u8 pio = drive->pio_mode - XFER_PIO_0;
reg = in_be32((void __iomem *)cckctrl_port);
if (reg & CCKCTRL_ATACLKOEN) {
@ -231,16 +231,15 @@ static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* scc_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Load the timing settings for this device mode into the
* controller.
*/
static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct scc_ports *ports = ide_get_hwifdata(hwif);
unsigned long ctl_base = ports->ctl;
unsigned long cckctrl_port = ctl_base + 0xff0;
@ -254,6 +253,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
int offset, idx;
unsigned long reg;
unsigned long jcactsel;
const u8 speed = drive->dma_mode;
reg = in_be32((void __iomem *)cckctrl_port);
if (reg & CCKCTRL_ATACLKOEN) {
@ -872,20 +872,18 @@ static struct pci_driver scc_pci_driver = {
.remove = __devexit_p(scc_remove),
};
static int scc_ide_init(void)
static int __init scc_ide_init(void)
{
return ide_pci_register_driver(&scc_pci_driver);
}
module_init(scc_ide_init);
/* -- No exit code?
static void scc_ide_exit(void)
static void __exit scc_ide_exit(void)
{
ide_pci_unregister_driver(&scc_pci_driver);
pci_unregister_driver(&scc_pci_driver);
}
module_exit(scc_ide_exit);
*/
module_init(scc_ide_init);
module_exit(scc_ide_exit);
MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -2,7 +2,7 @@
* Copyright (C) 1998-2000 Michel Aubry
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
* Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
* Portions copyright (c) 2001 Sun Microsystems
*
*
@ -52,8 +52,6 @@ static const char *svwks_bad_ata100[] = {
NULL
};
static struct pci_dev *isa_dev;
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
char *m = (char *)&drive->id[ATA_ID_PROD];
@ -67,26 +65,14 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
static u8 svwks_udma_filter(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
u8 mask = 0;
if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) {
return 0x1f;
if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
u32 reg = 0;
if (isa_dev)
pci_read_config_dword(isa_dev, 0x64, &reg);
/*
* Don't enable UDMA on disk devices for the moment
*/
if(drive->media == ide_disk)
return 0;
/* Check the OSB4 DMA33 enable bit */
return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0;
} else if (dev->revision < SVWKS_CSB5_REVISION_NEW) {
return 0x07;
} else if (dev->revision >= SVWKS_CSB5_REVISION_NEW) {
u8 btr = 0, mode;
} else {
u8 btr = 0, mode, mask;
pci_read_config_byte(dev, 0x5A, &btr);
mode = btr & 0x3;
@ -101,13 +87,9 @@ static u8 svwks_udma_filter(ide_drive_t *drive)
case 1: mask = 0x07; break;
default: mask = 0x00; break;
}
}
if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
(dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
(!(PCI_FUNC(dev->devfn) & 1)))
mask = 0x1f;
return mask;
return mask;
}
}
static u8 svwks_csb_check (struct pci_dev *dev)
@ -124,12 +106,13 @@ static u8 svwks_csb_check (struct pci_dev *dev)
return 0;
}
static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void svwks_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
struct pci_dev *dev = to_pci_dev(hwif->dev);
const u8 pio = drive->pio_mode - XFER_PIO_0;
pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]);
@ -145,14 +128,14 @@ static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
}
static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void svwks_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
static const u8 dma_modes[] = { 0x77, 0x21, 0x20 };
static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 };
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
const u8 speed = drive->dma_mode;
u8 unit = drive->dn & 1;
u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0;
@ -185,8 +168,9 @@ static int init_chipset_svwks(struct pci_dev *dev)
/* OSB4 : South Bridge and IDE */
if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
struct pci_dev *isa_dev =
pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
if (isa_dev) {
pci_read_config_dword(isa_dev, 0x64, &reg);
reg &= ~0x00002000; /* disable 600ns interrupt mask */
@ -195,6 +179,7 @@ static int init_chipset_svwks(struct pci_dev *dev)
"enabled.\n", pci_name(dev));
reg |= 0x00004000; /* enable UDMA/33 support */
pci_write_config_dword(isa_dev, 0x64, reg);
pci_dev_put(isa_dev);
}
}
@ -343,7 +328,6 @@ static u8 svwks_cable_detect(ide_hwif_t *hwif)
static const struct ide_port_ops osb4_port_ops = {
.set_pio_mode = svwks_set_pio_mode,
.set_dma_mode = svwks_set_dma_mode,
.udma_filter = svwks_udma_filter,
};
static const struct ide_port_ops svwks_port_ops = {
@ -460,6 +444,6 @@ static void __exit svwks_ide_exit(void)
module_init(svwks_ide_init);
module_exit(svwks_ide_exit);
MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick");
MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for Serverworks OSB4/CSB5/CSB6 IDE");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -255,7 +255,7 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
return dma_stat;
}
static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void sgiioc4_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
}

Просмотреть файл

@ -229,19 +229,18 @@ static u8 sil_sata_udma_filter(ide_drive_t *drive)
/**
* sil_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* Load the timing settings for this device mode into the
* controller.
*/
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
ide_drive_t *pair = ide_get_pair_dev(drive);
u32 speedt = 0;
@ -249,6 +248,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
unsigned long addr = siimage_seldev(drive, 0x04);
unsigned long tfaddr = siimage_selreg(hwif, 0x02);
unsigned long base = (unsigned long)hwif->hwif_data;
const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 tf_pio = pio;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
@ -258,7 +258,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
/* trim *taskfile* PIO to the slowest of the master/slave */
if (pair) {
u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
u8 pair_pio = pair->pio_mode - XFER_PIO_0;
if (pair_pio < tf_pio)
tf_pio = pair_pio;
@ -289,19 +289,18 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
/**
* sil_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
* @speed: DMA mode
*
* Tune the SiI chipset for the desired DMA mode.
*/
static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 };
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long base = (unsigned long)hwif->hwif_data;
u16 ultra = 0, multi = 0;
@ -311,6 +310,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
: (mmio ? 0xB4 : 0x80);
unsigned long ma = siimage_seldev(drive, 0x08);
unsigned long ua = siimage_seldev(drive, 0x0C);
const u8 speed = drive->dma_mode;
scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A));
mode = sil_ioread8 (dev, base + addr_mask);

Просмотреть файл

@ -290,10 +290,10 @@ static void config_drive_art_rwp(ide_drive_t *drive)
pci_write_config_byte(dev, 0x4b, rw_prefetch);
}
static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void sis_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
config_drive_art_rwp(drive);
sis_program_timings(drive, XFER_PIO_0 + pio);
sis_program_timings(drive, drive->pio_mode);
}
static void sis_ata133_program_udma_timings(ide_drive_t *drive, const u8 mode)
@ -340,8 +340,10 @@ static void sis_program_udma_timings(ide_drive_t *drive, const u8 mode)
sis_ata33_program_udma_timings(drive, mode);
}
static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void sis_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
const u8 speed = drive->dma_mode;
if (speed >= XFER_UDMA_0)
sis_program_udma_timings(drive, speed);
else

Просмотреть файл

@ -63,12 +63,13 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
/*
* Configure the chipset for PIO mode.
*/
static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void sl82c105_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long timings = (unsigned long)ide_get_drivedata(drive);
int reg = 0x44 + drive->dn * 4;
u16 drv_ctrl;
const u8 pio = drive->pio_mode - XFER_PIO_0;
drv_ctrl = get_pio_timings(drive, pio);
@ -91,11 +92,12 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
/*
* Configure the chipset for DMA mode.
*/
static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void sl82c105_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200};
unsigned long timings = (unsigned long)ide_get_drivedata(drive);
u16 drv_ctrl;
const u8 speed = drive->dma_mode;
drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0];

Просмотреть файл

@ -18,9 +18,8 @@
static DEFINE_SPINLOCK(slc90e66_lock);
static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void slc90e66_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int is_slave = drive->dn & 1;
int master_port = hwif->channel ? 0x42 : 0x40;
@ -29,6 +28,8 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
u16 master_data;
u8 slave_data;
int control = 0;
const u8 pio = drive->pio_mode - XFER_PIO_0;
/* ISP RTC */
static const u8 timings[][2] = {
{ 0, 0 },
@ -71,14 +72,14 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
spin_unlock_irqrestore(&slc90e66_lock, flags);
}
static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void slc90e66_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 maslave = hwif->channel ? 0x42 : 0x40;
int sitre = 0, a_speed = 7 << (drive->dn * 4);
int u_speed = 0, u_flag = 1 << drive->dn;
u16 reg4042, reg44, reg48, reg4a;
const u8 speed = drive->dma_mode;
pci_read_config_word(dev, maslave, &reg4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
@ -98,7 +99,6 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
u8 pio;
if (reg48 & u_flag)
pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
@ -106,11 +106,12 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
if (speed >= XFER_MW_DMA_0)
pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
drive->pio_mode =
mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
else
pio = 2; /* only SWDMA2 is allowed */
drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
slc90e66_set_pio_mode(drive, pio);
slc90e66_set_pio_mode(hwif, drive);
}
}

Просмотреть файл

@ -13,11 +13,11 @@
#define DRV_NAME "tc86c001"
static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
static void tc86c001_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00);
u16 mode, scr = inw(scr_port);
const u8 speed = drive->dma_mode;
switch (speed) {
case XFER_UDMA_4: mode = 0x00c0; break;
@ -41,9 +41,10 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
outw(scr, scr_port);
}
static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void tc86c001_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
tc86c001_set_mode(drive, XFER_PIO_0 + pio);
drive->dma_mode = drive->pio_mode;
tc86c001_set_mode(hwif, drive);
}
/*

Просмотреть файл

@ -34,9 +34,8 @@
#define DRV_NAME "triflex"
static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
static void triflex_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u32 triflex_timings = 0;
u16 timing = 0;
@ -44,7 +43,7 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
pci_read_config_dword(dev, channel_offset, &triflex_timings);
switch(speed) {
switch (drive->dma_mode) {
case XFER_MW_DMA_2:
timing = 0x0103;
break;
@ -82,9 +81,10 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_dword(dev, channel_offset, triflex_timings);
}
static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void triflex_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
triflex_set_mode(drive, XFER_PIO_0 + pio);
drive->dma_mode = drive->pio_mode;
triflex_set_mode(hwif, drive);
}
static const struct ide_port_ops triflex_port_ops = {

Просмотреть файл

@ -56,16 +56,15 @@ static void tx4938ide_tune_ebusc(unsigned int ebus_ch,
&tx4938_ebuscptr->cr[ebus_ch]);
}
static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void tx4938ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct tx4938ide_platform_info *pdata = hwif->dev->platform_data;
u8 safe = pio;
u8 safe = drive->pio_mode - XFER_PIO_0;
ide_drive_t *pair;
pair = ide_get_pair_dev(drive);
if (pair)
safe = min(safe, ide_get_best_pio_mode(pair, 255, 5));
safe = min(safe, pair->pio_mode - XFER_PIO_0);
tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, safe);
}

Просмотреть файл

@ -104,17 +104,17 @@ static void tx4939ide_writeb(u8 val, void __iomem *base, u32 reg)
#define TX4939IDE_BASE(hwif) ((void __iomem *)(hwif)->extra_base)
static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void tx4939ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
int is_slave = drive->dn;
u32 mask, val;
const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 safe = pio;
ide_drive_t *pair;
pair = ide_get_pair_dev(drive);
if (pair)
safe = min(safe, ide_get_best_pio_mode(pair, 255, 4));
safe = min(safe, pair->pio_mode - XFER_PIO_0);
/*
* Update Command Transfer Mode for master/slave and Data
* Transfer Mode for this drive.
@ -125,10 +125,10 @@ static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
/* tx4939ide_tf_load_fixup() will set the Sys_Ctl register */
}
static void tx4939ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void tx4939ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u32 mask, val;
const u8 mode = drive->dma_mode;
/* Update Data Transfer Mode for this drive. */
if (mode >= XFER_UDMA_0)

Просмотреть файл

@ -104,10 +104,11 @@ static void umc_set_speeds(u8 speeds[])
speeds[0], speeds[1], speeds[2], speeds[3]);
}
static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void umc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif, *mate = hwif->mate;
ide_hwif_t *mate = hwif->mate;
unsigned long uninitialized_var(flags);
const u8 pio = drive->pio_mode - XFER_PIO_0;
printk("%s: setting umc8672 to PIO mode%d (speed %d)\n",
drive->name, pio, pio_to_umc[pio]);

Просмотреть файл

@ -6,7 +6,7 @@
* vt8235, vt8237, vt8237a
*
* Copyright (c) 2000-2002 Vojtech Pavlik
* Copyright (c) 2007 Bartlomiej Zolnierkiewicz
* Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
*
* Based on the work of:
* Michel Aubry
@ -54,6 +54,11 @@
#define VIA_NO_UNMASK 0x08 /* Doesn't work with IRQ unmasking on */
#define VIA_BAD_ID 0x10 /* Has wrong vendor ID (0x1107) */
#define VIA_BAD_AST 0x20 /* Don't touch Address Setup Timing */
#define VIA_SATA_PATA 0x80 /* SATA/PATA combined configuration */
enum {
VIA_IDFLAG_SINGLE = (1 << 1), /* single channel controller */
};
/*
* VIA SouthBridge chips.
@ -67,11 +72,13 @@ static struct via_isa_bridge {
u8 udma_mask;
u8 flags;
} via_isa_bridges[] = {
{ "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
{ "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt6415", PCI_DEVICE_ID_VIA_6410, 0x00, 0xff, ATA_UDMA6, VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
@ -92,6 +99,7 @@ static struct via_isa_bridge {
{ "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, 0x00, VIA_SET_FIFO },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
{ "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ NULL }
};
@ -102,6 +110,7 @@ struct via82cxxx_dev
{
struct via_isa_bridge *via_config;
unsigned int via_80w;
u8 cached_device[2];
};
/**
@ -137,30 +146,45 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break;
case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
default: return;
}
pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t);
/* Set UDMA unless device is not UDMA capable */
if (vdev->via_config->udma_mask) {
u8 udma_etc;
pci_read_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, &udma_etc);
/* clear transfer mode bit */
udma_etc &= ~0x20;
if (timing->udma) {
/* preserve 80-wire cable detection bit */
udma_etc &= 0x10;
udma_etc |= t;
}
pci_write_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, udma_etc);
}
}
/**
* via_set_drive - configure transfer mode
* @hwif: port
* @drive: Drive to set up
* @speed: desired speed
*
* via_set_drive() computes timing values configures the chipset to
* a desired transfer mode. It also can be called by upper layers.
*/
static void via_set_drive(ide_drive_t *drive, const u8 speed)
static void via_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
ide_drive_t *peer = ide_get_pair_dev(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct via82cxxx_dev *vdev = host->host_priv;
struct ide_timing t, p;
unsigned int T, UT;
const u8 speed = drive->dma_mode;
T = 1000000000 / via_clock;
@ -175,7 +199,7 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed)
ide_timing_compute(drive, speed, &t, T, UT);
if (peer) {
ide_timing_compute(peer, peer->current_speed, &p, T, UT);
ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
@ -184,22 +208,24 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed)
/**
* via_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
* @pio: PIO mode number
*
* A callback from the upper layers for PIO-only tuning.
*/
static void via_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void via_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
via_set_drive(drive, XFER_PIO_0 + pio);
drive->dma_mode = drive->pio_mode;
via_set_drive(hwif, drive);
}
static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
{
struct via_isa_bridge *via_config;
for (via_config = via_isa_bridges; via_config->id; via_config++)
for (via_config = via_isa_bridges;
via_config->id != PCI_DEVICE_ID_VIA_ANON; via_config++)
if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
!!(via_config->flags & VIA_BAD_ID),
via_config->id, NULL))) {
@ -362,6 +388,9 @@ static u8 via82cxxx_cable_detect(ide_hwif_t *hwif)
if (via_cable_override(pdev))
return ATA_CBL_PATA40_SHORT;
if ((vdev->via_config->flags & VIA_SATA_PATA) && hwif->channel == 0)
return ATA_CBL_SATA;
if ((vdev->via_80w >> hwif->channel) & 1)
return ATA_CBL_PATA80;
else
@ -374,10 +403,66 @@ static const struct ide_port_ops via_port_ops = {
.cable_detect = via82cxxx_cable_detect,
};
static void via_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
struct via82cxxx_dev *vdev = hwif->host->host_priv;
outb(ctl, hwif->io_ports.ctl_addr);
outb(vdev->cached_device[hwif->channel], hwif->io_ports.device_addr);
}
static void __via_dev_select(ide_drive_t *drive, u8 select)
{
ide_hwif_t *hwif = drive->hwif;
struct via82cxxx_dev *vdev = hwif->host->host_priv;
outb(select, hwif->io_ports.device_addr);
vdev->cached_device[hwif->channel] = select;
}
static void via_dev_select(ide_drive_t *drive)
{
__via_dev_select(drive, drive->select | ATA_DEVICE_OBS);
}
static void via_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
if (valid & IDE_VALID_FEATURE)
outb(tf->feature, io_ports->feature_addr);
if (valid & IDE_VALID_NSECT)
outb(tf->nsect, io_ports->nsect_addr);
if (valid & IDE_VALID_LBAL)
outb(tf->lbal, io_ports->lbal_addr);
if (valid & IDE_VALID_LBAM)
outb(tf->lbam, io_ports->lbam_addr);
if (valid & IDE_VALID_LBAH)
outb(tf->lbah, io_ports->lbah_addr);
if (valid & IDE_VALID_DEVICE)
__via_dev_select(drive, tf->device);
}
const struct ide_tp_ops via_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = via_write_devctl,
.dev_select = via_dev_select,
.tf_load = via_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
static const struct ide_port_info via82cxxx_chipset __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_via82cxxx,
.enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
.tp_ops = &via_tp_ops,
.port_ops = &via_port_ops,
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
IDE_HFLAG_POST_SET_MODE |
@ -402,11 +487,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
* Find the ISA bridge and check we know what it is.
*/
via_config = via_config_find(&isa);
if (!via_config->id) {
printk(KERN_WARNING DRV_NAME " %s: unknown chipset, skipping\n",
pci_name(dev));
return -ENODEV;
}
/*
* Print the boot message.
@ -436,10 +516,13 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
via_clock = 33333;
}
if (idx == 0)
d.host_flags |= IDE_HFLAG_NO_AUTODMA;
else
if (idx == 1)
d.enablebits[1].reg = d.enablebits[0].reg = 0;
else
d.host_flags |= IDE_HFLAG_NO_AUTODMA;
if (idx == VIA_IDFLAG_SINGLE)
d.host_flags |= IDE_HFLAG_SINGLE;
if ((via_config->flags & VIA_NO_UNMASK) == 0)
d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
@ -475,8 +558,9 @@ static const struct pci_device_id via_pci_tbl[] = {
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), VIA_IDFLAG_SINGLE },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6415), 1 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
{ 0, },
};
@ -504,6 +588,6 @@ static void __exit via_ide_exit(void)
module_init(via_ide_init);
module_exit(via_ide_exit);
MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick");
MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz, Michel Aubry, Jeff Garzik, Andre Hedrick");
MODULE_DESCRIPTION("PCI driver module for VIA IDE");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -515,6 +515,8 @@ struct ide_drive_s {
u8 init_speed; /* transfer rate set at boot */
u8 current_speed; /* current transfer rate set */
u8 desired_speed; /* desired transfer rate set */
u8 pio_mode; /* for ->set_pio_mode _only_ */
u8 dma_mode; /* for ->dma_pio_mode _only_ */
u8 dn; /* now wide spread use */
u8 acoustic; /* acoustic management */
u8 media; /* disk, cdrom, tape, floppy, ... */
@ -622,8 +624,8 @@ extern const struct ide_tp_ops default_tp_ops;
*/
struct ide_port_ops {
void (*init_dev)(ide_drive_t *);
void (*set_pio_mode)(ide_drive_t *, const u8);
void (*set_dma_mode)(ide_drive_t *, const u8);
void (*set_pio_mode)(struct hwif_s *, ide_drive_t *);
void (*set_dma_mode)(struct hwif_s *, ide_drive_t *);
int (*reset_poll)(ide_drive_t *);
void (*pre_reset)(ide_drive_t *);
void (*resetproc)(ide_drive_t *);
@ -1494,7 +1496,6 @@ int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int);
#ifdef CONFIG_IDE_XFER_MODE
int ide_scan_pio_blacklist(char *);
const char *ide_xfer_verbose(u8);
u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
int ide_pio_need_iordy(ide_drive_t *, const u8);
int ide_set_pio_mode(ide_drive_t *, u8);
int ide_set_dma_mode(ide_drive_t *, u8);