++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/kernel/driver.h ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 09000 /* Types and constants shared between the generic and device dependent 09001 * device driver code. 09002 */ 09009 /* Info about and entry points into the device dependent code. */ 09010 struct driver { 09011 _PROTOTYPE( char *(*dr_name), (void) ); 09012 _PROTOTYPE( int (*dr_open), (struct driver *dp, message *m_ptr) ); 09013 _PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) ); 09014 _PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr) ); 09015 _PROTOTYPE( struct device *(*dr_prepare), (int device) ); 09016 _PROTOTYPE( int (*dr_schedule), (int proc_nr, struct iorequest_s *request) ); 09017 _PROTOTYPE( int (*dr_finish), (void) ); 09018 _PROTOTYPE( void (*dr_cleanup), (void) ); 09019 _PROTOTYPE( void (*dr_geometry), (struct partition *entry) ); 09020 }; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/kernel/driver.c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 09141 /*===========================================================================* 09142 * driver_task * 09143 *===========================================================================*/ 09144 PUBLIC void driver_task(dp) 09145 struct driver *dp; /* Device dependent entry points. */ 09146 { 09147 /* Main program of any device driver task. */ 09148 09149 int r, caller, proc_nr; 09150 message mess; 09151 09152 init_buffer(); /* Get a DMA buffer. */ 09153 09154 /* Here is the main loop of the disk task. It waits for a message, carries 09155 * it out, and sends a reply. 09156 */ 09157 09158 while (TRUE) { 09159 /* First wait for a request to read or write a disk block. */ 09160 receive(ANY, &mess); 09161 09162 caller = mess.m_source; 09163 proc_nr = mess.PROC_NR; 09164 09165 switch (caller) { 09166 case HARDWARE: 09167 /* Leftover interrupt. */ 09168 continue; 09169 case FS_PROC_NR: 09170 /* The only legitimate caller. */ 09171 break; 09172 default: 09173 printf("%s: got message from %d\n", (*dp->dr_name)(), caller); 09174 continue; 09175 } 09176 09177 /* Now carry out the work. */ 09178 switch(mess.m_type) { 09179 case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break; 09180 case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break; 09181 case DEV_IOCTL: r = (*dp->dr_ioctl)(dp, &mess); break; 09182 09183 case DEV_READ: 09184 case DEV_WRITE: r = do_rdwt(dp, &mess); break; 09185 09186 case SCATTERED_IO: r = do_vrdwt(dp, &mess); break; 09187 default: r = EINVAL; break; 09188 } 09189 09190 /* Clean up leftover state. */ 09191 (*dp->dr_cleanup)(); 09192 09193 /* Finally, prepare and send the reply message. */ 09194 mess.m_type = TASK_REPLY; 09195 mess.REP_PROC_NR = proc_nr; 09196 09197 mess.REP_STATUS = r; /* # of bytes transferred or error code */ 09198 send(caller, &mess); /* send reply to caller */ 09199 } 09200 }