1 |
1275 |
phoenix |
/*
|
2 |
|
|
*
|
3 |
|
|
|
4 |
|
|
Copyright (C) 1993,1994 Jon Tombs.
|
5 |
|
|
|
6 |
|
|
This program is distributed in the hope that it will be useful,
|
7 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
8 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
9 |
|
|
GNU General Public License for more details.
|
10 |
|
|
|
11 |
|
|
The entire guts of this program was written by dosemu, modified to
|
12 |
|
|
record reads and writes to the ports in the 0x180-0x188 address space,
|
13 |
|
|
while running the CMS program TAPE.EXE V2.0.5 supplied with the drive.
|
14 |
|
|
|
15 |
|
|
Modified to use an array of addresses and generally cleaned up (made
|
16 |
|
|
much shorter) 4 June 94, dosemu isn't that good at writing short code it
|
17 |
|
|
would seem :-). Made independent of 0x180, but I doubt it will work
|
18 |
|
|
at any other address.
|
19 |
|
|
|
20 |
|
|
Modified for distribution with ftape source. 21 June 94, SJL.
|
21 |
|
|
|
22 |
|
|
Modifications on 20 October 95, by Daniel Cohen (catman@wpi.edu):
|
23 |
|
|
Modified to support different DMA, IRQ, and IO Ports. Borland's
|
24 |
|
|
Turbo Debugger in virtual 8086 mode (TD386.EXE with hardware breakpoints
|
25 |
|
|
provided by the TDH386.SYS Device Driver) was used on the CMS program
|
26 |
|
|
TAPE V4.0.5. I set breakpoints on I/O to ports 0x180-0x187. Note that
|
27 |
|
|
CMS's program will not successfully configure the tape drive if you set
|
28 |
|
|
breakpoints on IO Reads, but you can set them on IO Writes without problems.
|
29 |
|
|
Known problems:
|
30 |
|
|
- You can not use DMA Channels 5 or 7.
|
31 |
|
|
|
32 |
|
|
Modification on 29 January 96, by Daniel Cohen (catman@wpi.edu):
|
33 |
|
|
Modified to only accept IRQs 3 - 7, or 9. Since we can only send a 3 bit
|
34 |
|
|
number representing the IRQ to the card, special handling is required when
|
35 |
|
|
IRQ 9 is selected. IRQ 2 and 9 are the same, and we should request IRQ 9
|
36 |
|
|
from the kernel while telling the card to use IRQ 2. Thanks to Greg
|
37 |
|
|
Crider (gcrider@iclnet.org) for finding and locating this bug, as well as
|
38 |
|
|
testing the patch.
|
39 |
|
|
|
40 |
|
|
Modification on 11 December 96, by Claus Heine (claus@momo.math.rwth-aachen.de):
|
41 |
|
|
Modified a little to use variahle ft_fdc_base, ft_fdc_irq, ft_fdc_dma
|
42 |
|
|
instead of preprocessor symbols. Thus we can compile this into the module
|
43 |
|
|
or kernel and let the user specify the options as command line arguments.
|
44 |
|
|
|
45 |
|
|
*
|
46 |
|
|
* $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/linux/linux-2.4/drivers/char/ftape/lowlevel/fc-10.c,v $
|
47 |
|
|
* $Revision: 1.1.1.1 $
|
48 |
|
|
* $Date: 2004-04-15 02:02:34 $
|
49 |
|
|
*
|
50 |
|
|
* This file contains code for the CMS FC-10/FC-20 card.
|
51 |
|
|
*/
|
52 |
|
|
|
53 |
|
|
#include <asm/io.h>
|
54 |
|
|
#include <linux/ftape.h>
|
55 |
|
|
#include "../lowlevel/ftape-tracing.h"
|
56 |
|
|
#include "../lowlevel/fdc-io.h"
|
57 |
|
|
#include "../lowlevel/fc-10.h"
|
58 |
|
|
|
59 |
|
|
__u16 inbs_magic[] = {
|
60 |
|
|
0x3, 0x3, 0x0, 0x4, 0x7, 0x2, 0x5, 0x3, 0x1, 0x4,
|
61 |
|
|
0x3, 0x5, 0x2, 0x0, 0x3, 0x7, 0x4, 0x2,
|
62 |
|
|
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
|
63 |
|
|
};
|
64 |
|
|
|
65 |
|
|
__u16 fc10_ports[] = {
|
66 |
|
|
0x180, 0x210, 0x2A0, 0x300, 0x330, 0x340, 0x370
|
67 |
|
|
};
|
68 |
|
|
|
69 |
|
|
int fc10_enable(void)
|
70 |
|
|
{
|
71 |
|
|
int i;
|
72 |
|
|
__u8 cardConfig = 0x00;
|
73 |
|
|
__u8 x;
|
74 |
|
|
TRACE_FUN(ft_t_flow);
|
75 |
|
|
|
76 |
|
|
/* This code will only work if the FC-10 (or FC-20) is set to
|
77 |
|
|
* use DMA channels 1, 2, or 3. DMA channels 5 and 7 seem to be
|
78 |
|
|
* initialized by the same command as channels 1 and 3, respectively.
|
79 |
|
|
*/
|
80 |
|
|
if (ft_fdc_dma > 3) {
|
81 |
|
|
TRACE_ABORT(0, ft_t_err,
|
82 |
|
|
"Error: The FC-10/20 must be set to use DMA channels 1, 2, or 3!");
|
83 |
|
|
}
|
84 |
|
|
/* Only allow the FC-10/20 to use IRQ 3-7, or 9. Note that CMS's program
|
85 |
|
|
* only accepts IRQ's 2-7, but in linux, IRQ 2 is the same as IRQ 9.
|
86 |
|
|
*/
|
87 |
|
|
if (ft_fdc_irq < 3 || ft_fdc_irq == 8 || ft_fdc_irq > 9) {
|
88 |
|
|
TRACE_ABORT(0, ft_t_err,
|
89 |
|
|
"Error: The FC-10/20 must be set to use IRQ levels 3 - 7, or 9!\n"
|
90 |
|
|
KERN_INFO "Note: IRQ 9 is the same as IRQ 2");
|
91 |
|
|
}
|
92 |
|
|
/* Clear state machine ???
|
93 |
|
|
*/
|
94 |
|
|
for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
|
95 |
|
|
inb(ft_fdc_base + inbs_magic[i]);
|
96 |
|
|
}
|
97 |
|
|
outb(0x0, ft_fdc_base);
|
98 |
|
|
|
99 |
|
|
x = inb(ft_fdc_base);
|
100 |
|
|
if (x == 0x13 || x == 0x93) {
|
101 |
|
|
for (i = 1; i < 8; i++) {
|
102 |
|
|
if (inb(ft_fdc_base + i) != x) {
|
103 |
|
|
TRACE_EXIT 0;
|
104 |
|
|
}
|
105 |
|
|
}
|
106 |
|
|
} else {
|
107 |
|
|
TRACE_EXIT 0;
|
108 |
|
|
}
|
109 |
|
|
|
110 |
|
|
outb(0x8, ft_fdc_base);
|
111 |
|
|
|
112 |
|
|
for (i = 0; i < 8; i++) {
|
113 |
|
|
if (inb(ft_fdc_base + i) != 0x0) {
|
114 |
|
|
TRACE_EXIT 0;
|
115 |
|
|
}
|
116 |
|
|
}
|
117 |
|
|
outb(0x10, ft_fdc_base);
|
118 |
|
|
|
119 |
|
|
for (i = 0; i < 8; i++) {
|
120 |
|
|
if (inb(ft_fdc_base + i) != 0xff) {
|
121 |
|
|
TRACE_EXIT 0;
|
122 |
|
|
}
|
123 |
|
|
}
|
124 |
|
|
|
125 |
|
|
/* Okay, we found a FC-10 card ! ???
|
126 |
|
|
*/
|
127 |
|
|
outb(0x0, fdc.ccr);
|
128 |
|
|
|
129 |
|
|
/* Clear state machine again ???
|
130 |
|
|
*/
|
131 |
|
|
for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
|
132 |
|
|
inb(ft_fdc_base + inbs_magic[i]);
|
133 |
|
|
}
|
134 |
|
|
/* Send io port */
|
135 |
|
|
for (i = 0; i < NR_ITEMS(fc10_ports); i++)
|
136 |
|
|
if (ft_fdc_base == fc10_ports[i])
|
137 |
|
|
cardConfig = i + 1;
|
138 |
|
|
if (cardConfig == 0) {
|
139 |
|
|
TRACE_EXIT 0; /* Invalid I/O Port */
|
140 |
|
|
}
|
141 |
|
|
/* and IRQ - If using IRQ 9, tell the FC card it is actually IRQ 2 */
|
142 |
|
|
if (ft_fdc_irq != 9)
|
143 |
|
|
cardConfig |= ft_fdc_irq << 3;
|
144 |
|
|
else
|
145 |
|
|
cardConfig |= 2 << 3;
|
146 |
|
|
|
147 |
|
|
/* and finally DMA Channel */
|
148 |
|
|
cardConfig |= ft_fdc_dma << 6;
|
149 |
|
|
outb(cardConfig, ft_fdc_base); /* DMA [2 bits]/IRQ [3 bits]/BASE [3 bits] */
|
150 |
|
|
|
151 |
|
|
/* Enable FC-10 ???
|
152 |
|
|
*/
|
153 |
|
|
outb(0, fdc.ccr);
|
154 |
|
|
outb(0, fdc.dor2);
|
155 |
|
|
outb(FDC_DMA_MODE /* 8 */, fdc.dor);
|
156 |
|
|
outb(FDC_DMA_MODE /* 8 */, fdc.dor);
|
157 |
|
|
outb(1, fdc.dor2);
|
158 |
|
|
|
159 |
|
|
/*************************************
|
160 |
|
|
*
|
161 |
|
|
* cH: why the hell should this be necessary? This is done
|
162 |
|
|
* by fdc_reset()!!!
|
163 |
|
|
*
|
164 |
|
|
*************************************/
|
165 |
|
|
/* Initialize fdc, select drive B:
|
166 |
|
|
*/
|
167 |
|
|
outb(FDC_DMA_MODE, fdc.dor); /* assert reset, dma & irq enabled */
|
168 |
|
|
/* 0x08 */
|
169 |
|
|
outb(FDC_DMA_MODE|FDC_RESET_NOT, fdc.dor); /* release reset */
|
170 |
|
|
/* 0x08 | 0x04 = 0x0c */
|
171 |
|
|
outb(FDC_DMA_MODE|FDC_RESET_NOT|FDC_MOTOR_1|FTAPE_SEL_B, fdc.dor);
|
172 |
|
|
/* 0x08 | 0x04 | 0x20 | 0x01 = 0x2d */
|
173 |
|
|
/* select drive 1 */ /* why not drive 0 ???? */
|
174 |
|
|
TRACE_EXIT (x == 0x93) ? 2 : 1;
|
175 |
|
|
}
|