forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 ...
- Loading branch information
Showing
52 changed files
with
617 additions
and
678 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
* Copyright (C) 2002 Alan Cox | ||
* ALi (now ULi M5228) support by Clear Zhang <[email protected]> | ||
* Copyright (C) 2007 MontaVista Software, Inc. <[email protected]> | ||
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz <[email protected]> | ||
* 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; | ||
|
||
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; | ||
|
||
if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { | ||
r_clc = 1; | ||
} else { | ||
if (r_clc >= 16) | ||
r_clc = 0; | ||
unsigned long T = 1000000 / bus_speed; /* PCI clock based */ | ||
struct ide_timing t; | ||
|
||
ide_timing_compute(drive, drive->pio_mode, &t, T, 1); | ||
if (pair) { | ||
struct ide_timing p; | ||
|
||
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); | ||
|
||
/* | ||
* FIXME: Oh, my... DMA timings are never set. | ||
*/ | ||
ide_timing_compute(drive, drive->dma_mode, &t, T, 1); | ||
if (pair) { | ||
struct ide_timing p; | ||
|
||
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"); |
Oops, something went wrong.