mirror of https://gitee.com/openkylin/linux.git
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:
commit
4c10c937cc
|
@ -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, ®U);
|
||||
regU &= ~(unit ? 0xCA : 0x35);
|
||||
}
|
||||
pci_read_config_byte(dev, pciU, ®U);
|
||||
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 @@ static u8 cs5530_udma_filter(ide_drive_t *drive)
|
|||
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 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
|
|||
|
||||
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, ®48);
|
||||
pci_read_config_byte(dev, 0x4a, ®4a);
|
||||
|
@ -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, ®4042);
|
||||
pci_read_config_byte(dev, 0x48, ®48);
|
||||
|
@ -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, ®4042);
|
||||
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 @@ static u8 sc1200_udma_filter(ide_drive_t *drive)
|
|||
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, ®);
|
||||
|
||||
/*
|
||||
* 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 &= ~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, ®4042);
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue