From: Ben Gras Date: Tue, 20 Jun 2006 08:55:35 +0000 (+0000) Subject: Understand *_S variants: DIAGNOSTICS_S, DEV_{READ,WRITE,IOCTL}_S, X-Git-Tag: v3.1.3~330 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/doc/processing.js?a=commitdiff_plain;h=60bbcab13fde46c8f95c44ddd7ba9ed8f0e05a00;p=minix.git Understand *_S variants: DIAGNOSTICS_S, DEV_{READ,WRITE,IOCTL}_S, include grant id in DEV_REVIVE messages --- diff --git a/drivers/log/diag.c b/drivers/log/diag.c index b829d10e5..7a1cce914 100644 --- a/drivers/log/diag.c +++ b/drivers/log/diag.c @@ -9,6 +9,8 @@ #include #include +#include +#include #include "log.h" #include "../../kernel/const.h" @@ -83,33 +85,33 @@ message *m; /* notification message */ /*===========================================================================* * do_diagnostics * *===========================================================================*/ -PUBLIC int do_diagnostics(message *m) +PUBLIC int do_diagnostics(message *m, int safe) { /* The LOG server handles all diagnostic messages from servers and device * drivers. It forwards the message to the TTY driver to display it to the * user. It also saves a copy in a local buffer so that messages can be * reviewed at a later time. */ - int proc_nr_e; vir_bytes src; int count; char c; - int i = 0; + int i = 0, offset = 0; static char diagbuf[10240]; - /* Change SELF to actual process number. */ - if ((proc_nr_e = m->DIAG_ENDPT) == SELF) - m->DIAG_ENDPT = proc_nr_e = m->m_source; - - /* Now also make a copy for the private buffer at the LOG server, so + /* Also make a copy for the private buffer at the LOG server, so * that the messages can be reviewed at a later time. */ - src = (vir_bytes) m->DIAG_PRINT_BUF; + src = (vir_bytes) m->DIAG_PRINT_BUF_G; count = m->DIAG_BUF_COUNT; while (count > 0 && i < sizeof(diagbuf)-1) { - if (sys_datacopy(proc_nr_e, src, SELF, (vir_bytes) &c, 1) != OK) - break; /* stop copying on error */ - src ++; + int r; + if(safe) { + r = sys_safecopyfrom(m->m_source, src, offset, (vir_bytes) &c, 1, D); + } else { + r = sys_datacopy(m->m_source, src+offset, SELF, (vir_bytes) &c, 1); + } + if(r != OK) break; + offset ++; count --; diagbuf[i++] = c; } diff --git a/drivers/log/kputc.c b/drivers/log/kputc.c index 8714f8272..f6e766557 100644 --- a/drivers/log/kputc.c +++ b/drivers/log/kputc.c @@ -22,8 +22,7 @@ int c; if ((c == 0 && buf_count > 0) || buf_count == sizeof(print_buf)) { m.DIAG_BUF_COUNT = buf_count; - m.DIAG_PRINT_BUF = print_buf; - m.DIAG_ENDPT = SELF; + m.DIAG_PRINT_BUF_G = print_buf; m.m_type = DIAGNOSTICS; /* request TTY to output this buffer */ _sendrec(TTY_PROC_NR, &m); /* if it fails, we give up */ buf_count = 0; /* clear buffer for next batch */ diff --git a/drivers/log/log.c b/drivers/log/log.c index 0424f5074..09e665d52 100644 --- a/drivers/log/log.c +++ b/drivers/log/log.c @@ -26,21 +26,21 @@ PRIVATE int log_device = -1; /* current device */ FORWARD _PROTOTYPE( char *log_name, (void) ); FORWARD _PROTOTYPE( struct device *log_prepare, (int device) ); FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, off_t position, - iovec_t *iov, unsigned nr_req) ); + iovec_t *iov, unsigned nr_req, int safe) ); FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int log_select, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( void log_signal, (struct driver *dp, message *m_ptr) ); -FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr) ); +FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr, int) ); FORWARD _PROTOTYPE( void log_geometry, (struct partition *entry) ); -FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) ); +FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir, size_t, int safe) ); /* Entry points to this driver. */ PRIVATE struct driver log_dtab = { log_name, /* current device's name */ log_do_open, /* open or mount */ do_nop, /* nothing on a close */ - do_nop, /* ioctl nop */ + nop_ioctl, /* ioctl nop */ log_prepare, /* prepare for I/O on a given minor device */ log_transfer, /* do the I/O */ nop_cleanup, /* no need to clean up */ @@ -104,7 +104,8 @@ int device; * subwrite * *===========================================================================*/ PRIVATE int -subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) +subwrite(struct logdevice *log, int count, int proc_nr, + vir_bytes user_vir, size_t offset, int safe) { char *buf; int r; @@ -116,8 +117,15 @@ subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) memcpy(buf, (char *) user_vir, count); } else { - if((r=sys_vircopy(proc_nr,D,user_vir, SELF,D,(int)buf, count)) != OK) + if(safe) { + if((r=sys_safecopyfrom(proc_nr, user_vir, offset, + (vir_bytes)buf, count, D)) != OK) return r; + } else { + if((r=sys_vircopy(proc_nr, D, + user_vir + offset, SELF,D,(int)buf, count)) != OK) + return r; + } } LOGINC(log->log_write, count); @@ -135,7 +143,8 @@ subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) * be revived. */ log->log_status = subread(log, log->log_iosize, - log->log_proc_nr, log->log_user_vir); + log->log_proc_nr, log->log_user_vir_g, + log->log_user_vir_offset, log->log_safe); notify(log->log_source); log->log_revive_alerted = 1; } @@ -174,10 +183,10 @@ log_append(char *buf, int count) if(count > LOG_SIZE) skip = count - LOG_SIZE; count -= skip; buf += skip; - w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf); + w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf,0,0); if(w > 0 && w < count) - subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w); + subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w,0,0); return; } @@ -185,7 +194,8 @@ log_append(char *buf, int count) * subread * *===========================================================================*/ PRIVATE int -subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) +subread(struct logdevice *log, int count, int proc_nr, + vir_bytes user_vir, size_t offset, int safe) { char *buf; int r; @@ -195,8 +205,15 @@ subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) count = LOG_SIZE - log->log_read; buf = log->log_buffer + log->log_read; - if((r=sys_vircopy(SELF,D,(int)buf,proc_nr,D,user_vir, count)) != OK) + if(safe) { + if((r=sys_safecopyto(proc_nr, user_vir, offset, + (vir_bytes)buf, count, D)) != OK) + return r; + } else { + if((r=sys_vircopy(SELF,D,(int)buf, + proc_nr, safe ? GRANT_SEG : D, user_vir + offset, count)) != OK) return r; + } LOGINC(log->log_read, count); log->log_size -= count; @@ -207,12 +224,13 @@ subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) /*===========================================================================* * log_transfer * *===========================================================================*/ -PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req) +PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req, safe) int proc_nr; /* process doing the request */ int opcode; /* DEV_GATHER or DEV_SCATTER */ off_t position; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ +int safe; /* safe copies? */ { /* Read or write one the driver's minor devices. */ unsigned count; @@ -222,6 +240,7 @@ unsigned nr_req; /* length of request vector */ int accumulated_read = 0; struct logdevice *log; static int f; + size_t vir_offset = 0; if(log_device < 0 || log_device >= NR_DEVS) return EIO; @@ -253,8 +272,10 @@ unsigned nr_req; /* length of request vector */ /* No data available; let caller block. */ log->log_proc_nr = proc_nr; log->log_iosize = count; - log->log_user_vir = user_vir; + log->log_user_vir_g = user_vir; + log->log_user_vir_offset = 0; log->log_revive_alerted = 0; + log->log_safe = safe; /* Device_caller is a global in drivers library. */ log->log_source = device_caller; @@ -264,13 +285,13 @@ unsigned nr_req; /* length of request vector */ #endif return(SUSPEND); } - count = subread(log, count, proc_nr, user_vir); + count = subread(log, count, proc_nr, user_vir, vir_offset, safe); if(count < 0) { return count; } accumulated_read += count; } else { - count = subwrite(log, count, proc_nr, user_vir); + count = subwrite(log, count, proc_nr, user_vir, vir_offset, safe); if(count < 0) return count; } @@ -281,8 +302,8 @@ unsigned nr_req; /* length of request vector */ } /* Book the number of bytes transferred. */ - iov->iov_addr += count; - if ((iov->iov_size -= count) == 0) { iov++; nr_req--; } + vir_offset += count; + if ((iov->iov_size -= count) == 0) { iov++; nr_req--; vir_offset = 0; } } return(OK); } @@ -401,9 +422,10 @@ message *m_ptr; /*============================================================================* * log_other * *============================================================================*/ -PRIVATE int log_other(dp, m_ptr) +PRIVATE int log_other(dp, m_ptr, safe) struct driver *dp; message *m_ptr; +int safe; { int r; @@ -412,7 +434,11 @@ message *m_ptr; */ switch(m_ptr->m_type) { case DIAGNOSTICS: { - r = do_diagnostics(m_ptr); + r = do_diagnostics(m_ptr, 0); + break; + } + case DIAGNOSTICS_S: { + r = do_diagnostics(m_ptr, 1); break; } case DEV_STATUS: { diff --git a/drivers/log/log.h b/drivers/log/log.h index 48060bf52..8928b525f 100644 --- a/drivers/log/log.h +++ b/drivers/log/log.h @@ -23,7 +23,8 @@ struct logdevice { log_iosize, log_revive_alerted, log_status; /* proc that is blocking on read */ - vir_bytes log_user_vir; + vir_bytes log_user_vir_g, log_user_vir_offset; + int log_safe; #endif int log_selected, log_select_proc, log_select_alerted, log_select_ready_ops; @@ -32,6 +33,6 @@ struct logdevice { /* Function prototypes. */ _PROTOTYPE( void kputc, (int c) ); _PROTOTYPE( int do_new_kmess, (message *m) ); -_PROTOTYPE( int do_diagnostics, (message *m) ); +_PROTOTYPE( int do_diagnostics, (message *m, int safe) ); _PROTOTYPE( void log_append, (char *buf, int len) );