TCP: Fixed RTO update and dup ACKs generation.
[haiku.git] / src / libs / compat / freebsd_network / firmware.c
blobaaa246e3f22721a91b317c6041ad703015f88308
1 /*
2 * Copyright 2009-2010, Colin Günther, coling@gmx.de.
3 * All Rights Reserved. Distributed under the terms of the MIT License.
5 */
8 #include <posix/sys/mman.h>
10 #include <compat/sys/param.h>
11 #include <compat/sys/firmware.h>
12 #include <compat/sys/haiku-module.h>
14 #include <stdlib.h>
15 #include <string.h>
17 #include <FindDirectory.h>
18 #include <StorageDefs.h>
19 #include <SupportDefs.h>
21 #include <device.h>
24 #define MAX_FBSD_FIRMWARE_NAME_CHARS 64
25 // For strndup, beeing cautious in kernel code is a good thing.
26 // NB: This constant doesn't exist in FreeBSD.
29 static const char*
30 getHaikuFirmwareName(const char* fbsdFirmwareName,
31 const char* unknownFirmwareName)
33 int i;
35 if (__haiku_firmware_name_map == NULL)
36 return unknownFirmwareName;
38 for (i = 0; i < __haiku_firmware_parts_count; i++) {
39 if (strcmp(__haiku_firmware_name_map[i][0], fbsdFirmwareName) == 0)
40 return __haiku_firmware_name_map[i][1];
42 return unknownFirmwareName;
46 const struct firmware*
47 firmware_get(const char* fbsdFirmwareName)
49 char* fbsdFirmwareNameCopy = NULL;
50 int fileDescriptor = -1;
51 struct firmware* firmware = NULL;
52 int32 firmwareFileSize;
53 char* firmwarePath = NULL;
54 const char* haikuFirmwareName = NULL;
55 ssize_t readCount = 0;
56 directory_which checkDirs[] = { B_SYSTEM_NONPACKAGED_DATA_DIRECTORY,
57 B_SYSTEM_DATA_DIRECTORY };
58 size_t numCheckDirs
59 = sizeof(checkDirs) / sizeof(checkDirs[0]);
60 size_t i = 0;
62 haikuFirmwareName = getHaikuFirmwareName(fbsdFirmwareName,
63 fbsdFirmwareName);
65 firmwarePath = (char*)malloc(B_PATH_NAME_LENGTH);
66 if (firmwarePath == NULL)
67 goto cleanup;
70 for (; i < numCheckDirs; i++) {
71 if (find_directory(checkDirs[i], -1, false, firmwarePath,
72 B_PATH_NAME_LENGTH) != B_OK) {
73 continue;
76 strlcat(firmwarePath, "/firmware/", B_PATH_NAME_LENGTH);
77 strlcat(firmwarePath, gDriverName, B_PATH_NAME_LENGTH);
78 strlcat(firmwarePath, "/", B_PATH_NAME_LENGTH);
79 strlcat(firmwarePath, haikuFirmwareName, B_PATH_NAME_LENGTH);
81 fileDescriptor = open(firmwarePath, B_READ_ONLY);
82 if (fileDescriptor >= 0)
83 break;
86 if (fileDescriptor < 0)
87 goto cleanup;
89 firmwareFileSize = lseek(fileDescriptor, 0, SEEK_END);
90 if (firmwareFileSize == -1)
91 goto cleanup;
93 lseek(fileDescriptor, 0, SEEK_SET);
95 fbsdFirmwareNameCopy = strndup(fbsdFirmwareName,
96 MAX_FBSD_FIRMWARE_NAME_CHARS);
97 if (fbsdFirmwareNameCopy == NULL)
98 goto cleanup;
100 firmware = (struct firmware*)malloc(sizeof(struct firmware));
101 if (firmware == NULL)
102 goto cleanup;
104 firmware->data = malloc(firmwareFileSize);
105 if (firmware->data == NULL)
106 goto cleanup;
108 readCount = read(fileDescriptor, (void*)firmware->data, firmwareFileSize);
109 if (readCount == -1 || readCount < firmwareFileSize) {
110 free((void*)firmware->data);
111 goto cleanup;
114 firmware->datasize = firmwareFileSize;
115 firmware->name = fbsdFirmwareNameCopy;
116 firmware->version = __haiku_firmware_version;
118 close(fileDescriptor);
119 free(firmwarePath);
120 return firmware;
122 cleanup:
123 if (firmware)
124 free(firmware);
125 if (fbsdFirmwareNameCopy)
126 free(fbsdFirmwareNameCopy);
127 if (firmwarePath)
128 free(firmwarePath);
129 if (fileDescriptor >= 0)
130 close(fileDescriptor);
131 return NULL;
135 void
136 firmware_put(const struct firmware* firmware, int flags)
138 if (firmware == NULL)
139 return;
141 if (firmware->data)
142 free((void*)firmware->data);
143 if (firmware->name)
144 free((void*)firmware->name);
145 free((void*)firmware);