aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-sparc
diff options
context:
space:
mode:
authorMark Fortescue <mark@mtfhpc.demon.co.uk>2007-07-26 02:45:10 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-30 03:27:30 -0400
commitb65f0755fd08c92f377fb434076865284283e2c1 (patch)
tree5d1af6164e3e1058b3e53ef395687be73dd60f37 /include/asm-sparc
parenta2d6ea0180531b5ace2dc1e64b6e22465ed51267 (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>
Diffstat (limited to 'include/asm-sparc')
-rw-r--r--include/asm-sparc/floppy.h80
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. */
104static 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
119static 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
104static unsigned char sun_82072_fd_inb(int port) 127static 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
175static void sun_82077_fd_outb(unsigned char value, int port) 192static 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... */