1 #ifdef OS_linux
2 
3 /*  Copyright 1996-2002,2009 Alain Knaff.
4  *  This file is part of mtools.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19 #include <sys/types.h>
20 
21 #ifdef HAVE_SYS_SYSMACROS_H
22 
23 #include <sys/sysmacros.h>
24 #ifndef MAJOR
25 #define MAJOR(dev) major(dev)
26 #endif  /* MAJOR not defined */
27 #ifndef MINOR
28 #define MINOR(dev) minor(dev)
29 #endif  /* MINOR not defined */
30 
31 #else
32 
33 #include <linux/fs.h>        /* get MAJOR/MINOR from Linux kernel */
34 #ifndef major
35 #define major(x) MAJOR(x)
36 #endif
37 
38 #endif /* HAVE_SYS_SYSMACROS_H */
39 
40 #include <linux/fd.h>
41 #include <linux/fdreg.h>
42 #include <linux/major.h>
43 
44 
45 typedef struct floppy_raw_cmd RawRequest_t;
46 
UNUSED(static __inline__ void RR_INIT (struct floppy_raw_cmd * request))47 UNUSED(static __inline__ void RR_INIT(struct floppy_raw_cmd *request))
48 {
49 	request->data = 0;
50 	request->length = 0;
51 	request->cmd_count = 9;
52 	request->flags = FD_RAW_INTR | FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK
53 #ifdef FD_RAW_SOFTFAILUE
54 		| FD_RAW_SOFTFAILURE | FD_RAW_STOP_IF_FAILURE
55 #endif
56 		;
57 	request->cmd[1] = 0;
58 	request->cmd[6] = 0;
59 	request->cmd[7] = 0x1b;
60 	request->cmd[8] = 0xff;
61 	request->reply_count = 0;
62 }
63 
UNUSED(static __inline__ void RR_SETRATE (struct floppy_raw_cmd * request,uint8_t rate))64 UNUSED(static __inline__ void RR_SETRATE(struct floppy_raw_cmd *request, uint8_t rate))
65 {
66 	request->rate = rate;
67 }
68 
UNUSED(static __inline__ void RR_SETDRIVE (struct floppy_raw_cmd * request,int drive))69 UNUSED(static __inline__ void RR_SETDRIVE(struct floppy_raw_cmd *request,int drive))
70 {
71 	request->cmd[1] = (request->cmd[1] & ~3) | (drive & 3);
72 }
73 
UNUSED(static __inline__ void RR_SETTRACK (struct floppy_raw_cmd * request,uint8_t track))74 UNUSED(static __inline__ void RR_SETTRACK(struct floppy_raw_cmd *request,uint8_t track))
75 {
76 	request->cmd[2] = track;
77 }
78 
UNUSED(static __inline__ void RR_SETPTRACK (struct floppy_raw_cmd * request,int track))79 UNUSED(static __inline__ void RR_SETPTRACK(struct floppy_raw_cmd *request,
80 				       int track))
81 {
82 	request->track = track;
83 }
84 
UNUSED(static __inline__ void RR_SETHEAD (struct floppy_raw_cmd * request,uint8_t head))85 UNUSED(static __inline__ void RR_SETHEAD(struct floppy_raw_cmd *request, uint8_t head))
86 {
87 	if(head)
88 		request->cmd[1] |= 4;
89 	else
90 		request->cmd[1] &= ~4;
91 	request->cmd[3] = head;
92 }
93 
UNUSED(static __inline__ void RR_SETSECTOR (struct floppy_raw_cmd * request,uint8_t sector))94 UNUSED(static __inline__ void RR_SETSECTOR(struct floppy_raw_cmd *request,
95 					   uint8_t sector))
96 {
97 	request->cmd[4] = sector;
98 	request->cmd[6] = sector-1;
99 }
100 
UNUSED(static __inline__ void RR_SETSIZECODE (struct floppy_raw_cmd * request,uint8_t sizecode))101 UNUSED(static __inline__ void RR_SETSIZECODE(struct floppy_raw_cmd *request,
102 					     uint8_t sizecode))
103 {
104 	request->cmd[5] = sizecode;
105 	request->cmd[6]++;
106 	request->length += 128 << sizecode;
107 }
108 
109 #if 0
110 static inline void RR_SETEND(struct floppy_raw_cmd *request, int end)
111 {
112 	request->cmd[6] = end;
113 }
114 #endif
115 
UNUSED(static __inline__ void RR_SETDIRECTION (struct floppy_raw_cmd * request,int direction))116 UNUSED(static __inline__ void RR_SETDIRECTION(struct floppy_raw_cmd *request,
117 					      int direction))
118 {
119 	if(direction == MT_READ) {
120 		request->flags |= FD_RAW_READ;
121 		request->cmd[0] = FD_READ & ~0x80;
122 	} else {
123 		request->flags |= FD_RAW_WRITE;
124 		request->cmd[0] = FD_WRITE & ~0x80;
125 	}
126 }
127 
128 
UNUSED(static __inline__ void RR_SETDATA (struct floppy_raw_cmd * request,caddr_t data))129 UNUSED(static __inline__ void RR_SETDATA(struct floppy_raw_cmd *request,
130 					 caddr_t data))
131 {
132 	request->data = data;
133 }
134 
135 
136 #if 0
137 static inline void RR_SETLENGTH(struct floppy_raw_cmd *request, int length)
138 {
139 	request->length += length;
140 }
141 #endif
142 
UNUSED(static __inline__ void RR_SETCONT (struct floppy_raw_cmd * request))143 UNUSED(static __inline__ void RR_SETCONT(struct floppy_raw_cmd *request))
144 {
145 #ifdef FD_RAW_MORE
146 	request->flags |= FD_RAW_MORE;
147 #endif
148 }
149 
150 
UNUSED(static __inline__ int RR_SIZECODE (struct floppy_raw_cmd * request))151 UNUSED(static __inline__ int RR_SIZECODE(struct floppy_raw_cmd *request))
152 {
153 	return request->cmd[5];
154 }
155 
156 
157 
UNUSED(static __inline__ int RR_TRACK (struct floppy_raw_cmd * request))158 UNUSED(static __inline__ int RR_TRACK(struct floppy_raw_cmd *request))
159 {
160 	return request->cmd[2];
161 }
162 
163 
UNUSED(static __inline__ int GET_DRIVE (int fd))164 UNUSED(static __inline__ int GET_DRIVE(int fd))
165 {
166 	struct MT_STAT statbuf;
167 
168 	if (MT_FSTAT(fd, &statbuf) < 0 ){
169 		perror("stat");
170 		return -1;
171 	}
172 
173 	if (!S_ISBLK(statbuf.st_mode) ||
174 	    MAJOR(statbuf.st_rdev) != FLOPPY_MAJOR)
175 		return -1;
176 
177 	return MINOR( statbuf.st_rdev );
178 }
179 
180 
181 
182 /* void print_message(RawRequest_t *raw_cmd,char *message);*/
183 int send_one_cmd(int fd, RawRequest_t *raw_cmd, const char *message);
184 int analyze_one_reply(RawRequest_t *raw_cmd, int *bytes, int do_print);
185 
186 
187 #endif
188