Import 2.3.18pre1
[davej-history.git] / drivers / block / hpt366.c
blobb61f7168727ef57ccae6839754f4e67109e8b225
1 /*
2 * linux/drivers/block/hpt366.c Version 0.12 August 16, 1999
4 * Copyright (C) 1999 Andre Hedrick <andre@suse.com>
6 * drive_number
7 * = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
8 * = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
9 */
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/delay.h>
14 #include <linux/timer.h>
15 #include <linux/mm.h>
16 #include <linux/ioport.h>
17 #include <linux/blkdev.h>
18 #include <linux/hdreg.h>
20 #include <linux/interrupt.h>
21 #include <linux/pci.h>
22 #include <linux/init.h>
23 #include <linux/ide.h>
25 #include <asm/io.h>
26 #include <asm/irq.h>
28 #include "ide_modes.h"
30 const char *bad_ata66_4[] = {
31 "WDC AC310200R",
32 NULL
35 const char *bad_ata66_3[] = {
36 "WDC AC310200R",
37 NULL
40 const char *bad_ata33[] = {
41 "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
42 "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
43 "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
44 "Maxtor 90510D4",
45 "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
46 "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
47 "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
48 NULL
51 struct chipset_bus_clock_list_entry {
52 byte xfer_speed;
53 unsigned int chipset_settings;
56 struct chipset_bus_clock_list_entry forty_base [] = {
58 { XFER_UDMA_4 , 0x900fd943 },
59 { XFER_UDMA_3 , 0x900ad943 },
60 { XFER_UDMA_2 , 0x900bd943 },
61 { XFER_UDMA_1 , 0x9008d943 },
62 { XFER_UDMA_0 , 0x9008d943 },
64 { XFER_MW_DMA_2 , 0xa008d943 },
65 { XFER_MW_DMA_1 , 0xa010d955 },
66 { XFER_MW_DMA_0 , 0xa010d9fc },
68 { XFER_PIO_4 , 0xc008d963 },
69 { XFER_PIO_3 , 0xc010d974 },
70 { XFER_PIO_2 , 0xc010d997 },
71 { XFER_PIO_1 , 0xc010d9c7 },
72 { XFER_PIO_0 , 0xc018d9d9 },
73 { 0 , 0x0120d9d9 }
76 struct chipset_bus_clock_list_entry thirty_three_base [] = {
78 { XFER_UDMA_4 , 0x90c9a731 },
79 { XFER_UDMA_3 , 0x90cfa731 },
80 { XFER_UDMA_2 , 0x90caa731 },
81 { XFER_UDMA_1 , 0x90cba731 },
82 { XFER_UDMA_0 , 0x90c8a731 },
84 { XFER_MW_DMA_2 , 0xa0c8a731 },
85 { XFER_MW_DMA_1 , 0xa0c8a732 }, /* 0xa0c8a733 */
86 { XFER_MW_DMA_0 , 0xa0c8a797 },
88 { XFER_PIO_4 , 0xc0c8a731 },
89 { XFER_PIO_3 , 0xc0c8a742 },
90 { XFER_PIO_2 , 0xc0d0a753 },
91 { XFER_PIO_1 , 0xc0d0a7a3 }, /* 0xc0d0a793 */
92 { XFER_PIO_0 , 0xc0d0a7aa }, /* 0xc0d0a7a7 */
93 { 0 , 0x0120a7a7 }
96 struct chipset_bus_clock_list_entry twenty_five_base [] = {
98 { XFER_UDMA_4 , 0x90c98521 },
99 { XFER_UDMA_3 , 0x90cf8521 },
100 { XFER_UDMA_2 , 0x90cf8521 },
101 { XFER_UDMA_1 , 0x90cb8521 },
102 { XFER_UDMA_0 , 0x90cb8521 },
104 { XFER_MW_DMA_2 , 0xa0ca8521 },
105 { XFER_MW_DMA_1 , 0xa0ca8532 },
106 { XFER_MW_DMA_0 , 0xa0ca8575 },
108 { XFER_PIO_4 , 0xc0ca8521 },
109 { XFER_PIO_3 , 0xc0ca8532 },
110 { XFER_PIO_2 , 0xc0ca8542 },
111 { XFER_PIO_1 , 0xc0d08572 },
112 { XFER_PIO_0 , 0xc0d08585 },
113 { 0 , 0x01208585 }
116 #define HPT366_DEBUG_DRIVE_INFO 0
117 #define HPT366_ALLOW_ATA66_4 0
118 #define HPT366_ALLOW_ATA66_3 1
119 #define HPT366_ALLOW_ATA33_2 1
120 #define HPT366_ALLOW_ATA33_1 1
121 #define HPT366_ALLOW_ATA33_0 1
123 extern char *ide_xfer_verbose (byte xfer_rate);
125 static int check_in_drive_lists (ide_drive_t *drive, const char **list)
127 struct hd_driveid *id = drive->id;
129 while (*list) {
130 if (!strcmp(*list++,id->model)) {
131 #ifdef DEBUG
132 printk("%s: Broken ASIC, BackSpeeding (U)DMA for %s\n", drive->name, id->model);
133 #endif /* DEBUG */
134 return 1;
137 return 0;
140 static unsigned int pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
142 for ( ; chipset_table->xfer_speed ; chipset_table++)
143 if (chipset_table->xfer_speed == speed)
144 return chipset_table->chipset_settings;
145 return 0x01208585;
148 static int hpt366_tune_chipset (ide_drive_t *drive, byte speed)
150 int err;
151 byte busclock;
153 #if HPT366_DEBUG_DRIVE_INFO
154 int drive_number = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
155 #endif /* HPT366_DEBUG_DRIVE_INFO */
156 byte regtime = (drive->select.b.unit & 0x01) ? 0x43 : 0x40;
157 unsigned int reg1 = 0;
158 unsigned int reg2 = 0;
160 pci_read_config_dword(HWIF(drive)->pci_dev, regtime, &reg1);
161 pci_read_config_byte(HWIF(drive)->pci_dev, regtime|0x01, &busclock);
162 switch(busclock) {
163 case 0xd9:
164 reg2 = pci_bus_clock_list(speed, forty_base);
165 break;
166 case 0x85:
167 reg2 = pci_bus_clock_list(speed, twenty_five_base);
168 break;
169 case 0xa7:
170 default:
171 reg2 = pci_bus_clock_list(speed, thirty_three_base);
172 break;
175 if (drive->id->dword_io & 1)
176 reg2 |= 0x80000000;
177 else
178 reg2 &= ~0x80000000;
180 pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2);
181 err = ide_config_drive_speed(drive, speed);
183 #if HPT366_DEBUG_DRIVE_INFO
184 printk("%s: %s drive%d (0x%08x 0x%08x) 0x%04x\n",
185 drive->name, ide_xfer_verbose(speed),
186 drive_number, reg1, reg2, err);
187 #endif /* HPT366_DEBUG_DRIVE_INFO */
188 return(err);
192 * This allows the configuration of ide_pci chipset registers
193 * for cards that learn about the drive's UDMA, DMA, PIO capabilities
194 * after the drive is reported by the OS. Initally for designed for
195 * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc.
197 * check_in_drive_lists(drive, bad_ata66_4)
198 * check_in_drive_lists(drive, bad_ata66_3)
199 * check_in_drive_lists(drive, bad_ata33)
202 static int config_chipset_for_dma (ide_drive_t *drive)
204 struct hd_driveid *id = drive->id;
205 byte speed = 0x00;
207 if ((id->dma_ultra & 0x0010) &&
208 (!check_in_drive_lists(drive, bad_ata66_4)) &&
209 (HPT366_ALLOW_ATA66_4) &&
210 (HWIF(drive)->udma_four)) {
211 if (!((id->dma_ultra >> 8) & 16)) {
212 drive->id->dma_ultra &= ~0xFF00;
213 drive->id->dma_ultra |= 0x1010;
214 drive->id->dma_mword &= ~0x0F00;
215 drive->id->dma_1word &= ~0x0F00;
217 speed = XFER_UDMA_4;
218 } else if ((id->dma_ultra & 0x0008) &&
219 (!check_in_drive_lists(drive, bad_ata66_3)) &&
220 (HPT366_ALLOW_ATA66_3) &&
221 (HWIF(drive)->udma_four)) {
222 if (!((id->dma_ultra >> 8) & 8)) {
223 drive->id->dma_ultra &= ~0xFF00;
224 drive->id->dma_ultra |= 0x0808;
225 drive->id->dma_mword &= ~0x0F00;
226 drive->id->dma_1word &= ~0x0F00;
228 speed = XFER_UDMA_3;
229 } else if ((id->dma_ultra & 0x0004) &&
230 (HPT366_ALLOW_ATA33_2) &&
231 (!check_in_drive_lists(drive, bad_ata33))) {
232 if (!((id->dma_ultra >> 8) & 4)) {
233 drive->id->dma_ultra &= ~0xFF00;
234 drive->id->dma_ultra |= 0x0404;
235 drive->id->dma_mword &= ~0x0F00;
236 drive->id->dma_1word &= ~0x0F00;
238 speed = XFER_UDMA_2;
239 } else if ((id->dma_ultra & 0x0002) &&
240 (HPT366_ALLOW_ATA33_1) &&
241 (!check_in_drive_lists(drive, bad_ata33))) {
242 if (!((id->dma_ultra >> 8) & 2)) {
243 drive->id->dma_ultra &= ~0xFF00;
244 drive->id->dma_ultra |= 0x0202;
245 drive->id->dma_mword &= ~0x0F00;
246 drive->id->dma_1word &= ~0x0F00;
248 speed = XFER_UDMA_1;
249 } else if ((id->dma_ultra & 0x0001) &&
250 (HPT366_ALLOW_ATA33_0) &&
251 (!check_in_drive_lists(drive, bad_ata33))) {
252 if (!((id->dma_ultra >> 8) & 1)) {
253 drive->id->dma_ultra &= ~0xFF00;
254 drive->id->dma_ultra |= 0x0101;
255 drive->id->dma_mword &= ~0x0F00;
256 drive->id->dma_1word &= ~0x0F00;
258 speed = XFER_UDMA_0;
259 } else if (id->dma_mword & 0x0004) {
260 drive->id->dma_ultra &= ~0xFF00;
261 if (!((id->dma_mword >> 8) & 4)) {
262 drive->id->dma_mword &= ~0x0F00;
263 drive->id->dma_mword |= 0x0404;
264 drive->id->dma_1word &= ~0x0F00;
266 speed = XFER_MW_DMA_2;
267 } else if (id->dma_mword & 0x0002) {
268 drive->id->dma_ultra &= ~0xFF00;
269 if (!((id->dma_mword >> 8) & 2)) {
270 drive->id->dma_mword &= ~0x0F00;
271 drive->id->dma_mword |= 0x0202;
272 drive->id->dma_1word &= ~0x0F00;
274 speed = XFER_MW_DMA_1;
275 } else if (id->dma_mword & 0x0001) {
276 drive->id->dma_ultra &= ~0xFF00;
277 if (!((id->dma_mword >> 8) & 1)) {
278 drive->id->dma_mword &= ~0x0F00;
279 drive->id->dma_mword |= 0x0101;
280 drive->id->dma_1word &= ~0x0F00;
282 speed = XFER_MW_DMA_0;
283 } else if (id->dma_1word & 0x0004) {
284 drive->id->dma_ultra &= ~0xFF00;
285 if (!((id->dma_1word >> 8) & 4)) {
286 drive->id->dma_1word &= ~0x0F00;
287 drive->id->dma_1word |= 0x0404;
288 drive->id->dma_mword &= ~0x0F00;
290 speed = XFER_SW_DMA_2;
291 } else if (id->dma_1word & 0x0002) {
292 drive->id->dma_ultra &= ~0xFF00;
293 if (!((id->dma_1word >> 8) & 2)) {
294 drive->id->dma_1word &= ~0x0F00;
295 drive->id->dma_1word |= 0x0202;
296 drive->id->dma_mword &= ~0x0F00;
298 speed = XFER_SW_DMA_1;
299 } else if (id->dma_1word & 0x0001) {
300 drive->id->dma_ultra &= ~0xFF00;
301 if (!((id->dma_1word >> 8) & 1)) {
302 drive->id->dma_1word &= ~0x0F00;
303 drive->id->dma_1word |= 0x0101;
304 drive->id->dma_mword &= ~0x0F00;
306 speed = XFER_SW_DMA_0;
307 } else {
308 return ((int) ide_dma_off_quietly);
311 (void) hpt366_tune_chipset(drive, speed);
313 return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
314 ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
315 ((id->dma_mword >> 8) & 7) ? ide_dma_on :
316 ((id->dma_1word >> 8) & 7) ? ide_dma_on :
317 ide_dma_off_quietly);
320 static void config_chipset_for_pio (ide_drive_t *drive)
322 unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
323 unsigned short xfer_pio = drive->id->eide_pio_modes;
325 byte timing, speed, pio;
327 pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
329 if (xfer_pio> 4)
330 xfer_pio = 0;
332 if (drive->id->eide_pio_iordy > 0) {
333 for (xfer_pio = 5;
334 xfer_pio>0 &&
335 drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
336 xfer_pio--);
337 } else {
338 xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
339 (drive->id->eide_pio_modes & 2) ? 0x04 :
340 (drive->id->eide_pio_modes & 1) ? 0x03 :
341 (drive->id->tPIO & 2) ? 0x02 :
342 (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
345 timing = (xfer_pio >= pio) ? xfer_pio : pio;
347 switch(timing) {
348 case 4: speed = XFER_PIO_4;break;
349 case 3: speed = XFER_PIO_3;break;
350 case 2: speed = XFER_PIO_2;break;
351 case 1: speed = XFER_PIO_1;break;
352 default:
353 speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
354 break;
356 (void) hpt366_tune_chipset(drive, speed);
359 static void hpt366_tune_drive (ide_drive_t *drive, byte pio)
361 byte speed;
362 switch(pio) {
363 case 4: speed = XFER_PIO_4;break;
364 case 3: speed = XFER_PIO_3;break;
365 case 2: speed = XFER_PIO_2;break;
366 case 1: speed = XFER_PIO_1;break;
367 default: speed = XFER_PIO_0;break;
369 (void) hpt366_tune_chipset(drive, speed);
372 static int config_drive_xfer_rate (ide_drive_t *drive)
374 struct hd_driveid *id = drive->id;
375 ide_dma_action_t dma_func = ide_dma_on;
377 if (id && (id->capability & 1) && HWIF(drive)->autodma) {
378 /* Consult the list of known "bad" drives */
379 if (ide_dmaproc(ide_dma_bad_drive, drive)) {
380 dma_func = ide_dma_off;
381 goto fast_ata_pio;
383 dma_func = ide_dma_off_quietly;
384 if (id->field_valid & 4) {
385 if (id->dma_ultra & 0x001F) {
386 /* Force if Capable UltraDMA */
387 dma_func = config_chipset_for_dma(drive);
388 if ((id->field_valid & 2) &&
389 (dma_func != ide_dma_on))
390 goto try_dma_modes;
392 } else if (id->field_valid & 2) {
393 try_dma_modes:
394 if ((id->dma_mword & 0x0007) ||
395 (id->dma_1word & 0x0007)) {
396 /* Force if Capable regular DMA modes */
397 dma_func = config_chipset_for_dma(drive);
398 if (dma_func != ide_dma_on)
399 goto no_dma_set;
401 } else if (ide_dmaproc(ide_dma_good_drive, drive)) {
402 if (id->eide_dma_time > 150) {
403 goto no_dma_set;
405 /* Consult the list of known "good" drives */
406 dma_func = config_chipset_for_dma(drive);
407 if (dma_func != ide_dma_on)
408 goto no_dma_set;
409 } else {
410 goto fast_ata_pio;
412 } else if ((id->capability & 8) || (id->field_valid & 2)) {
413 fast_ata_pio:
414 dma_func = ide_dma_off_quietly;
415 no_dma_set:
417 config_chipset_for_pio(drive);
419 return HWIF(drive)->dmaproc(dma_func, drive);
423 * hpt366_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
425 * This is specific to the HPT366 UDMA bios chipset
426 * by HighPoint|Triones Technologies, Inc.
429 int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
431 byte reg50h = 0, reg52h = 0;
433 switch (func) {
434 case ide_dma_check:
435 return config_drive_xfer_rate(drive);
436 #if 0
437 case ide_dma_lostirq:
438 pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, &reg52h);
439 printk("%s: (ide_dma_lostirq) reg52h=0x%02x\n", drive->name, reg52h);
440 break;
441 case ide_dma_timeout:
442 (void) ide_dmaproc(ide_dma_off_quietly, drive);
443 pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, &reg52h);
444 printk("%s: (ide_dma_timeout) reg52h=0x%02x\n", drive->name, reg52h);
445 if (reg52h & 0x04) {
446 pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
447 pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0xff);
448 pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h);
450 pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
451 pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, &reg52h);
452 printk("%s: (ide_dma_timeout) reg50h=0x%02x reg52h=0x%02x :: again\n", drive->name, reg50h, reg52h);
453 (void) ide_dmaproc(ide_dma_on, drive);
454 if (reg52h & 0x04)
455 (void) ide_dmaproc(ide_dma_off, drive);
456 return 1;
457 #endif
458 default:
459 break;
461 return ide_dmaproc(func, drive); /* use standard DMA stuff */
464 unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name)
466 byte ata66 = 0;
468 pci_read_config_byte(dev, 0x5a, &ata66);
469 if (dev->resource[PCI_ROM_RESOURCE].start)
470 pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
471 printk("%s: reg5ah=0x%02x ATA-%s Cable Port%d\n", name, ata66, (ata66 & 0x02) ? "33" : "66", PCI_FUNC(dev->devfn));
472 return dev->irq;
475 void __init ide_init_hpt366 (ide_hwif_t *hwif)
477 hwif->tuneproc = &hpt366_tune_drive;
478 if (hwif->dma_base) {
479 byte ata66 = 0;
481 hwif->dmaproc = &hpt366_dmaproc;
482 pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66);
483 hwif->udma_four = (ata66 & 0x02) ? 0 : 1;
484 } else {
485 hwif->udma_four = 0;
486 hwif->autodma = 0;
487 hwif->drives[0].autotune = 1;
488 hwif->drives[1].autotune = 1;