diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2007-05-05 16:03:49 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-05-05 16:03:49 -0400 |
commit | e93df705af1992dbf5956a8c80fcb9987bc595c0 (patch) | |
tree | 62ceef1f46ecde9782d7ee3f26f0a0e108418b69 /drivers/ide/pci/sl82c105.c | |
parent | 62ea6d80211ecc88ef516927ecebf64cb505be3f (diff) |
sl82c105: rework PIO support (take 2)
Get rid of the 'pio_speed' member of 'ide_drive_t' that was only used by this
driver by storing the PIO mode timings in the 'drive_data' instead -- this
allows us to greatly simplify the process of "reloading" of the chip's timing
register and do it right in sl82c150_dma_off_quietly() and to get rid of two
extra arguments to config_for_pio() -- which got renamed to sl82c105_tune_pio()
and now returns a PIO mode selected, with ide_config_drive_speed() call moved
into the tuneproc() method, now called sl82c105_tune_drive() with the code to
set drive's 'io_32bit' and 'unmask' flags in its turn moved to its proper place
in the init_hwif() method.
Also, while at it, rename get_timing_sl82c105() into get_pio_timings() and get
rid of the code in it clamping cycle counts to 32 which was both incorrect and
never executed anyway...
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci/sl82c105.c')
-rw-r--r-- | drivers/ide/pci/sl82c105.c | 99 |
1 files changed, 41 insertions, 58 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; |