Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | /* fdformat.c - Low-level formats a floppy disk - Werner Almesberger */ /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> * - added Native Language Support * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br> * - more i18n/nls translatable strings marked * * 5 July 2003 -- modified for Busybox by Erik Andersen */ #include <stdio.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/ioctl.h> #include "busybox.h" /* Stuff extracted from linux/fd.h */ struct floppy_struct { unsigned int size, /* nr of sectors total */ sect, /* sectors per track */ head, /* nr of heads */ track, /* nr of tracks */ stretch; /* !=0 means double track steps */ #define FD_STRETCH 1 #define FD_SWAPSIDES 2 unsigned char gap, /* gap1 size */ rate, /* data rate. |= 0x40 for perpendicular */ #define FD_2M 0x4 #define FD_SIZECODEMASK 0x38 #define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8) #define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ? \ 512 : 128 << FD_SIZECODE(floppy) ) #define FD_PERP 0x40 spec1, /* stepping rate, head unload time */ fmt_gap; /* gap2 size */ const char * name; /* used only for predefined formats */ }; struct format_descr { unsigned int device,head,track; }; #define FDFMTBEG _IO(2,0x47) #define FDFMTTRK _IOW(2,0x48, struct format_descr) #define FDFMTEND _IO(2,0x49) #define FDGETPRM _IOR(2, 0x04, struct floppy_struct) #define FD_FILL_BYTE 0xF6 /* format fill byte. */ static void format_disk(int ctrl, char *name, struct floppy_struct *param) { struct format_descr descr; int track; printf("Formatting ... "); fflush(stdout); if (ioctl(ctrl,FDFMTBEG,NULL) < 0) { bb_perror_msg_and_die("FDFMTBEG"); } for (track = 0; track < param->track; track++) { descr.track = track; descr.head = 0; if (ioctl(ctrl,FDFMTTRK,(long) &descr) < 0) { bb_perror_msg_and_die("FDFMTTRK"); } printf("%3d\b\b\b",track); fflush(stdout); if (param->head == 2) { descr.head = 1; if (ioctl(ctrl,FDFMTTRK,(long) &descr) < 0) { bb_perror_msg_and_die("FDFMTTRK"); } } } if (ioctl(ctrl,FDFMTEND,NULL) < 0) { bb_perror_msg_and_die("FDFMTEND"); } printf("done\n"); } static void verify_disk(char *name, struct floppy_struct *param) { unsigned char *data; int fd,cyl_size,cyl,count,read_bytes; cyl_size = param->sect*param->head*512; data = xmalloc(cyl_size); printf("Verifying ... "); fflush(stdout); fd = bb_xopen(name,O_RDONLY); for (cyl = 0; cyl < param->track; cyl++) { printf("%3d\b\b\b",cyl); fflush(stdout); read_bytes = safe_read(fd,data,cyl_size); if(read_bytes != cyl_size) { if(read_bytes < 0) { bb_perror_msg("Read: "); } bb_error_msg_and_die("Problem reading cylinder %d, " "expected %d, read %d", cyl, cyl_size, read_bytes); } for (count = 0; count < cyl_size; count++) if (data[count] != FD_FILL_BYTE) { printf("bad data in cyl %d\nContinuing ... ",cyl); fflush(stdout); break; } } printf("done\n"); close(fd); } int fdformat_main(int argc,char **argv) { int ctrl; int verify; struct stat st; struct floppy_struct param; if (argc < 2) { bb_show_usage(); } verify != bb_getopt_ulflags(argc, argv, "n"); argv += optind; if (stat(*argv,&st) < 0 || access(*argv,W_OK) < 0) { bb_perror_msg_and_die(*argv); } if (!S_ISBLK(st.st_mode)) { bb_error_msg_and_die("%s: not a block device",*argv); /* do not test major - perhaps this was an USB floppy */ } ctrl = bb_xopen(*argv,O_WRONLY); if (ioctl(ctrl,FDGETPRM,(long) ¶m) < 0) { bb_perror_msg_and_die("Could not determine current format type"); } printf("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n", (param.head == 2) ? "Double" : "Single", param.track, param.sect,param.size >> 1); format_disk(ctrl, *argv, ¶m); close(ctrl); if (verify) { verify_disk(*argv, ¶m); } return EXIT_SUCCESS; } |