diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/ide/alim15x3.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/ide/alim15x3.c')
-rw-r--r-- | drivers/ide/alim15x3.c | 183 |
1 files changed, 93 insertions, 90 deletions
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index e59b6dee9ae2..2c8016ad0e26 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 2002 Alan Cox | 8 | * Copyright (C) 2002 Alan Cox |
9 | * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> | 9 | * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> |
10 | * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> | 10 | * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> |
11 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 11 | * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz |
12 | * | 12 | * |
13 | * (U)DMA capable version of ali 1533/1543(C), 1535(D) | 13 | * (U)DMA capable version of ali 1533/1543(C), 1535(D) |
14 | * | 14 | * |
@@ -40,16 +40,6 @@ | |||
40 | #define DRV_NAME "alim15x3" | 40 | #define DRV_NAME "alim15x3" |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Allow UDMA on M1543C-E chipset for WDC disks that ignore CRC checking | ||
44 | * (this is DANGEROUS and could result in data corruption). | ||
45 | */ | ||
46 | static int wdc_udma; | ||
47 | |||
48 | module_param(wdc_udma, bool, 0); | ||
49 | MODULE_PARM_DESC(wdc_udma, | ||
50 | "allow UDMA on M1543C-E chipset for WDC disks (DANGEROUS)"); | ||
51 | |||
52 | /* | ||
53 | * ALi devices are not plug in. Otherwise these static values would | 43 | * ALi devices are not plug in. Otherwise these static values would |
54 | * need to go. They ought to go away anyway | 44 | * need to go. They ought to go away anyway |
55 | */ | 45 | */ |
@@ -58,61 +48,84 @@ static u8 m5229_revision; | |||
58 | static u8 chip_is_1543c_e; | 48 | static u8 chip_is_1543c_e; |
59 | static struct pci_dev *isa_dev; | 49 | static struct pci_dev *isa_dev; |
60 | 50 | ||
51 | static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on) | ||
52 | { | ||
53 | struct pci_dev *pdev = to_pci_dev(hwif->dev); | ||
54 | int pio_fifo = 0x54 + hwif->channel; | ||
55 | u8 fifo; | ||
56 | int shift = 4 * (drive->dn & 1); | ||
57 | |||
58 | pci_read_config_byte(pdev, pio_fifo, &fifo); | ||
59 | fifo &= ~(0x0F << shift); | ||
60 | fifo |= (on << shift); | ||
61 | pci_write_config_byte(pdev, pio_fifo, fifo); | ||
62 | } | ||
63 | |||
64 | static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive, | ||
65 | struct ide_timing *t, u8 ultra) | ||
66 | { | ||
67 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
68 | int port = hwif->channel ? 0x5c : 0x58; | ||
69 | int udmat = 0x56 + hwif->channel; | ||
70 | u8 unit = drive->dn & 1, udma; | ||
71 | int shift = 4 * unit; | ||
72 | |||
73 | /* Set up the UDMA */ | ||
74 | pci_read_config_byte(dev, udmat, &udma); | ||
75 | udma &= ~(0x0F << shift); | ||
76 | udma |= ultra << shift; | ||
77 | pci_write_config_byte(dev, udmat, udma); | ||
78 | |||
79 | if (t == NULL) | ||
80 | return; | ||
81 | |||
82 | t->setup = clamp_val(t->setup, 1, 8) & 7; | ||
83 | t->act8b = clamp_val(t->act8b, 1, 8) & 7; | ||
84 | t->rec8b = clamp_val(t->rec8b, 1, 16) & 15; | ||
85 | t->active = clamp_val(t->active, 1, 8) & 7; | ||
86 | t->recover = clamp_val(t->recover, 1, 16) & 15; | ||
87 | |||
88 | pci_write_config_byte(dev, port, t->setup); | ||
89 | pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b); | ||
90 | pci_write_config_byte(dev, port + unit + 2, | ||
91 | (t->active << 4) | t->recover); | ||
92 | } | ||
93 | |||
61 | /** | 94 | /** |
62 | * ali_set_pio_mode - set host controller for PIO mode | 95 | * ali_set_pio_mode - set host controller for PIO mode |
96 | * @hwif: port | ||
63 | * @drive: drive | 97 | * @drive: drive |
64 | * @pio: PIO mode number | ||
65 | * | 98 | * |
66 | * Program the controller for the given PIO mode. | 99 | * Program the controller for the given PIO mode. |
67 | */ | 100 | */ |
68 | 101 | ||
69 | static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) | 102 | static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
70 | { | 103 | { |
71 | ide_hwif_t *hwif = drive->hwif; | 104 | ide_drive_t *pair = ide_get_pair_dev(drive); |
72 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
73 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
74 | int s_time = t->setup, a_time = t->active, c_time = t->cycle; | ||
75 | u8 s_clc, a_clc, r_clc; | ||
76 | unsigned long flags; | ||
77 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; | 105 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; |
78 | int port = hwif->channel ? 0x5c : 0x58; | 106 | unsigned long T = 1000000 / bus_speed; /* PCI clock based */ |
79 | int portFIFO = hwif->channel ? 0x55 : 0x54; | 107 | struct ide_timing t; |
80 | u8 cd_dma_fifo = 0, unit = drive->dn & 1; | 108 | |
81 | 109 | ide_timing_compute(drive, drive->pio_mode, &t, T, 1); | |
82 | if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) | 110 | if (pair) { |
83 | s_clc = 0; | 111 | struct ide_timing p; |
84 | if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8) | 112 | |
85 | a_clc = 0; | 113 | ide_timing_compute(pair, pair->pio_mode, &p, T, 1); |
86 | 114 | ide_timing_merge(&p, &t, &t, | |
87 | if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { | 115 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); |
88 | r_clc = 1; | 116 | if (pair->dma_mode) { |
89 | } else { | 117 | ide_timing_compute(pair, pair->dma_mode, &p, T, 1); |
90 | if (r_clc >= 16) | 118 | ide_timing_merge(&p, &t, &t, |
91 | r_clc = 0; | 119 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); |
120 | } | ||
92 | } | 121 | } |
93 | local_irq_save(flags); | 122 | |
94 | |||
95 | /* | 123 | /* |
96 | * PIO mode => ATA FIFO on, ATAPI FIFO off | 124 | * PIO mode => ATA FIFO on, ATAPI FIFO off |
97 | */ | 125 | */ |
98 | pci_read_config_byte(dev, portFIFO, &cd_dma_fifo); | 126 | ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00); |
99 | if (drive->media==ide_disk) { | 127 | |
100 | if (unit) { | 128 | ali_program_timings(hwif, drive, &t, 0); |
101 | pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50); | ||
102 | } else { | ||
103 | pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05); | ||
104 | } | ||
105 | } else { | ||
106 | if (unit) { | ||
107 | pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F); | ||
108 | } else { | ||
109 | pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | pci_write_config_byte(dev, port, s_clc); | ||
114 | pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc); | ||
115 | local_irq_restore(flags); | ||
116 | } | 129 | } |
117 | 130 | ||
118 | /** | 131 | /** |
@@ -132,7 +145,7 @@ static u8 ali_udma_filter(ide_drive_t *drive) | |||
132 | if (m5229_revision > 0x20 && m5229_revision < 0xC2) { | 145 | if (m5229_revision > 0x20 && m5229_revision < 0xC2) { |
133 | if (drive->media != ide_disk) | 146 | if (drive->media != ide_disk) |
134 | return 0; | 147 | return 0; |
135 | if (wdc_udma == 0 && chip_is_1543c_e && | 148 | if (chip_is_1543c_e && |
136 | strstr((char *)&drive->id[ATA_ID_PROD], "WDC ")) | 149 | strstr((char *)&drive->id[ATA_ID_PROD], "WDC ")) |
137 | return 0; | 150 | return 0; |
138 | } | 151 | } |
@@ -142,44 +155,42 @@ static u8 ali_udma_filter(ide_drive_t *drive) | |||
142 | 155 | ||
143 | /** | 156 | /** |
144 | * ali_set_dma_mode - set host controller for DMA mode | 157 | * ali_set_dma_mode - set host controller for DMA mode |
158 | * @hwif: port | ||
145 | * @drive: drive | 159 | * @drive: drive |
146 | * @speed: DMA mode | ||
147 | * | 160 | * |
148 | * Configure the hardware for the desired IDE transfer mode. | 161 | * Configure the hardware for the desired IDE transfer mode. |
149 | */ | 162 | */ |
150 | 163 | ||
151 | static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) | 164 | static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
152 | { | 165 | { |
153 | ide_hwif_t *hwif = drive->hwif; | 166 | static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD }; |
154 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 167 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
155 | u8 speed1 = speed; | 168 | ide_drive_t *pair = ide_get_pair_dev(drive); |
156 | u8 unit = drive->dn & 1; | 169 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; |
170 | unsigned long T = 1000000 / bus_speed; /* PCI clock based */ | ||
171 | const u8 speed = drive->dma_mode; | ||
157 | u8 tmpbyte = 0x00; | 172 | u8 tmpbyte = 0x00; |
158 | int m5229_udma = (hwif->channel) ? 0x57 : 0x56; | 173 | struct ide_timing t; |
159 | |||
160 | if (speed == XFER_UDMA_6) | ||
161 | speed1 = 0x47; | ||
162 | 174 | ||
163 | if (speed < XFER_UDMA_0) { | 175 | if (speed < XFER_UDMA_0) { |
164 | u8 ultra_enable = (unit) ? 0x7f : 0xf7; | 176 | ide_timing_compute(drive, drive->dma_mode, &t, T, 1); |
165 | /* | 177 | if (pair) { |
166 | * clear "ultra enable" bit | 178 | struct ide_timing p; |
167 | */ | 179 | |
168 | pci_read_config_byte(dev, m5229_udma, &tmpbyte); | 180 | ide_timing_compute(pair, pair->pio_mode, &p, T, 1); |
169 | tmpbyte &= ultra_enable; | 181 | ide_timing_merge(&p, &t, &t, |
170 | pci_write_config_byte(dev, m5229_udma, tmpbyte); | 182 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); |
171 | 183 | if (pair->dma_mode) { | |
172 | /* | 184 | ide_timing_compute(pair, pair->dma_mode, |
173 | * FIXME: Oh, my... DMA timings are never set. | 185 | &p, T, 1); |
174 | */ | 186 | ide_timing_merge(&p, &t, &t, |
187 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); | ||
188 | } | ||
189 | } | ||
190 | ali_program_timings(hwif, drive, &t, 0); | ||
175 | } else { | 191 | } else { |
176 | pci_read_config_byte(dev, m5229_udma, &tmpbyte); | 192 | ali_program_timings(hwif, drive, NULL, |
177 | tmpbyte &= (0x0f << ((1-unit) << 2)); | 193 | udma_timing[speed - XFER_UDMA_0]); |
178 | /* | ||
179 | * enable ultra dma and set timing | ||
180 | */ | ||
181 | tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2)); | ||
182 | pci_write_config_byte(dev, m5229_udma, tmpbyte); | ||
183 | if (speed >= XFER_UDMA_3) { | 194 | if (speed >= XFER_UDMA_3) { |
184 | pci_read_config_byte(dev, 0x4b, &tmpbyte); | 195 | pci_read_config_byte(dev, 0x4b, &tmpbyte); |
185 | tmpbyte |= 1; | 196 | tmpbyte |= 1; |
@@ -365,19 +376,13 @@ static int ali_cable_override(struct pci_dev *pdev) | |||
365 | * | 376 | * |
366 | * This checks if the controller and the cable are capable | 377 | * This checks if the controller and the cable are capable |
367 | * of UDMA66 transfers. It doesn't check the drives. | 378 | * of UDMA66 transfers. It doesn't check the drives. |
368 | * But see note 2 below! | ||
369 | * | ||
370 | * FIXME: frobs bits that are not defined on newer ALi devicea | ||
371 | */ | 379 | */ |
372 | 380 | ||
373 | static u8 ali_cable_detect(ide_hwif_t *hwif) | 381 | static u8 ali_cable_detect(ide_hwif_t *hwif) |
374 | { | 382 | { |
375 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 383 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
376 | unsigned long flags; | ||
377 | u8 cbl = ATA_CBL_PATA40, tmpbyte; | 384 | u8 cbl = ATA_CBL_PATA40, tmpbyte; |
378 | 385 | ||
379 | local_irq_save(flags); | ||
380 | |||
381 | if (m5229_revision >= 0xC2) { | 386 | if (m5229_revision >= 0xC2) { |
382 | /* | 387 | /* |
383 | * m5229 80-pin cable detection (from Host View) | 388 | * m5229 80-pin cable detection (from Host View) |
@@ -397,8 +402,6 @@ static u8 ali_cable_detect(ide_hwif_t *hwif) | |||
397 | } | 402 | } |
398 | } | 403 | } |
399 | 404 | ||
400 | local_irq_restore(flags); | ||
401 | |||
402 | return cbl; | 405 | return cbl; |
403 | } | 406 | } |
404 | 407 | ||
@@ -594,6 +597,6 @@ static void __exit ali15x3_ide_exit(void) | |||
594 | module_init(ali15x3_ide_init); | 597 | module_init(ali15x3_ide_init); |
595 | module_exit(ali15x3_ide_exit); | 598 | module_exit(ali15x3_ide_exit); |
596 | 599 | ||
597 | MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox"); | 600 | MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz"); |
598 | MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE"); | 601 | MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE"); |
599 | MODULE_LICENSE("GPL"); | 602 | MODULE_LICENSE("GPL"); |