📄 driver.h
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/kernel/driver.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
09000 /* Types and constants shared between the generic and device dependent
09001 * device driver code.
09002 */
09003
09004 #include <minix/callnr.h>
09005 #include <minix/com.h>
09006 #include "proc.h"
09007 #include <minix/partition.h>
09008
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 };
09021
09022 #if (CHIP == INTEL)
09023
09024 /* Number of bytes you can DMA before hitting a 64K boundary: */
09025 #define dma_bytes_left(phys) \
09026 ((unsigned) (sizeof(int) == 2 ? 0 : 0x10000) - (unsigned) ((phys) & 0xFFFF))
09027
09028 #endif /* CHIP == INTEL */
09029
09030 /* Base and size of a partition in bytes. */
09031 struct device {
09032 unsigned long dv_base;
09033 unsigned long dv_size;
09034 };
09035
09036 #define NIL_DEV ((struct device *) 0)
09037
09038 /* Functions defined by driver.c: */
09039 _PROTOTYPE( void driver_task, (struct driver *dr) );
09040 _PROTOTYPE( int do_rdwt, (struct driver *dr, message *m_ptr) );
09041 _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *m_ptr) );
09042 _PROTOTYPE( char *no_name, (void) );
09043 _PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) );
09044 _PROTOTYPE( int nop_finish, (void) );
09045 _PROTOTYPE( void nop_cleanup, (void) );
09046 _PROTOTYPE( void clock_mess, (int ticks, watchdog_t func) );
09047 _PROTOTYPE( int do_diocntl, (struct driver *dr, message *m_ptr) );
09048
09049 /* Parameters for the disk drive. */
09050 #define SECTOR_SIZE 512 /* physical sector size in bytes */
09051 #define SECTOR_SHIFT 9 /* for division */
09052 #define SECTOR_MASK 511 /* and remainder */
09053
09054 /* Size of the DMA buffer buffer in bytes. */
09055 #define DMA_BUF_SIZE (DMA_SECTORS * SECTOR_SIZE)
09056
09057 #if (CHIP == INTEL)
09058 extern u8_t *tmp_buf; /* the DMA buffer */
09059 #else
09060 extern u8_t tmp_buf[]; /* the DMA buffer */
09061 #endif
09062 extern phys_bytes tmp_phys; /* phys address of DMA buffer */
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/kernel/driver.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
09100 /* This file contains device independent device driver interface.
09101 * Author: Kees J. Bot.
09102 *
09103 * The drivers support the following operations (using message format m2):
09104 *
09105 * m_type DEVICE PROC_NR COUNT POSITION ADRRESS
09106 * ----------------------------------------------------------------
09107 * | DEV_OPEN | device | proc nr | | | |
09108 * |------------+---------+---------+---------+---------+---------|
09109 * | DEV_CLOSE | device | proc nr | | | |
09110 * |------------+---------+---------+---------+---------+---------|
09111 * | DEV_READ | device | proc nr | bytes | offset | buf ptr |
09112 * |------------+---------+---------+---------+---------+---------|
09113 * | DEV_WRITE | device | proc nr | bytes | offset | buf ptr |
09114 * |------------+---------+---------+---------+---------+---------|
09115 * |SCATTERED_IO| device | proc nr | requests| | iov ptr |
09116 * ----------------------------------------------------------------
09117 * | DEV_IOCTL | device | proc nr |func code| | buf ptr |
09118 * ----------------------------------------------------------------
09119 *
09120 * The file contains one entry point:
09121 *
09122 * driver_task: called by the device dependent task entry
09123 *
09124 *
09125 * Constructed 92/04/02 by Kees J. Bot from the old AT wini and floppy driver.
09126 */
09127
09128 #include "kernel.h"
09129 #include <sys/ioctl.h>
09130 #include "driver.h"
09131
09132 #define BUF_EXTRA 0
09133
09134 /* Claim space for variables. */
09135 PRIVATE u8_t buffer[(unsigned) 2 * DMA_BUF_SIZE + BUF_EXTRA];
09136 u8_t *tmp_buf; /* the DMA buffer eventually */
09137 phys_bytes tmp_phys; /* phys address of DMA buffer */
09138
09139 FORWARD _PROTOTYPE( void init_buffer, (void) );
09140
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 }
09202 /*===========================================================================*
09203 * init_buffer *
09204 *===========================================================================*/
09205 PRIVATE void init_buffer()
09206 {
09207 /* Select a buffer that can safely be used for dma transfers. It may also
09208 * be used to read partition tables and such. Its absolute address is
09209 * 'tmp_phys', the normal address is 'tmp_buf'.
09210 */
09211
09212 tmp_buf = buffer;
09213 tmp_phys = vir2phys(buffer);
09214
09215 if (tmp_phys == 0) panic("no DMA buffer", NO_NUM);
09216
09217 if (dma_bytes_left(tmp_phys) < DMA_BUF_SIZE) {
09218 /* First half of buffer crosses a 64K boundary, can't DMA into that */
09219 tmp_buf += DMA_BUF_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -