diff options
author | Mark Fortescue <mark@mtfhpc.demon.co.uk> | 2007-07-26 02:45:10 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-30 03:27:30 -0400 |
commit | b65f0755fd08c92f377fb434076865284283e2c1 (patch) | |
tree | 5d1af6164e3e1058b3e53ef395687be73dd60f37 | |
parent | a2d6ea0180531b5ace2dc1e64b6e22465ed51267 (diff) |
[SPARC]: Fix floppy on some sun4c systems.
Add in code to support an 82077 FDC on sun4c systems. There is a
problem with spurious interrupts but it does apear to work.
Testing on my SS2 (82072A FDC) shows that the floppy driver is not
100% with sun4c any way (any spurious interrupt kills it, requiring a
reboot to recover).
Signed-off-by: Mark Fortescue <mark@mtfhpc.demon.co.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/asm-sparc/floppy.h | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h index 9073c84218ce..28ce2b9c3da8 100644 --- a/include/asm-sparc/floppy.h +++ b/include/asm-sparc/floppy.h | |||
@@ -101,6 +101,29 @@ static struct sun_floppy_ops sun_fdops; | |||
101 | #define CROSS_64KB(a,s) (0) | 101 | #define CROSS_64KB(a,s) (0) |
102 | 102 | ||
103 | /* Routines unique to each controller type on a Sun. */ | 103 | /* Routines unique to each controller type on a Sun. */ |
104 | static void sun_set_dor(unsigned char value, int fdc_82077) | ||
105 | { | ||
106 | if (sparc_cpu_model == sun4c) { | ||
107 | unsigned int bits = 0; | ||
108 | if (value & 0x10) | ||
109 | bits |= AUXIO_FLPY_DSEL; | ||
110 | if ((value & 0x80) == 0) | ||
111 | bits |= AUXIO_FLPY_EJCT; | ||
112 | set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT)); | ||
113 | } | ||
114 | if (fdc_82077) { | ||
115 | sun_fdc->dor_82077 = value; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static unsigned char sun_read_dir(void) | ||
120 | { | ||
121 | if (sparc_cpu_model == sun4c) | ||
122 | return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0; | ||
123 | else | ||
124 | return sun_fdc->dir_82077; | ||
125 | } | ||
126 | |||
104 | static unsigned char sun_82072_fd_inb(int port) | 127 | static unsigned char sun_82072_fd_inb(int port) |
105 | { | 128 | { |
106 | udelay(5); | 129 | udelay(5); |
@@ -113,7 +136,7 @@ static unsigned char sun_82072_fd_inb(int port) | |||
113 | case 5: /* FD_DATA */ | 136 | case 5: /* FD_DATA */ |
114 | return sun_fdc->data_82072; | 137 | return sun_fdc->data_82072; |
115 | case 7: /* FD_DIR */ | 138 | case 7: /* FD_DIR */ |
116 | return (get_auxio() & AUXIO_FLPY_DCHG)? 0x80: 0; | 139 | return sun_read_dir(); |
117 | }; | 140 | }; |
118 | panic("sun_82072_fd_inb: How did I get here?"); | 141 | panic("sun_82072_fd_inb: How did I get here?"); |
119 | } | 142 | } |
@@ -126,20 +149,7 @@ static void sun_82072_fd_outb(unsigned char value, int port) | |||
126 | printk("floppy: Asked to write to unknown port %d\n", port); | 149 | printk("floppy: Asked to write to unknown port %d\n", port); |
127 | panic("floppy: Port bolixed."); | 150 | panic("floppy: Port bolixed."); |
128 | case 2: /* FD_DOR */ | 151 | case 2: /* FD_DOR */ |
129 | /* Oh geese, 82072 on the Sun has no DOR register, | 152 | sun_set_dor(value, 0); |
130 | * the functionality is implemented via the AUXIO | ||
131 | * I/O register. So we must emulate the behavior. | ||
132 | * | ||
133 | * ASSUMPTIONS: There will only ever be one floppy | ||
134 | * drive attached to a Sun controller | ||
135 | * and it will be at drive zero. | ||
136 | */ | ||
137 | { | ||
138 | unsigned bits = 0; | ||
139 | if (value & 0x10) bits |= AUXIO_FLPY_DSEL; | ||
140 | if ((value & 0x80) == 0) bits |= AUXIO_FLPY_EJCT; | ||
141 | set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT)); | ||
142 | } | ||
143 | break; | 153 | break; |
144 | case 5: /* FD_DATA */ | 154 | case 5: /* FD_DATA */ |
145 | sun_fdc->data_82072 = value; | 155 | sun_fdc->data_82072 = value; |
@@ -161,15 +171,22 @@ static unsigned char sun_82077_fd_inb(int port) | |||
161 | default: | 171 | default: |
162 | printk("floppy: Asked to read unknown port %d\n", port); | 172 | printk("floppy: Asked to read unknown port %d\n", port); |
163 | panic("floppy: Port bolixed."); | 173 | panic("floppy: Port bolixed."); |
174 | case 0: /* FD_STATUS_0 */ | ||
175 | return sun_fdc->status1_82077; | ||
176 | case 1: /* FD_STATUS_1 */ | ||
177 | return sun_fdc->status2_82077; | ||
178 | case 2: /* FD_DOR */ | ||
179 | return sun_fdc->dor_82077; | ||
180 | case 3: /* FD_TDR */ | ||
181 | return sun_fdc->tapectl_82077; | ||
164 | case 4: /* FD_STATUS */ | 182 | case 4: /* FD_STATUS */ |
165 | return sun_fdc->status_82077 & ~STATUS_DMA; | 183 | return sun_fdc->status_82077 & ~STATUS_DMA; |
166 | case 5: /* FD_DATA */ | 184 | case 5: /* FD_DATA */ |
167 | return sun_fdc->data_82077; | 185 | return sun_fdc->data_82077; |
168 | case 7: /* FD_DIR */ | 186 | case 7: /* FD_DIR */ |
169 | /* XXX: Is DCL on 0x80 in sun4m? */ | 187 | return sun_read_dir(); |
170 | return sun_fdc->dir_82077; | ||
171 | }; | 188 | }; |
172 | panic("sun_82072_fd_inb: How did I get here?"); | 189 | panic("sun_82077_fd_inb: How did I get here?"); |
173 | } | 190 | } |
174 | 191 | ||
175 | static void sun_82077_fd_outb(unsigned char value, int port) | 192 | static void sun_82077_fd_outb(unsigned char value, int port) |
@@ -180,8 +197,7 @@ static void sun_82077_fd_outb(unsigned char value, int port) | |||
180 | printk("floppy: Asked to write to unknown port %d\n", port); | 197 | printk("floppy: Asked to write to unknown port %d\n", port); |
181 | panic("floppy: Port bolixed."); | 198 | panic("floppy: Port bolixed."); |
182 | case 2: /* FD_DOR */ | 199 | case 2: /* FD_DOR */ |
183 | /* Happily, the 82077 has a real DOR register. */ | 200 | sun_set_dor(value, 1); |
184 | sun_fdc->dor_82077 = value; | ||
185 | break; | 201 | break; |
186 | case 5: /* FD_DATA */ | 202 | case 5: /* FD_DATA */ |
187 | sun_fdc->data_82077 = value; | 203 | sun_fdc->data_82077 = value; |
@@ -192,6 +208,9 @@ static void sun_82077_fd_outb(unsigned char value, int port) | |||
192 | case 4: /* FD_STATUS */ | 208 | case 4: /* FD_STATUS */ |
193 | sun_fdc->status_82077 = value; | 209 | sun_fdc->status_82077 = value; |
194 | break; | 210 | break; |
211 | case 3: /* FD_TDR */ | ||
212 | sun_fdc->tapectl_82077 = value; | ||
213 | break; | ||
195 | }; | 214 | }; |
196 | return; | 215 | return; |
197 | } | 216 | } |
@@ -332,16 +351,17 @@ static int sun_floppy_init(void) | |||
332 | goto no_sun_fdc; | 351 | goto no_sun_fdc; |
333 | } | 352 | } |
334 | 353 | ||
335 | if(sparc_cpu_model == sun4c) { | 354 | sun_fdops.fd_inb = sun_82077_fd_inb; |
336 | sun_fdops.fd_inb = sun_82072_fd_inb; | 355 | sun_fdops.fd_outb = sun_82077_fd_outb; |
337 | sun_fdops.fd_outb = sun_82072_fd_outb; | 356 | fdc_status = &sun_fdc->status_82077; |
338 | fdc_status = &sun_fdc->status_82072; | 357 | |
339 | /* printk("AUXIO @0x%lx\n", auxio_register); */ /* P3 */ | 358 | if (sun_fdc->dor_82077 == 0x80) { |
340 | } else { | 359 | sun_fdc->dor_82077 = 0x02; |
341 | sun_fdops.fd_inb = sun_82077_fd_inb; | 360 | if (sun_fdc->dor_82077 == 0x80) { |
342 | sun_fdops.fd_outb = sun_82077_fd_outb; | 361 | sun_fdops.fd_inb = sun_82072_fd_inb; |
343 | fdc_status = &sun_fdc->status_82077; | 362 | sun_fdops.fd_outb = sun_82072_fd_outb; |
344 | /* printk("DOR @0x%p\n", &sun_fdc->dor_82077); */ /* P3 */ | 363 | fdc_status = &sun_fdc->status_82072; |
364 | } | ||
345 | } | 365 | } |
346 | 366 | ||
347 | /* Success... */ | 367 | /* Success... */ |