~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Minix Cross Reference
Minix/kernel/sunfloppy.c


  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.