1 static char rcsid[] = "$Id: sunfloppy.c,v 1.3 1996/06/04 09:01:39 paul Exp $";
2
3 /*
4 * This file contains the device driver for accessing smx filesystems, each
5 * which is stored as a SunOS file. While called sunfloppy.c, this file
6 * actually has nothing to do with floppy disks at all!
7 *
8 * The file contains one entry point:
9 * - floppy_task: main "program" for the floppy task. Calls driver_task
10 * to do the work, with callbacks being made to this file.
11 *
12 */
13
14 #include "kernel.h"
15 #include <minix/callnr.h>
16 #include <minix/com.h>
17 #include <minix/boot.h>
18 #include <sun/syscall.h>
19 #include <sys/ioctl.h>
20 #include "driver.h"
21
22 static int f_device; /* current device */
23
24 static struct device *f_prepare(int device);
25 static int f_schedule(int proc_nr, struct iorequest_s *iop);
26 static int f_do_open(struct driver *dp, message *m_ptr);
27 static int f_do_ioctl(struct driver *dp, message *m_ptr);
28
29
30 /*
31 * Entry points to this driver.
32 */
33 static struct driver f_dtab = {
34 no_name, /* current device's name */
35 f_do_open, /* open or mount */
36 do_nop, /* nothing on a close */
37 f_do_ioctl, /* ioctl */
38 f_prepare, /* prepare for I/O on a given minor device */
39 f_schedule, /* do the I/O */
40 nop_finish, /* schedule does the work, no need to be smart */
41 nop_cleanup /* nothing's dirty */
42 };
43
44
45 /*
46 * Function: floppy_task
47 *
48 * The main program of the floppy task. Calls driver task to do all the
49 * work, supplying f_dtab to allow call backs into this .c file.
50 */
51 void floppy_task(void)
52 {
53 driver_task(&f_dtab);
54 /* NOTREACHED */
55 }
56
57
58 /*
59 * Function: f_prepare
60 * Parameter: device - the device we are about to access
61 * Returns: a null pointer on failer, a non-null "pointer" on success
62 *
63 * Prepare for I/O on a device. *
64 */
65 static struct device *f_prepare(int device)
66 {
67 if (device < 0 || device >= NR_SMX_DISKS) return(NIL_DEV);
68 f_device = device;
69
70 return (struct device *)1; /* A bit ugly */
71 }
72
73
74 /*
75 * Fucntion: f_schedule
76 * Parameters: proc_nr - process making the IO request
77 * iop - the IO request
78 * Returns: OK if the transfer is successful; a minix error code if an
79 * error occurs
80 *
81 * Do a transfer between process proc_nr and an smx filesystem
82 * as specified by iop.
83 */
84 static int f_schedule(int proc_nr, struct iorequest_s *iop)
85 {
86 int opcode;
87 int r;
88 phys_bytes user_phys;
89
90 /*
91 * Isolate the Type of request
92 */
93 opcode = iop->io_request & ~OPTIONAL_IO;
94
95 /*
96 * Determine address where data is to go or to come from.
97 */
98 user_phys = numap(proc_nr, (vir_bytes) iop->io_buf, iop->io_nbytes);
99 if (user_phys == 0) return(iop->io_nbytes = EINVAL);
100
101 /*
102 * With SunOS disks (disk files) we can simply lseek() to the correct
103 * position.
104 */
105 if ( (r = SunOS(SYS_lseek, DISK_FD + f_device, iop->io_position, 0)) == -1)
106 return(iop->io_nbytes = EIO);
107
108 /*
109 * Next we can read or write a block by using SunOS's read and write.
110 * lock() is needed in case the read or write gets interrupted by an
111 * asynchronous signal, such as ALRM or IO. Also, we need to ensure
112 * that we have access to the area being trasnferred to/form. Note how
113 * the SunOS fd is determined by adding the device number to DISK_FD.
114 * The disks are opened by the smx bootstrap programs on these fds.
115 */
116 set_protect(user_phys, iop->io_nbytes, PROT_READ_WRITE);
117 lock();
118 if (opcode == DEV_READ)
119 r = SunOS(SYS_read, DISK_FD + f_device, user_phys, iop->io_nbytes);
120 else
121 r = SunOS(SYS_write, DISK_FD + f_device, user_phys, iop->io_nbytes);
122 unlock();
123 set_protect(user_phys, iop->io_nbytes, PROT_NONE);
124
125 /*
126 * This extra case is for when we wish to make the SunOS disk files
127 * read only. Even though they may mounted as read only from Minix's point
128 * of view, it will still be written to when updating times etc.
129 */
130 if (r != iop->io_nbytes && !(opcode == DEV_WRITE && errno == 9)) {
131 return iop->io_nbytes = EIO;
132 }
133 return(iop->io_nbytes = OK);
134 }
135
136
137 /*
138 * Function: f_do_open
139 * Parameters: dp - driver structure (will be ptr to f_dtab)
140 * m_ptr - device open message
141 * Returns: OK if the operation is successful; ENXIO if the specified
142 * device does not exist.
143 *
144 * An smx file system is being opened. All we do is call prepare to make
145 * sure that the device number is in the right range. Perhaps
146 * the SunOS fd corresponding to the device should be checked to make sure
147 * that a file has been opened on it.
148 */
149 static int f_do_open(struct driver *dp, message *m_ptr)
150 {
151 if (f_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
152
153 return(OK);
154 }
155
156
157 /*
158 * Function: f_do_open
159 * Parameters: dp - driver structure (will be ptr to f_dtab)
160 * m_ptr - device open message
161 * Returns: OK if the ioctl is successful; a minix error code if an
162 * error occurs.
163 *
164 * Currently the FIOISRDONLY ioctl is the only one supported. For any
165 * other ioctls, ENOTTY is returned in line with other Minix disk
166 * drivers.
167 */
168 static int f_do_ioctl(struct driver *dp, message *m_ptr)
169 {
170 int fcntl_ret;
171 unsigned int ro;
172 phys_bytes get_phys;
173
174 if (f_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
175
176 if (m_ptr->REQUEST == FIOISRDONLY) {
177 /*
178 * Use fcntl to see if the disk is writable
179 */
180 fcntl_ret = SunOS(SYS_fcntl, DISK_FD + f_device, 3 /*F_GETFL*/, 0);
181 if (fcntl_ret == -1) {
182 return(EIO);
183 }
184
185 ro = ((fcntl_ret & 03) == 0); /* Read-only if write bit not set */
186
187 /*
188 * Return the read-only flag to the caller.
189 */
190 get_phys = numap(m_ptr->m_source, (vir_bytes) m_ptr->ADDRESS,
191 sizeof(ro));
192 if (get_phys == 0) return(EINVAL);
193 phys_copy(vir2phys(&ro), get_phys, (phys_bytes) sizeof(ro));
194
195 } else {
196 /*
197 * No other ioctls are implemented.
198 */
199 return(ENOTTY);
200 }
201 return(OK);
202 }
203
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.