3 /* Copyright 1996-2002,2009 Alain Knaff.
4 * This file is part of mtools.
6 * Mtools is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Mtools is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
21 #ifdef HAVE_SYS_SYSMACROS_H
23 #include <sys/sysmacros.h>
25 #define MAJOR(dev) major(dev)
26 #endif /* MAJOR not defined */
28 #define MINOR(dev) minor(dev)
29 #endif /* MINOR not defined */
33 #include <linux/fs.h> /* get MAJOR/MINOR from Linux kernel */
35 #define major(x) MAJOR(x)
38 #endif /* HAVE_SYS_SYSMACROS_H */
44 #include <linux/fdreg.h>
45 #include <linux/major.h>
48 typedef struct floppy_raw_cmd RawRequest_t;
50 static inline void RR_INIT(struct floppy_raw_cmd *request)
54 request->cmd_count = 9;
55 request->flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK
56 #ifdef FD_RAW_SOFTFAILUE
57 | FD_RAW_SOFTFAILURE | FD_RAW_STOP_IF_FAILURE
62 request->cmd[7] = 0x1b;
63 request->cmd[8] = 0xff;
64 request->reply_count = 0;
67 static inline void RR_SETRATE(struct floppy_raw_cmd *request, uint8_t rate)
72 static inline void RR_SETDRIVE(struct floppy_raw_cmd *request,int drive)
74 request->cmd[1] = (request->cmd[1] & ~3) | (drive & 3);
77 static inline void RR_SETTRACK(struct floppy_raw_cmd *request,uint8_t track)
79 request->cmd[2] = track;
82 static inline void RR_SETPTRACK(struct floppy_raw_cmd *request,
85 request->track = track;
88 static inline void RR_SETHEAD(struct floppy_raw_cmd *request, uint8_t head)
93 request->cmd[1] &= ~4;
94 request->cmd[3] = head;
97 static inline void RR_SETSECTOR(struct floppy_raw_cmd *request,
100 request->cmd[4] = sector;
101 request->cmd[6] = sector-1;
104 static inline void RR_SETSIZECODE(struct floppy_raw_cmd *request,
107 request->cmd[5] = sizecode;
109 request->length += 128 << sizecode;
113 static inline void RR_SETEND(struct floppy_raw_cmd *request, int end)
115 request->cmd[6] = end;
119 static inline void RR_SETDIRECTION(struct floppy_raw_cmd *request,
122 if(direction == MT_READ) {
123 request->flags |= FD_RAW_READ;
124 request->cmd[0] = FD_READ & ~0x80;
126 request->flags |= FD_RAW_WRITE;
127 request->cmd[0] = FD_WRITE & ~0x80;
132 static inline void RR_SETDATA(struct floppy_raw_cmd *request,
135 request->data = data;
140 static inline void RR_SETLENGTH(struct floppy_raw_cmd *request, int length)
142 request->length += length;
146 static inline void RR_SETCONT(struct floppy_raw_cmd *request)
149 request->flags |= FD_RAW_MORE;
154 static inline int RR_SIZECODE(struct floppy_raw_cmd *request)
156 return request->cmd[5];
161 static inline int RR_TRACK(struct floppy_raw_cmd *request)
163 return request->cmd[2];
167 static inline int GET_DRIVE(int fd)
169 struct MT_STAT statbuf;
171 if (MT_FSTAT(fd, &statbuf) < 0 ){
176 if (!S_ISBLK(statbuf.st_mode) ||
177 MAJOR(statbuf.st_rdev) != FLOPPY_MAJOR)
180 return (int) MINOR( statbuf.st_rdev );
185 /* void print_message(RawRequest_t *raw_cmd,char *message);*/
186 int send_one_cmd(int fd, RawRequest_t *raw_cmd, const char *message);
187 int analyze_one_reply(RawRequest_t *raw_cmd, int *bytes, int do_print);
191 int init_geom(int fd, struct device *dev, struct device *orig_dev,
192 struct MT_STAT *statbuf);