fdc-io.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:38k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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