home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / asm / SCSIDRV.ZIP / SFORMAT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-06  |  5.9 KB  |  258 lines

  1. /*
  2. ** SCSI Disk Formatter (Low Level)
  3. **
  4. ** usage: sformat drive:
  5. **
  6. ** Revision History:
  7. **
  8. ** Version 1.0  08/03/90 Initial Release
  9. **
  10. ** Version 1.1  08/20/90 Add verification message.
  11. **
  12. ** Version 1.2  09/18/90 Correct ioctl_data struct.
  13. **
  14. ** Version 1.3  10/04/90 Update the i/o packet structure.
  15. **                       Allow for inputing of the defect list.
  16. **
  17. ** Version 1.4  10/17/90 Use Defines from ioctl.h for commands.
  18. **                       If no defect list is entered, ask if
  19. **                       the existing list should be used.
  20. **
  21. ** Version 1.5  11/10/90 Allow for either logical block or cyl-head-index
  22. **                       styles of defect information.
  23. */
  24. #include <stdio.h>
  25. #include <dos.h>
  26. #include "ioctl.h"
  27.  
  28. #define TRUE (1)
  29. #define FALSE (0)
  30. #define VERSION "sformat Version 1.5 BWA"
  31.  
  32. extern int _doserrno;
  33.  
  34. struct cmd ioctl_data;
  35. struct defects_lba defect_list_lba;
  36. struct defects_chi defect_list_chi;
  37. union REGS inregs, outregs;
  38. struct SREGS segregs;
  39. unsigned short interleave = 0, format_type = FORMAT_NORMAL;
  40. int defect_type = DEFECT_LBA;
  41. unsigned char drive;
  42. char far *cp;
  43.  
  44. main(argc, argv)
  45. int argc;
  46. char *argv[];
  47. {
  48.     long block, cyl, head, index;
  49.     short defect_count = 0;
  50.     char answer[BUFSIZ];
  51.  
  52.     /*
  53.     ** say hello
  54.     */
  55.     puts(VERSION);
  56.     if (argc != 2) usage();
  57.  
  58.     /*
  59.     ** figure out who to format
  60.     */
  61.     if (argv[1][1] != ':') usage();
  62.     drive = argv[1][0];
  63.     drive = toupper(drive);
  64.     drive -= '@';
  65.  
  66.     /*
  67.     ** ask about interleave
  68.     */
  69.     printf("Interleave [0]? ");
  70.     fflush(stdout);
  71.     fgets(answer, BUFSIZ, stdin);
  72.     if ( strlen(answer) ) interleave = atoi(answer);
  73.  
  74.     /*
  75.     ** ask for defect list
  76.     */
  77.     puts("Input your defect list, <enter> to terminate.");
  78.     while (defect_count < MAX_DEFECTS)
  79.     {
  80.         /*
  81.         ** which prompt
  82.         */
  83.         switch ( defect_type )
  84.         {
  85.             case DEFECT_LBA:
  86.             printf("Logical Block Address: ");
  87.             break;
  88.             
  89.             case DEFECT_CHI:
  90.             printf("Cyl, Head, Index: ");
  91.             break;
  92.         }
  93.         fflush(stdout);
  94.         fgets(answer, BUFSIZ, stdin);
  95.         if ( answer[0] == '\n' ) break;
  96.  
  97.         /*
  98.         ** switch to cyl-head-index?
  99.         */
  100.         if ( strchr(answer, ',') ) defect_type = DEFECT_CHI;
  101.  
  102.         /*
  103.         ** scan the answer
  104.         */
  105.         switch ( defect_type )
  106.         {
  107.             case DEFECT_LBA:
  108.             sscanf(answer, "%lx", &block);
  109.             defect_list_lba.list[defect_count].defect_lba3 = (block >> 24) & 0x00FF;
  110.             defect_list_lba.list[defect_count].defect_lba2 = (block >> 16) & 0x00FF;
  111.             defect_list_lba.list[defect_count].defect_lba1 = (block >> 8) & 0x00FF;
  112.             defect_list_lba.list[defect_count].defect_lba0 = block & 0x00FF;
  113.             format_type = FORMAT_ADDLBA;
  114.             break;
  115.             
  116.             case DEFECT_CHI:
  117.             sscanf(answer, "%ld, %ld, %ld", &cyl, &head, &index);
  118.             defect_list_chi.list[defect_count].defect_cyl2 = (cyl >> 16) & 0x00FF;
  119.             defect_list_chi.list[defect_count].defect_cyl1 = (cyl >> 8) & 0x00FF;
  120.             defect_list_chi.list[defect_count].defect_cyl0 = cyl & 0x00FF;
  121.             defect_list_chi.list[defect_count].defect_head = head & 0x00FF;
  122.             defect_list_chi.list[defect_count].defect_idx3 = (index >> 24) & 0x00FF;
  123.             defect_list_chi.list[defect_count].defect_idx2 = (index >> 16) & 0x00FF;
  124.             defect_list_chi.list[defect_count].defect_idx1 = (index >> 8) & 0x00FF;
  125.             defect_list_chi.list[defect_count].defect_idx0 = index & 0x00FF;
  126.             format_type = FORMAT_ADDCHI;
  127.             break;
  128.         }
  129.         defect_count++;
  130.     }
  131.  
  132.     /*
  133.     ** adjust to be length of list in bytes
  134.     */
  135.     switch ( defect_type )
  136.     {
  137.         case DEFECT_LBA:
  138.         defect_count *= sizeof(struct defect_entry_lba);
  139.         break;
  140.  
  141.         case DEFECT_CHI:
  142.         defect_count *= sizeof(struct defect_entry_chi);
  143.         break;
  144.     }
  145.  
  146.     /*
  147.     ** if no defect list was entered, check to see if the
  148.     ** existing list should be used.
  149.     */
  150.     if ( !defect_count )
  151.     {
  152.         printf("Should the existing G_LIST be used (y,n)? ");
  153.         fflush(stdout);
  154.         fgets(answer, BUFSIZ, stdin);
  155.         if ( answer[0] == 'n' ) format_type = FORMAT_ORIG;
  156.     }
  157.  
  158.     /*
  159.     ** verify that this is what the user really wants to do
  160.     */
  161.     printf("Do you really wish to format the SCSI\n");
  162.     printf("device that contains drive %c: (y,n)? ", argv[1][0]);
  163.     fflush(stdout);
  164.     fgets(answer, BUFSIZ, stdin);
  165.     if ( answer[0] != 'y' )
  166.     {
  167.         puts("Aborting low level format ....");
  168.         exit(1);
  169.     }
  170.  
  171.     /*
  172.     ** build the defect list header
  173.     */
  174.     switch ( defect_type )
  175.     {
  176.         case DEFECT_LBA:
  177.         defect_list_lba.header.reserved = 0;
  178.         defect_list_lba.header.options = 0;
  179.         defect_list_lba.header.dll_msb = (defect_count >> 8) & 0x00FF;
  180.         defect_list_lba.header.dll_lsb = defect_count & 0x00FF;
  181.         break;
  182.         
  183.         case DEFECT_CHI:
  184.         defect_list_chi.header.reserved = 0;
  185.         defect_list_chi.header.options = 0;    
  186.         defect_list_chi.header.dll_msb = (defect_count >> 8) & 0x00FF;
  187.         defect_list_chi.header.dll_lsb = defect_count & 0x00FF;
  188.         break;
  189.     }
  190.  
  191.     /*
  192.     ** put together the command
  193.     */
  194.     inregs.h.ah = 0x44;            /* ioctl */
  195.     inregs.h.al = 0x05;            /* write */
  196.     inregs.h.bl = drive;        /* unit */
  197.     inregs.x.cx = sizeof(struct cmd);
  198.     cp = (char *) &ioctl_data;
  199.     inregs.x.dx = FP_OFF(cp);
  200.     segregs.ds = FP_SEG(cp);
  201.     ioctl_data.command = I_FORMAT;
  202.     ioctl_data.arg1 = interleave;
  203.     ioctl_data.arg2 = format_type;
  204.     switch ( defect_type )
  205.     {
  206.         case DEFECT_LBA:
  207.         cp = (char *) &defect_list_lba;
  208.         break;
  209.         
  210.         case DEFECT_CHI:
  211.         cp = (char *) &defect_list_chi;
  212.         break;
  213.     }
  214.     ioctl_data.buf_ofs = FP_OFF(cp);
  215.     ioctl_data.buf_seg = FP_SEG(cp);
  216.     ioctl_data.buf_len = sizeof(struct defect_header) + defect_count;
  217.  
  218.     /*
  219.     ** start the format
  220.     */
  221.     printf("Now formating with ");
  222.     switch (format_type)
  223.     {
  224.         case FORMAT_NORMAL:
  225.         puts("P_LIST and G_LIST ...");
  226.         break;
  227.  
  228.         case FORMAT_ADDLBA:
  229.         printf("P_LIST, G_LIST and %d defects ...\n", (defect_count / sizeof(struct defect_entry_lba)));
  230.         break;
  231.             
  232.         case FORMAT_ADDCHI:
  233.         printf("%d defects ...\n", (defect_count / sizeof(struct defect_entry_chi)));
  234.         break;
  235.  
  236.         case FORMAT_ORIG:
  237.         puts("P_LIST only ...");
  238.         break;
  239.     }
  240.     puts("Please wait ....");
  241.     intdosx(&inregs, &outregs, &segregs);
  242.  
  243.     /*
  244.     ** see what happened
  245.     */
  246.     if ( outregs.x.cflag )
  247.         printf("DOS error %d occured during format.\n", _doserrno);
  248.     else
  249.         puts("Formating complete.");
  250.     exit(0);
  251. }
  252.  
  253. usage()
  254. {
  255.     puts("usage: sformat drive:");
  256.     exit(1);
  257. }
  258.