1 /*
2  * Copyright (C) 1993-1996 Bas Laarhoven,
3  *           (C) 1996-1997 Claus-Justus Heine.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2, or (at your option)
8  any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING.  If not, write to
17  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19  *
20  * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-io.c,v $
21  * $Revision: 1.7.4.2 $
22  * $Date: 1997/11/16 14:48:17 $
23  *
24  *      This file contains the low-level floppy disk interface code
25  *      for the QIC-40/80/3010/3020 floppy-tape driver "ftape" for
26  *      Linux.
27  */
28 
29 #include <linux/config.h> /* for CONFIG_FT_* */
30 #include <linux/errno.h>
31 #include <linux/sched.h>
32 #include <linux/ioport.h>
33 #include <linux/version.h>
34 #include <linux/interrupt.h>
35 #include <asm/system.h>
36 #include <asm/io.h>
37 #include <asm/dma.h>
38 #include <asm/irq.h>
39 
40 #include <linux/ftape.h>
41 #include <linux/qic117.h>
42 #include "../lowlevel/ftape-tracing.h"
43 #include "../lowlevel/fdc-io.h"
44 #include "../lowlevel/fdc-isr.h"
45 #include "../lowlevel/ftape-io.h"
46 #include "../lowlevel/ftape-rw.h"
47 #include "../lowlevel/ftape-ctl.h"
48 #include "../lowlevel/ftape-calibr.h"
49 #include "../lowlevel/fc-10.h"
50 
51 /*      Global vars.
52  */
53 int ftape_motor;
54 volatile int ftape_current_cylinder = -1;
55 volatile fdc_mode_enum fdc_mode = fdc_idle;
56 fdc_config_info fdc;
57 DECLARE_WAIT_QUEUE_HEAD(ftape_wait_intr);
58 
59 unsigned int ft_fdc_base       = CONFIG_FT_FDC_BASE;
60 unsigned int ft_fdc_irq        = CONFIG_FT_FDC_IRQ;
61 unsigned int ft_fdc_dma        = CONFIG_FT_FDC_DMA;
62 unsigned int ft_fdc_threshold  = CONFIG_FT_FDC_THR;  /* bytes */
63 unsigned int ft_fdc_rate_limit = CONFIG_FT_FDC_MAX_RATE; /* bits/sec */
64 int ft_probe_fc10        = CONFIG_FT_PROBE_FC10;
65 int ft_mach2             = CONFIG_FT_MACH2;
66 
67 /*      Local vars.
68  */
69 static unsigned int fdc_calibr_count;
70 static unsigned int fdc_calibr_time;
71 static int fdc_status;
72 volatile __u8 fdc_head;		/* FDC head from sector id */
73 volatile __u8 fdc_cyl;		/* FDC track from sector id */
74 volatile __u8 fdc_sect;		/* FDC sector from sector id */
75 static int fdc_data_rate = 500;	/* data rate (Kbps) */
76 static int fdc_rate_code;	/* data rate code (0 == 500 Kbps) */
77 static int fdc_seek_rate = 2;	/* step rate (msec) */
78 static void (*do_ftape) (void);
79 static int fdc_fifo_state;	/* original fifo setting - fifo enabled */
80 static int fdc_fifo_thr;	/* original fifo setting - threshold */
81 static int fdc_lock_state;	/* original lock setting - locked */
82 static int fdc_fifo_locked;	/* has fifo && lock set ? */
83 static __u8 fdc_precomp;	/* default precomp. value (nsec) */
84 static __u8 fdc_prec_code;	/* fdc precomp. select code */
85 
86 static char ftape_id[] = "ftape";  /* used by request irq and free irq */
87 
fdc_catch_stray_interrupts(int count)88 void fdc_catch_stray_interrupts(int count)
89 {
90 	unsigned long flags;
91 
92 	save_flags(flags);
93 	cli();
94 	if (count == 0) {
95 		ft_expected_stray_interrupts = 0;
96 	} else {
97 		ft_expected_stray_interrupts += count;
98 	}
99 	restore_flags(flags);
100 }
101 
102 /*  Wait during a timeout period for a given FDC status.
103  *  If usecs == 0 then just test status, else wait at least for usecs.
104  *  Returns -ETIME on timeout. Function must be calibrated first !
105  */
fdc_wait(unsigned int usecs,__u8 mask,__u8 state)106 int fdc_wait(unsigned int usecs, __u8 mask, __u8 state)
107 {
108 	int count_1 = (fdc_calibr_count * usecs +
109                        fdc_calibr_count - 1) / fdc_calibr_time;
110 
111 	do {
112 		fdc_status = inb_p(fdc.msr);
113 		if ((fdc_status & mask) == state) {
114 			return 0;
115 		}
116 	} while (count_1-- >= 0);
117 	return -ETIME;
118 }
119 
fdc_ready_wait(unsigned int usecs)120 int fdc_ready_wait(unsigned int usecs)
121 {
122 	return fdc_wait(usecs, FDC_DATA_READY | FDC_BUSY, FDC_DATA_READY);
123 }
124 
125 /* Why can't we just use udelay()?
126  */
fdc_usec_wait(unsigned int usecs)127 static void fdc_usec_wait(unsigned int usecs)
128 {
129 	fdc_wait(usecs, 0, 1);	/* will always timeout ! */
130 }
131 
fdc_ready_out_wait(unsigned int usecs)132 int fdc_ready_out_wait(unsigned int usecs)
133 {
134 	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
135 	return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_OUT_READY);
136 }
137 
fdc_ready_in_wait(unsigned int usecs)138 int fdc_ready_in_wait(unsigned int usecs)
139 {
140 	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
141 	return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_IN_READY);
142 }
143 
fdc_wait_calibrate(void)144 void fdc_wait_calibrate(void)
145 {
146 	ftape_calibrate("fdc_wait",
147 			fdc_usec_wait, &fdc_calibr_count, &fdc_calibr_time);
148 }
149 
150 /*  Wait for a (short) while for the FDC to become ready
151  *  and transfer the next command byte.
152  *  Return -ETIME on timeout on getting ready (depends on hardware!).
153  */
fdc_write(const __u8 data)154 static int fdc_write(const __u8 data)
155 {
156 	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
157 	if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_IN_READY) < 0) {
158 		return -ETIME;
159 	} else {
160 		outb(data, fdc.fifo);
161 		return 0;
162 	}
163 }
164 
165 /*  Wait for a (short) while for the FDC to become ready
166  *  and transfer the next result byte.
167  *  Return -ETIME if timeout on getting ready (depends on hardware!).
168  */
fdc_read(__u8 * data)169 static int fdc_read(__u8 * data)
170 {
171 	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
172 	if (fdc_wait(150, FDC_DATA_READY_MASK, FDC_DATA_OUT_READY) < 0) {
173 		return -ETIME;
174 	} else {
175 		*data = inb(fdc.fifo);
176 		return 0;
177 	}
178 }
179 
180 /*  Output a cmd_len long command string to the FDC.
181  *  The FDC should be ready to receive a new command or
182  *  an error (EBUSY or ETIME) will occur.
183  */
fdc_command(const __u8 * cmd_data,int cmd_len)184 int fdc_command(const __u8 * cmd_data, int cmd_len)
185 {
186 	int result = 0;
187 	unsigned long flags;
188 	int count = cmd_len;
189 	int retry = 0;
190 #ifdef TESTING
191 	static unsigned int last_time;
192 	unsigned int time;
193 #endif
194 	TRACE_FUN(ft_t_any);
195 
196 	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
197 	save_flags(flags);
198 	cli();
199 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,30)
200 	if (!in_interrupt())
201 #else
202 	if (!intr_count)
203 #endif
204 		/* Yes, I know, too much comments inside this function
205 		 * ...
206 		 *
207 		 * Yet another bug in the original driver. All that
208 		 * havoc is caused by the fact that the isr() sends
209 		 * itself a command to the floppy tape driver (pause,
210 		 * micro step pause).  Now, the problem is that
211 		 * commands are transmitted via the fdc_seek
212 		 * command. But: the fdc performs seeks in the
213 		 * background i.e. it doesn't signal busy while
214 		 * sending the step pulses to the drive. Therefore the
215 		 * non-interrupt level driver has no chance to tell
216 		 * whether the isr() just has issued a seek. Therefore
217 		 * we HAVE TO have a look at the ft_hide_interrupt
218 		 * flag: it signals the non-interrupt level part of
219 		 * the driver that it has to wait for the fdc until it
220 		 * has completet seeking.
221 		 *
222 		 * THIS WAS PRESUMABLY THE REASON FOR ALL THAT
223 		 * "fdc_read timeout" errors, I HOPE :-)
224 		 */
225 		if (ft_hide_interrupt) {
226 			restore_flags(flags);
227 			TRACE(ft_t_info,
228 			      "Waiting for the isr() completing fdc_seek()");
229 			if (fdc_interrupt_wait(2 * FT_SECOND) < 0) {
230 				TRACE(ft_t_warn,
231 		      "Warning: timeout waiting for isr() seek to complete");
232 			}
233 			if (ft_hide_interrupt || !ft_seek_completed) {
234 				/* There cannot be another
235 				 * interrupt. The isr() only stops
236 				 * the tape and the next interrupt
237 				 * won't come until we have send our
238 				 * command to the drive.
239 				 */
240 				TRACE_ABORT(-EIO, ft_t_bug,
241 					    "BUG? isr() is still seeking?\n"
242 					    KERN_INFO "hide: %d\n"
243 					    KERN_INFO "seek: %d",
244 					    ft_hide_interrupt,
245 					    ft_seek_completed);
246 
247 			}
248 			fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
249 			save_flags(flags);
250 			cli();
251 		}
252 	fdc_status = inb(fdc.msr);
253 	if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) {
254 		restore_flags(flags);
255 		TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready");
256 	}
257 	fdc_mode = *cmd_data;	/* used by isr */
258 #ifdef TESTING
259 	if (fdc_mode == FDC_SEEK) {
260 		time = ftape_timediff(last_time, ftape_timestamp());
261 		if (time < 6000) {
262 	TRACE(ft_t_bug,"Warning: short timeout between seek commands: %d",
263 	      time);
264 		}
265 	}
266 #endif
267 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,30)
268 	if (!in_interrupt()) {
269 		/* shouldn't be cleared if called from isr
270 		 */
271 		ft_interrupt_seen = 0;
272 	}
273 #else
274 	if (!intr_count) {
275 		/* shouldn't be cleared if called from isr
276 		 */
277 		ft_interrupt_seen = 0;
278 	}
279 #endif
280 	while (count) {
281 		result = fdc_write(*cmd_data);
282 		if (result < 0) {
283 			TRACE(ft_t_fdc_dma,
284 			      "fdc_mode = %02x, status = %02x at index %d",
285 			      (int) fdc_mode, (int) fdc_status,
286 			      cmd_len - count);
287 			if (++retry <= 3) {
288 				TRACE(ft_t_warn, "fdc_write timeout, retry");
289 			} else {
290 				TRACE(ft_t_err, "fdc_write timeout, fatal");
291 				/* recover ??? */
292 				break;
293 			}
294 		} else {
295 			--count;
296 			++cmd_data;
297 		}
298         }
299 #ifdef TESTING
300 	if (fdc_mode == FDC_SEEK) {
301 		last_time = ftape_timestamp();
302 	}
303 #endif
304 	restore_flags(flags);
305 	TRACE_EXIT result;
306 }
307 
308 /*  Input a res_len long result string from the FDC.
309  *  The FDC should be ready to send the result or an error
310  *  (EBUSY or ETIME) will occur.
311  */
fdc_result(__u8 * res_data,int res_len)312 int fdc_result(__u8 * res_data, int res_len)
313 {
314 	int result = 0;
315 	unsigned long flags;
316 	int count = res_len;
317 	int retry = 0;
318 	TRACE_FUN(ft_t_any);
319 
320 	save_flags(flags);
321 	cli();
322 	fdc_status = inb(fdc.msr);
323 	if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) {
324 		TRACE(ft_t_err, "fdc not ready");
325 		result = -EBUSY;
326 	} else while (count) {
327 		if (!(fdc_status & FDC_BUSY)) {
328 			restore_flags(flags);
329 			TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase");
330 		}
331 		result = fdc_read(res_data);
332 		if (result < 0) {
333 			TRACE(ft_t_fdc_dma,
334 			      "fdc_mode = %02x, status = %02x at index %d",
335 			      (int) fdc_mode,
336 			      (int) fdc_status,
337 			      res_len - count);
338 			if (++retry <= 3) {
339 				TRACE(ft_t_warn, "fdc_read timeout, retry");
340 			} else {
341 				TRACE(ft_t_err, "fdc_read timeout, fatal");
342 				/* recover ??? */
343 				break;
344 				++retry;
345 			}
346 		} else {
347 			--count;
348 			++res_data;
349 		}
350 	}
351 	restore_flags(flags);
352 	fdc_usec_wait(FT_RQM_DELAY);	/* allow FDC to negate BSY */
353 	TRACE_EXIT result;
354 }
355 
356 /*      Handle command and result phases for
357  *      commands without data phase.
358  */
fdc_issue_command(const __u8 * out_data,int out_count,__u8 * in_data,int in_count)359 int fdc_issue_command(const __u8 * out_data, int out_count,
360 		      __u8 * in_data, int in_count)
361 {
362 	TRACE_FUN(ft_t_any);
363 
364 	if (out_count > 0) {
365 		TRACE_CATCH(fdc_command(out_data, out_count),);
366 	}
367 	/* will take 24 - 30 usec for fdc_sense_drive_status and
368 	 * fdc_sense_interrupt_status commands.
369 	 *    35 fails sometimes (5/9/93 SJL)
370 	 * On a loaded system it incidentally takes longer than
371 	 * this for the fdc to get ready ! ?????? WHY ??????
372 	 * So until we know what's going on use a very long timeout.
373 	 */
374 	TRACE_CATCH(fdc_ready_out_wait(500 /* usec */),);
375 	if (in_count > 0) {
376 		TRACE_CATCH(fdc_result(in_data, in_count),
377 			    TRACE(ft_t_err, "result phase aborted"));
378 	}
379 	TRACE_EXIT 0;
380 }
381 
382 /*      Wait for FDC interrupt with timeout (in milliseconds).
383  *      Signals are blocked so the wait will not be aborted.
384  *      Note: interrupts must be enabled ! (23/05/93 SJL)
385  */
fdc_interrupt_wait(unsigned int time)386 int fdc_interrupt_wait(unsigned int time)
387 {
388 	DECLARE_WAITQUEUE(wait,current);
389 	sigset_t old_sigmask;
390 	static int resetting;
391 	long timeout;
392 
393 	TRACE_FUN(ft_t_fdc_dma);
394 
395 #if LINUX_VERSION_CODE >= KERNEL_VER(2,0,16)
396  	if (waitqueue_active(&ftape_wait_intr)) {
397 		TRACE_ABORT(-EIO, ft_t_err, "error: nested call");
398 	}
399 #else
400 	if (ftape_wait_intr) {
401 		TRACE_ABORT(-EIO, ft_t_err, "error: nested call");
402 	}
403 #endif
404 	/* timeout time will be up to USPT microseconds too long ! */
405 	timeout = (1000 * time + FT_USPT - 1) / FT_USPT;
406 
407 	spin_lock_irq(&current->sigmask_lock);
408 	old_sigmask = current->blocked;
409 	sigfillset(&current->blocked);
410 	recalc_sigpending(current);
411 	spin_unlock_irq(&current->sigmask_lock);
412 
413 	current->state = TASK_INTERRUPTIBLE;
414 	add_wait_queue(&ftape_wait_intr, &wait);
415 	while (!ft_interrupt_seen && (current->state == TASK_INTERRUPTIBLE)) {
416 		timeout = schedule_timeout(timeout);
417         }
418 
419 	spin_lock_irq(&current->sigmask_lock);
420 	current->blocked = old_sigmask;
421 	recalc_sigpending(current);
422 	spin_unlock_irq(&current->sigmask_lock);
423 
424 	remove_wait_queue(&ftape_wait_intr, &wait);
425 	/*  the following IS necessary. True: as well
426 	 *  wake_up_interruptible() as the schedule() set TASK_RUNNING
427 	 *  when they wakeup a task, BUT: it may very well be that
428 	 *  ft_interrupt_seen is already set to 1 when we enter here
429 	 *  in which case schedule() gets never called, and
430 	 *  TASK_RUNNING never set. This has the funny effect that we
431 	 *  execute all the code until we leave kernel space, but then
432 	 *  the task is stopped (a task CANNOT be preempted while in
433 	 *  kernel mode. Sending a pair of SIGSTOP/SIGCONT to the
434 	 *  tasks wakes it up again. Funny! :-)
435 	 */
436 	current->state = TASK_RUNNING;
437 	if (ft_interrupt_seen) { /* woken up by interrupt */
438 		ft_interrupt_seen = 0;
439 		TRACE_EXIT 0;
440 	}
441 	/*  Original comment:
442 	 *  In first instance, next statement seems unnecessary since
443 	 *  it will be cleared in fdc_command. However, a small part of
444 	 *  the software seems to rely on this being cleared here
445 	 *  (ftape_close might fail) so stick to it until things get fixed !
446 	 */
447 	/*  My deeply sought of knowledge:
448 	 *  Behold NO! It is obvious. fdc_reset() doesn't call fdc_command()
449 	 *  but nevertheless uses fdc_interrupt_wait(). OF COURSE this needs to
450 	 *  be reset here.
451 	 */
452 	ft_interrupt_seen = 0;	/* clear for next call */
453 	if (!resetting) {
454 		resetting = 1;	/* break infinite recursion if reset fails */
455 		TRACE(ft_t_any, "cleanup reset");
456 		fdc_reset();
457 		resetting = 0;
458 	}
459 	TRACE_EXIT (signal_pending(current)) ? -EINTR : -ETIME;
460 }
461 
462 /*      Start/stop drive motor. Enable DMA mode.
463  */
fdc_motor(int motor)464 void fdc_motor(int motor)
465 {
466 	int unit = ft_drive_sel;
467 	int data = unit | FDC_RESET_NOT | FDC_DMA_MODE;
468 	TRACE_FUN(ft_t_any);
469 
470 	ftape_motor = motor;
471 	if (ftape_motor) {
472 		data |= FDC_MOTOR_0 << unit;
473 		TRACE(ft_t_noise, "turning motor %d on", unit);
474 	} else {
475 		TRACE(ft_t_noise, "turning motor %d off", unit);
476 	}
477 	if (ft_mach2) {
478 		outb_p(data, fdc.dor2);
479 	} else {
480 		outb_p(data, fdc.dor);
481 	}
482 	ftape_sleep(10 * FT_MILLISECOND);
483 	TRACE_EXIT;
484 }
485 
fdc_update_dsr(void)486 static void fdc_update_dsr(void)
487 {
488 	TRACE_FUN(ft_t_any);
489 
490 	TRACE(ft_t_flow, "rate = %d Kbps, precomp = %d ns",
491 	      fdc_data_rate, fdc_precomp);
492 	if (fdc.type >= i82077) {
493 		outb_p((fdc_rate_code & 0x03) | fdc_prec_code, fdc.dsr);
494 	} else {
495 		outb_p(fdc_rate_code & 0x03, fdc.ccr);
496 	}
497 	TRACE_EXIT;
498 }
499 
fdc_set_write_precomp(int precomp)500 void fdc_set_write_precomp(int precomp)
501 {
502 	TRACE_FUN(ft_t_any);
503 
504 	TRACE(ft_t_noise, "New precomp: %d nsec", precomp);
505 	fdc_precomp = precomp;
506 	/*  write precompensation can be set in multiples of 41.67 nsec.
507 	 *  round the parameter to the nearest multiple and convert it
508 	 *  into a fdc setting. Note that 0 means default to the fdc,
509 	 *  7 is used instead of that.
510 	 */
511 	fdc_prec_code = ((fdc_precomp + 21) / 42) << 2;
512 	if (fdc_prec_code == 0 || fdc_prec_code > (6 << 2)) {
513 		fdc_prec_code = 7 << 2;
514 	}
515 	fdc_update_dsr();
516 	TRACE_EXIT;
517 }
518 
519 /*  Reprogram the 82078 registers to use Data Rate Table 1 on all drives.
520  */
fdc_set_drive_specs(void)521 void fdc_set_drive_specs(void)
522 {
523 	__u8 cmd[] = { FDC_DRIVE_SPEC, 0x00, 0x00, 0x00, 0x00, 0xc0};
524 	int result;
525 	TRACE_FUN(ft_t_any);
526 
527 	TRACE(ft_t_flow, "Setting of drive specs called");
528 	if (fdc.type >= i82078_1) {
529 		cmd[1] = (0 << 5) | (2 << 2);
530 		cmd[2] = (1 << 5) | (2 << 2);
531 		cmd[3] = (2 << 5) | (2 << 2);
532 		cmd[4] = (3 << 5) | (2 << 2);
533 		result = fdc_command(cmd, NR_ITEMS(cmd));
534 		if (result < 0) {
535 			TRACE(ft_t_err, "Setting of drive specs failed");
536 		}
537 	}
538 	TRACE_EXIT;
539 }
540 
541 /* Select clock for fdc, must correspond with tape drive setting !
542  * This also influences the fdc timing so we must adjust some values.
543  */
fdc_set_data_rate(int rate)544 int fdc_set_data_rate(int rate)
545 {
546 	int bad_rate = 0;
547 	TRACE_FUN(ft_t_any);
548 
549 	/* Select clock for fdc, must correspond with tape drive setting !
550 	 * This also influences the fdc timing so we must adjust some values.
551 	 */
552 	TRACE(ft_t_fdc_dma, "new rate = %d", rate);
553 	switch (rate) {
554 	case 250:
555 		fdc_rate_code = fdc_data_rate_250;
556 		break;
557 	case 500:
558 		fdc_rate_code = fdc_data_rate_500;
559 		break;
560 	case 1000:
561 		if (fdc.type < i82077) {
562 			bad_rate = 1;
563                 } else {
564 			fdc_rate_code = fdc_data_rate_1000;
565 		}
566 		break;
567 	case 2000:
568 		if (fdc.type < i82078_1) {
569 			bad_rate = 1;
570                 } else {
571 			fdc_rate_code = fdc_data_rate_2000;
572 		}
573 		break;
574 	default:
575 		bad_rate = 1;
576         }
577 	if (bad_rate) {
578 		TRACE_ABORT(-EIO,
579 			    ft_t_fdc_dma, "%d is not a valid data rate", rate);
580 	}
581 	fdc_data_rate = rate;
582 	fdc_update_dsr();
583 	fdc_set_seek_rate(fdc_seek_rate);  /* clock changed! */
584 	ftape_udelay(1000);
585 	TRACE_EXIT 0;
586 }
587 
588 /*  keep the unit select if keep_select is != 0,
589  */
fdc_dor_reset(int keep_select)590 static void fdc_dor_reset(int keep_select)
591 {
592 	__u8 fdc_ctl = ft_drive_sel;
593 
594 	if (keep_select != 0) {
595 		fdc_ctl |= FDC_DMA_MODE;
596 		if (ftape_motor) {
597 			fdc_ctl |= FDC_MOTOR_0 << ft_drive_sel;
598 		}
599 	}
600 	ftape_udelay(10); /* ??? but seems to be necessary */
601 	if (ft_mach2) {
602 		outb_p(fdc_ctl & 0x0f, fdc.dor);
603 		outb_p(fdc_ctl, fdc.dor2);
604 	} else {
605 		outb_p(fdc_ctl, fdc.dor);
606 	}
607 	fdc_usec_wait(10); /* delay >= 14 fdc clocks */
608 	if (keep_select == 0) {
609 		fdc_ctl = 0;
610 	}
611 	fdc_ctl |= FDC_RESET_NOT;
612 	if (ft_mach2) {
613 		outb_p(fdc_ctl & 0x0f, fdc.dor);
614 		outb_p(fdc_ctl, fdc.dor2);
615 	} else {
616 		outb_p(fdc_ctl, fdc.dor);
617 	}
618 }
619 
620 /*      Reset the floppy disk controller. Leave the ftape_unit selected.
621  */
fdc_reset(void)622 void fdc_reset(void)
623 {
624 	int st0;
625 	int i;
626 	int dummy;
627 	unsigned long flags;
628 	TRACE_FUN(ft_t_any);
629 
630 	save_flags(flags);
631 	cli();
632 
633 	fdc_dor_reset(1); /* keep unit selected */
634 
635 	fdc_mode = fdc_idle;
636 
637 	/*  maybe the cli()/sti() pair is not necessary, BUT:
638 	 *  the following line MUST be here. Otherwise fdc_interrupt_wait()
639 	 *  won't wait. Note that fdc_reset() is called from
640 	 *  ftape_dumb_stop() when the fdc is busy transferring data. In this
641 	 *  case fdc_isr() MOST PROBABLY sets ft_interrupt_seen, and tries
642 	 *  to get the result bytes from the fdc etc. CLASH.
643 	 */
644 	ft_interrupt_seen = 0;
645 
646 	/*  Program data rate
647 	 */
648 	fdc_update_dsr();               /* restore data rate and precomp */
649 
650 	restore_flags(flags);
651 
652         /*
653          *	Wait for first polling cycle to complete
654 	 */
655 	if (fdc_interrupt_wait(1 * FT_SECOND) < 0) {
656 		TRACE(ft_t_err, "no drive polling interrupt!");
657 	} else {	/* clear all disk-changed statuses */
658 		for (i = 0; i < 4; ++i) {
659 			if(fdc_sense_interrupt_status(&st0, &dummy) != 0) {
660 				TRACE(ft_t_err, "sense failed for %d", i);
661 			}
662 			if (i == ft_drive_sel) {
663 				ftape_current_cylinder = dummy;
664 			}
665 		}
666 		TRACE(ft_t_noise, "drive polling completed");
667 	}
668 	/*
669          *	SPECIFY COMMAND
670 	 */
671 	fdc_set_seek_rate(fdc_seek_rate);
672 	/*
673 	 *	DRIVE SPECIFICATION COMMAND (if fdc type known)
674 	 */
675 	if (fdc.type >= i82078_1) {
676 		fdc_set_drive_specs();
677 	}
678 	TRACE_EXIT;
679 }
680 
681 #if !defined(CLK_48MHZ)
682 # define CLK_48MHZ 1
683 #endif
684 
685 /*  When we're done, put the fdc into reset mode so that the regular
686  *  floppy disk driver will figure out that something is wrong and
687  *  initialize the controller the way it wants.
688  */
fdc_disable(void)689 void fdc_disable(void)
690 {
691 	__u8 cmd1[] = {FDC_CONFIGURE, 0x00, 0x00, 0x00};
692 	__u8 cmd2[] = {FDC_LOCK};
693 	__u8 cmd3[] = {FDC_UNLOCK};
694 	__u8 stat[1];
695 	TRACE_FUN(ft_t_flow);
696 
697 	if (!fdc_fifo_locked) {
698 		fdc_reset();
699 		TRACE_EXIT;
700 	}
701 	if (fdc_issue_command(cmd3, 1, stat, 1) < 0 || stat[0] != 0x00) {
702 		fdc_dor_reset(0);
703 		TRACE_ABORT(/**/, ft_t_bug,
704 		"couldn't unlock fifo, configuration remains changed");
705 	}
706 	fdc_fifo_locked = 0;
707 	if (CLK_48MHZ && fdc.type >= i82078) {
708 		cmd1[0] |= FDC_CLK48_BIT;
709 	}
710 	cmd1[2] = ((fdc_fifo_state) ? 0 : 0x20) + (fdc_fifo_thr - 1);
711 	if (fdc_command(cmd1, NR_ITEMS(cmd1)) < 0) {
712 		fdc_dor_reset(0);
713 		TRACE_ABORT(/**/, ft_t_bug,
714 		"couldn't reconfigure fifo to old state");
715 	}
716 	if (fdc_lock_state &&
717 	    fdc_issue_command(cmd2, 1, stat, 1) < 0) {
718 		fdc_dor_reset(0);
719 		TRACE_ABORT(/**/, ft_t_bug, "couldn't lock old state again");
720 	}
721 	TRACE(ft_t_noise, "fifo restored: %sabled, thr. %d, %slocked",
722 	      fdc_fifo_state ? "en" : "dis",
723 	      fdc_fifo_thr, (fdc_lock_state) ? "" : "not ");
724 	fdc_dor_reset(0);
725 	TRACE_EXIT;
726 }
727 
728 /*      Specify FDC seek-rate (milliseconds)
729  */
fdc_set_seek_rate(int seek_rate)730 int fdc_set_seek_rate(int seek_rate)
731 {
732 	/* set step rate, dma mode, and minimal head load and unload times
733 	 */
734 	__u8 in[3] = { FDC_SPECIFY, 1, (1 << 1)};
735 
736 	fdc_seek_rate = seek_rate;
737 	in[1] |= (16 - (fdc_data_rate * fdc_seek_rate) / 500) << 4;
738 
739 	return fdc_command(in, 3);
740 }
741 
742 /*      Sense drive status: get unit's drive status (ST3)
743  */
fdc_sense_drive_status(int * st3)744 int fdc_sense_drive_status(int *st3)
745 {
746 	__u8 out[2];
747 	__u8 in[1];
748 	TRACE_FUN(ft_t_any);
749 
750 	out[0] = FDC_SENSED;
751 	out[1] = ft_drive_sel;
752 	TRACE_CATCH(fdc_issue_command(out, 2, in, 1),);
753 	*st3 = in[0];
754 	TRACE_EXIT 0;
755 }
756 
757 /*      Sense Interrupt Status command:
758  *      should be issued at the end of each seek.
759  *      get ST0 and current cylinder.
760  */
fdc_sense_interrupt_status(int * st0,int * current_cylinder)761 int fdc_sense_interrupt_status(int *st0, int *current_cylinder)
762 {
763 	__u8 out[1];
764 	__u8 in[2];
765 	TRACE_FUN(ft_t_any);
766 
767 	out[0] = FDC_SENSEI;
768 	TRACE_CATCH(fdc_issue_command(out, 1, in, 2),);
769 	*st0 = in[0];
770 	*current_cylinder = in[1];
771 	TRACE_EXIT 0;
772 }
773 
774 /*      step to track
775  */
fdc_seek(int track)776 int fdc_seek(int track)
777 {
778 	__u8 out[3];
779 	int st0, pcn;
780 #ifdef TESTING
781 	unsigned int time;
782 #endif
783 	TRACE_FUN(ft_t_any);
784 
785 	out[0] = FDC_SEEK;
786 	out[1] = ft_drive_sel;
787 	out[2] = track;
788 #ifdef TESTING
789 	time = ftape_timestamp();
790 #endif
791 	/*  We really need this command to work !
792 	 */
793 	ft_seek_completed = 0;
794 	TRACE_CATCH(fdc_command(out, 3),
795 		    fdc_reset();
796 		    TRACE(ft_t_noise, "destination was: %d, resetting FDC...",
797 			  track));
798 	/*    Handle interrupts until ft_seek_completed or timeout.
799 	 */
800 	for (;;) {
801 		TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
802 		if (ft_seek_completed) {
803 			TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
804 			if ((st0 & ST0_SEEK_END) == 0) {
805 				TRACE_ABORT(-EIO, ft_t_err,
806 				      "no seek-end after seek completion !??");
807 			}
808 			break;
809 		}
810 	}
811 #ifdef TESTING
812 	time = ftape_timediff(time, ftape_timestamp()) / ABS(track - ftape_current_cylinder);
813 	if ((time < 900 || time > 3100) && ABS(track - ftape_current_cylinder) > 5) {
814 		TRACE(ft_t_warn, "Wrong FDC STEP interval: %d usecs (%d)",
815                          time, track - ftape_current_cylinder);
816 	}
817 #endif
818 	/*    Verify whether we issued the right tape command.
819 	 */
820 	/* Verify that we seek to the proper track. */
821 	if (pcn != track) {
822 		TRACE_ABORT(-EIO, ft_t_err, "bad seek..");
823 	}
824 	ftape_current_cylinder = track;
825 	TRACE_EXIT 0;
826 }
827 
828 /*      Recalibrate and wait until home.
829  */
fdc_recalibrate(void)830 int fdc_recalibrate(void)
831 {
832 	__u8 out[2];
833 	int st0;
834 	int pcn;
835 	int retry;
836 	int old_seek_rate = fdc_seek_rate;
837 	TRACE_FUN(ft_t_any);
838 
839 	TRACE_CATCH(fdc_set_seek_rate(6),);
840 	out[0] = FDC_RECAL;
841 	out[1] = ft_drive_sel;
842 	ft_seek_completed = 0;
843 	TRACE_CATCH(fdc_command(out, 2),);
844 	/*    Handle interrupts until ft_seek_completed or timeout.
845 	 */
846 	for (retry = 0;; ++retry) {
847 		TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
848 		if (ft_seek_completed) {
849 			TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
850 			if ((st0 & ST0_SEEK_END) == 0) {
851 				if (retry < 1) {
852 					continue; /* some drives/fdc's
853 						   * give an extra interrupt
854 						   */
855 				} else {
856 					TRACE_ABORT(-EIO, ft_t_err,
857 				    "no seek-end after seek completion !??");
858 				}
859 			}
860 			break;
861 		}
862 	}
863 	ftape_current_cylinder = pcn;
864 	if (pcn != 0) {
865 		TRACE(ft_t_err, "failed: resulting track = %d", pcn);
866 	}
867 	TRACE_CATCH(fdc_set_seek_rate(old_seek_rate),);
868 	TRACE_EXIT 0;
869 }
870 
871 static int perpend_mode; /* set if fdc is in perpendicular mode */
872 
perpend_off(void)873 static int perpend_off(void)
874 {
875  	__u8 perpend[] = {FDC_PERPEND, 0x00};
876 	TRACE_FUN(ft_t_any);
877 
878 	if (perpend_mode) {
879 		/* Turn off perpendicular mode */
880 		perpend[1] = 0x80;
881 		TRACE_CATCH(fdc_command(perpend, 2),
882 			    TRACE(ft_t_err,"Perpendicular mode exit failed!"));
883 		perpend_mode = 0;
884 	}
885 	TRACE_EXIT 0;
886 }
887 
handle_perpend(int segment_id)888 static int handle_perpend(int segment_id)
889 {
890  	__u8 perpend[] = {FDC_PERPEND, 0x00};
891 	TRACE_FUN(ft_t_any);
892 
893 	/* When writing QIC-3020 tapes, turn on perpendicular mode
894 	 * if tape is moving in forward direction (even tracks).
895 	 */
896 	if (ft_qic_std == QIC_TAPE_QIC3020 &&
897 	    ((segment_id / ft_segments_per_track) & 1) == 0) {
898 /*  FIXME: some i82077 seem to support perpendicular mode as
899  *  well.
900  */
901 #if 0
902 		if (fdc.type < i82077AA) {}
903 #else
904 		if (fdc.type < i82077 && ft_data_rate < 1000) {
905 #endif
906 			/*  fdc does not support perpendicular mode: complain
907 			 */
908 			TRACE_ABORT(-EIO, ft_t_err,
909 				    "Your FDC does not support QIC-3020.");
910 		}
911 		perpend[1] = 0x03 /* 0x83 + (0x4 << ft_drive_sel) */ ;
912 		TRACE_CATCH(fdc_command(perpend, 2),
913 			   TRACE(ft_t_err,"Perpendicular mode entry failed!"));
914 		TRACE(ft_t_flow, "Perpendicular mode set");
915 		perpend_mode = 1;
916 		TRACE_EXIT 0;
917 	}
918 	TRACE_EXIT perpend_off();
919 }
920 
fdc_setup_dma(char mode,volatile void * addr,unsigned int count)921 static inline void fdc_setup_dma(char mode,
922 				 volatile void *addr, unsigned int count)
923 {
924 	/* Program the DMA controller.
925 	 */
926 	disable_dma(fdc.dma);
927 	clear_dma_ff(fdc.dma);
928 	set_dma_mode(fdc.dma, mode);
929 	set_dma_addr(fdc.dma, virt_to_bus((void*)addr));
930 	set_dma_count(fdc.dma, count);
931 #ifdef GCC_2_4_5_BUG
932 	/*  This seemingly stupid construction confuses the gcc-2.4.5
933 	 *  code generator enough to create correct code.
934 	 */
935 	if (1) {
936 		int i;
937 
938 		for (i = 0; i < 1; ++i) {
939 			ftape_udelay(1);
940 		}
941 	}
942 #endif
943 	enable_dma(fdc.dma);
944 }
945 
946 /*  Setup fdc and dma for formatting the next segment
947  */
fdc_setup_formatting(buffer_struct * buff)948 int fdc_setup_formatting(buffer_struct * buff)
949 {
950 	unsigned long flags;
951 	__u8 out[6] = {
952 		FDC_FORMAT, 0x00, 3, 4 * FT_SECTORS_PER_SEGMENT, 0x00, 0x6b
953 	};
954 	TRACE_FUN(ft_t_any);
955 
956 	TRACE_CATCH(handle_perpend(buff->segment_id),);
957 	/* Program the DMA controller.
958 	 */
959         TRACE(ft_t_fdc_dma,
960 	      "phys. addr. = %lx", virt_to_bus((void*) buff->ptr));
961 	save_flags(flags);
962 	cli();			/* could be called from ISR ! */
963 	fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4);
964 	/* Issue FDC command to start reading/writing.
965 	 */
966 	out[1] = ft_drive_sel;
967 	out[4] = buff->gap3;
968 	TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)),
969 		    restore_flags(flags); fdc_mode = fdc_idle);
970 	restore_flags(flags);
971 	TRACE_EXIT 0;
972 }
973 
974 
975 /*      Setup Floppy Disk Controller and DMA to read or write the next cluster
976  *      of good sectors from or to the current segment.
977  */
fdc_setup_read_write(buffer_struct * buff,__u8 operation)978 int fdc_setup_read_write(buffer_struct * buff, __u8 operation)
979 {
980 	unsigned long flags;
981 	__u8 out[9];
982 	int dma_mode;
983 	TRACE_FUN(ft_t_any);
984 
985 	switch(operation) {
986 	case FDC_VERIFY:
987 		if (fdc.type < i82077) {
988 			operation = FDC_READ;
989 		}
990 	case FDC_READ:
991 	case FDC_READ_DELETED:
992 		dma_mode = DMA_MODE_READ;
993 		TRACE(ft_t_fdc_dma, "xfer %d sectors to 0x%p",
994 		      buff->sector_count, buff->ptr);
995 		TRACE_CATCH(perpend_off(),);
996 		break;
997 	case FDC_WRITE_DELETED:
998 		TRACE(ft_t_noise, "deleting segment %d", buff->segment_id);
999 	case FDC_WRITE:
1000 		dma_mode = DMA_MODE_WRITE;
1001 		/* When writing QIC-3020 tapes, turn on perpendicular mode
1002 		 * if tape is moving in forward direction (even tracks).
1003 		 */
1004 		TRACE_CATCH(handle_perpend(buff->segment_id),);
1005 		TRACE(ft_t_fdc_dma, "xfer %d sectors from 0x%p",
1006 		      buff->sector_count, buff->ptr);
1007 		break;
1008 	default:
1009 		TRACE_ABORT(-EIO,
1010 			    ft_t_bug, "bug: illegal operation parameter");
1011 	}
1012 	TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr));
1013 	save_flags(flags);
1014 	cli();			/* could be called from ISR ! */
1015 	if (operation != FDC_VERIFY) {
1016 		fdc_setup_dma(dma_mode, buff->ptr,
1017 			      FT_SECTOR_SIZE * buff->sector_count);
1018 	}
1019 	/* Issue FDC command to start reading/writing.
1020 	 */
1021 	out[0] = operation;
1022 	out[1] = ft_drive_sel;
1023 	out[2] = buff->cyl;
1024 	out[3] = buff->head;
1025 	out[4] = buff->sect + buff->sector_offset;
1026 	out[5] = 3;		/* Sector size of 1K. */
1027 	out[6] = out[4] + buff->sector_count - 1;	/* last sector */
1028 	out[7] = 109;		/* Gap length. */
1029 	out[8] = 0xff;		/* No limit to transfer size. */
1030 	TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x",
1031 		out[2], out[3], out[4], out[6] - out[4] + 1);
1032 	restore_flags(flags);
1033 	TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle);
1034 	TRACE_EXIT 0;
1035 }
1036 
fdc_fifo_threshold(__u8 threshold,int * fifo_state,int * lock_state,int * fifo_thr)1037 int fdc_fifo_threshold(__u8 threshold,
1038 		       int *fifo_state, int *lock_state, int *fifo_thr)
1039 {
1040 	const __u8 cmd0[] = {FDC_DUMPREGS};
1041 	__u8 cmd1[] = {FDC_CONFIGURE, 0, (0x0f & (threshold - 1)), 0};
1042 	const __u8 cmd2[] = {FDC_LOCK};
1043 	const __u8 cmd3[] = {FDC_UNLOCK};
1044 	__u8 reg[10];
1045 	__u8 stat;
1046 	int i;
1047 	int result;
1048 	TRACE_FUN(ft_t_any);
1049 
1050 	if (CLK_48MHZ && fdc.type >= i82078) {
1051 		cmd1[0] |= FDC_CLK48_BIT;
1052 	}
1053 	/*  Dump fdc internal registers for examination
1054 	 */
1055 	TRACE_CATCH(fdc_command(cmd0, NR_ITEMS(cmd0)),
1056 		    TRACE(ft_t_warn, "dumpreg cmd failed, fifo unchanged"));
1057 	/*  Now read fdc internal registers from fifo
1058 	 */
1059 	for (i = 0; i < (int)NR_ITEMS(reg); ++i) {
1060 		fdc_read(&reg[i]);
1061 		TRACE(ft_t_fdc_dma, "Register %d = 0x%02x", i, reg[i]);
1062 	}
1063 	if (fifo_state && lock_state && fifo_thr) {
1064 		*fifo_state = (reg[8] & 0x20) == 0;
1065 		*lock_state = reg[7] & 0x80;
1066 		*fifo_thr = 1 + (reg[8] & 0x0f);
1067 	}
1068 	TRACE(ft_t_noise,
1069 	      "original fifo state: %sabled, threshold %d, %slocked",
1070 	      ((reg[8] & 0x20) == 0) ? "en" : "dis",
1071 	      1 + (reg[8] & 0x0f), (reg[7] & 0x80) ? "" : "not ");
1072 	/*  If fdc is already locked, unlock it first ! */
1073 	if (reg[7] & 0x80) {
1074 		fdc_ready_wait(100);
1075 		TRACE_CATCH(fdc_issue_command(cmd3, NR_ITEMS(cmd3), &stat, 1),
1076 			    TRACE(ft_t_bug, "FDC unlock command failed, "
1077 				  "configuration unchanged"));
1078 	}
1079 	fdc_fifo_locked = 0;
1080 	/*  Enable fifo and set threshold at xx bytes to allow a
1081 	 *  reasonably large latency and reduce number of dma bursts.
1082 	 */
1083 	fdc_ready_wait(100);
1084 	if ((result = fdc_command(cmd1, NR_ITEMS(cmd1))) < 0) {
1085 		TRACE(ft_t_bug, "configure cmd failed, fifo unchanged");
1086 	}
1087 	/*  Now lock configuration so reset will not change it
1088 	 */
1089         if(fdc_issue_command(cmd2, NR_ITEMS(cmd2), &stat, 1) < 0 ||
1090 	   stat != 0x10) {
1091 		TRACE_ABORT(-EIO, ft_t_bug,
1092 			    "FDC lock command failed, stat = 0x%02x", stat);
1093 	}
1094 	fdc_fifo_locked = 1;
1095 	TRACE_EXIT result;
1096 }
1097 
fdc_fifo_enable(void)1098 static int fdc_fifo_enable(void)
1099 {
1100 	TRACE_FUN(ft_t_any);
1101 
1102 	if (fdc_fifo_locked) {
1103 		TRACE_ABORT(0, ft_t_warn, "Fifo not enabled because locked");
1104 	}
1105 	TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
1106 				       &fdc_fifo_state,
1107 				       &fdc_lock_state,
1108 				       &fdc_fifo_thr),);
1109 	TRACE_CATCH(fdc_fifo_threshold(ft_fdc_threshold /* bytes */,
1110 				       NULL, NULL, NULL),);
1111 	TRACE_EXIT 0;
1112 }
1113 
1114 /*   Determine fd controller type
1115  */
1116 static __u8 fdc_save_state[2];
1117 
fdc_probe(void)1118 int fdc_probe(void)
1119 {
1120 	__u8 cmd[1];
1121 	__u8 stat[16]; /* must be able to hold dumpregs & save results */
1122 	int i;
1123 	TRACE_FUN(ft_t_any);
1124 
1125 	/*  Try to find out what kind of fd controller we have to deal with
1126 	 *  Scheme borrowed from floppy driver:
1127 	 *  first try if FDC_DUMPREGS command works
1128 	 *  (this indicates that we have a 82072 or better)
1129 	 *  then try the FDC_VERSION command (82072 doesn't support this)
1130 	 *  then try the FDC_UNLOCK command (some older 82077's don't support this)
1131 	 *  then try the FDC_PARTID command (82078's support this)
1132 	 */
1133 	cmd[0] = FDC_DUMPREGS;
1134 	if (fdc_issue_command(cmd, 1, stat, 1) != 0) {
1135 		TRACE_ABORT(no_fdc, ft_t_bug, "No FDC found");
1136 	}
1137 	if (stat[0] == 0x80) {
1138 		/* invalid command: must be pre 82072 */
1139 		TRACE_ABORT(i8272,
1140 			    ft_t_warn, "Type 8272A/765A compatible FDC found");
1141 	}
1142 	fdc_result(&stat[1], 9);
1143 	fdc_save_state[0] = stat[7];
1144 	fdc_save_state[1] = stat[8];
1145 	cmd[0] = FDC_VERSION;
1146 	if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
1147 		TRACE_ABORT(i8272, ft_t_warn, "Type 82072 FDC found");
1148 	}
1149 	if (*stat != 0x90) {
1150 		TRACE_ABORT(i8272, ft_t_warn, "Unknown FDC found");
1151 	}
1152 	cmd[0] = FDC_UNLOCK;
1153 	if(fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] != 0x00) {
1154 		TRACE_ABORT(i8272, ft_t_warn,
1155 			    "Type pre-1991 82077 FDC found, "
1156 			    "treating it like a 82072");
1157 	}
1158 	if (fdc_save_state[0] & 0x80) { /* was locked */
1159 		cmd[0] = FDC_LOCK; /* restore lock */
1160 		(void)fdc_issue_command(cmd, 1, stat, 1);
1161 		TRACE(ft_t_warn, "FDC is already locked");
1162 	}
1163 	/* Test for a i82078 FDC */
1164 	cmd[0] = FDC_PARTID;
1165 	if (fdc_issue_command(cmd, 1, stat, 1) < 0 || stat[0] == 0x80) {
1166 		/* invalid command: not a i82078xx type FDC */
1167 		for (i = 0; i < 4; ++i) {
1168 			outb_p(i, fdc.tdr);
1169 			if ((inb_p(fdc.tdr) & 0x03) != i) {
1170 				TRACE_ABORT(i82077,
1171 					    ft_t_warn, "Type 82077 FDC found");
1172 			}
1173 		}
1174 		TRACE_ABORT(i82077AA, ft_t_warn, "Type 82077AA FDC found");
1175 	}
1176 	/* FDC_PARTID cmd succeeded */
1177 	switch (stat[0] >> 5) {
1178 	case 0x0:
1179 		/* i82078SL or i82078-1.  The SL part cannot run at
1180 		 * 2Mbps (the SL and -1 dies are identical; they are
1181 		 * speed graded after production, according to Intel).
1182 		 * Some SL's can be detected by doing a SAVE cmd and
1183 		 * look at bit 7 of the first byte (the SEL3V# bit).
1184 		 * If it is 0, the part runs off 3Volts, and hence it
1185 		 * is a SL.
1186 		 */
1187 		cmd[0] = FDC_SAVE;
1188 		if(fdc_issue_command(cmd, 1, stat, 16) < 0) {
1189 			TRACE(ft_t_err, "FDC_SAVE failed. Dunno why");
1190 			/* guess we better claim the fdc to be a i82078 */
1191 			TRACE_ABORT(i82078,
1192 				    ft_t_warn,
1193 				    "Type i82078 FDC (i suppose) found");
1194 		}
1195 		if ((stat[0] & FDC_SEL3V_BIT)) {
1196 			/* fdc running off 5Volts; Pray that it's a i82078-1
1197 			 */
1198 			TRACE_ABORT(i82078_1, ft_t_warn,
1199 				  "Type i82078-1 or 5Volt i82078SL FDC found");
1200 		}
1201 		TRACE_ABORT(i82078, ft_t_warn,
1202 			    "Type 3Volt i82078SL FDC (1Mbps) found");
1203 	case 0x1:
1204 	case 0x2: /* S82078B  */
1205 		/* The '78B  isn't '78 compatible.  Detect it as a '77AA */
1206 		TRACE_ABORT(i82077AA, ft_t_warn, "Type i82077AA FDC found");
1207 	case 0x3: /* NSC PC8744 core; used in several super-IO chips */
1208 		TRACE_ABORT(i82077AA,
1209 			    ft_t_warn, "Type 82077AA compatible FDC found");
1210 	default:
1211 		TRACE(ft_t_warn, "A previously undetected FDC found");
1212 		TRACE_ABORT(i82077AA, ft_t_warn,
1213 			  "Treating it as a 82077AA. Please report partid= %d",
1214 			    stat[0]);
1215 	} /* switch(stat[ 0] >> 5) */
1216 	TRACE_EXIT no_fdc;
1217 }
1218 
fdc_request_regions(void)1219 static int fdc_request_regions(void)
1220 {
1221 	TRACE_FUN(ft_t_flow);
1222 
1223 	if (ft_mach2 || ft_probe_fc10) {
1224 		if (check_region(fdc.sra, 8) < 0) {
1225 #ifndef BROKEN_FLOPPY_DRIVER
1226 			TRACE_EXIT -EBUSY;
1227 #else
1228 			TRACE(ft_t_warn,
1229 "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
1230 #endif
1231 		}
1232 		request_region(fdc.sra, 8, "fdc (ft)");
1233 	} else {
1234 		if (check_region(fdc.sra, 6) < 0 ||
1235 		    check_region(fdc.dir, 1) < 0) {
1236 #ifndef BROKEN_FLOPPY_DRIVER
1237 			TRACE_EXIT -EBUSY;
1238 #else
1239 			TRACE(ft_t_warn,
1240 "address 0x%03x occupied (by floppy driver?), using it anyway", fdc.sra);
1241 #endif
1242 		}
1243 		request_region(fdc.sra, 6, "fdc (ft)");
1244 		request_region(fdc.sra + 7, 1, "fdc (ft)");
1245 	}
1246 	TRACE_EXIT 0;
1247 }
1248 
fdc_release_regions(void)1249 void fdc_release_regions(void)
1250 {
1251 	TRACE_FUN(ft_t_flow);
1252 
1253 	if (fdc.sra != 0) {
1254 		if (fdc.dor2 != 0) {
1255 			release_region(fdc.sra, 8);
1256 		} else {
1257 			release_region(fdc.sra, 6);
1258 			release_region(fdc.dir, 1);
1259 		}
1260 	}
1261 	TRACE_EXIT;
1262 }
1263 
fdc_config_regs(unsigned int fdc_base,unsigned int fdc_irq,unsigned int fdc_dma)1264 static int fdc_config_regs(unsigned int fdc_base,
1265 			   unsigned int fdc_irq,
1266 			   unsigned int fdc_dma)
1267 {
1268 	TRACE_FUN(ft_t_flow);
1269 
1270 	fdc.irq = fdc_irq;
1271 	fdc.dma = fdc_dma;
1272 	fdc.sra = fdc_base;
1273 	fdc.srb = fdc_base + 1;
1274 	fdc.dor = fdc_base + 2;
1275 	fdc.tdr = fdc_base + 3;
1276 	fdc.msr = fdc.dsr = fdc_base + 4;
1277 	fdc.fifo = fdc_base + 5;
1278 	fdc.dir = fdc.ccr = fdc_base + 7;
1279 	fdc.dor2 = (ft_mach2 || ft_probe_fc10) ? fdc_base + 6 : 0;
1280 	TRACE_CATCH(fdc_request_regions(), fdc.sra = 0);
1281 	TRACE_EXIT 0;
1282 }
1283 
fdc_config(void)1284 static int fdc_config(void)
1285 {
1286 	static int already_done;
1287 	TRACE_FUN(ft_t_any);
1288 
1289 	if (already_done) {
1290 		TRACE_CATCH(fdc_request_regions(),);
1291 		*(fdc.hook) = fdc_isr;	/* hook our handler in */
1292 		TRACE_EXIT 0;
1293 	}
1294 	if (ft_probe_fc10) {
1295 		int fc_type;
1296 
1297 		TRACE_CATCH(fdc_config_regs(ft_fdc_base,
1298 					    ft_fdc_irq, ft_fdc_dma),);
1299 		fc_type = fc10_enable();
1300 		if (fc_type != 0) {
1301 			TRACE(ft_t_warn, "FC-%c0 controller found", '0' + fc_type);
1302 			fdc.type = fc10;
1303 			fdc.hook = &do_ftape;
1304 			*(fdc.hook) = fdc_isr;	/* hook our handler in */
1305 			already_done = 1;
1306 			TRACE_EXIT 0;
1307 		} else {
1308 			TRACE(ft_t_warn, "FC-10/20 controller not found");
1309 			fdc_release_regions();
1310 			fdc.type = no_fdc;
1311 			ft_probe_fc10 = 0;
1312 			ft_fdc_base   = 0x3f0;
1313 			ft_fdc_irq    = 6;
1314 			ft_fdc_dma    = 2;
1315 		}
1316 	}
1317 	TRACE(ft_t_warn, "fdc base: 0x%x, irq: %d, dma: %d",
1318 	      ft_fdc_base, ft_fdc_irq, ft_fdc_dma);
1319 	TRACE_CATCH(fdc_config_regs(ft_fdc_base, ft_fdc_irq, ft_fdc_dma),);
1320 	fdc.hook = &do_ftape;
1321 	*(fdc.hook) = fdc_isr;	/* hook our handler in */
1322 	already_done = 1;
1323 	TRACE_EXIT 0;
1324 }
1325 
ftape_interrupt(int irq,void * dev_id,struct pt_regs * regs)1326 static void ftape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1327 {
1328 	void (*handler) (void) = *fdc.hook;
1329 	TRACE_FUN(ft_t_any);
1330 
1331 	*fdc.hook = NULL;
1332 	if (handler) {
1333 		handler();
1334 	} else {
1335 		TRACE(ft_t_bug, "Unexpected ftape interrupt");
1336 	}
1337 	TRACE_EXIT;
1338 }
1339 
fdc_grab_irq_and_dma(void)1340 int fdc_grab_irq_and_dma(void)
1341 {
1342 	TRACE_FUN(ft_t_any);
1343 
1344 	if (fdc.hook == &do_ftape) {
1345 		/*  Get fast interrupt handler.
1346 		 */
1347 		if (request_irq(fdc.irq, ftape_interrupt,
1348 				SA_INTERRUPT, "ft", ftape_id)) {
1349 			TRACE_ABORT(-EIO, ft_t_bug,
1350 				    "Unable to grab IRQ%d for ftape driver",
1351 				    fdc.irq);
1352 		}
1353 		if (request_dma(fdc.dma, ftape_id)) {
1354 			free_irq(fdc.irq, ftape_id);
1355 			TRACE_ABORT(-EIO, ft_t_bug,
1356 			      "Unable to grab DMA%d for ftape driver",
1357 			      fdc.dma);
1358 		}
1359 	}
1360 	if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
1361 		/* Using same dma channel or irq as standard fdc, need
1362 		 * to disable the dma-gate on the std fdc. This
1363 		 * couldn't be done in the floppy driver as some
1364 		 * laptops are using the dma-gate to enter a low power
1365 		 * or even suspended state :-(
1366 		 */
1367 		outb_p(FDC_RESET_NOT, 0x3f2);
1368 		TRACE(ft_t_noise, "DMA-gate on standard fdc disabled");
1369 	}
1370 	TRACE_EXIT 0;
1371 }
1372 
fdc_release_irq_and_dma(void)1373 int fdc_release_irq_and_dma(void)
1374 {
1375 	TRACE_FUN(ft_t_any);
1376 
1377 	if (fdc.hook == &do_ftape) {
1378 		disable_dma(fdc.dma);	/* just in case... */
1379 		free_dma(fdc.dma);
1380 		free_irq(fdc.irq, ftape_id);
1381 	}
1382 	if (ft_fdc_base != 0x3f0 && (ft_fdc_dma == 2 || ft_fdc_irq == 6)) {
1383 		/* Using same dma channel as standard fdc, need to
1384 		 * disable the dma-gate on the std fdc. This couldn't
1385 		 * be done in the floppy driver as some laptops are
1386 		 * using the dma-gate to enter a low power or even
1387 		 * suspended state :-(
1388 		 */
1389 		outb_p(FDC_RESET_NOT | FDC_DMA_MODE, 0x3f2);
1390 		TRACE(ft_t_noise, "DMA-gate on standard fdc enabled again");
1391 	}
1392 	TRACE_EXIT 0;
1393 }
1394 
fdc_init(void)1395 int fdc_init(void)
1396 {
1397 	TRACE_FUN(ft_t_any);
1398 
1399 	/* find a FDC to use */
1400 	TRACE_CATCH(fdc_config(),);
1401 	TRACE_CATCH(fdc_grab_irq_and_dma(), fdc_release_regions());
1402 	ftape_motor = 0;
1403 	fdc_catch_stray_interrupts(0);	/* clear number of awainted
1404 					 * stray interrupte
1405 					 */
1406 	fdc_catch_stray_interrupts(1);	/* one always comes (?) */
1407 	TRACE(ft_t_flow, "resetting fdc");
1408 	fdc_set_seek_rate(2);		/* use nominal QIC step rate */
1409 	fdc_reset();			/* init fdc & clear track counters */
1410 	if (fdc.type == no_fdc) {	/* no FC-10 or FC-20 found */
1411 		fdc.type = fdc_probe();
1412 		fdc_reset();		/* update with new knowledge */
1413 	}
1414 	if (fdc.type == no_fdc) {
1415 		fdc_release_irq_and_dma();
1416 		fdc_release_regions();
1417 		TRACE_EXIT -ENXIO;
1418 	}
1419 	if (fdc.type >= i82077) {
1420 		if (fdc_fifo_enable() < 0) {
1421 			TRACE(ft_t_warn, "couldn't enable fdc fifo !");
1422 		} else {
1423 			TRACE(ft_t_flow, "fdc fifo enabled and locked");
1424 		}
1425 	}
1426 	TRACE_EXIT 0;
1427 }
1428