status_t load_driver_settings(stage2_args* /*args*/, Directory* volume) { int fd = open_from(volume, "home/config/settings/kernel/drivers", O_RDONLY); if (fd < B_OK) return fd; Directory* settings = (Directory*)get_node_from(fd); if (settings == NULL) return B_ENTRY_NOT_FOUND; void* cookie; if (settings->Open(&cookie, O_RDONLY) == B_OK) { char name[B_FILE_NAME_LENGTH]; while (settings->GetNextEntry(cookie, name, sizeof(name)) == B_OK) { if (!strcmp(name, ".") || !strcmp(name, "..")) continue; status_t status = load_driver_settings_file(settings, name); if (status != B_OK) dprintf("Could not load \"%s\" error %ld\n", name, status); } settings->Close(cookie); } return B_OK; }
Node * Directory::Lookup(const char *name, bool traverseLinks) { off_t id; if (fTree.Find((uint8 *)name, strlen(name), &id) < B_OK) return NULL; Node *node = Stream::NodeFactory(fStream.GetVolume(), id); if (!node) return NULL; if (S_ISLNK(node->Type())) { // the node is a symbolic link, so we have to resolve the path char linkPath[B_PATH_NAME_LENGTH]; ((Link *)node)->ReadLink(linkPath, sizeof(linkPath)); delete node; // we don't need this one anymore int fd = open_from(this, linkPath, O_RDONLY); if (fd >= 0) { node = get_node_from(fd); if (node != NULL) node->Acquire(); close(fd); return node; } return NULL; } return node; }
::Node* TarFS::Directory::Lookup(const char* name, bool traverseLinks) { TarFS::Entry* entry = LookupEntry(name); if (!entry) return NULL; Node* node = entry->ToNode(); if (traverseLinks) { if (S_ISLNK(node->Type())) { Symlink* symlink = static_cast<Symlink*>(node); int fd = open_from(this, symlink->LinkPath(), O_RDONLY); if (fd >= 0) { node = get_node_from(fd); close(fd); } } } if (node) node->Acquire(); return node; }
static status_t load_modules_from(Directory *volume, const char *path) { // we don't have readdir() & co. (yet?)... int fd = open_from(volume, path, O_RDONLY); if (fd < B_OK) return fd; Directory *modules = (Directory *)get_node_from(fd); if (modules == NULL) return B_ENTRY_NOT_FOUND; void *cookie; if (modules->Open(&cookie, O_RDONLY) == B_OK) { char name[B_FILE_NAME_LENGTH]; while (modules->GetNextEntry(cookie, name, sizeof(name)) == B_OK) { if (!strcmp(name, ".") || !strcmp(name, "..")) continue; status_t status = elf_load_image(modules, name); if (status != B_OK) dprintf("Could not load \"%s\" error %ld\n", name, status); } modules->Close(cookie); } return B_OK; }
/** * @brief Callback for data receiving * * The callback function provided to device driver for being notified when * driver received a data stream. * * This function Must be called from interrupt context. * * It put the current operation to received queue and gets another operation to * continue receiving. Then notifies rx thread to process. * * @param buffer Data buffer. * @param length Received data length. * @param error Error code when driver receiving. * @return None. */ static void uart_rx_callback(uint8_t *buffer, int length, int error) { struct op_node *node; int ret; *info->rx_node->data_size = cpu_to_le16(length); put_node_back(&info->data_queue, info->rx_node); /* notify rx thread to process this data*/ sem_post(&info->rx_sem); node = get_node_from(&info->free_queue); if (!node) { /* * there is no free buffer, inform the rx thread to engage another uart * receiver. */ info->require_node = 1; return; } info->rx_node = node; ret = device_uart_start_receiver(info->dev, node->buffer, info->rx_buf_size, NULL, NULL, uart_rx_callback); if (ret) { uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__); } }
/** * @brief Data receiving process thread * * This function is the thread for processing data receiving tasks. When * it wake up, it checks the receiving queue for processing the come in data. * If protocol is running out of operation, once it gets a free operation, * it passes to driver for continuing the receiving. * * @param data The regular thread data. * @return None. */ static void *uart_rx_thread(void *data) { struct op_node *node = NULL; int ret; while (1) { sem_wait(&info->rx_sem); if (info->thread_stop) { break; } node = get_node_from(&info->data_queue); if (node) { ret = gb_operation_send_request(node->operation, NULL, false); if (ret) { uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__); } put_node_back(&info->free_queue, node); } /* * In case there is no free node in callback. */ if (info->require_node) { node = get_node_from(&info->free_queue); info->rx_node = node; ret = device_uart_start_receiver(info->dev, node->buffer, info->rx_buf_size, NULL, NULL, uart_rx_callback); if (ret) { uart_report_error(GB_UART_EVENT_DEVICE_ERROR, __func__); } info->require_node = 0; } } return NULL; }
/** * @brief Callback for data receiving * * The callback function provided to device driver for being notified when * driver received a data stream. * * This function Must be called from interrupt context. * * It put the current buffer to received queue and gets another buffer to * continue receiving. Then notifies rx thread to process. * * @param dev Pointer to the UART device controller * @param data Pointer to struct gb_uart_info. * @param buffer Data buffer. * @param length Received data length. * @param error Error code when driver receiving. * @return None. */ static void uart_rx_callback(struct device *dev, void *data, uint8_t *buffer, int length, int error) { struct gb_uart_info *info; struct buf_node *node; int ret; uint8_t flags = 0; DEBUGASSERT(data); info = data; info->rx_node->data_size = length; if (error & LSR_OE) { flags |= GB_UART_RECV_FLAG_OVERRUN; } if (error & LSR_PE) { flags |= GB_UART_RECV_FLAG_PARITY; } if (error & LSR_FE) { flags |= GB_UART_RECV_FLAG_FRAMING; } if (error & LSR_BI) { flags |= GB_UART_RECV_FLAG_BREAK; } info->rx_node->data_flags = flags; put_node_back(&info->data_queue, info->rx_node); /* notify rx thread to process this data*/ sem_post(&info->rx_sem); node = get_node_from(&info->free_queue); if (!node) { /* * there is no free buffer, inform the rx thread to engage another uart * receiver. */ info->require_node = 1; return; } info->rx_node = node; ret = device_uart_start_receiver(dev, node->buffer, info->rx_buf_size, NULL, NULL, uart_rx_callback); if (ret) { uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__); } }
static status_t load_module(BootVolume& volume, const char* name) { char moduleName[B_FILE_NAME_LENGTH]; if (strlcpy(moduleName, name, sizeof(moduleName)) > sizeof(moduleName)) return B_NAME_TOO_LONG; for (int32 i = 0; sAddonPaths[i]; i++) { // get base path int baseFD = open_maybe_packaged(volume, sAddonPaths[i], O_RDONLY); if (baseFD < B_OK) continue; Directory *base = (Directory *)get_node_from(baseFD); if (base == NULL) { close(baseFD); continue; } while (true) { int fd = open_from(base, moduleName, O_RDONLY); if (fd >= B_OK) { struct stat stat; if (fstat(fd, &stat) != 0 || !S_ISREG(stat.st_mode)) return B_BAD_VALUE; status_t status = elf_load_image(base, moduleName); close(fd); close(baseFD); return status; } // cut off last name element (or stop trying if there are no more) char *last = strrchr(moduleName, '/'); if (last != NULL) last[0] = '\0'; else break; } close(baseFD); } return B_OK; }