1 /* The kernel call implemented in this file: 2 * m_type: SYS_DIAGCTL 3 * 4 * The parameters for this kernel call are: 5 * m_lsys_krn_sys_diagctl.code request 6 * and then request-specific arguments in 7 * m_lsys_krn_sys_diagctl.buf 8 * m_lsys_krn_sys_diagctl.len 9 * m_lsys_krn_sys_diagctl.endpt 10 */ 11 12 #include "kernel/system.h" 13 14 15 /*===========================================================================* 16 * do_diagctl * 17 *===========================================================================*/ 18 int do_diagctl(struct proc * caller, message * m_ptr) 19 { 20 vir_bytes len, buf; 21 static char mybuf[DIAG_BUFSIZE]; 22 int s, i, proc_nr; 23 24 switch (m_ptr->m_lsys_krn_sys_diagctl.code) { 25 case DIAGCTL_CODE_DIAG: 26 buf = m_ptr->m_lsys_krn_sys_diagctl.buf; 27 len = m_ptr->m_lsys_krn_sys_diagctl.len; 28 if(len < 1 || len > DIAG_BUFSIZE) { 29 printf("do_diagctl: diag for %d: len %d out of range\n", 30 caller->p_endpoint, len); 31 return EINVAL; 32 } 33 if((s=data_copy_vmcheck(caller, caller->p_endpoint, buf, KERNEL, 34 (vir_bytes) mybuf, len)) != OK) { 35 printf("do_diagctl: diag for %d: len %d: copy failed: %d\n", 36 caller->p_endpoint, len, s); 37 return s; 38 } 39 for(i = 0; i < len; i++) 40 kputc(mybuf[i]); 41 kputc(END_OF_KMESS); 42 return OK; 43 case DIAGCTL_CODE_STACKTRACE: 44 if(!isokendpt(m_ptr->m_lsys_krn_sys_diagctl.endpt, &proc_nr)) 45 return EINVAL; 46 proc_stacktrace(proc_addr(proc_nr)); 47 return OK; 48 case DIAGCTL_CODE_REGISTER: 49 if (!(priv(caller)->s_flags & SYS_PROC)) 50 return EPERM; 51 priv(caller)->s_diag_sig = TRUE; 52 /* If the message log is not empty, send a first notification 53 * immediately. After bootup the log is basically never empty. 54 */ 55 if (kmess.km_size > 0 && !kinfo.do_serial_debug) 56 send_sig(caller->p_endpoint, SIGKMESS); 57 return OK; 58 case DIAGCTL_CODE_UNREGISTER: 59 if (!(priv(caller)->s_flags & SYS_PROC)) 60 return EPERM; 61 priv(caller)->s_diag_sig = FALSE; 62 return OK; 63 default: 64 printf("do_diagctl: invalid request %d\n", m_ptr->m_lsys_krn_sys_diagctl.code); 65 return(EINVAL); 66 } 67 } 68 69