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