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 #undefREALLY_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 #undefALWAYS_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 staticvoidsub22 (charb, charc)
/* */ 42 { 43 inti;
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 staticvoidtune_dtc2278 (ide_drive_t *drive, bytepio)
/* */ 60 { 61 unsignedlongflags;
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 voidinit_dtc2278 (void)
/* */ 87 { 88 unsignedlongflags;
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 #ifdefALWAYS_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 }