home *** CD-ROM | disk | FTP | other *** search
- /*
- ** SCSI Disk Formatter (Low Level)
- **
- ** usage: sformat drive:
- **
- ** Revision History:
- **
- ** Version 1.0 08/03/90 Initial Release
- **
- ** Version 1.1 08/20/90 Add verification message.
- **
- ** Version 1.2 09/18/90 Correct ioctl_data struct.
- **
- ** Version 1.3 10/04/90 Update the i/o packet structure.
- ** Allow for inputing of the defect list.
- **
- ** Version 1.4 10/17/90 Use Defines from ioctl.h for commands.
- ** If no defect list is entered, ask if
- ** the existing list should be used.
- **
- ** Version 1.5 11/10/90 Allow for either logical block or cyl-head-index
- ** styles of defect information.
- */
- #include <stdio.h>
- #include <dos.h>
- #include "ioctl.h"
-
- #define TRUE (1)
- #define FALSE (0)
- #define VERSION "sformat Version 1.5 BWA"
-
- extern int _doserrno;
-
- struct cmd ioctl_data;
- struct defects_lba defect_list_lba;
- struct defects_chi defect_list_chi;
- union REGS inregs, outregs;
- struct SREGS segregs;
- unsigned short interleave = 0, format_type = FORMAT_NORMAL;
- int defect_type = DEFECT_LBA;
- unsigned char drive;
- char far *cp;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- long block, cyl, head, index;
- short defect_count = 0;
- char answer[BUFSIZ];
-
- /*
- ** say hello
- */
- puts(VERSION);
- if (argc != 2) usage();
-
- /*
- ** figure out who to format
- */
- if (argv[1][1] != ':') usage();
- drive = argv[1][0];
- drive = toupper(drive);
- drive -= '@';
-
- /*
- ** ask about interleave
- */
- printf("Interleave [0]? ");
- fflush(stdout);
- fgets(answer, BUFSIZ, stdin);
- if ( strlen(answer) ) interleave = atoi(answer);
-
- /*
- ** ask for defect list
- */
- puts("Input your defect list, <enter> to terminate.");
- while (defect_count < MAX_DEFECTS)
- {
- /*
- ** which prompt
- */
- switch ( defect_type )
- {
- case DEFECT_LBA:
- printf("Logical Block Address: ");
- break;
-
- case DEFECT_CHI:
- printf("Cyl, Head, Index: ");
- break;
- }
- fflush(stdout);
- fgets(answer, BUFSIZ, stdin);
- if ( answer[0] == '\n' ) break;
-
- /*
- ** switch to cyl-head-index?
- */
- if ( strchr(answer, ',') ) defect_type = DEFECT_CHI;
-
- /*
- ** scan the answer
- */
- switch ( defect_type )
- {
- case DEFECT_LBA:
- sscanf(answer, "%lx", &block);
- defect_list_lba.list[defect_count].defect_lba3 = (block >> 24) & 0x00FF;
- defect_list_lba.list[defect_count].defect_lba2 = (block >> 16) & 0x00FF;
- defect_list_lba.list[defect_count].defect_lba1 = (block >> 8) & 0x00FF;
- defect_list_lba.list[defect_count].defect_lba0 = block & 0x00FF;
- format_type = FORMAT_ADDLBA;
- break;
-
- case DEFECT_CHI:
- sscanf(answer, "%ld, %ld, %ld", &cyl, &head, &index);
- defect_list_chi.list[defect_count].defect_cyl2 = (cyl >> 16) & 0x00FF;
- defect_list_chi.list[defect_count].defect_cyl1 = (cyl >> 8) & 0x00FF;
- defect_list_chi.list[defect_count].defect_cyl0 = cyl & 0x00FF;
- defect_list_chi.list[defect_count].defect_head = head & 0x00FF;
- defect_list_chi.list[defect_count].defect_idx3 = (index >> 24) & 0x00FF;
- defect_list_chi.list[defect_count].defect_idx2 = (index >> 16) & 0x00FF;
- defect_list_chi.list[defect_count].defect_idx1 = (index >> 8) & 0x00FF;
- defect_list_chi.list[defect_count].defect_idx0 = index & 0x00FF;
- format_type = FORMAT_ADDCHI;
- break;
- }
- defect_count++;
- }
-
- /*
- ** adjust to be length of list in bytes
- */
- switch ( defect_type )
- {
- case DEFECT_LBA:
- defect_count *= sizeof(struct defect_entry_lba);
- break;
-
- case DEFECT_CHI:
- defect_count *= sizeof(struct defect_entry_chi);
- break;
- }
-
- /*
- ** if no defect list was entered, check to see if the
- ** existing list should be used.
- */
- if ( !defect_count )
- {
- printf("Should the existing G_LIST be used (y,n)? ");
- fflush(stdout);
- fgets(answer, BUFSIZ, stdin);
- if ( answer[0] == 'n' ) format_type = FORMAT_ORIG;
- }
-
- /*
- ** verify that this is what the user really wants to do
- */
- printf("Do you really wish to format the SCSI\n");
- printf("device that contains drive %c: (y,n)? ", argv[1][0]);
- fflush(stdout);
- fgets(answer, BUFSIZ, stdin);
- if ( answer[0] != 'y' )
- {
- puts("Aborting low level format ....");
- exit(1);
- }
-
- /*
- ** build the defect list header
- */
- switch ( defect_type )
- {
- case DEFECT_LBA:
- defect_list_lba.header.reserved = 0;
- defect_list_lba.header.options = 0;
- defect_list_lba.header.dll_msb = (defect_count >> 8) & 0x00FF;
- defect_list_lba.header.dll_lsb = defect_count & 0x00FF;
- break;
-
- case DEFECT_CHI:
- defect_list_chi.header.reserved = 0;
- defect_list_chi.header.options = 0;
- defect_list_chi.header.dll_msb = (defect_count >> 8) & 0x00FF;
- defect_list_chi.header.dll_lsb = defect_count & 0x00FF;
- break;
- }
-
- /*
- ** put together the command
- */
- inregs.h.ah = 0x44; /* ioctl */
- inregs.h.al = 0x05; /* write */
- inregs.h.bl = drive; /* unit */
- inregs.x.cx = sizeof(struct cmd);
- cp = (char *) &ioctl_data;
- inregs.x.dx = FP_OFF(cp);
- segregs.ds = FP_SEG(cp);
- ioctl_data.command = I_FORMAT;
- ioctl_data.arg1 = interleave;
- ioctl_data.arg2 = format_type;
- switch ( defect_type )
- {
- case DEFECT_LBA:
- cp = (char *) &defect_list_lba;
- break;
-
- case DEFECT_CHI:
- cp = (char *) &defect_list_chi;
- break;
- }
- ioctl_data.buf_ofs = FP_OFF(cp);
- ioctl_data.buf_seg = FP_SEG(cp);
- ioctl_data.buf_len = sizeof(struct defect_header) + defect_count;
-
- /*
- ** start the format
- */
- printf("Now formating with ");
- switch (format_type)
- {
- case FORMAT_NORMAL:
- puts("P_LIST and G_LIST ...");
- break;
-
- case FORMAT_ADDLBA:
- printf("P_LIST, G_LIST and %d defects ...\n", (defect_count / sizeof(struct defect_entry_lba)));
- break;
-
- case FORMAT_ADDCHI:
- printf("%d defects ...\n", (defect_count / sizeof(struct defect_entry_chi)));
- break;
-
- case FORMAT_ORIG:
- puts("P_LIST only ...");
- break;
- }
- puts("Please wait ....");
- intdosx(&inregs, &outregs, &segregs);
-
- /*
- ** see what happened
- */
- if ( outregs.x.cflag )
- printf("DOS error %d occured during format.\n", _doserrno);
- else
- puts("Formating complete.");
- exit(0);
- }
-
- usage()
- {
- puts("usage: sformat drive:");
- exit(1);
- }
-