home *** CD-ROM | disk | FTP | other *** search
/ Amiga GigaPD 3 / Amiga_GigaPD_v3_3of3.iso / netbsd / docs / mailinglist-archive / 1993-09 / text0024.txt < prev    next >
Encoding:
Text File  |  1993-06-25  |  11.3 KB  |  362 lines

  1.     It's been tape drive weekend here at hack central.
  2.  
  3.     I've had two problems using my A3070 drive with NetBSD -- the
  4. first is that I couldn't work with multiple files on a single tape.
  5. Every command after doing a 'mt -f /dev/nrst0 fsf 1' resulted in an
  6. error.  That kinda sucks.  The problem appears to be that the SCSI tape
  7. driver (.../amiga/dev/st.c) will send a mode-select command to the
  8. driver every time you open the device and the Caliper CP150 (what's
  9. inside the A3070) doesn't like that very much.  It only seems to take
  10. mode-select when the tape is fully rewound.  (The mode-select chooses
  11. between 120M and 150M operation, and probably does some other stuff,
  12. too).  Here are the patches I used (613 source base).  The second
  13. problem is described after this:
  14.  
  15. ------------------------------------------------------------------------
  16. *** arch/amiga/dev/st.c-orig    Thu Aug 12 14:49:01 1993
  17. --- arch/amiga/dev/st.c    Sun Sep  5 21:48:40 1993
  18. ***************
  19. *** 111,117 ****
  20.   extern int sterror (int unit, struct st_softc *sc, int stat);
  21.   extern int stxsense (int ctlr, int slave, int unit, struct st_softc *sc);
  22.   extern int prtkey (int unit, struct st_softc *sc);
  23. ! extern int dumpxsense (struct st_xsense *sensebuf);
  24.   extern int prtmodsel (struct mode_select_data *msd, int modlen);
  25.   extern int prtmodstat (struct mode_sense *mode);
  26.   
  27. --- 111,117 ----
  28.   extern int sterror (int unit, struct st_softc *sc, int stat);
  29.   extern int stxsense (int ctlr, int slave, int unit, struct st_softc *sc);
  30.   extern int prtkey (int unit, struct st_softc *sc);
  31. ! extern int dumpxsense (struct st_xsense *sensebuf, struct st_softc *sc);
  32.   extern int prtmodsel (struct mode_select_data *msd, int modlen);
  33.   extern int prtmodstat (struct mode_sense *mode);
  34.   
  35. ***************
  36. *** 156,163 ****
  37.    */
  38.   static struct st_xsense {
  39.       struct    scsi_xsense sc_xsense;    /* data from sense */
  40. !     struct    exb_xsense exb_xsense;    /* additional info from exabyte */
  41.   } st_xsense[NST];
  42.   
  43.   static struct scsi_fmt_cdb stcmd[NST];
  44.   
  45. --- 156,168 ----
  46.    */
  47.   static struct st_xsense {
  48.       struct    scsi_xsense sc_xsense;    /* data from sense */
  49. !     union {
  50. !         struct exb_xsense uexb_xsense; /* additional info from exabyte */
  51. !         struct cpr_xsense ucpr_xsense; /* additional info from caliper */
  52. !     } u;
  53.   } st_xsense[NST];
  54. + #define exb_xsense u.uexb_xsense
  55. + #define cpr_xsense u.ucpr_xsense
  56.   
  57.   static struct scsi_fmt_cdb stcmd[NST];
  58.   
  59. ***************
  60. *** 316,325 ****
  61.               if (idstr[i] != ' ')
  62.                   break;
  63.           idstr[i+1] = 0;
  64. !         printf("st%d: %s >%s< rev %s\n", ad->amiga_unit, idstr, &idstr[8],
  65.                  &idstr[24]);
  66.       } else if (inqlen == 5)
  67. !         /* great it's a stupid device, doesn't know it's know name */
  68.           idstr[0] = idstr[8] = '\0';
  69.       else
  70.           idstr[8] = '\0';
  71. --- 321,330 ----
  72.               if (idstr[i] != ' ')
  73.                   break;
  74.           idstr[i+1] = 0;
  75. !         printf("st%d: %s %s rev %s\n", ad->amiga_unit, idstr, &idstr[8],
  76.                  &idstr[24]);
  77.       } else if (inqlen == 5)
  78. !         /* great it's a stupid device, doesn't know it's own name */
  79.           idstr[0] = idstr[8] = '\0';
  80.       else
  81.           idstr[8] = '\0';
  82. ***************
  83. *** 362,367 ****
  84. --- 367,378 ----
  85.           sc->sc_datalen[CMD_INQUIRY] = 36;
  86.           sc->sc_datalen[CMD_MODE_SELECT] = 12;
  87.           sc->sc_datalen[CMD_MODE_SENSE] = 12;
  88. +     } else if (bcmp("CP150", &idstr[8], 5) == 0) {
  89. +         sc->sc_tapeid = MT_ISCALIPER;
  90. +         sc->sc_datalen[CMD_REQUEST_SENSE] = 14;
  91. +         sc->sc_datalen[CMD_INQUIRY] = 36;
  92. +         sc->sc_datalen[CMD_MODE_SELECT] = 12;
  93. +         sc->sc_datalen[CMD_MODE_SENSE] = 12;
  94.       } else {
  95.           if (idstr[8] == '\0')
  96.               printf("st%d: No ID, assuming Archive\n", ad->amiga_unit);
  97. ***************
  98. *** 414,419 ****
  99. --- 425,431 ----
  100.       struct mode_select_data msd;
  101.       struct mode_sense mode;
  102.       int modlen;
  103. +     int skip_modsel = 0;
  104.       static struct scsi_fmt_cdb modsel = {
  105.           6,
  106.           CMD_MODE_SELECT, 0, 0, 0, sizeof(msd), 0
  107. ***************
  108. *** 471,476 ****
  109. --- 483,497 ----
  110.           sc->sc_blklen = 512;
  111.           break;
  112.   #endif
  113. +     case MT_ISCALIPER:
  114. +         sc->sc_blklen = 512;
  115. +         stxsense(ctlr, slave, unit, sc);
  116. +         /* Calipers can't handle a mode-select if the tape
  117. +          * isn't rewound.
  118. +          */
  119. +         if (xsense->cpr_xsense.b11)
  120. +             skip_modsel = 1;
  121. +         break;
  122.       case MT_ISWANGTEK:
  123.           sc->sc_blklen = 512;
  124.           break;
  125. ***************
  126. *** 485,490 ****
  127. --- 506,514 ----
  128.               sc->sc_blklen = 512;
  129.       }
  130.   
  131. +     if (skip_modsel)
  132. +         goto mode_selected;
  133.       /* setup for mode select */
  134.       msd.rsvd1 = 0;
  135.       msd.rsvd2 = 0;
  136. ***************
  137. *** 513,518 ****
  138. --- 537,543 ----
  139.               msd.density = 0x4;
  140.           }
  141.           break;
  142. +     case MT_ISCALIPER:
  143.       case MT_ISWANGTEK:
  144.           if (minor (dev) & STDEV_HIDENSITY)
  145.               msd.density = 0x10;
  146. ***************
  147. *** 586,591 ****
  148. --- 611,617 ----
  149.           goto retryselect;
  150.       }
  151.   
  152. + mode_selected:
  153.       /* drive ready ? */
  154.       stat = scsi_test_unit_rdy(ctlr, slave, unit);
  155.   
  156. ***************
  157. *** 622,627 ****
  158. --- 648,654 ----
  159.           case MT_ISHPDAT:
  160.           case MT_ISVIPER1:
  161.           case MT_ISPYTHON:
  162. +         case MT_ISCALIPER:
  163.           case MT_ISWANGTEK:
  164.               if (xsense->sc_xsense.key == XSK_UNTATTEN)
  165.                   stat = scsi_test_unit_rdy(ctlr, slave, unit);
  166. ***************
  167. *** 654,660 ****
  168.           stxsense(ctlr, slave, unit, sc);
  169.   #ifdef DEBUG
  170.           if (st_debug & ST_OPEN)
  171. !             dumpxsense(xsense);
  172.   #endif
  173.       }
  174.       if (stat)
  175. --- 681,687 ----
  176.           stxsense(ctlr, slave, unit, sc);
  177.   #ifdef DEBUG
  178.           if (st_debug & ST_OPEN)
  179. !             dumpxsense(xsense, sc);
  180.   #endif
  181.       }
  182.       if (stat)
  183. ***************
  184. *** 1387,1394 ****
  185.   
  186.   #ifdef DEBUG
  187.   
  188. ! dumpxsense(sensebuf)
  189.       struct st_xsense *sensebuf;
  190.   {
  191.           struct st_xsense *xp = sensebuf;
  192.   
  193. --- 1414,1422 ----
  194.   
  195.   #ifdef DEBUG
  196.   
  197. ! dumpxsense(sensebuf, sc)
  198.       struct st_xsense *sensebuf;
  199. +     struct st_softc *sc;
  200.   {
  201.           struct st_xsense *xp = sensebuf;
  202.   
  203. ***************
  204. *** 1404,1432 ****
  205.               (xp->sc_xsense.info3<<8)|(xp->sc_xsense.info4)) );
  206.       printf("ASenseL 0x%x\n", xp->sc_xsense.len);
  207.   
  208. !     if (xp->sc_xsense.len != 0x12) /* MT_ISEXB Exabyte only ?? */
  209. !         return;            /* What about others */
  210.   
  211. !     printf("ASenseC 0x%x\n", xp->exb_xsense.addsens);
  212. !     printf("AsenseQ 0x%x\n", xp->exb_xsense.addsensq);
  213. !     printf("R/W Errors 0x%lx\n", 
  214. !            (u_long)((xp->exb_xsense.rwerrcnt2<<16)|
  215. !             (xp->exb_xsense.rwerrcnt1<<8)|
  216. !             (xp->exb_xsense.rwerrcnt1)) );
  217. !     printf("PF   0x%x BPE  0x%x FPE 0x%x ME   0x%x ECO 0x%x TME 0x%x TNP 0x%x BOT 0x%x\n",
  218. !            xp->exb_xsense.pf, xp->exb_xsense.bpe, xp->exb_xsense.fpe, 
  219. !            xp->exb_xsense.me, xp->exb_xsense.eco, xp->exb_xsense.tme, 
  220. !            xp->exb_xsense.tnp, xp->exb_xsense.bot);
  221. !     printf("XFR  0x%x TMD  0x%x WP  0x%x FMKE 0x%x URE 0x%x WE1 0x%x SSE 0x%x FE  0x%x\n",
  222. !            xp->exb_xsense.xfr, xp->exb_xsense.tmd, xp->exb_xsense.wp, 
  223. !            xp->exb_xsense.fmke, xp->exb_xsense.ure, xp->exb_xsense.we1, 
  224. !            xp->exb_xsense.sse, xp->exb_xsense.fe);
  225. !     printf("WSEB 0x%x WSEO 0x%x\n",
  226. !            xp->exb_xsense.wseb, xp->exb_xsense.wseo);
  227. !     printf("Remaining Tape 0x%lx\n", 
  228. !            (u_long)((xp->exb_xsense.tplft2<<16)|
  229. !             (xp->exb_xsense.tplft1<<8)|
  230. !             (xp->exb_xsense.tplft0)) );
  231.   }
  232.   
  233.   prtmodsel(msd, modlen)
  234. --- 1432,1474 ----
  235.               (xp->sc_xsense.info3<<8)|(xp->sc_xsense.info4)) );
  236.       printf("ASenseL 0x%x\n", xp->sc_xsense.len);
  237.   
  238. !     switch (sc->sc_tapeid) {
  239. !     case MT_ISEXABYTE:
  240. !         printf("ASenseC 0x%x\n", xp->exb_xsense.addsens);
  241. !         printf("AsenseQ 0x%x\n", xp->exb_xsense.addsensq);
  242. !         printf("R/W Errors 0x%lx\n", 
  243. !                (u_long)((xp->exb_xsense.rwerrcnt2<<16)|
  244. !                 (xp->exb_xsense.rwerrcnt1<<8)|
  245. !                 (xp->exb_xsense.rwerrcnt1)) );
  246. !         printf("PF   0x%x BPE  0x%x FPE 0x%x ME   0x%x ECO 0x%x TME 0x%x TNP 0x%x BOT 0x%x\n",
  247. !                xp->exb_xsense.pf, xp->exb_xsense.bpe,
  248. !                xp->exb_xsense.fpe, xp->exb_xsense.me,
  249. !                xp->exb_xsense.eco, xp->exb_xsense.tme,
  250. !                xp->exb_xsense.tnp, xp->exb_xsense.bot);
  251. !         printf("XFR  0x%x TMD  0x%x WP  0x%x FMKE 0x%x URE 0x%x WE1 0x%x SSE 0x%x FE  0x%x\n",
  252. !                xp->exb_xsense.xfr, xp->exb_xsense.tmd,
  253. !                xp->exb_xsense.wp, xp->exb_xsense.fmke,
  254. !                xp->exb_xsense.ure, xp->exb_xsense.we1,
  255. !                xp->exb_xsense.sse, xp->exb_xsense.fe);
  256. !         printf("WSEB 0x%x WSEO 0x%x\n",
  257. !                xp->exb_xsense.wseb, xp->exb_xsense.wseo);
  258. !         printf("Remaining Tape 0x%lx\n", 
  259. !                (u_long)((xp->exb_xsense.tplft2<<16)|
  260. !                 (xp->exb_xsense.tplft1<<8)|
  261. !                 (xp->exb_xsense.tplft0)) );
  262. !         break;
  263. !     case MT_ISCALIPER:
  264. !         printf("b8 0x%x (wp 0x%x) b9 0x%x b10 0x%x b11 0x%x b12 0x%x b13 0x%x\n",
  265. !                xp->cpr_xsense.b8, xp->cpr_xsense.b8 & CPR_WP,
  266. !                xp->cpr_xsense.b9, xp->cpr_xsense.b10,
  267. !                xp->cpr_xsense.b11, xp->cpr_xsense.b12,
  268. !                xp->cpr_xsense.b13);
  269. !         break;
  270.   
  271. !     default:
  272. !         break;
  273. !     }
  274.   }
  275.   
  276.   prtmodsel(msd, modlen)
  277. *** arch/amiga/dev/stvar.h-orig    Sat May 15 06:45:00 1993
  278. --- arch/amiga/dev/stvar.h    Sun Sep  5 00:05:41 1993
  279. ***************
  280. *** 101,106 ****
  281. --- 101,116 ----
  282.       char    venderunique[16];
  283.   };
  284.   
  285. + struct cpr_xsense {
  286. +     u_char    b8;
  287. + #define CPR_WP    0x10
  288. +     u_char    b9;
  289. +     u_char  b10;
  290. +     u_char  b11;
  291. +     u_char  b12;
  292. +     u_char  b13;
  293. + };
  294.   struct    st_mode {
  295.       u_char    sdl;    
  296.       u_char  medtype;
  297. *** sys/mtio.h-orig    Sat Jun 19 09:45:39 1993
  298. --- sys/mtio.h    Sat Sep  4 16:42:02 1993
  299. ***************
  300. *** 96,101 ****
  301. --- 96,102 ----
  302.   #define MT_ISPYTHON    0x0f        /* Archive Python (DAT) */
  303.   #define MT_ISHPDAT    0x10        /* HP 35450A DAT drive */
  304.   #define MT_ISWANGTEK    0x11        /* WANGTEK 5150ES */
  305. + #define MT_ISCALIPER    0x12        /* Caliper CP150 */
  306.   
  307.   /* mag tape io control commands */
  308.   #define    MTIOCTOP    _IOW('m', 1, struct mtop)    /* do a mag tape op */
  309.  
  310. ------------------------------------------------------------------------
  311.  
  312.     The other problem I had was that a tape error would crash the
  313. kernel -- woo hoo!  My specific test case was putting a fresh tape in
  314. the drive and doing a 'mt -f /dev/rst0 fsf 1'.  The problem goes
  315. something like this:  When an I/O operation is done and hasn't failed
  316. early because something like a mode-select failed, the tape driver
  317. calls stfinish(), which then calls biodone() on the I/O buffer which
  318. was being used for the I/O operation.  biodone() wakes up anyone who
  319. was waiting on the buffer; someone (probably the tape driver but I
  320. haven't checked) is stuck in biowait() sleeping on that buffer.
  321. biowait() wakes up, looks at the buffer, sees that its error flag is
  322. set, and proceeds to remove it from its hash queue and put it somewhere
  323. else.  Unfortunately, that buffer was never on a hash queue -- it was
  324. an element in an array of buffers defined inside st.c.  Wa ha ha ha!
  325. What a good joke!  The b_back and b_forw pointers are 0!  Here's what I
  326. did to fix that:
  327.  
  328. ------------------------------------------------------------------------
  329. *** kern/vfs_bio.c-orig    Sun Aug  8 05:47:13 1993
  330. --- kern/vfs_bio.c    Sun Sep  5 21:48:07 1993
  331. ***************
  332. *** 653,660 ****
  333.    *    and i believe it's wrong to let bp->b_error override B_ERROR
  334.    *    but it certainly appears to work OK this way...
  335.    */    
  336. !             bremhash(bp);
  337. !             binshash(bp, bfreelist + BQ_AGE);
  338.           }
  339.           if (!bp->b_error)
  340.               bp->b_error = EIO;
  341. --- 653,663 ----
  342.    *    and i believe it's wrong to let bp->b_error override B_ERROR
  343.    *    but it certainly appears to work OK this way...
  344.    */    
  345. !             /* Some bufs aren't in the buffer cache, you fool. */
  346. !             if (bp->b_back && bp->b_forw) {
  347. !                 bremhash(bp);
  348. !                 binshash(bp, bfreelist + BQ_AGE);
  349. !             }
  350.           }
  351.           if (!bp->b_error)
  352.               bp->b_error = EIO;
  353. ------------------------------------------------------------------------
  354.  
  355. --
  356. ------------------------------------------------------------------------
  357. Andy Heffernan                                            ahh@netcom.com
  358.  
  359.