1 /*
2 * linux/drivers/block/dtc2278.c Version 0.02 Feb 10, 1996
3 *
4 * Copyright (C) 1996 Linus Torvalds & author (see below)
5 */
6
7 #undef REALLY_SLOW_IO /* most systems can safely undef this */
8
9 #include <linux/types.h>
10 #include <linux/kernel.h>
11 #include <linux/delay.h>
12 #include <linux/timer.h>
13 #include <linux/mm.h>
14 #include <linux/ioport.h>
15 #include <linux/blkdev.h>
16 #include <linux/hdreg.h>
17 #include <asm/io.h>
18 #include "ide.h"
19 #include "ide_modes.h"
20
21 /*
22 * Changing this #undef to #define may solve start up problems in some systems.
23 */
24 #undef ALWAYS_SET_DTC2278_PIO_MODE
25
26 /*
27 * From: andy@cercle.cts.com (Dyan Wile)
28 *
29 * Below is a patch for DTC-2278 - alike software-programmable controllers
30 * The code enables the secondary IDE controller and the PIO4 (3?) timings on
31 * the primary (EIDE). You may probably have to enable the 32-bit support to
32 * get the full speed. You better get the disk interrupts disabled ( hdparm -u0
33 * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my
34 * filesystem corrupted with -u1, but under heavy disk load only :-)
35 *
36 * This chipset is now forced to use the "serialize" feature,
37 * and irq-unmasking is disallowed. If io_32bit is enabled,
38 * it must be done for BOTH drives on each interface.
39 */
40
41 static void sub22 (char b, char c)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
42 {
43 int i;
44
45 for(i = 0; i < 3; ++i) {
46 inb(0x3f6);
47 outb_p(b,0xb0);
48 inb(0x3f6);
49 outb_p(c,0xb4);
50 inb(0x3f6);
51 if(inb(0xb4) == c) {
52 outb_p(7,0xb0);
53 inb(0x3f6);
54 return; /* success */
55 }
56 }
57 }
58
59 static void tune_dtc2278 (ide_drive_t *drive, byte pio)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
60 {
61 unsigned long flags;
62
63 if (pio == 255)
64 pio = ide_get_best_pio_mode(drive);
65
66 if (pio >= 3) {
67 save_flags(flags);
68 cli();
69 /*
70 * This enables PIO mode4 (3?) on the first interface
71 */
72 sub22(1,0xc3);
73 sub22(0,0xa0);
74 restore_flags(flags);
75 } else {
76 /* we don't know how to set it back again.. */
77 }
78
79 /*
80 * 32bit I/O has to be enabled for *both* drives at the same time.
81 */
82 drive->io_32bit = 1;
83 HWIF(drive)->drives[!drive->select.b.unit].io_32bit = 1;
84 }
85
86 void init_dtc2278 (void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
87 {
88 unsigned long flags;
89
90 save_flags(flags);
91 cli();
92 /*
93 * This enables the second interface
94 */
95 outb_p(4,0xb0);
96 inb(0x3f6);
97 outb_p(0x20,0xb4);
98 inb(0x3f6);
99 #ifdef ALWAYS_SET_DTC2278_PIO_MODE
100 /*
101 * This enables PIO mode4 (3?) on the first interface
102 * and may solve start-up problems for some people.
103 */
104 sub22(1,0xc3);
105 sub22(0,0xa0);
106 #endif
107 restore_flags(flags);
108
109 ide_hwifs[0].serialized = 1;
110 ide_hwifs[0].chipset = ide_dtc2278;
111 ide_hwifs[1].chipset = ide_dtc2278;
112 ide_hwifs[0].tuneproc = &tune_dtc2278;
113 ide_hwifs[0].no_unmask = 1;
114 ide_hwifs[1].no_unmask = 1;
115 }