fdc-io.c 37 KB

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