1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "libbb.h"
25
26
27
28struct floppy_struct {
29 unsigned int size,
30 sect,
31 head,
32 track,
33 stretch;
34#define FD_STRETCH 1
35#define FD_SWAPSIDES 2
36
37 unsigned char gap,
38
39 rate,
40#define FD_2M 0x4
41#define FD_SIZECODEMASK 0x38
42#define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8)
43#define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ? \
44 512 : 128 << FD_SIZECODE(floppy) )
45#define FD_PERP 0x40
46
47 spec1,
48 fmt_gap;
49 const char * name;
50};
51struct format_descr {
52 unsigned int device,head,track;
53};
54#define FDFMTBEG _IO(2,0x47)
55#define FDFMTTRK _IOW(2,0x48, struct format_descr)
56#define FDFMTEND _IO(2,0x49)
57#define FDGETPRM _IOR(2, 0x04, struct floppy_struct)
58#define FD_FILL_BYTE 0xF6
59
60int fdformat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
61int fdformat_main(int argc UNUSED_PARAM, char **argv)
62{
63 int fd, n, cyl, read_bytes, verify;
64 unsigned char *data;
65 struct stat st;
66 struct floppy_struct param;
67 struct format_descr descr;
68
69 verify = !getopt32(argv, "^" "n" "\0" "=1");
70 argv += optind;
71
72 xstat(*argv, &st);
73 if (!S_ISBLK(st.st_mode)) {
74 bb_error_msg_and_die("%s: not a block device", *argv);
75
76 }
77
78
79 fd = xopen(*argv, O_RDWR);
80
81
82 xioctl(fd, FDGETPRM, ¶m);
83
84 printf("%s-sided, %u tracks, %u sec/track. Total capacity %d kB\n",
85 (param.head == 2) ? "Double" : "Single",
86 param.track, param.sect, param.size >> 1);
87
88
89 printf("Formatting... ");
90 xioctl(fd, FDFMTBEG, NULL);
91
92
93 for (n = 0; n < param.track; n++) {
94 descr.head = 0;
95 descr.track = n;
96 xioctl(fd, FDFMTTRK, &descr);
97 printf("%3d\b\b\b", n);
98 if (param.head == 2) {
99 descr.head = 1;
100 xioctl(fd, FDFMTTRK, &descr);
101 }
102 }
103
104 xioctl(fd, FDFMTEND, NULL);
105 puts("Done");
106
107
108 if (verify) {
109
110 n = param.sect*param.head*512;
111
112 data = xmalloc(n);
113 printf("Verifying... ");
114 for (cyl = 0; cyl < param.track; cyl++) {
115 printf("%3d\b\b\b", cyl);
116 read_bytes = safe_read(fd, data, n);
117 if (read_bytes != n) {
118 if (read_bytes < 0) {
119 bb_simple_perror_msg(bb_msg_read_error);
120 }
121 bb_error_msg_and_die("problem reading cylinder %d, "
122 "expected %d, read %d", cyl, n, read_bytes);
123
124 }
125
126 while (--read_bytes >= 0) {
127 if (data[read_bytes] != FD_FILL_BYTE) {
128 printf("bad data in cyl %d\nContinuing... ", cyl);
129 }
130 }
131 }
132
133
134
135
136 if (ENABLE_FEATURE_CLEAN_UP) free(data);
137
138 puts("Done");
139 }
140
141 if (ENABLE_FEATURE_CLEAN_UP) close(fd);
142
143
144
145 return EXIT_SUCCESS;
146}
147