diff --git a/src/libs/compat/freebsd_network/compat/sys/cdefs.h b/src/libs/compat/freebsd_network/compat/sys/cdefs.h index 1e24e18225..04e32f1b15 100644 --- a/src/libs/compat/freebsd_network/compat/sys/cdefs.h +++ b/src/libs/compat/freebsd_network/compat/sys/cdefs.h @@ -35,6 +35,10 @@ #ifndef _FBSD_COMPAT_SYS_CDEFS_H_ #define _FBSD_COMPAT_SYS_CDEFS_H_ + +#include + + #define __FBSDID(str) static const char __fbsdid[] = str /* @@ -174,7 +178,6 @@ * a feature that we cannot live without. */ #ifdef lint -#define __dead2 #define __pure2 #define __unused #define __packed @@ -182,18 +185,15 @@ #define __section(x) #else #if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER) -#define __dead2 #define __pure2 #define __unused #endif #if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER) -#define __dead2 __attribute__((__noreturn__)) #define __pure2 __attribute__((__const__)) #define __unused /* XXX Find out what to do for __packed, __aligned and __section */ #endif #if __GNUC_PREREQ__(2, 7) -#define __dead2 __attribute__((__noreturn__)) #define __pure2 __attribute__((__const__)) #define __unused __attribute__((__unused__)) #define __packed __attribute__((__packed__)) @@ -210,7 +210,6 @@ #endif #if defined(__INTEL_COMPILER) -#define __dead2 __attribute__((__noreturn__)) #define __pure2 __attribute__((__const__)) #define __unused __attribute__((__unused__)) #define __used __attribute__((__used__)) @@ -263,10 +262,6 @@ * first. It is only available with ANSI C. */ #if defined(__STDC__) || defined(__cplusplus) -#define __P(protos) protos /* full-blown ANSI C */ -#define __CONCAT1(x,y) x ## y -#define __CONCAT(x,y) __CONCAT1(x,y) -#define __STRING(x) #x /* stringify without expanding x */ #define __XSTRING(x) __STRING(x) /* expand x, then stringify */ #define __const const /* define reserved names to standard */ @@ -281,9 +276,6 @@ #endif /* !__cplusplus */ #else /* !(__STDC__ || __cplusplus) */ -#define __P(protos) () /* traditional C preprocessor */ -#define __CONCAT(x,y) x/**/y -#define __STRING(x) "x" #if !defined(__CC_SUPPORTS___INLINE) #define __const /* delete pseudo-ANSI C keywords */ diff --git a/src/libs/compat/freebsd_network/compat/sys/firmware.h b/src/libs/compat/freebsd_network/compat/sys/firmware.h index a1a8a78f6a..bfc52b26b1 100644 --- a/src/libs/compat/freebsd_network/compat/sys/firmware.h +++ b/src/libs/compat/freebsd_network/compat/sys/firmware.h @@ -6,16 +6,18 @@ #define _FBSD_COMPAT_SYS_FIRMWARE_H_ +#define FIRMWARE_UNLOAD 0x0001 + + struct firmware { - const char* name; /* system-wide name */ - const void* data; /* location of image */ - size_t datasize; /* size of image in bytes */ - unsigned int version; /* version of the image */ + const char* name; // system-wide name + const void* data; // location of image + size_t datasize; // size of image in bytes + unsigned int version; // version of the image }; -const struct firmware* firmware_get(const char*); -#define FIRMWARE_UNLOAD 0x0001 /* unload if unreferenced */ +const struct firmware* firmware_get(const char*); void firmware_put(const struct firmware*, int); #endif /* _FBSD_COMPAT_SYS_FIRMWARE_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/libkern.h b/src/libs/compat/freebsd_network/compat/sys/libkern.h index 49523b5a73..3d67b6e42d 100644 --- a/src/libs/compat/freebsd_network/compat/sys/libkern.h +++ b/src/libs/compat/freebsd_network/compat/sys/libkern.h @@ -16,6 +16,6 @@ uint32_t arc4random(void); static __inline int imax(int a, int b) { return (a > b ? a : b); } -static __inline int abs(int a) { return (a < 0 ? -a : a); } +extern int abs(int a); #endif /* _FBSD_COMPAT_SYS_LIBKERN_H_ */ diff --git a/src/libs/compat/freebsd_network/firmware.c b/src/libs/compat/freebsd_network/firmware.c index 67f2745577..a829d5566b 100644 --- a/src/libs/compat/freebsd_network/firmware.c +++ b/src/libs/compat/freebsd_network/firmware.c @@ -1,10 +1,12 @@ /* - * Copyright 2009, Colin Günther, coling@gmx.de. + * Copyright 2009-2010, Colin Günther, coling@gmx.de. * All Rights Reserved. Distributed under the terms of the MIT License. * */ +#include + #include #include #include @@ -16,78 +18,115 @@ #include #include +#include +#include +#include +#include + +#include + + + +#define MAX_FBSD_FIRMWARE_NAME_CHARS 64 + // For strndup, beeing cautious in kernel code is a good thing. + // NB: This constant doesn't exist in FreeBSD. + const struct firmware* -firmware_get(const char* imageName) +firmware_get(const char* fbsdFirmwareName) { - int fileDescriptor; + area_id area; + void* driverSettings = NULL; + char* fbsdFirmwareNameCopy = NULL; + int fileDescriptor = 0; struct firmware* firmware = NULL; int32 firmwareFileSize; - char* firmwareName; - char* firmwarePath; - ssize_t readCount; + char* firmwarePath = NULL; + const char* haikuFirmwareName = NULL; + + driverSettings = load_driver_settings(gDriverName); + if (driverSettings == NULL) { + driver_printf("%s: settings file %s is missing.\n", __func__, + gDriverName); + return NULL; + } + + haikuFirmwareName = get_driver_parameter(driverSettings, fbsdFirmwareName, + NULL, NULL); + if (haikuFirmwareName == NULL) { + driver_printf("%s: settings file %s file contains no mapping for %s.\n", + __func__, gDriverName, fbsdFirmwareName); + goto cleanup; + } firmwarePath = (char*)malloc(B_PATH_NAME_LENGTH); if (firmwarePath == NULL) - goto cleanup0; + goto cleanup; if (find_directory(B_SYSTEM_DATA_DIRECTORY, -1, false, firmwarePath, B_PATH_NAME_LENGTH) != B_OK) - goto cleanup1; + goto cleanup; strlcat(firmwarePath, "/firmware/", B_PATH_NAME_LENGTH); strlcat(firmwarePath, gDriverName, B_PATH_NAME_LENGTH); strlcat(firmwarePath, "/", B_PATH_NAME_LENGTH); - strlcat(firmwarePath, imageName, B_PATH_NAME_LENGTH); + strlcat(firmwarePath, haikuFirmwareName, B_PATH_NAME_LENGTH); fileDescriptor = open(firmwarePath, B_READ_ONLY); if (fileDescriptor == -1) - goto cleanup1; + goto cleanup; firmwareFileSize = lseek(fileDescriptor, 0, SEEK_END); lseek(fileDescriptor, 0, SEEK_SET); - firmwareName = (char*)malloc(strlen(imageName) + 1); - if (firmwareName == NULL) - goto cleanup2; - - strncpy(firmwareName, imageName, strlen(imageName) + 1); + fbsdFirmwareNameCopy = strndup(fbsdFirmwareName, + MAX_FBSD_FIRMWARE_NAME_CHARS); + if (fbsdFirmwareNameCopy == NULL) + goto cleanup; firmware = (struct firmware*)malloc(sizeof(struct firmware)); if (firmware == NULL) - goto cleanup3; + goto cleanup; - firmware->data = malloc(firmwareFileSize); - if (firmware->data == NULL) - goto cleanup4; - - readCount = read(fileDescriptor, (void*)firmware->data, firmwareFileSize); - if (readCount == -1) - goto cleanup5; + firmware->data = NULL; + area = _user_map_file("mmap area", (void*)&firmware->data, B_ANY_ADDRESS, + firmwareFileSize, B_READ_AREA, REGION_PRIVATE_MAP, true, fileDescriptor, + 0); + if (area < 0) + goto cleanup; firmware->datasize = firmwareFileSize; - firmware->name = firmwareName; + firmware->name = fbsdFirmwareNameCopy; firmware->version = __haiku_firmware_version; - goto cleanup2; -cleanup5: - free(&firmware->data); -cleanup4: - free(firmware); - firmware = NULL; -cleanup3: - free(firmwareName); -cleanup2: close(fileDescriptor); -cleanup1: free(firmwarePath); -cleanup0: + unload_driver_settings(driverSettings); return firmware; + +cleanup: + if (firmware) + free(firmware); + if (fbsdFirmwareNameCopy) + free(fbsdFirmwareNameCopy); + if (firmwarePath) + free(firmwarePath); + if (fileDescriptor) + close(fileDescriptor); + if (driverSettings) + unload_driver_settings(driverSettings); + return NULL; } void -firmware_put(const struct firmware* pointer, int flags) +firmware_put(const struct firmware* firmware, int flags) { + if (firmware == NULL) + return; + _user_unmap_memory((void*)firmware->data, firmware->datasize); + if (firmware->name) + free((void*)firmware->name); + free((void*)firmware); }