fdc-isr.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170
  1. /*
  2. * Copyright (C) 1994-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-isr.c,v $
  17. * $Revision: 1.9 $
  18. * $Date: 1997/10/17 23:01:53 $
  19. *
  20. * This file contains the interrupt service routine and
  21. * associated code for the QIC-40/80/3010/3020 floppy-tape driver
  22. * "ftape" for Linux.
  23. */
  24. #include <asm/io.h>
  25. #include <asm/dma.h>
  26. #define volatile /* */
  27. #include <linux/ftape.h>
  28. #include <linux/qic117.h>
  29. #include "../lowlevel/ftape-tracing.h"
  30. #include "../lowlevel/fdc-isr.h"
  31. #include "../lowlevel/fdc-io.h"
  32. #include "../lowlevel/ftape-ctl.h"
  33. #include "../lowlevel/ftape-rw.h"
  34. #include "../lowlevel/ftape-io.h"
  35. #include "../lowlevel/ftape-calibr.h"
  36. #include "../lowlevel/ftape-bsm.h"
  37. /* Global vars.
  38. */
  39. volatile int ft_expected_stray_interrupts;
  40. volatile int ft_interrupt_seen;
  41. volatile int ft_seek_completed;
  42. volatile int ft_hide_interrupt;
  43. /* Local vars.
  44. */
  45. typedef enum {
  46. no_error = 0, id_am_error = 0x01, id_crc_error = 0x02,
  47. data_am_error = 0x04, data_crc_error = 0x08,
  48. no_data_error = 0x10, overrun_error = 0x20,
  49. } error_cause;
  50. static int stop_read_ahead;
  51. static void print_error_cause(int cause)
  52. {
  53. TRACE_FUN(ft_t_any);
  54. switch (cause) {
  55. case no_data_error:
  56. TRACE(ft_t_noise, "no data error");
  57. break;
  58. case id_am_error:
  59. TRACE(ft_t_noise, "id am error");
  60. break;
  61. case id_crc_error:
  62. TRACE(ft_t_noise, "id crc error");
  63. break;
  64. case data_am_error:
  65. TRACE(ft_t_noise, "data am error");
  66. break;
  67. case data_crc_error:
  68. TRACE(ft_t_noise, "data crc error");
  69. break;
  70. case overrun_error:
  71. TRACE(ft_t_noise, "overrun error");
  72. break;
  73. default:;
  74. }
  75. TRACE_EXIT;
  76. }
  77. static char *fdc_mode_txt(fdc_mode_enum mode)
  78. {
  79. switch (mode) {
  80. case fdc_idle:
  81. return "fdc_idle";
  82. case fdc_reading_data:
  83. return "fdc_reading_data";
  84. case fdc_seeking:
  85. return "fdc_seeking";
  86. case fdc_writing_data:
  87. return "fdc_writing_data";
  88. case fdc_reading_id:
  89. return "fdc_reading_id";
  90. case fdc_recalibrating:
  91. return "fdc_recalibrating";
  92. case fdc_formatting:
  93. return "fdc_formatting";
  94. case fdc_verifying:
  95. return "fdc_verifying";
  96. default:
  97. return "unknown";
  98. }
  99. }
  100. static inline error_cause decode_irq_cause(fdc_mode_enum mode, __u8 st[])
  101. {
  102. error_cause cause = no_error;
  103. TRACE_FUN(ft_t_any);
  104. /* Valid st[], decode cause of interrupt.
  105. */
  106. switch (st[0] & ST0_INT_MASK) {
  107. case FDC_INT_NORMAL:
  108. TRACE(ft_t_fdc_dma,"normal completion: %s",fdc_mode_txt(mode));
  109. break;
  110. case FDC_INT_ABNORMAL:
  111. TRACE(ft_t_flow, "abnormal completion %s", fdc_mode_txt(mode));
  112. TRACE(ft_t_fdc_dma, "ST0: 0x%02x, ST1: 0x%02x, ST2: 0x%02x",
  113. st[0], st[1], st[2]);
  114. TRACE(ft_t_fdc_dma,
  115. "C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x",
  116. st[3], st[4], st[5], st[6]);
  117. if (st[1] & 0x01) {
  118. if (st[2] & 0x01) {
  119. cause = data_am_error;
  120. } else {
  121. cause = id_am_error;
  122. }
  123. } else if (st[1] & 0x20) {
  124. if (st[2] & 0x20) {
  125. cause = data_crc_error;
  126. } else {
  127. cause = id_crc_error;
  128. }
  129. } else if (st[1] & 0x04) {
  130. cause = no_data_error;
  131. } else if (st[1] & 0x10) {
  132. cause = overrun_error;
  133. }
  134. print_error_cause(cause);
  135. break;
  136. case FDC_INT_INVALID:
  137. TRACE(ft_t_flow, "invalid completion %s", fdc_mode_txt(mode));
  138. break;
  139. case FDC_INT_READYCH:
  140. if (st[0] & ST0_SEEK_END) {
  141. TRACE(ft_t_flow, "drive poll completed");
  142. } else {
  143. TRACE(ft_t_flow, "ready change %s",fdc_mode_txt(mode));
  144. }
  145. break;
  146. default:
  147. break;
  148. }
  149. TRACE_EXIT cause;
  150. }
  151. static void update_history(error_cause cause)
  152. {
  153. switch (cause) {
  154. case id_am_error:
  155. ft_history.id_am_errors++;
  156. break;
  157. case id_crc_error:
  158. ft_history.id_crc_errors++;
  159. break;
  160. case data_am_error:
  161. ft_history.data_am_errors++;
  162. break;
  163. case data_crc_error:
  164. ft_history.data_crc_errors++;
  165. break;
  166. case overrun_error:
  167. ft_history.overrun_errors++;
  168. break;
  169. case no_data_error:
  170. ft_history.no_data_errors++;
  171. break;
  172. default:;
  173. }
  174. }
  175. static void skip_bad_sector(buffer_struct * buff)
  176. {
  177. TRACE_FUN(ft_t_any);
  178. /* Mark sector as soft error and skip it
  179. */
  180. if (buff->remaining > 0) {
  181. ++buff->sector_offset;
  182. ++buff->data_offset;
  183. --buff->remaining;
  184. buff->ptr += FT_SECTOR_SIZE;
  185. buff->bad_sector_map >>= 1;
  186. } else {
  187. /* Hey, what is this????????????? C code: if we shift
  188. * more than 31 bits, we get no shift. That's bad!!!!!!
  189. */
  190. ++buff->sector_offset; /* hack for error maps */
  191. TRACE(ft_t_warn, "skipping last sector in segment");
  192. }
  193. TRACE_EXIT;
  194. }
  195. static void update_error_maps(buffer_struct * buff, unsigned int error_offset)
  196. {
  197. int hard = 0;
  198. TRACE_FUN(ft_t_any);
  199. if (buff->retry < FT_SOFT_RETRIES) {
  200. buff->soft_error_map |= (1 << error_offset);
  201. } else {
  202. buff->hard_error_map |= (1 << error_offset);
  203. buff->soft_error_map &= ~buff->hard_error_map;
  204. buff->retry = -1; /* will be set to 0 in setup_segment */
  205. hard = 1;
  206. }
  207. TRACE(ft_t_noise, "sector %d : %s error\n"
  208. KERN_INFO "hard map: 0x%08lx\n"
  209. KERN_INFO "soft map: 0x%08lx",
  210. FT_SECTOR(error_offset), hard ? "hard" : "soft",
  211. (long) buff->hard_error_map, (long) buff->soft_error_map);
  212. TRACE_EXIT;
  213. }
  214. static void print_progress(buffer_struct *buff, error_cause cause)
  215. {
  216. TRACE_FUN(ft_t_any);
  217. switch (cause) {
  218. case no_error:
  219. TRACE(ft_t_flow,"%d Sector(s) transferred", buff->sector_count);
  220. break;
  221. case no_data_error:
  222. TRACE(ft_t_flow, "Sector %d not found",
  223. FT_SECTOR(buff->sector_offset));
  224. break;
  225. case overrun_error:
  226. /* got an overrun error on the first byte, must be a
  227. * hardware problem
  228. */
  229. TRACE(ft_t_bug,
  230. "Unexpected error: failing DMA or FDC controller ?");
  231. break;
  232. case data_crc_error:
  233. TRACE(ft_t_flow, "Error in sector %d",
  234. FT_SECTOR(buff->sector_offset - 1));
  235. break;
  236. case id_crc_error:
  237. case id_am_error:
  238. case data_am_error:
  239. TRACE(ft_t_flow, "Error in sector %d",
  240. FT_SECTOR(buff->sector_offset));
  241. break;
  242. default:
  243. TRACE(ft_t_flow, "Unexpected error at sector %d",
  244. FT_SECTOR(buff->sector_offset));
  245. break;
  246. }
  247. TRACE_EXIT;
  248. }
  249. /*
  250. * Error cause: Amount xferred: Action:
  251. *
  252. * id_am_error 0 mark bad and skip
  253. * id_crc_error 0 mark bad and skip
  254. * data_am_error 0 mark bad and skip
  255. * data_crc_error % 1024 mark bad and skip
  256. * no_data_error 0 retry on write
  257. * mark bad and skip on read
  258. * overrun_error [ 0..all-1 ] mark bad and skip
  259. * no_error all continue
  260. */
  261. /* the arg `sector' is returned by the fdc and tells us at which sector we
  262. * are positioned at (relative to starting sector of segment)
  263. */
  264. static void determine_verify_progress(buffer_struct *buff,
  265. error_cause cause,
  266. __u8 sector)
  267. {
  268. TRACE_FUN(ft_t_any);
  269. if (cause == no_error && sector == 1) {
  270. buff->sector_offset = FT_SECTORS_PER_SEGMENT;
  271. buff->remaining = 0;
  272. if (TRACE_LEVEL >= ft_t_flow) {
  273. print_progress(buff, cause);
  274. }
  275. } else {
  276. buff->sector_offset = sector - buff->sect;
  277. buff->remaining = FT_SECTORS_PER_SEGMENT - buff->sector_offset;
  278. TRACE(ft_t_noise, "%ssector offset: 0x%04x",
  279. (cause == no_error) ? "unexpected " : "",
  280. buff->sector_offset);
  281. switch (cause) {
  282. case overrun_error:
  283. break;
  284. #if 0
  285. case no_data_error:
  286. buff->retry = FT_SOFT_RETRIES;
  287. if (buff->hard_error_map &&
  288. buff->sector_offset > 1 &&
  289. (buff->hard_error_map &
  290. (1 << (buff->sector_offset-2)))) {
  291. buff->retry --;
  292. }
  293. break;
  294. #endif
  295. default:
  296. buff->retry = FT_SOFT_RETRIES;
  297. break;
  298. }
  299. if (TRACE_LEVEL >= ft_t_flow) {
  300. print_progress(buff, cause);
  301. }
  302. /* Sector_offset points to the problem area Now adjust
  303. * sector_offset so it always points one past he failing
  304. * sector. I.e. skip the bad sector.
  305. */
  306. ++buff->sector_offset;
  307. --buff->remaining;
  308. update_error_maps(buff, buff->sector_offset - 1);
  309. }
  310. TRACE_EXIT;
  311. }
  312. static void determine_progress(buffer_struct *buff,
  313. error_cause cause,
  314. __u8 sector)
  315. {
  316. unsigned int dma_residue;
  317. TRACE_FUN(ft_t_any);
  318. /* Using less preferred order of disable_dma and
  319. * get_dma_residue because this seems to fail on at least one
  320. * system if reversed!
  321. */
  322. dma_residue = get_dma_residue(fdc.dma);
  323. disable_dma(fdc.dma);
  324. if (cause != no_error || dma_residue != 0) {
  325. TRACE(ft_t_noise, "%sDMA residue: 0x%04x",
  326. (cause == no_error) ? "unexpected " : "",
  327. dma_residue);
  328. /* adjust to actual value: */
  329. if (dma_residue == 0) {
  330. /* this happens sometimes with overrun errors.
  331. * I don't know whether we could ignore the
  332. * overrun error. Play save.
  333. */
  334. buff->sector_count --;
  335. } else {
  336. buff->sector_count -= ((dma_residue +
  337. (FT_SECTOR_SIZE - 1)) /
  338. FT_SECTOR_SIZE);
  339. }
  340. }
  341. /* Update var's influenced by the DMA operation.
  342. */
  343. if (buff->sector_count > 0) {
  344. buff->sector_offset += buff->sector_count;
  345. buff->data_offset += buff->sector_count;
  346. buff->ptr += (buff->sector_count *
  347. FT_SECTOR_SIZE);
  348. buff->remaining -= buff->sector_count;
  349. buff->bad_sector_map >>= buff->sector_count;
  350. }
  351. if (TRACE_LEVEL >= ft_t_flow) {
  352. print_progress(buff, cause);
  353. }
  354. if (cause != no_error) {
  355. if (buff->remaining == 0) {
  356. TRACE(ft_t_warn, "foo?\n"
  357. KERN_INFO "count : %d\n"
  358. KERN_INFO "offset: %d\n"
  359. KERN_INFO "soft : %08x\n"
  360. KERN_INFO "hard : %08x",
  361. buff->sector_count,
  362. buff->sector_offset,
  363. buff->soft_error_map,
  364. buff->hard_error_map);
  365. }
  366. /* Sector_offset points to the problem area, except if we got
  367. * a data_crc_error. In that case it points one past the
  368. * failing sector.
  369. *
  370. * Now adjust sector_offset so it always points one past he
  371. * failing sector. I.e. skip the bad sector.
  372. */
  373. if (cause != data_crc_error) {
  374. skip_bad_sector(buff);
  375. }
  376. update_error_maps(buff, buff->sector_offset - 1);
  377. }
  378. TRACE_EXIT;
  379. }
  380. static int calc_steps(int cmd)
  381. {
  382. if (ftape_current_cylinder > cmd) {
  383. return ftape_current_cylinder - cmd;
  384. } else {
  385. return ftape_current_cylinder + cmd;
  386. }
  387. }
  388. static void pause_tape(int retry, int mode)
  389. {
  390. int result;
  391. __u8 out[3] = {FDC_SEEK, ft_drive_sel, 0};
  392. TRACE_FUN(ft_t_any);
  393. /* We'll use a raw seek command to get the tape to rewind and
  394. * stop for a retry.
  395. */
  396. ++ft_history.rewinds;
  397. if (qic117_cmds[ftape_current_command].non_intr) {
  398. TRACE(ft_t_warn, "motion command may be issued too soon");
  399. }
  400. if (retry && (mode == fdc_reading_data ||
  401. mode == fdc_reading_id ||
  402. mode == fdc_verifying)) {
  403. ftape_current_command = QIC_MICRO_STEP_PAUSE;
  404. ftape_might_be_off_track = 1;
  405. } else {
  406. ftape_current_command = QIC_PAUSE;
  407. }
  408. out[2] = calc_steps(ftape_current_command);
  409. result = fdc_command(out, 3); /* issue QIC_117 command */
  410. ftape_current_cylinder = out[ 2];
  411. if (result < 0) {
  412. TRACE(ft_t_noise, "qic-pause failed, status = %d", result);
  413. } else {
  414. ft_location.known = 0;
  415. ft_runner_status = idle;
  416. ft_hide_interrupt = 1;
  417. ftape_tape_running = 0;
  418. }
  419. TRACE_EXIT;
  420. }
  421. static void continue_xfer(buffer_struct *buff,
  422. fdc_mode_enum mode,
  423. unsigned int skip)
  424. {
  425. int write = 0;
  426. TRACE_FUN(ft_t_any);
  427. if (mode == fdc_writing_data || mode == fdc_deleting) {
  428. write = 1;
  429. }
  430. /* This part can be removed if it never happens
  431. */
  432. if (skip > 0 &&
  433. (ft_runner_status != running ||
  434. (write && (buff->status != writing)) ||
  435. (!write && (buff->status != reading &&
  436. buff->status != verifying)))) {
  437. TRACE(ft_t_err, "unexpected runner/buffer state %d/%d",
  438. ft_runner_status, buff->status);
  439. buff->status = error;
  440. /* finish this buffer: */
  441. (void)ftape_next_buffer(ft_queue_head);
  442. ft_runner_status = aborting;
  443. fdc_mode = fdc_idle;
  444. } else if (buff->remaining > 0 && ftape_calc_next_cluster(buff) > 0) {
  445. /* still sectors left in current segment, continue
  446. * with this segment
  447. */
  448. if (fdc_setup_read_write(buff, mode) < 0) {
  449. /* failed, abort operation
  450. */
  451. buff->bytes = buff->ptr - buff->address;
  452. buff->status = error;
  453. /* finish this buffer: */
  454. (void)ftape_next_buffer(ft_queue_head);
  455. ft_runner_status = aborting;
  456. fdc_mode = fdc_idle;
  457. }
  458. } else {
  459. /* current segment completed
  460. */
  461. unsigned int last_segment = buff->segment_id;
  462. int eot = ((last_segment + 1) % ft_segments_per_track) == 0;
  463. unsigned int next = buff->next_segment; /* 0 means stop ! */
  464. buff->bytes = buff->ptr - buff->address;
  465. buff->status = done;
  466. buff = ftape_next_buffer(ft_queue_head);
  467. if (eot) {
  468. /* finished last segment on current track,
  469. * can't continue
  470. */
  471. ft_runner_status = logical_eot;
  472. fdc_mode = fdc_idle;
  473. TRACE_EXIT;
  474. }
  475. if (next <= 0) {
  476. /* don't continue with next segment
  477. */
  478. TRACE(ft_t_noise, "no %s allowed, stopping tape",
  479. (write) ? "write next" : "read ahead");
  480. pause_tape(0, mode);
  481. ft_runner_status = idle; /* not quite true until
  482. * next irq
  483. */
  484. TRACE_EXIT;
  485. }
  486. /* continue with next segment
  487. */
  488. if (buff->status != waiting) {
  489. TRACE(ft_t_noise, "all input buffers %s, pausing tape",
  490. (write) ? "empty" : "full");
  491. pause_tape(0, mode);
  492. ft_runner_status = idle; /* not quite true until
  493. * next irq
  494. */
  495. TRACE_EXIT;
  496. }
  497. if (write && next != buff->segment_id) {
  498. TRACE(ft_t_noise,
  499. "segments out of order, aborting write");
  500. ft_runner_status = do_abort;
  501. fdc_mode = fdc_idle;
  502. TRACE_EXIT;
  503. }
  504. ftape_setup_new_segment(buff, next, 0);
  505. if (stop_read_ahead) {
  506. buff->next_segment = 0;
  507. stop_read_ahead = 0;
  508. }
  509. if (ftape_calc_next_cluster(buff) == 0 ||
  510. fdc_setup_read_write(buff, mode) != 0) {
  511. TRACE(ft_t_err, "couldn't start %s-ahead",
  512. write ? "write" : "read");
  513. ft_runner_status = do_abort;
  514. fdc_mode = fdc_idle;
  515. } else {
  516. /* keep on going */
  517. switch (ft_driver_state) {
  518. case reading: buff->status = reading; break;
  519. case verifying: buff->status = verifying; break;
  520. case writing: buff->status = writing; break;
  521. case deleting: buff->status = deleting; break;
  522. default:
  523. TRACE(ft_t_err,
  524. "BUG: ft_driver_state %d should be one out of "
  525. "{reading, writing, verifying, deleting}",
  526. ft_driver_state);
  527. buff->status = write ? writing : reading;
  528. break;
  529. }
  530. }
  531. }
  532. TRACE_EXIT;
  533. }
  534. static void retry_sector(buffer_struct *buff,
  535. int mode,
  536. unsigned int skip)
  537. {
  538. TRACE_FUN(ft_t_any);
  539. TRACE(ft_t_noise, "%s error, will retry",
  540. (mode == fdc_writing_data || mode == fdc_deleting) ? "write" : "read");
  541. pause_tape(1, mode);
  542. ft_runner_status = aborting;
  543. buff->status = error;
  544. buff->skip = skip;
  545. TRACE_EXIT;
  546. }
  547. static unsigned int find_resume_point(buffer_struct *buff)
  548. {
  549. int i = 0;
  550. SectorMap mask;
  551. SectorMap map;
  552. TRACE_FUN(ft_t_any);
  553. /* This function is to be called after all variables have been
  554. * updated to point past the failing sector.
  555. * If there are any soft errors before the failing sector,
  556. * find the first soft error and return the sector offset.
  557. * Otherwise find the last hard error.
  558. * Note: there should always be at least one hard or soft error !
  559. */
  560. if (buff->sector_offset < 1 || buff->sector_offset > 32) {
  561. TRACE(ft_t_bug, "BUG: sector_offset = %d",
  562. buff->sector_offset);
  563. TRACE_EXIT 0;
  564. }
  565. if (buff->sector_offset >= 32) { /* C-limitation on shift ! */
  566. mask = 0xffffffff;
  567. } else {
  568. mask = (1 << buff->sector_offset) - 1;
  569. }
  570. map = buff->soft_error_map & mask;
  571. if (map) {
  572. while ((map & (1 << i)) == 0) {
  573. ++i;
  574. }
  575. TRACE(ft_t_noise, "at sector %d", FT_SECTOR(i));
  576. } else {
  577. map = buff->hard_error_map & mask;
  578. i = buff->sector_offset - 1;
  579. if (map) {
  580. while ((map & (1 << i)) == 0) {
  581. --i;
  582. }
  583. TRACE(ft_t_noise, "after sector %d", FT_SECTOR(i));
  584. ++i; /* first sector after last hard error */
  585. } else {
  586. TRACE(ft_t_bug, "BUG: no soft or hard errors");
  587. }
  588. }
  589. TRACE_EXIT i;
  590. }
  591. /* check possible dma residue when formatting, update position record in
  592. * buffer struct. This is, of course, modelled after determine_progress(), but
  593. * we don't need to set up for retries because the format process cannot be
  594. * interrupted (except at the end of the tape track).
  595. */
  596. static int determine_fmt_progress(buffer_struct *buff, error_cause cause)
  597. {
  598. unsigned int dma_residue;
  599. TRACE_FUN(ft_t_any);
  600. /* Using less preferred order of disable_dma and
  601. * get_dma_residue because this seems to fail on at least one
  602. * system if reversed!
  603. */
  604. dma_residue = get_dma_residue(fdc.dma);
  605. disable_dma(fdc.dma);
  606. if (cause != no_error || dma_residue != 0) {
  607. TRACE(ft_t_info, "DMA residue = 0x%04x", dma_residue);
  608. fdc_mode = fdc_idle;
  609. switch(cause) {
  610. case no_error:
  611. ft_runner_status = aborting;
  612. buff->status = idle;
  613. break;
  614. case overrun_error:
  615. /* got an overrun error on the first byte, must be a
  616. * hardware problem
  617. */
  618. TRACE(ft_t_bug,
  619. "Unexpected error: failing DMA controller ?");
  620. ft_runner_status = do_abort;
  621. buff->status = error;
  622. break;
  623. default:
  624. TRACE(ft_t_noise, "Unexpected error at segment %d",
  625. buff->segment_id);
  626. ft_runner_status = do_abort;
  627. buff->status = error;
  628. break;
  629. }
  630. TRACE_EXIT -EIO; /* can only retry entire track in format mode
  631. */
  632. }
  633. /* Update var's influenced by the DMA operation.
  634. */
  635. buff->ptr += FT_SECTORS_PER_SEGMENT * 4;
  636. buff->bytes -= FT_SECTORS_PER_SEGMENT * 4;
  637. buff->remaining -= FT_SECTORS_PER_SEGMENT;
  638. buff->segment_id ++; /* done with segment */
  639. TRACE_EXIT 0;
  640. }
  641. /*
  642. * Continue formatting, switch buffers if there is no data left in
  643. * current buffer. This is, of course, modelled after
  644. * continue_xfer(), but we don't need to set up for retries because
  645. * the format process cannot be interrupted (except at the end of the
  646. * tape track).
  647. */
  648. static void continue_formatting(buffer_struct *buff)
  649. {
  650. TRACE_FUN(ft_t_any);
  651. if (buff->remaining <= 0) { /* no space left in dma buffer */
  652. unsigned int next = buff->next_segment;
  653. if (next == 0) { /* end of tape track */
  654. buff->status = done;
  655. ft_runner_status = logical_eot;
  656. fdc_mode = fdc_idle;
  657. TRACE(ft_t_noise, "Done formatting track %d",
  658. ft_location.track);
  659. TRACE_EXIT;
  660. }
  661. /*
  662. * switch to next buffer!
  663. */
  664. buff->status = done;
  665. buff = ftape_next_buffer(ft_queue_head);
  666. if (buff->status != waiting || next != buff->segment_id) {
  667. goto format_setup_error;
  668. }
  669. }
  670. if (fdc_setup_formatting(buff) < 0) {
  671. goto format_setup_error;
  672. }
  673. buff->status = formatting;
  674. TRACE(ft_t_fdc_dma, "Formatting segment %d on track %d",
  675. buff->segment_id, ft_location.track);
  676. TRACE_EXIT;
  677. format_setup_error:
  678. ft_runner_status = do_abort;
  679. fdc_mode = fdc_idle;
  680. buff->status = error;
  681. TRACE(ft_t_err, "Error setting up for segment %d on track %d",
  682. buff->segment_id, ft_location.track);
  683. TRACE_EXIT;
  684. }
  685. /* this handles writing, read id, reading and formatting
  686. */
  687. static void handle_fdc_busy(buffer_struct *buff)
  688. {
  689. static int no_data_error_count;
  690. int retry = 0;
  691. error_cause cause;
  692. __u8 in[7];
  693. int skip;
  694. fdc_mode_enum fmode = fdc_mode;
  695. TRACE_FUN(ft_t_any);
  696. if (fdc_result(in, 7) < 0) { /* better get it fast ! */
  697. TRACE(ft_t_err,
  698. "Probably fatal error during FDC Result Phase\n"
  699. KERN_INFO
  700. "drive may hang until (power on) reset :-(");
  701. /* what to do next ????
  702. */
  703. TRACE_EXIT;
  704. }
  705. cause = decode_irq_cause(fdc_mode, in);
  706. #ifdef TESTING
  707. { int i;
  708. for (i = 0; i < (int)ft_nr_buffers; ++i)
  709. TRACE(ft_t_any, "buffer[%d] status: %d, segment_id: %d",
  710. i, ft_buffer[i]->status, ft_buffer[i]->segment_id);
  711. }
  712. #endif
  713. if (fmode == fdc_reading_data && ft_driver_state == verifying) {
  714. fmode = fdc_verifying;
  715. }
  716. switch (fmode) {
  717. case fdc_verifying:
  718. if (ft_runner_status == aborting ||
  719. ft_runner_status == do_abort) {
  720. TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
  721. break;
  722. }
  723. if (buff->retry > 0) {
  724. TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
  725. }
  726. switch (cause) {
  727. case no_error:
  728. no_data_error_count = 0;
  729. determine_verify_progress(buff, cause, in[5]);
  730. if (in[2] & 0x40) {
  731. /* This should not happen when verifying
  732. */
  733. TRACE(ft_t_warn,
  734. "deleted data in segment %d/%d",
  735. buff->segment_id,
  736. FT_SECTOR(buff->sector_offset - 1));
  737. buff->remaining = 0; /* abort transfer */
  738. buff->hard_error_map = EMPTY_SEGMENT;
  739. skip = 1;
  740. } else {
  741. skip = 0;
  742. }
  743. continue_xfer(buff, fdc_mode, skip);
  744. break;
  745. case no_data_error:
  746. no_data_error_count ++;
  747. case overrun_error:
  748. retry ++;
  749. case id_am_error:
  750. case id_crc_error:
  751. case data_am_error:
  752. case data_crc_error:
  753. determine_verify_progress(buff, cause, in[5]);
  754. if (cause == no_data_error) {
  755. if (no_data_error_count >= 2) {
  756. TRACE(ft_t_warn,
  757. "retrying because of successive "
  758. "no data errors");
  759. no_data_error_count = 0;
  760. } else {
  761. retry --;
  762. }
  763. } else {
  764. no_data_error_count = 0;
  765. }
  766. if (retry) {
  767. skip = find_resume_point(buff);
  768. } else {
  769. skip = buff->sector_offset;
  770. }
  771. if (retry && skip < 32) {
  772. retry_sector(buff, fdc_mode, skip);
  773. } else {
  774. continue_xfer(buff, fdc_mode, skip);
  775. }
  776. update_history(cause);
  777. break;
  778. default:
  779. /* Don't know why this could happen
  780. * but find out.
  781. */
  782. determine_verify_progress(buff, cause, in[5]);
  783. retry_sector(buff, fdc_mode, 0);
  784. TRACE(ft_t_err, "Error: unexpected error");
  785. break;
  786. }
  787. break;
  788. case fdc_reading_data:
  789. #ifdef TESTING
  790. /* I'm sorry, but: NOBODY ever used this trace
  791. * messages for ages. I guess that Bas was the last person
  792. * that ever really used this (thank you, between the lines)
  793. */
  794. if (cause == no_error) {
  795. TRACE(ft_t_flow,"reading segment %d",buff->segment_id);
  796. } else {
  797. TRACE(ft_t_noise, "error reading segment %d",
  798. buff->segment_id);
  799. TRACE(ft_t_noise, "\n"
  800. KERN_INFO
  801. "IRQ:C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x\n"
  802. KERN_INFO
  803. "BUF:C: 0x%02x, H: 0x%02x, R: 0x%02x",
  804. in[3], in[4], in[5], in[6],
  805. buff->cyl, buff->head, buff->sect);
  806. }
  807. #endif
  808. if (ft_runner_status == aborting ||
  809. ft_runner_status == do_abort) {
  810. TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
  811. break;
  812. }
  813. if (buff->bad_sector_map == FAKE_SEGMENT) {
  814. /* This condition occurs when reading a `fake'
  815. * sector that's not accessible. Doesn't
  816. * really matter as we would have ignored it
  817. * anyway !
  818. *
  819. * Chance is that we're past the next segment
  820. * now, so the next operation may fail and
  821. * result in a retry.
  822. */
  823. buff->remaining = 0; /* skip failing sector */
  824. /* buff->ptr = buff->address; */
  825. /* fake success: */
  826. continue_xfer(buff, fdc_mode, 1);
  827. /* trace calls are expensive: place them AFTER
  828. * the real stuff has been done.
  829. *
  830. */
  831. TRACE(ft_t_noise, "skipping empty segment %d (read), size? %d",
  832. buff->segment_id, buff->ptr - buff->address);
  833. TRACE_EXIT;
  834. }
  835. if (buff->retry > 0) {
  836. TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
  837. }
  838. switch (cause) {
  839. case no_error:
  840. determine_progress(buff, cause, in[5]);
  841. if (in[2] & 0x40) {
  842. /* Handle deleted data in header segments.
  843. * Skip segment and force read-ahead.
  844. */
  845. TRACE(ft_t_warn,
  846. "deleted data in segment %d/%d",
  847. buff->segment_id,
  848. FT_SECTOR(buff->sector_offset - 1));
  849. buff->deleted = 1;
  850. buff->remaining = 0;/*abort transfer */
  851. buff->soft_error_map |=
  852. (-1L << buff->sector_offset);
  853. if (buff->segment_id == 0) {
  854. /* stop on next segment */
  855. stop_read_ahead = 1;
  856. }
  857. /* force read-ahead: */
  858. buff->next_segment =
  859. buff->segment_id + 1;
  860. skip = (FT_SECTORS_PER_SEGMENT -
  861. buff->sector_offset);
  862. } else {
  863. skip = 0;
  864. }
  865. continue_xfer(buff, fdc_mode, skip);
  866. break;
  867. case no_data_error:
  868. /* Tape started too far ahead of or behind the
  869. * right sector. This may also happen in the
  870. * middle of a segment !
  871. *
  872. * Handle no-data as soft error. If next
  873. * sector fails too, a retry (with needed
  874. * reposition) will follow.
  875. */
  876. retry ++;
  877. case id_am_error:
  878. case id_crc_error:
  879. case data_am_error:
  880. case data_crc_error:
  881. case overrun_error:
  882. retry += (buff->soft_error_map != 0 ||
  883. buff->hard_error_map != 0);
  884. determine_progress(buff, cause, in[5]);
  885. #if 1 || defined(TESTING)
  886. if (cause == overrun_error) retry ++;
  887. #endif
  888. if (retry) {
  889. skip = find_resume_point(buff);
  890. } else {
  891. skip = buff->sector_offset;
  892. }
  893. /* Try to resume with next sector on single
  894. * errors (let ecc correct it), but retry on
  895. * no_data (we'll be past the target when we
  896. * get here so we cannot retry) or on
  897. * multiple errors (reduce chance on ecc
  898. * failure).
  899. */
  900. /* cH: 23/02/97: if the last sector in the
  901. * segment was a hard error, then there is
  902. * no sense in a retry. This occasion seldom
  903. * occurs but ... @:³²¸`@%&§$
  904. */
  905. if (retry && skip < 32) {
  906. retry_sector(buff, fdc_mode, skip);
  907. } else {
  908. continue_xfer(buff, fdc_mode, skip);
  909. }
  910. update_history(cause);
  911. break;
  912. default:
  913. /* Don't know why this could happen
  914. * but find out.
  915. */
  916. determine_progress(buff, cause, in[5]);
  917. retry_sector(buff, fdc_mode, 0);
  918. TRACE(ft_t_err, "Error: unexpected error");
  919. break;
  920. }
  921. break;
  922. case fdc_reading_id:
  923. if (cause == no_error) {
  924. fdc_cyl = in[3];
  925. fdc_head = in[4];
  926. fdc_sect = in[5];
  927. TRACE(ft_t_fdc_dma,
  928. "id read: C: 0x%02x, H: 0x%02x, R: 0x%02x",
  929. fdc_cyl, fdc_head, fdc_sect);
  930. } else { /* no valid information, use invalid sector */
  931. fdc_cyl = fdc_head = fdc_sect = 0;
  932. TRACE(ft_t_flow, "Didn't find valid sector Id");
  933. }
  934. fdc_mode = fdc_idle;
  935. break;
  936. case fdc_deleting:
  937. case fdc_writing_data:
  938. #ifdef TESTING
  939. if (cause == no_error) {
  940. TRACE(ft_t_flow, "writing segment %d", buff->segment_id);
  941. } else {
  942. TRACE(ft_t_noise, "error writing segment %d",
  943. buff->segment_id);
  944. }
  945. #endif
  946. if (ft_runner_status == aborting ||
  947. ft_runner_status == do_abort) {
  948. TRACE(ft_t_flow, "aborting %s",fdc_mode_txt(fdc_mode));
  949. break;
  950. }
  951. if (buff->retry > 0) {
  952. TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
  953. }
  954. if (buff->bad_sector_map == FAKE_SEGMENT) {
  955. /* This condition occurs when trying to write to a
  956. * `fake' sector that's not accessible. Doesn't really
  957. * matter as it isn't used anyway ! Might be located
  958. * at wrong segment, then we'll fail on the next
  959. * segment.
  960. */
  961. TRACE(ft_t_noise, "skipping empty segment (write)");
  962. buff->remaining = 0; /* skip failing sector */
  963. /* fake success: */
  964. continue_xfer(buff, fdc_mode, 1);
  965. break;
  966. }
  967. switch (cause) {
  968. case no_error:
  969. determine_progress(buff, cause, in[5]);
  970. continue_xfer(buff, fdc_mode, 0);
  971. break;
  972. case no_data_error:
  973. case id_am_error:
  974. case id_crc_error:
  975. case data_am_error:
  976. case overrun_error:
  977. update_history(cause);
  978. determine_progress(buff, cause, in[5]);
  979. skip = find_resume_point(buff);
  980. retry_sector(buff, fdc_mode, skip);
  981. break;
  982. default:
  983. if (in[1] & 0x02) {
  984. TRACE(ft_t_err, "media not writable");
  985. } else {
  986. TRACE(ft_t_bug, "unforeseen write error");
  987. }
  988. fdc_mode = fdc_idle;
  989. break;
  990. }
  991. break; /* fdc_deleting || fdc_writing_data */
  992. case fdc_formatting:
  993. /* The interrupt comes after formatting a segment. We then
  994. * have to set up QUICKLY for the next segment. But
  995. * afterwards, there is plenty of time.
  996. */
  997. switch (cause) {
  998. case no_error:
  999. /* would like to keep most of the formatting stuff
  1000. * outside the isr code, but timing is too critical
  1001. */
  1002. if (determine_fmt_progress(buff, cause) >= 0) {
  1003. continue_formatting(buff);
  1004. }
  1005. break;
  1006. case no_data_error:
  1007. case id_am_error:
  1008. case id_crc_error:
  1009. case data_am_error:
  1010. case overrun_error:
  1011. default:
  1012. determine_fmt_progress(buff, cause);
  1013. update_history(cause);
  1014. if (in[1] & 0x02) {
  1015. TRACE(ft_t_err, "media not writable");
  1016. } else {
  1017. TRACE(ft_t_bug, "unforeseen write error");
  1018. }
  1019. break;
  1020. } /* cause */
  1021. break;
  1022. default:
  1023. TRACE(ft_t_warn, "Warning: unexpected irq during: %s",
  1024. fdc_mode_txt(fdc_mode));
  1025. fdc_mode = fdc_idle;
  1026. break;
  1027. }
  1028. TRACE_EXIT;
  1029. }
  1030. /* FDC interrupt service routine.
  1031. */
  1032. void fdc_isr(void)
  1033. {
  1034. static int isr_active;
  1035. #ifdef TESTING
  1036. unsigned int t0 = ftape_timestamp();
  1037. #endif
  1038. TRACE_FUN(ft_t_any);
  1039. if (isr_active++) {
  1040. --isr_active;
  1041. TRACE(ft_t_bug, "BUG: nested interrupt, not good !");
  1042. *fdc.hook = fdc_isr; /* hook our handler into the fdc
  1043. * code again
  1044. */
  1045. TRACE_EXIT;
  1046. }
  1047. sti();
  1048. if (inb_p(fdc.msr) & FDC_BUSY) { /* Entering Result Phase */
  1049. ft_hide_interrupt = 0;
  1050. handle_fdc_busy(ftape_get_buffer(ft_queue_head));
  1051. if (ft_runner_status == do_abort) {
  1052. /* cease operation, remember tape position
  1053. */
  1054. TRACE(ft_t_flow, "runner aborting");
  1055. ft_runner_status = aborting;
  1056. ++ft_expected_stray_interrupts;
  1057. }
  1058. } else { /* !FDC_BUSY */
  1059. /* clear interrupt, cause should be gotten by issuing
  1060. * a Sense Interrupt Status command.
  1061. */
  1062. if (fdc_mode == fdc_recalibrating || fdc_mode == fdc_seeking) {
  1063. if (ft_hide_interrupt) {
  1064. int st0;
  1065. int pcn;
  1066. if (fdc_sense_interrupt_status(&st0, &pcn) < 0)
  1067. TRACE(ft_t_err,
  1068. "sense interrupt status failed");
  1069. ftape_current_cylinder = pcn;
  1070. TRACE(ft_t_flow, "handled hidden interrupt");
  1071. }
  1072. ft_seek_completed = 1;
  1073. fdc_mode = fdc_idle;
  1074. } else if (!waitqueue_active(&ftape_wait_intr)) {
  1075. if (ft_expected_stray_interrupts == 0) {
  1076. TRACE(ft_t_warn, "unexpected stray interrupt");
  1077. } else {
  1078. TRACE(ft_t_flow, "expected stray interrupt");
  1079. --ft_expected_stray_interrupts;
  1080. }
  1081. } else {
  1082. if (fdc_mode == fdc_reading_data ||
  1083. fdc_mode == fdc_verifying ||
  1084. fdc_mode == fdc_writing_data ||
  1085. fdc_mode == fdc_deleting ||
  1086. fdc_mode == fdc_formatting ||
  1087. fdc_mode == fdc_reading_id) {
  1088. if (inb_p(fdc.msr) & FDC_BUSY) {
  1089. TRACE(ft_t_bug,
  1090. "***** FDC failure, busy too late");
  1091. } else {
  1092. TRACE(ft_t_bug,
  1093. "***** FDC failure, no busy");
  1094. }
  1095. } else {
  1096. TRACE(ft_t_fdc_dma, "awaited stray interrupt");
  1097. }
  1098. }
  1099. ft_hide_interrupt = 0;
  1100. }
  1101. /* Handle sleep code.
  1102. */
  1103. if (!ft_hide_interrupt) {
  1104. ft_interrupt_seen ++;
  1105. if (waitqueue_active(&ftape_wait_intr)) {
  1106. wake_up_interruptible(&ftape_wait_intr);
  1107. }
  1108. } else {
  1109. TRACE(ft_t_flow, "hiding interrupt while %s",
  1110. waitqueue_active(&ftape_wait_intr) ? "waiting":"active");
  1111. }
  1112. #ifdef TESTING
  1113. t0 = ftape_timediff(t0, ftape_timestamp());
  1114. if (t0 >= 1000) {
  1115. /* only tell us about long calls */
  1116. TRACE(ft_t_noise, "isr() duration: %5d usec", t0);
  1117. }
  1118. #endif
  1119. *fdc.hook = fdc_isr; /* hook our handler into the fdc code again */
  1120. --isr_active;
  1121. TRACE_EXIT;
  1122. }