/*===========================================================================* * do_mapdriver * *===========================================================================*/ PUBLIC int do_mapdriver() { /* Create a device->driver mapping. RS will tell us which major is driven by * this driver, what type of device it is (regular, TTY, asynchronous, clone, * etc), and its label. This label is registered with DS, and allows us to * retrieve the driver's endpoint. */ int r, flags, major; endpoint_t endpoint; vir_bytes label_vir; size_t label_len; char label[LABEL_MAX]; /* Only RS can map drivers. */ if (who_e != RS_PROC_NR) return(EPERM); /* Get the label */ label_vir = (vir_bytes) m_in.md_label; label_len = (size_t) m_in.md_label_len; if (label_len+1 > sizeof(label)) { /* Can we store this label? */ printf("VFS: do_mapdriver: label too long\n"); return(EINVAL); } r = sys_vircopy(who_e, D, label_vir, SELF, D, (vir_bytes) label, label_len); if (r != OK) { printf("VFS: do_mapdriver: sys_vircopy failed: %d\n", r); return(EINVAL); } label[label_len] = '\0'; /* Terminate label */ /* Now we know how the driver is called, fetch its endpoint */ r = ds_retrieve_label_endpt(label, &endpoint); if (r != OK) { printf("VFS: do_mapdriver: label '%s' unknown\n", label); return(EINVAL); } /* Try to update device mapping. */ major = m_in.md_major; flags = m_in.md_flags; return map_driver(label, major, endpoint, m_in.md_style, flags); }
/*===========================================================================* * do_mapdriver * *===========================================================================*/ PUBLIC int do_mapdriver() { int r, force, major, proc_nr_n; unsigned long tasknr; vir_bytes label_vir; size_t label_len; char label[LABEL_MAX]; if (!super_user) { printf("FS: unauthorized call of do_mapdriver by proc %d\n", who_e); return(EPERM); /* only su (should be only RS or some drivers) * may call do_mapdriver. */ } /* Get the label */ label_vir= (vir_bytes)m_in.md_label; label_len= m_in.md_label_len; if (label_len+1 > sizeof(label)) { printf("vfs:do_mapdriver: label too long\n"); return EINVAL; } r= sys_vircopy(who_e, D, label_vir, SELF, D, (vir_bytes)label, label_len); if (r != OK) { printf("vfs:do_mapdriver: sys_vircopy failed: %d\n", r); return EINVAL; } label[label_len]= '\0'; r= ds_retrieve_label_num(label, &tasknr); if (r != OK) { printf("vfs:do_mapdriver: ds doesn't know '%s'\n", label); return EINVAL; } if (isokendpt(tasknr, &proc_nr_n) != OK) { printf("vfs:do_mapdriver: bad endpoint %d\n", tasknr); return(EINVAL); } /* Try to update device mapping. */ major= m_in.md_major; force= m_in.md_force; r= map_driver(label, major, tasknr, m_in.md_style, force); if (r == OK) { /* If a driver has completed its exec(), it can be announced * to be up. */ if(force || fproc[proc_nr_n].fp_execced) { dev_up(major); } else { dmap[major].dmap_flags |= DMAP_BABY; } } return(r); }