home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / f / ftp-102.zip / ftape-1.02 / driver / userft.c < prev   
C/C++ Source or Header  |  1992-10-12  |  10KB  |  423 lines

  1. /* User code for floppytape.
  2.    Copyright (C) 1992 David L. Brown, Jr.
  3.  
  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.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING.  If not, write to
  16. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /*
  19.  * userft.c,v 1.14 1992/10/13 01:45:08 dbrown Exp
  20.  *
  21.  * userft.c,v
  22.  * Revision 1.14  1992/10/13  01:45:08  dbrown
  23.  * Added FSF copyright.
  24.  *
  25.  * Revision 1.13  1992/10/12  05:13:33  dbrown
  26.  * Added ioctl to set drive data rate.
  27.  *
  28.  * Revision 1.12  1992/10/10  07:02:09  dbrown
  29.  * Made write stream.
  30.  *
  31.  * Revision 1.11  1992/10/10  03:19:38  dbrown
  32.  * Added write error handling so that errors and their location can be
  33.  * passed back to the user.
  34.  *
  35.  * Revision 1.10  1992/10/09  05:53:44  dbrown
  36.  * Read is reliable.  Write is flaky and can't handle errors.
  37.  *
  38.  * Revision 1.9  1992/10/09  01:29:22  dbrown
  39.  * Write now streams and works somewhat robustly.  One little possible
  40.  * crashing position left.
  41.  *
  42.  * Revision 1.8  1992/10/09  00:36:15  dbrown
  43.  * Initial writing of full write.  Untested.
  44.  *
  45.  * Revision 1.7  1992/10/08  23:45:24  dbrown
  46.  * Read now does a copyout instead of using mapped buffers.  Before, read
  47.  * didn't have any control of when the user would actually get the data
  48.  * out of the buffer.  If the user delayed, then that data could be
  49.  * overwritten with the read from tape.
  50.  *
  51.  * Revision 1.6  1992/10/08  23:29:28  dbrown
  52.  * Performs streaming reliable reads.
  53.  *
  54.  * Revision 1.5  1992/10/08  04:52:42  dbrown
  55.  * First attempt to add streaming read.  Doesn't really work and panics
  56.  * periodically.
  57.  *
  58.  * Revision 1.4  1992/10/04  23:10:14  dbrown
  59.  * Added facilities for performing seek test.
  60.  *
  61.  * Revision 1.3  1992/10/04  21:46:01  dbrown
  62.  * Now supports non-streaming, single sector reads.
  63.  *
  64.  * Revision 1.2  1992/10/03  23:56:40  dbrown
  65.  * Moved enough of the old driver into the new to get drive status, and
  66.  * seek the tape and the tape head.
  67.  *
  68.  * Revision 1.1  1992/10/03  22:54:02  dbrown
  69.  * Copied from old driver.
  70.  */
  71.  
  72. #include <stdio.h>
  73. #include <sys/file.h>
  74. #include <sys/ioctl.h>
  75. #include <sys/types.h>
  76. #include <sys/mman.h>
  77. #include "fdtape-io.h"
  78.  
  79. void run (int fd);
  80. void read_many (int fd);
  81.  
  82. main (int argc, char **argv)
  83. {
  84.   int fd;
  85.   char *name;
  86. #if 0
  87.   char *data;
  88. #endif
  89.   int done = 0;
  90.   int status, result;
  91.   struct fdt_error error;
  92.   struct _fdt_id id;
  93.   int value;
  94.   int is_tty = 1;
  95.   struct write_cease wc;
  96.  
  97.   if (argc < 2)
  98.     name = "/dev/ftape";
  99.   else
  100.     {
  101.       name = argv[1];
  102.       if (argc >= 2)
  103.     is_tty = 0;
  104.     }
  105.  
  106.   fd = open (name, O_RDWR);
  107.   if (fd < 0)
  108.     {
  109.       perror ("Opening tape");
  110.       exit (1);
  111.     }
  112.  
  113.   run (fd);
  114.  
  115. #if 0
  116.   /* Map the tape buffer. */
  117.   data = (char *) malloc (65536);
  118.   if (mmap (data, 65536,
  119.         PROT_READ | PROT_WRITE,
  120.         MAP_SHARED, fd, 0) < 0)
  121.     perror ("Can't map tape buffer"), exit (1);
  122. #endif
  123.  
  124.   printf ("h for Help\n");
  125.   while (!done)
  126.     {
  127.       char cmd[80];
  128.       printf ("--> ");
  129.       gets (cmd);        /* Yuck. */
  130.       if (!is_tty)
  131.     puts (cmd), fflush (stdout);
  132.       switch (*cmd)
  133.     {
  134.     case 'h':
  135.       printf ("s  - Status              e  - Error\n");
  136.       printf ("B  - Beginning of tape   E  - End of tape.\n");
  137.       printf ("fn - forward n segments  rn - reverse n segments\n");
  138.       printf ("<n m - read m segments starting at n\n");
  139.       printf (">n m - write m segments starting at m\n");
  140.       printf ("#  - Submit error map    I  - Read id\n");
  141.       printf ("Sn - Seek to track.      @n - Set data rate to n bps.\n");
  142. /*
  143. e - Error\n\
  144. B - Beginning of tape.\n\
  145. E - End of tape.\n\
  146. fn - Forward n segments.\n\
  147. rn - Reverse n segments.\n\
  148. t - Stop tape.\n\
  149. R - Reset tape drive.\n\
  150. F - Logical forward.\n\
  151. P - Pause.\n\
  152. Sn - Seek to track.\n\
  153. I - Read id.\n\
  154. M - Read many ids.\n\
  155. # - Submit an error map (causes sync)\n\
  156. <n - Read segment n\n
  157. */
  158.       printf ("Q - Quit\n");
  159.       break;
  160.     case 's':
  161.       result = ioctl (fd, FDT_REPORT_STATUS, &status);
  162.       if (result != 0)
  163.         perror ("report drive status");
  164.       else
  165.         printf ("Status = 0x%x\n", status);
  166.       break;
  167.     case 'e':
  168.       result = ioctl (fd, FDT_REPORT_ERROR_CODE, &error);
  169.       if (result != 0)
  170.         perror ("report drive error");
  171.       else
  172.         {
  173.           printf ("Error = 0x%x (command = %d)\n", error.error,
  174.               error.command);
  175.         }
  176.       break;
  177.     case 'B':
  178.       result = ioctl (fd, FDT_SEEK_TO_BEGINNING, 0);
  179.       if (result != 0)
  180.         perror ("Seek to beginning");
  181.       break;
  182.     case 'E':
  183.       result = ioctl (fd, FDT_SEEK_TO_END, 0);
  184.       if (result != 0)
  185.         perror ("Seek to end");
  186.       break;
  187.     case 'f':
  188.       value = atoi (&cmd[1]);
  189.       result = ioctl (fd, FDT_SEEK_FORWARD, &value);
  190.       if (result != 0)
  191.         perror ("Seek forward");
  192.       break;
  193.     case 'r':
  194.       value = atoi (&cmd[1]);
  195.       result = ioctl (fd, FDT_SEEK_REVERSE, &value);
  196.       if (result != 0)
  197.         perror ("Seek backward");
  198.       break;
  199.     case '@':
  200.       value = atoi (&cmd[1]);
  201.       result = ioctl (fd, FDT_SET_DATA_RATE, &value);
  202.       if (result != 0)
  203.         perror ("Select data rate");
  204.       break;
  205.     case 'I':
  206.       {
  207.         struct _fdt_find_me fm;
  208.         fm.segment = 0;
  209.         result = ioctl (fd, FDT_FIND_ME, &fm);
  210.         printf ("result = %d, actual = %d\n",
  211.             result, fm.actual_segment);
  212.       }
  213.       break;
  214. #if 0
  215.     case 't':
  216.       result = ioctl (fd, FDT_STOP_TAPE, 0);
  217.       if (result != 0)
  218.         perror ("Stop tape");
  219.       break;
  220.     case 'R':
  221.       result = ioctl (fd, FDT_RESET, 0);
  222.       if (result != 0)
  223.         perror ("Reset tape drive");
  224.       break;
  225.     case 'F':
  226.       result = ioctl (fd, FDT_LOGICAL_FORWARD, 0);
  227.       if (result != 0)
  228.         perror ("Logical forward");
  229.       break;
  230.     case 'P':
  231.       result = ioctl (fd, FDT_PAUSE, 0);
  232.       if (result != 0)
  233.         perror ("Pause");
  234.       break;
  235. #endif
  236.     case 'S':
  237.       value = atoi (&cmd[1]);
  238.       result = ioctl (fd, FDT_SEEK_TO_TRACK, &value);
  239.       if (result != 0)
  240.         perror ("Seek to track");
  241.       break;
  242. #if 0
  243.     case 'I':
  244.       result = ioctl (fd, FDT_READ_ID, &id);
  245.       if (result != 0)
  246.         perror ("Read id.");
  247.       else
  248.         {
  249.           printf ("ID: cylinder = %d, head = %d, sector = %d\n",
  250.               id.cylinder, id.head, id.sector);
  251.         }
  252.       break;
  253. #endif
  254.     case '#':
  255.       {
  256.         struct error_map emap;
  257.         unsigned long error_masks[150];
  258.         bzero (error_masks, 150 * sizeof (unsigned long));
  259.         emap.count = 150;
  260.         emap.error_masks = error_masks;
  261.         result = ioctl (fd, FDT_SUBMIT_ERROR_MAP, &emap);
  262.         if (result != 0)
  263.           {
  264.         perror ("Cannot submit error map");
  265.         exit (1);
  266.           }
  267.       }
  268.       break;
  269.     case '>':
  270.       {
  271.         int fdi;
  272.         struct tape_write tw;
  273.         char buffer[32768];
  274.         int count;
  275.  
  276.         sscanf (&cmd[1], "%d%d", &tw.segment,
  277.             &count);
  278.         fdi = open ("INPUT", O_RDONLY);
  279.         if (fdi < 0)
  280.           {
  281.         perror ("Can't open input\n");
  282.         break;
  283.           }
  284.  
  285.         tw.buffer = buffer;
  286.         while (count > 0)
  287.           {
  288.         result = read (fdi, buffer, 32768);
  289.         if (result != 32768)
  290.           {
  291.             perror ("Can't read");
  292.             continue;
  293.           }
  294.         result = ioctl (fd, FDT_WRITE, &tw);
  295.         printf ("Write result = %d, (%d), error on %d\n", result,
  296.             tw.actual_segment, tw.error_location);
  297.         if (result != 0)
  298.           perror ("");
  299. #if 0
  300.         printf ("  ++] ");
  301.         getchar ();
  302. #endif
  303.         tw.segment++;
  304.         count--;
  305.           }
  306.         result = ioctl (fd, FDT_CEASE_WRITING, &wc);
  307.         if (result != 0)
  308.           perror ("Ceasing");
  309.         printf ("Ceased actual_segment = %d, error on %d\n",
  310.             wc.actual_segment, wc.error_location);
  311.         close (fdi);
  312.       }
  313.       break;
  314.     case '<':
  315.       {
  316.         int fdo;
  317.         struct tape_read tr;
  318.         char buffer[32768];
  319.         tr.buffer = buffer;
  320.         sscanf (&cmd[1], "%d%d", &tr.segment,
  321.             &tr.count);
  322.  
  323.         fdo = open ("OUTPUT", O_WRONLY | O_TRUNC | O_CREAT,
  324.             0666);
  325.         if (fdo < 0)
  326.           perror ("Can't create OUTPUT"), exit (1);
  327.  
  328.         while (tr.count > 0)
  329.           {
  330.         result = ioctl (fd, FDT_READ, &tr);
  331.         if (result < 0)
  332.           perror ("Read error");
  333.         result = write (fdo, buffer, 32768);
  334.         if (result != 32768)
  335.           perror ("Can't write");
  336.         printf ("actual = %d, buffer = %d, error_bits = 0x%08x\n",
  337.             tr.actual_segment,
  338.             tr.buffer,
  339.             tr.error_bits);
  340. #if 0
  341.         printf ("  ++] ");
  342.         getchar ();
  343. #endif
  344.         tr.segment++;
  345.         tr.count--;
  346.           }
  347.       }
  348.       break;
  349.     case 'Q':
  350.       done = 1;
  351.       break;
  352.     default:
  353.       printf ("Unknown command\n");
  354.       break;
  355.     }
  356.     }
  357.  
  358.   close (fd);
  359. }
  360.  
  361. void
  362. run (int fd)
  363. {
  364.   int status;
  365.   struct fdt_error error;
  366.   int result;
  367.  
  368.   result = ioctl (fd, FDT_REPORT_STATUS, &status);
  369.   if (result != 0)
  370.     perror ("report drive status");
  371.   else
  372.     printf ("status = 0x%x\n", status);
  373.  
  374.   result = ioctl (fd, FDT_REPORT_ERROR_CODE, &error);
  375.   if (result != 0)
  376.     perror ("report error");
  377.   else
  378.     printf ("error = 0x%x, command = 0x%x\n", error.error,
  379.         error.command);
  380. #if 0
  381.   result = ioctl (fd, FDT_REPORT_CONFIGURATION, &status);
  382.   if (result != 0)
  383.     perror ("report drive configuration");
  384.   else
  385.     printf ("configuration = 0x%x\n", status);
  386.  
  387.   result = ioctl (fd, FDT_REPORT_ROM_VERSION, &status);
  388.   if (result != 0)
  389.     perror ("report rom version");
  390.   else
  391.     printf ("rom version = 0x%x\n", status);
  392.  
  393.   result = ioctl (fd, FDT_REPORT_VENDOR_ID, &status);
  394.   if (result != 0)
  395.     perror ("report vendor id");
  396.   else
  397.     printf ("vendor id = 0x%x\n", status);
  398. #endif
  399. }
  400.  
  401. #if 0
  402. void
  403. read_many (int fd)
  404. {
  405.   struct _fdt_id ids[5000];
  406.   int count, i, done = 0;
  407.   int result;
  408.  
  409.   for (count = 0; count < 5000 && !done; count++)
  410.     {
  411.       result = ioctl (fd, FDT_READ_ID, &ids[count]);
  412.       if (result != 0)
  413.     done = 1;
  414.     }
  415.  
  416.   for (i = 0; i < count; i++)
  417.     {
  418.       printf ("%d %d %d\n", ids[i].cylinder,
  419.           ids[i].head, ids[i].sector);
  420.     }
  421. }
  422. #endif
  423.