xref: /haiku/src/system/boot/loader/load_driver_settings.cpp (revision 3be9edf8da228afd9fec0390f408c964766122aa)
1 /*
2  * Copyright 2008, Rene Gollent, rene@gollent.com. All rights reserved.
3  * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include "load_driver_settings.h"
9 
10 #include <string.h>
11 #include <unistd.h>
12 
13 #include <OS.h>
14 #include <drivers/driver_settings.h>
15 
16 #include <boot/driver_settings.h>
17 #include <boot/kernel_args.h>
18 #include <boot/stage2.h>
19 #include <boot/platform.h>
20 
21 
22 static status_t
23 load_driver_settings_file(Directory* directory, const char* name)
24 {
25 	int fd = open_from(directory, name, O_RDONLY);
26 	if (fd < 0)
27 		return fd;
28 
29 	struct stat stat;
30 	fstat(fd, &stat);
31 
32 	char* buffer = (char*)kernel_args_malloc(stat.st_size + 1);
33 	if (buffer == NULL)
34 		return B_NO_MEMORY;
35 
36 	if (read(fd, buffer, stat.st_size) != stat.st_size)
37 		return B_IO_ERROR;
38 
39 	driver_settings_file* file = (driver_settings_file*)kernel_args_malloc(
40 		sizeof(driver_settings_file));
41 	if (file == NULL) {
42 		kernel_args_free(buffer);
43 		return B_NO_MEMORY;
44 	}
45 
46 	buffer[stat.st_size] = '\0';
47 		// null terminate the buffer
48 
49 	strlcpy(file->name, name, sizeof(file->name));
50 	file->buffer = buffer;
51 	file->size = stat.st_size;
52 
53 	// add it to the list
54 	file->next = gKernelArgs.driver_settings;
55 	gKernelArgs.driver_settings = file;
56 
57 	return B_OK;
58 }
59 
60 
61 //	#pragma mark -
62 
63 
64 status_t
65 load_driver_settings(stage2_args* /*args*/, Directory* volume)
66 {
67 	int fd = open_from(volume, "home/config/settings/kernel/drivers", O_RDONLY);
68 	if (fd < B_OK)
69 		return fd;
70 
71 	Directory* settings = (Directory*)get_node_from(fd);
72 	if (settings == NULL)
73 		return B_ENTRY_NOT_FOUND;
74 
75 	void* cookie;
76 	if (settings->Open(&cookie, O_RDONLY) == B_OK) {
77 		char name[B_FILE_NAME_LENGTH];
78 		while (settings->GetNextEntry(cookie, name, sizeof(name)) == B_OK) {
79 			if (!strcmp(name, ".") || !strcmp(name, ".."))
80 				continue;
81 
82 			status_t status = load_driver_settings_file(settings, name);
83 			if (status != B_OK)
84 				dprintf("Could not load \"%s\" error %ld\n", name, status);
85 		}
86 
87 		settings->Close(cookie);
88 	}
89 
90 	return B_OK;
91 }
92 
93 
94 status_t
95 add_stage2_driver_settings(stage2_args* args)
96 {
97 	// TODO: split more intelligently
98 	for (const char** arg = args->arguments;
99 			arg != NULL && arg[0] != NULL; arg++) {
100 		dprintf("adding args: '%s'\n", arg[0]);
101 		add_safe_mode_settings((char*)arg[0]);
102 	}
103 	return B_OK;
104 }
105 
106 
107 status_t
108 add_safe_mode_settings(char* settings)
109 {
110 	if (settings == NULL || settings[0] == '\0')
111 		return B_OK;
112 
113 	size_t length = strlen(settings);
114 	char* buffer = (char*)kernel_args_malloc(length + 1);
115 	if (buffer == NULL)
116 		return B_NO_MEMORY;
117 
118 	driver_settings_file* file = (driver_settings_file*)kernel_args_malloc(
119 		sizeof(driver_settings_file));
120 	if (file == NULL) {
121 		kernel_args_free(buffer);
122 		return B_NO_MEMORY;
123 	}
124 
125 	strlcpy(file->name, B_SAFEMODE_DRIVER_SETTINGS, sizeof(file->name));
126 	memcpy(buffer, settings, length + 1);
127 	file->buffer = buffer;
128 	file->size = length;
129 
130 	// add it to the list
131 	file->next = gKernelArgs.driver_settings;
132 	gKernelArgs.driver_settings = file;
133 
134 	return B_OK;
135 }
136