floppy.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. /*
  2. * Papa's got a brand new bag on the side.
  3. */
  4. #include "all.h"
  5. #include "io.h"
  6. #include "mem.h"
  7. #define DPRINT if(0)print
  8. typedef struct Floppy Floppy;
  9. typedef struct Ctlr Ctlr;
  10. typedef struct Type Type;
  11. enum
  12. {
  13. Pdor= 0x3f2, /* motor port */
  14. Fintena= 0x8, /* enable floppy interrupt */
  15. Fena= 0x4, /* 0 == reset controller */
  16. Pmsr= 0x3f4, /* controller main status port */
  17. Fready= 0x80, /* ready to be touched */
  18. Ffrom= 0x40, /* data from controller */
  19. Fbusy= 0x10, /* operation not over */
  20. Pdata= 0x3f5, /* controller data port */
  21. Frecal= 0x7, /* recalibrate cmd */
  22. Fseek= 0xf, /* seek cmd */
  23. Fsense= 0x8, /* sense cmd */
  24. Fread= 0x66, /* read cmd */
  25. Fwrite= 0x45, /* write cmd */
  26. Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
  27. /* digital input register */
  28. Pdir= 0x3F7, /* disk changed port (read only) */
  29. Pdsr= 0x3F7, /* data rate select port (write only) */
  30. Fchange= 0x80, /* disk has changed */
  31. DMAmode0= 0xb,
  32. DMAmode1= 0xc,
  33. DMAaddr= 0x4,
  34. DMAtop= 0x81,
  35. DMAinit= 0xa,
  36. DMAcount= 0x5,
  37. Maxfloppy= 4, /* floppies/controller */
  38. /* sector size encodings */
  39. S128= 0,
  40. S256= 1,
  41. S512= 2,
  42. S1024= 3,
  43. /* status 0 byte */
  44. Floppymask= 3<<0,
  45. Seekend= 1<<5,
  46. Codemask= (3<<6)|(3<<3),
  47. Cmdexec= 1<<6,
  48. /* status 1 byte */
  49. Overrun= 0x10,
  50. };
  51. #define MOTORBIT(i) (1<<((i)+4))
  52. /*
  53. * types of drive (from PC equipment byte)
  54. */
  55. enum
  56. {
  57. T360kb= 1,
  58. T1200kb= 2,
  59. T720kb= 3,
  60. T1440kb= 4,
  61. };
  62. /*
  63. * floppy types (all MFM encoding)
  64. */
  65. struct Type
  66. {
  67. char *name;
  68. int dt; /* compatible drive type */
  69. int bytes; /* bytes/sector */
  70. int sectors; /* sectors/track */
  71. int heads; /* number of heads */
  72. int steps; /* steps per cylinder */
  73. int tracks; /* tracks/disk */
  74. int gpl; /* intersector gap length for read/write */
  75. int fgpl; /* intersector gap length for format */
  76. int rate; /* rate code */
  77. /*
  78. * these depend on previous entries and are set filled in
  79. * by floppyinit
  80. */
  81. int bcode; /* coded version of bytes for the controller */
  82. long cap; /* drive capacity in bytes */
  83. long tsize; /* track size in bytes */
  84. };
  85. Type floppytype[] =
  86. {
  87. { "3½HD", T1440kb, 512, 18, 2, 1, 80, 0x1B, 0x54, 0, },
  88. { "3½DD", T1440kb, 512, 9, 2, 1, 80, 0x1B, 0x54, 2, },
  89. { "3½DD", T720kb, 512, 9, 2, 1, 80, 0x1B, 0x54, 2, },
  90. { "5¼HD", T1200kb, 512, 15, 2, 1, 80, 0x2A, 0x50, 0, },
  91. { "5¼DD", T1200kb, 512, 9, 2, 2, 40, 0x2A, 0x50, 1, },
  92. { "5¼DD", T360kb, 512, 9, 2, 1, 40, 0x2A, 0x50, 2, },
  93. };
  94. #define NTYPES (sizeof(floppytype)/sizeof(Type))
  95. /*
  96. * bytes per sector encoding for the controller.
  97. * - index for b2c is is (bytes per sector/128).
  98. * - index for c2b is code from b2c
  99. */
  100. static int b2c[] =
  101. {
  102. [1] 0,
  103. [2] 1,
  104. [4] 2,
  105. [8] 3,
  106. };
  107. static int c2b[] =
  108. {
  109. 128,
  110. 256,
  111. 512,
  112. 1024,
  113. };
  114. /*
  115. * a floppy drive
  116. */
  117. struct Floppy
  118. {
  119. Type *t;
  120. int dt;
  121. int dev;
  122. Timet lasttouched; /* time last touched */
  123. int cyl; /* current cylinder */
  124. int confused; /* needs to be recalibrated (or worse) */
  125. long offset; /* current offset */
  126. int tcyl; /* target cylinder */
  127. int thead; /* target head */
  128. int tsec; /* target sector */
  129. long len;
  130. int maxtries;
  131. };
  132. /*
  133. * NEC PD765A controller for 4 floppys
  134. */
  135. struct Ctlr
  136. {
  137. QLock;
  138. Rendez;
  139. Floppy d[Maxfloppy]; /* the floppy drives */
  140. int rw; /* true if a read or write in progress */
  141. int seek; /* one bit for each seek in progress */
  142. uchar stat[8]; /* status of an operation */
  143. int intr;
  144. int confused;
  145. int motor;
  146. Floppy *selected;
  147. int rate;
  148. int cdev;
  149. uchar *ccache; /* cyclinder cache */
  150. int ccyl;
  151. int chead;
  152. };
  153. Ctlr fl;
  154. static int floppysend(int);
  155. static int floppyrcv(void);
  156. static int floppyrdstat(int);
  157. static void floppypos(Floppy*, long);
  158. static void floppywait(char*);
  159. static int floppysense(Floppy*);
  160. static int floppyrecal(Floppy*);
  161. static void floppyon(Floppy*);
  162. static long floppyxfer(Floppy*, int, void*, long);
  163. static void floppyrevive(void);
  164. static void
  165. timedsleep(int ms)
  166. {
  167. ulong end;
  168. end = MACHP(0)->ticks + 1 + MS2TK(ms);
  169. while(MACHP(0)->ticks < end)
  170. ;
  171. }
  172. /*
  173. * set floppy drive to its default type
  174. */
  175. static void
  176. setdef(Floppy *dp)
  177. {
  178. Type *t;
  179. for(t = floppytype; t < &floppytype[NTYPES]; t++)
  180. if(dp->dt == t->dt){
  181. dp->t = t;
  182. break;
  183. }
  184. }
  185. static void
  186. floppyintr(Ureg *ur, void *arg)
  187. {
  188. USED(ur, arg);
  189. fl.intr = 1;
  190. }
  191. static void
  192. floppystop(Floppy *dp)
  193. {
  194. fl.motor &= ~MOTORBIT(dp->dev);
  195. outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
  196. }
  197. void
  198. floppyhalt(void)
  199. {
  200. Floppy *dp;
  201. for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++)
  202. if((fl.motor&MOTORBIT(dp->dev)) && canqlock(&fl)){
  203. floppystop(dp);
  204. qunlock(&fl);
  205. }
  206. }
  207. static void
  208. floppyalarm(Alarm* a, void *arg)
  209. {
  210. USED(arg);
  211. cancel(a);
  212. wakeup(&fl);
  213. }
  214. void
  215. floppyproc(void)
  216. {
  217. Floppy *dp;
  218. for(;;){
  219. for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++){
  220. if((fl.motor&MOTORBIT(dp->dev))
  221. && TK2SEC(MACHP(0)->ticks - dp->lasttouched) > 5
  222. && canqlock(&fl)){
  223. if(TK2SEC(MACHP(0)->ticks - dp->lasttouched) > 5)
  224. floppystop(dp);
  225. qunlock(&fl);
  226. }
  227. }
  228. alarm(5*1000, floppyalarm, 0);
  229. sleep(&fl, no, 0);
  230. }
  231. }
  232. int
  233. floppyinit(void)
  234. {
  235. Floppy *dp;
  236. uchar equip;
  237. int nfloppy = 0;
  238. Type *t;
  239. setvec(Floppyvec, floppyintr, &fl);
  240. delay(10);
  241. outb(Pdor, 0);
  242. delay(1);
  243. outb(Pdor, Fintena | Fena);
  244. delay(10);
  245. /*
  246. * init dependent parameters
  247. */
  248. for(t = floppytype; t < &floppytype[NTYPES]; t++){
  249. t->cap = t->bytes * t->heads * t->sectors * t->tracks;
  250. t->bcode = b2c[t->bytes/128];
  251. t->tsize = t->bytes * t->sectors;
  252. }
  253. /*
  254. * init drive parameters
  255. */
  256. for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++){
  257. dp->cyl = -1;
  258. dp->dev = dp - fl.d;
  259. dp->maxtries = 1;
  260. }
  261. /*
  262. * read nvram for types of floppies 0 & 1
  263. */
  264. equip = nvramread(0x10);
  265. if(Maxfloppy > 0){
  266. fl.d[0].dt = (equip >> 4) & 0xf;
  267. setdef(&fl.d[0]);
  268. nfloppy++;
  269. }
  270. if(Maxfloppy > 1){
  271. fl.d[1].dt = equip & 0xf;
  272. setdef(&fl.d[1]);
  273. nfloppy++;
  274. }
  275. fl.rate = -1;
  276. fl.motor = 0;
  277. fl.confused = 1;
  278. fl.ccyl = -1;
  279. fl.chead = -1;
  280. fl.cdev = -1;
  281. fl.ccache = (uchar*)ialloc(18*2*512, 64*1024);
  282. if(DMAOK(fl.ccache, 18*2*512) == 0)
  283. panic("floppy: no memory < 16Mb\n");
  284. return nfloppy;
  285. }
  286. static void
  287. floppyon(Floppy *dp)
  288. {
  289. int alreadyon;
  290. int tries;
  291. if(fl.confused)
  292. floppyrevive();
  293. dp->lasttouched = MACHP(0)->ticks;
  294. alreadyon = fl.motor & MOTORBIT(dp->dev);
  295. fl.motor |= MOTORBIT(dp->dev);
  296. outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
  297. /* get motor going */
  298. if(!alreadyon)
  299. timedsleep(750);
  300. /* set transfer rate */
  301. if(fl.rate != dp->t->rate){
  302. fl.rate = dp->t->rate;
  303. outb(Pdsr, fl.rate);
  304. }
  305. /* get drive to a known cylinder */
  306. if(dp->confused)
  307. for(tries = 0; tries < 4; tries++)
  308. if(floppyrecal(dp) >= 0)
  309. break;
  310. dp->lasttouched = MACHP(0)->ticks;
  311. fl.selected = dp;
  312. }
  313. static void
  314. floppyrevive(void)
  315. {
  316. Floppy *dp;
  317. /*
  318. * reset the controller if it's confused
  319. */
  320. if(fl.confused){
  321. /* reset controller and turn all motors off */
  322. fl.intr = 0;
  323. splhi();
  324. outb(Pdor, 0);
  325. delay(1);
  326. outb(Pdor, Fintena|Fena);
  327. spllo();
  328. for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++)
  329. dp->confused = 1;
  330. fl.motor = 0;
  331. floppywait("revive");
  332. fl.confused = 0;
  333. outb(Pdsr, 0);
  334. }
  335. }
  336. static int
  337. floppysend(int data)
  338. {
  339. int tries;
  340. for(tries = 0; tries < 1000; tries++){
  341. if((inb(Pmsr)&(Ffrom|Fready)) == Fready){
  342. outb(Pdata, data);
  343. return 0;
  344. }
  345. microdelay(8);
  346. }
  347. return -1;
  348. }
  349. static int
  350. floppyrcv(void)
  351. {
  352. int tries;
  353. uchar c;
  354. for(tries = 0; tries < 1000; tries++){
  355. if((inb(Pmsr)&(Ffrom|Fready)) == (Ffrom|Fready))
  356. return inb(Pdata)&0xff;
  357. microdelay(8);
  358. }
  359. DPRINT("floppyrcv returns -1 status = %ux\n", c);
  360. return -1;
  361. }
  362. static int
  363. floppyrdstat(int n)
  364. {
  365. int i;
  366. int c;
  367. for(i = 0; i < n; i++){
  368. c = floppyrcv();
  369. if(c < 0)
  370. return -1;
  371. fl.stat[i] = c;
  372. }
  373. return 0;
  374. }
  375. static void
  376. floppypos(Floppy *dp, long off)
  377. {
  378. int lsec;
  379. int cyl;
  380. lsec = off/dp->t->bytes;
  381. dp->tcyl = lsec/(dp->t->sectors*dp->t->heads);
  382. dp->tsec = (lsec % dp->t->sectors) + 1;
  383. dp->thead = (lsec/dp->t->sectors) % dp->t->heads;
  384. /*
  385. * can't read across cylinder boundaries.
  386. * if so, decrement the bytes to be read.
  387. */
  388. lsec = (off+dp->len)/dp->t->bytes;
  389. cyl = lsec/(dp->t->sectors*dp->t->heads);
  390. if(cyl != dp->tcyl){
  391. dp->len -= (lsec % dp->t->sectors)*dp->t->bytes;
  392. dp->len -= ((lsec/dp->t->sectors) % dp->t->heads)*dp->t->bytes
  393. *dp->t->sectors;
  394. }
  395. dp->lasttouched = MACHP(0)->ticks;
  396. fl.intr = 0;
  397. }
  398. static void
  399. floppywait(char *cmd)
  400. {
  401. ulong end;
  402. end = MACHP(0)->ticks + 1 + MS2TK(750);
  403. while(MACHP(0)->ticks < end && fl.intr == 0)
  404. ;
  405. if(m->ticks > end)
  406. DPRINT("floppy timed out, cmd=%s\n", cmd);
  407. fl.intr = 0;
  408. }
  409. static int
  410. floppysense(Floppy *dp)
  411. {
  412. /*
  413. * ask for floppy status
  414. */
  415. if(floppysend(Fsense) < 0){
  416. fl.confused = 1;
  417. return -1;
  418. }
  419. if(floppyrdstat(2) < 0){
  420. fl.confused = 1;
  421. dp->confused = 1;
  422. return -1;
  423. }
  424. /*
  425. * make sure it's the right drive
  426. */
  427. if((fl.stat[0] & Floppymask) != dp->dev){
  428. DPRINT("sense failed, %ux %ux\n", fl.stat[0], fl.stat[1]);
  429. dp->confused = 1;
  430. return -1;
  431. }
  432. return 0;
  433. }
  434. static int
  435. floppyrecal(Floppy *dp)
  436. {
  437. fl.intr = 0;
  438. if(floppysend(Frecal) < 0
  439. || floppysend(dp - fl.d) < 0){
  440. DPRINT("recalibrate rejected\n");
  441. fl.confused = 0;
  442. return -1;
  443. }
  444. floppywait("recal");
  445. /*
  446. * get return values
  447. */
  448. if(floppysense(dp) < 0)
  449. return -1;
  450. /*
  451. * see what cylinder we got to
  452. */
  453. dp->tcyl = 0;
  454. dp->cyl = fl.stat[1]/dp->t->steps;
  455. if(dp->cyl != dp->tcyl){
  456. DPRINT("recalibrate went to wrong cylinder %d\n", dp->cyl);
  457. dp->confused = 1;
  458. return -1;
  459. }
  460. dp->confused = 0;
  461. return 0;
  462. }
  463. Devsize
  464. floppyseek(int dev, Devsize off)
  465. {
  466. Floppy *dp;
  467. dp = &fl.d[dev];
  468. floppyon(dp);
  469. floppypos(dp, off);
  470. if(dp->cyl == dp->tcyl){
  471. dp->offset = off;
  472. return off;
  473. }
  474. /*
  475. * tell floppy to seek
  476. */
  477. if(floppysend(Fseek) < 0
  478. || floppysend((dp->thead<<2) | dp->dev) < 0
  479. || floppysend(dp->tcyl * dp->t->steps) < 0){
  480. DPRINT("seek cmd failed\n");
  481. fl.confused = 1;
  482. return -1;
  483. }
  484. /*
  485. * wait for interrupt
  486. */
  487. floppywait("seek");
  488. /*
  489. * get floppy status
  490. */
  491. if(floppysense(dp) < 0)
  492. return -1;
  493. /*
  494. * see if it worked
  495. */
  496. if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
  497. DPRINT("seek failed\n");
  498. dp->confused = 1;
  499. return -1;
  500. }
  501. /*
  502. * see what cylinder we got to
  503. */
  504. dp->cyl = fl.stat[1]/dp->t->steps;
  505. if(dp->cyl != dp->tcyl){
  506. DPRINT("seek went to wrong cylinder %d instead of %d\n",
  507. dp->cyl, dp->tcyl);
  508. dp->confused = 1;
  509. return -1;
  510. }
  511. dp->offset = off;
  512. DPRINT("seek to %ld succeeded\n", dp->offset);
  513. return dp->offset;
  514. }
  515. static long
  516. floppyxfer(Floppy *dp, int cmd, void *a, long n)
  517. {
  518. ulong addr;
  519. long offset;
  520. addr = (ulong)a;
  521. /*
  522. * dma can't cross 64 k boundaries
  523. */
  524. if((addr & 0xffff0000) != ((addr+n) & 0xffff0000))
  525. n -= (addr+n)&0xffff;
  526. dp->len = n;
  527. if(floppyseek(dp->dev, dp->offset) < 0){
  528. DPRINT("xfer seek failed\n");
  529. return -1;
  530. }
  531. DPRINT("floppy %d tcyl %d, thead %d, tsec %d, addr %lux, n %ld\n",
  532. dp->dev, dp->tcyl, dp->thead, dp->tsec, addr, n);/**/
  533. /*
  534. * set up the dma
  535. */
  536. outb(DMAmode1, cmd==Fread ? 0x46 : 0x4a);
  537. outb(DMAmode0, cmd==Fread ? 0x46 : 0x4a);
  538. outb(DMAaddr, addr);
  539. outb(DMAaddr, addr>>8);
  540. outb(DMAtop, addr>>16);
  541. outb(DMAcount, n-1);
  542. outb(DMAcount, (n-1)>>8);
  543. outb(DMAinit, 2);
  544. /*
  545. * tell floppy to go
  546. */
  547. cmd = cmd | (dp->t->heads > 1 ? Fmulti : 0);
  548. if(floppysend(cmd) < 0
  549. || floppysend((dp->thead<<2) | dp->dev) < 0
  550. || floppysend(dp->tcyl * dp->t->steps) < 0
  551. || floppysend(dp->thead) < 0
  552. || floppysend(dp->tsec) < 0
  553. || floppysend(dp->t->bcode) < 0
  554. || floppysend(dp->t->sectors) < 0
  555. || floppysend(dp->t->gpl) < 0
  556. || floppysend(0xFF) < 0){
  557. DPRINT("xfer cmd failed\n");
  558. fl.confused = 1;
  559. return -1;
  560. }
  561. floppywait("xfer");
  562. /*
  563. * get status
  564. */
  565. if(floppyrdstat(7) < 0){
  566. DPRINT("xfer status failed\n");
  567. fl.confused = 1;
  568. return -1;
  569. }
  570. if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){
  571. DPRINT("xfer failed %ux %ux %ux\n", fl.stat[0],
  572. fl.stat[1], fl.stat[2]);
  573. if((fl.stat[0]&Codemask)==Cmdexec && fl.stat[1]==Overrun){
  574. DPRINT("DMA overrun: retry\n");
  575. return 0;
  576. }
  577. dp->confused = 1;
  578. return -1;
  579. }
  580. offset = (fl.stat[3]/dp->t->steps) * dp->t->heads + fl.stat[4];
  581. offset = offset*dp->t->sectors + fl.stat[5] - 1;
  582. offset = offset * c2b[fl.stat[6]];
  583. if(offset != dp->offset+n){
  584. DPRINT("new offset %ld instead of %ld\n", offset, dp->offset+dp->len);
  585. dp->confused = 1;
  586. return -1;/**/
  587. }
  588. dp->offset += dp->len;
  589. return dp->len;
  590. }
  591. Off
  592. floppyread(int dev, void *a, long n)
  593. {
  594. Floppy *dp;
  595. int tries;
  596. Off rv, i, nn, offset, sec;
  597. uchar *aa;
  598. dp = &fl.d[dev];
  599. dp->len = n;
  600. qlock(&fl);
  601. floppypos(dp, dp->offset);
  602. offset = dp->offset;
  603. sec = dp->tsec + (Off)dp->t->sectors*(Off)dp->thead;
  604. n = dp->len;
  605. if(fl.ccyl==dp->tcyl && fl.cdev==dev)
  606. goto out;
  607. fl.ccyl = -1;
  608. fl.cdev = dev;
  609. aa = fl.ccache;
  610. nn = (Off)dp->t->bytes * (Off)dp->t->sectors * (Off)dp->t->heads;
  611. dp->offset = dp->tcyl * nn;
  612. for(rv = 0; rv < nn; rv += i){
  613. i = 0;
  614. for(tries = 0; tries < dp->maxtries; tries++){
  615. i = floppyxfer(dp, Fread, aa+rv, nn-rv);
  616. if(i > 0)
  617. break;
  618. }
  619. if(tries == dp->maxtries)
  620. break;
  621. }
  622. if(rv != nn){
  623. dp->confused = 1;
  624. return -1; // ?!!? no qunlock(&fl)? no "goto out"?
  625. }
  626. fl.ccyl = dp->tcyl;
  627. out:
  628. memmove(a, fl.ccache + dp->t->bytes*(sec-1), n);
  629. dp->offset = offset + n;
  630. dp->maxtries = 3;
  631. qunlock(&fl);
  632. return n;
  633. }
  634. Off
  635. floppywrite(int dev, void *a, long n)
  636. {
  637. Floppy *dp;
  638. int tries;
  639. Off rv, i, offset;
  640. uchar *aa;
  641. dp = &fl.d[dev];
  642. qlock(&fl);
  643. fl.ccyl = -1;
  644. fl.cdev = dev;
  645. dp->len = n;
  646. offset = dp->offset;
  647. aa = a;
  648. if(DMAOK(aa, n) == 0){
  649. aa = fl.ccache;
  650. memmove(aa, a, n);
  651. }
  652. for(rv = 0; rv < n; rv += i){
  653. i = 0;
  654. for(tries = 0; tries < dp->maxtries; tries++){
  655. floppypos(dp, offset+rv);
  656. i = floppyxfer(dp, Fwrite, aa+rv, n-rv);
  657. if(i > 0)
  658. break;
  659. }
  660. if(tries == dp->maxtries)
  661. break;
  662. }
  663. if(rv != n)
  664. dp->confused = 1;
  665. dp->offset = offset + rv;
  666. dp->maxtries = 20;
  667. qunlock(&fl);
  668. return rv;
  669. }