/* * Construct one requested file entry, or all file entries, in a PID directory. */ static void construct_pid_entries(struct inode * parent, char * name) { int slot; slot = get_inode_index(parent); assert(slot >= 0 && slot < NR_TASKS + NR_PROCS); /* If this process is already gone, delete the directory now. */ if (!slot_in_use(slot)) { delete_inode(parent); return; } /* * If a specific file name is being looked up, see if we have to add * an inode for that file. If the directory contents are being * retrieved, add all files that have not yet been added. */ if (name != NULL) make_one_pid_entry(parent, name, slot); else make_all_pid_entries(parent, slot); }
static void *atben_open(const char *arg) { struct atben_dsc *dsc; if (slot_in_use()) return NULL; dsc = malloc(sizeof(*dsc)); if (!dsc) { perror("malloc"); exit(1); } dsc->fd = open("/dev/mem", O_RDWR | O_SYNC); if (dsc->fd < 0) { perror("/dev/mem"); exit(1); } dsc->mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE, MAP_SHARED, dsc->fd, SOC_BASE); if (dsc->mem == MAP_FAILED) { perror("mmap"); exit(1); } /* set the output levels */ PDDATS = nSEL | VDD_OFF; PDDATC = SCLK; /* take the GPIOs away from the MMC controller */ #ifdef OLD PDFUNC = MOSI | MISO | SCLK | IRQ | nSEL; PDFUNS = CLK; #else PDFUNC = MOSI | MISO | SCLK | IRQ | nSEL | SLP_TR; #endif /* set the pin directions */ PDDIRC = MISO | IRQ; #ifdef OLD PDDIRS = MOSI | CLK | SCLK | nSEL; #else PDDIRS = MOSI | SLP_TR | SCLK | nSEL; #endif /* let capacitors precharge */ wait_for_power(); /* enable power */ PDDATC = VDD_OFF; #ifdef OLD /* set the MSC clock to 336 MHz / 21 = 16 MHz */ MSCCDR = 20; /* * Enable the MSC clock. We need to do this before accessing any * registers of the MSC block ! */ CLKGR &= ~(1 << 7); /* bus clock = MSC clock / 1 */ MSC_CLKRT = 0; /* start MMC clock output */ MSC_STRPCL = 2; #endif wait_for_power(); atben_reset_rf(dsc); return dsc; }
/* * Regenerate the set of PID directories in the root directory of the file * system. Add new directories and delete old directories as appropriate; * leave unchanged those that should remain the same. */ static void construct_pid_dirs(void) { /* * We have to make two passes. Otherwise, we would trigger a vtreefs * assert when we add an entry for a PID before deleting the previous * entry for that PID. While rare, such rapid PID reuse does occur in * practice. */ struct inode *root, *node; struct inode_stat stat; char name[PNAME_MAX+1]; pid_t pid; int i; root = get_root_inode(); /* First pass: delete old entries. */ for (i = 0; i < NR_PROCS + NR_TASKS; i++) { /* Do we already have an inode associated with this slot? */ node = get_inode_by_index(root, i); if (node == NULL) continue; /* * If the process slot is not in use, delete the associated * inode. */ if (!slot_in_use(i)) { delete_inode(node); continue; } /* Otherwise, get the process ID. */ if (i < NR_TASKS) pid = (pid_t)(i - NR_TASKS); else pid = mproc[i - NR_TASKS].mp_pid; /* * If there is an old entry, see if the pid matches the current * entry, and the owner is still the same. Otherwise, delete * the old entry first. We reconstruct the entire subtree even * if only the owner changed, for security reasons: if a * process could keep open a file or directory across the owner * change, it might be able to access information it shouldn't. */ if (pid != (pid_t)get_inode_cbdata(node) || !check_owner(node, i)) delete_inode(node); } /* Second pass: add new entries. */ for (i = 0; i < NR_PROCS + NR_TASKS; i++) { /* If the process slot is not in use, skip this slot. */ if (!slot_in_use(i)) continue; /* * If we have an inode associated with this slot, we have * already checked it to be up-to-date above. */ if (get_inode_by_index(root, i) != NULL) continue; /* Get the process ID. */ if (i < NR_TASKS) pid = (pid_t)(i - NR_TASKS); else pid = mproc[i - NR_TASKS].mp_pid; /* Add the entry for the process slot. */ snprintf(name, PNAME_MAX + 1, "%d", pid); make_stat(&stat, i, NO_INDEX); node = add_inode(root, name, i, &stat, nr_pid_entries, (cbdata_t)pid); if (node == NULL) out_of_inodes(); } }