diff options
| -rw-r--r-- | drivers/ide/pci/sl82c105.c | 99 | ||||
| -rw-r--r-- | include/linux/ide.h | 1 |
2 files changed, 41 insertions, 59 deletions
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 3a8a76fc78c7..ee6dd45a9ba7 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | * Merge in Russell's HW workarounds, fix various problems | 11 | * Merge in Russell's HW workarounds, fix various problems |
| 12 | * with the timing registers setup. | 12 | * with the timing registers setup. |
| 13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org | 13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org |
| 14 | * | ||
| 15 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> | ||
| 14 | */ | 16 | */ |
| 15 | 17 | ||
| 16 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| @@ -47,25 +49,19 @@ | |||
| 47 | #define CTRL_P0EN (1 << 0) | 49 | #define CTRL_P0EN (1 << 0) |
| 48 | 50 | ||
| 49 | /* | 51 | /* |
| 50 | * Convert a PIO mode and cycle time to the required on/off | 52 | * Convert a PIO mode and cycle time to the required on/off times |
| 51 | * times for the interface. This has protection against run-away | 53 | * for the interface. This has protection against runaway timings. |
| 52 | * timings. | ||
| 53 | */ | 54 | */ |
| 54 | static unsigned int get_timing_sl82c105(ide_pio_data_t *p) | 55 | static unsigned int get_pio_timings(ide_pio_data_t *p) |
| 55 | { | 56 | { |
| 56 | unsigned int cmd_on; | 57 | unsigned int cmd_on, cmd_off; |
| 57 | unsigned int cmd_off; | ||
| 58 | 58 | ||
| 59 | cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; | 59 | cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; |
| 60 | cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; | 60 | cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; |
| 61 | 61 | ||
| 62 | if (cmd_on > 32) | ||
| 63 | cmd_on = 32; | ||
| 64 | if (cmd_on == 0) | 62 | if (cmd_on == 0) |
| 65 | cmd_on = 1; | 63 | cmd_on = 1; |
| 66 | 64 | ||
| 67 | if (cmd_off > 32) | ||
| 68 | cmd_off = 32; | ||
| 69 | if (cmd_off == 0) | 65 | if (cmd_off == 0) |
| 70 | cmd_off = 1; | 66 | cmd_off = 1; |
| 71 | 67 | ||
| @@ -73,44 +69,34 @@ static unsigned int get_timing_sl82c105(ide_pio_data_t *p) | |||
| 73 | } | 69 | } |
| 74 | 70 | ||
| 75 | /* | 71 | /* |
| 76 | * Configure the drive and chipset for PIO | 72 | * Configure the chipset for PIO mode. |
| 77 | */ | 73 | */ |
| 78 | static void config_for_pio(ide_drive_t *drive, int pio, int report, int chipset_only) | 74 | static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) |
| 79 | { | 75 | { |
| 80 | ide_hwif_t *hwif = HWIF(drive); | 76 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
| 81 | struct pci_dev *dev = hwif->pci_dev; | 77 | int reg = 0x44 + drive->dn * 4; |
| 82 | ide_pio_data_t p; | 78 | ide_pio_data_t p; |
| 83 | u16 drv_ctrl = 0x909; | 79 | u16 drv_ctrl; |
| 84 | unsigned int xfer_mode, reg; | ||
| 85 | 80 | ||
| 86 | DBG(("config_for_pio(drive:%s, pio:%d, report:%d, chipset_only:%d)\n", | 81 | DBG(("sl82c105_tune_pio(drive:%s, pio:%u)\n", drive->name, pio)); |
| 87 | drive->name, pio, report, chipset_only)); | ||
| 88 | |||
| 89 | reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); | ||
| 90 | 82 | ||
| 91 | pio = ide_get_best_pio_mode(drive, pio, 5, &p); | 83 | pio = ide_get_best_pio_mode(drive, pio, 5, &p); |
| 92 | 84 | ||
| 93 | xfer_mode = XFER_PIO_0 + pio; | 85 | drive->drive_data = drv_ctrl = get_pio_timings(&p); |
| 94 | 86 | ||
| 95 | if (chipset_only || ide_config_drive_speed(drive, xfer_mode) == 0) { | 87 | if (!drive->using_dma) { |
| 96 | drv_ctrl = get_timing_sl82c105(&p); | ||
| 97 | drive->pio_speed = xfer_mode; | ||
| 98 | } else | ||
| 99 | drive->pio_speed = XFER_PIO_0; | ||
| 100 | |||
| 101 | if (drive->using_dma == 0) { | ||
| 102 | /* | 88 | /* |
| 103 | * If we are actually using MW DMA, then we can not | 89 | * If we are actually using MW DMA, then we can not |
| 104 | * reprogram the interface drive control register. | 90 | * reprogram the interface drive control register. |
| 105 | */ | 91 | */ |
| 106 | pci_write_config_word(dev, reg, drv_ctrl); | 92 | pci_write_config_word(dev, reg, drv_ctrl); |
| 107 | pci_read_config_word(dev, reg, &drv_ctrl); | 93 | pci_read_config_word (dev, reg, &drv_ctrl); |
| 108 | |||
| 109 | if (report) { | ||
| 110 | printk("%s: selected %s (%dns) (%04X)\n", drive->name, | ||
| 111 | ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); | ||
| 112 | } | ||
| 113 | } | 94 | } |
| 95 | |||
| 96 | printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, | ||
| 97 | ide_xfer_verbose(pio + XFER_PIO_0), p.cycle_time, drv_ctrl); | ||
| 98 | |||
| 99 | return pio; | ||
| 114 | } | 100 | } |
| 115 | 101 | ||
| 116 | /* | 102 | /* |
| @@ -267,14 +253,14 @@ static int sl82c105_ide_dma_on (ide_drive_t *drive) | |||
| 267 | 253 | ||
| 268 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) | 254 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) |
| 269 | { | 255 | { |
| 270 | u8 speed = XFER_PIO_0; | 256 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
| 257 | int reg = 0x44 + drive->dn * 4; | ||
| 271 | 258 | ||
| 272 | DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); | 259 | DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); |
| 273 | 260 | ||
| 261 | pci_write_config_word(dev, reg, drive->drive_data); | ||
| 262 | |||
| 274 | ide_dma_off_quietly(drive); | 263 | ide_dma_off_quietly(drive); |
| 275 | if (drive->pio_speed) | ||
| 276 | speed = drive->pio_speed - XFER_PIO_0; | ||
| 277 | config_for_pio(drive, speed, 0, 1); | ||
| 278 | } | 264 | } |
| 279 | 265 | ||
| 280 | /* | 266 | /* |
| @@ -323,18 +309,12 @@ static void sl82c105_resetproc(ide_drive_t *drive) | |||
| 323 | * We only deal with PIO mode here - DMA mode 'using_dma' is not | 309 | * We only deal with PIO mode here - DMA mode 'using_dma' is not |
| 324 | * initialised at the point that this function is called. | 310 | * initialised at the point that this function is called. |
| 325 | */ | 311 | */ |
| 326 | static void tune_sl82c105(ide_drive_t *drive, u8 pio) | 312 | static void sl82c105_tune_drive(ide_drive_t *drive, u8 pio) |
| 327 | { | 313 | { |
| 328 | DBG(("tune_sl82c105(drive:%s)\n", drive->name)); | 314 | DBG(("sl82c105_tune_drive(drive:%s, pio:%u)\n", drive->name, pio)); |
| 329 | 315 | ||
| 330 | config_for_pio(drive, pio, 1, 0); | 316 | pio = sl82c105_tune_pio(drive, pio); |
| 331 | 317 | (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); | |
| 332 | /* | ||
| 333 | * We support 32-bit I/O on this interface, and it | ||
| 334 | * doesn't have problems with interrupts. | ||
| 335 | */ | ||
| 336 | drive->io_32bit = 1; | ||
| 337 | drive->unmask = 1; | ||
| 338 | } | 318 | } |
| 339 | 319 | ||
| 340 | /* | 320 | /* |
| @@ -401,19 +381,22 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
| 401 | 381 | ||
| 402 | DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); | 382 | DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); |
| 403 | 383 | ||
| 404 | hwif->tuneproc = tune_sl82c105; | 384 | hwif->tuneproc = &sl82c105_tune_drive; |
| 405 | hwif->selectproc = sl82c105_selectproc; | 385 | hwif->selectproc = &sl82c105_selectproc; |
| 406 | hwif->resetproc = sl82c105_resetproc; | 386 | hwif->resetproc = &sl82c105_resetproc; |
| 387 | |||
| 388 | /* | ||
| 389 | * We support 32-bit I/O on this interface, and | ||
| 390 | * it doesn't have problems with interrupts. | ||
| 391 | */ | ||
| 392 | hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1; | ||
| 393 | hwif->drives[0].unmask = hwif->drives[1].unmask = 1; | ||
| 407 | 394 | ||
| 408 | /* | 395 | /* |
| 409 | * Default to PIO 0 for fallback unless tuned otherwise. | ||
| 410 | * We always autotune PIO, this is done before DMA is checked, | 396 | * We always autotune PIO, this is done before DMA is checked, |
| 411 | * so there's no risk of accidentally disabling DMA | 397 | * so there's no risk of accidentally disabling DMA |
| 412 | */ | 398 | */ |
| 413 | hwif->drives[0].pio_speed = XFER_PIO_0; | 399 | hwif->drives[0].autotune = hwif->drives[1].autotune = 1; |
| 414 | hwif->drives[0].autotune = 1; | ||
| 415 | hwif->drives[1].pio_speed = XFER_PIO_0; | ||
| 416 | hwif->drives[1].autotune = 1; | ||
| 417 | 400 | ||
| 418 | hwif->atapi_dma = 0; | 401 | hwif->atapi_dma = 0; |
| 419 | hwif->mwdma_mask = 0; | 402 | hwif->mwdma_mask = 0; |
diff --git a/include/linux/ide.h b/include/linux/ide.h index d3bbc7188b6a..418dfb5adadd 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -613,7 +613,6 @@ typedef struct ide_drive_s { | |||
| 613 | 613 | ||
| 614 | u8 quirk_list; /* considered quirky, set for a specific host */ | 614 | u8 quirk_list; /* considered quirky, set for a specific host */ |
| 615 | u8 init_speed; /* transfer rate set at boot */ | 615 | u8 init_speed; /* transfer rate set at boot */ |
| 616 | u8 pio_speed; /* unused by core, used by some drivers for fallback from DMA */ | ||
| 617 | u8 current_speed; /* current transfer rate set */ | 616 | u8 current_speed; /* current transfer rate set */ |
| 618 | u8 desired_speed; /* desired transfer rate set */ | 617 | u8 desired_speed; /* desired transfer rate set */ |
| 619 | u8 dn; /* now wide spread use */ | 618 | u8 dn; /* now wide spread use */ |
