From 865639deac83c5041404684ca5342ceb59f9b1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20G=C3=BCnther?= Date: Tue, 19 Jan 2010 09:08:52 +0000 Subject: [PATCH] * Changing the naming scheme for firmwares. Instead of directly renaming the respective firmware files renaming is now done within the firmware loader. The mapping of original firmware names to FreeBSD internal firmware names is now done within driver specific settings files. Those are committed in a next step. This approach allows a clean separation of FreeBSD compat layer requirements and native driver requirements. For example: we have two Intel PRO/Wireless 2100 drivers. Do we prefer the naming scheme of the native driver or do we force the native driver to use the one of the FreeBSD driver? With this commit we prefer native over FreeBSD. * Changed the firmware loader to make use of Haiku's file mapping facility. * Implementing firmware unloading. * Some minor cleanups in two compat layer header files, which are using Haiku defined identifiers, where apropriate. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35156 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../compat/freebsd_network/compat/sys/cdefs.h | 16 +-- .../freebsd_network/compat/sys/firmware.h | 14 ++- .../freebsd_network/compat/sys/libkern.h | 2 +- src/libs/compat/freebsd_network/firmware.c | 111 ++++++++++++------ 4 files changed, 88 insertions(+), 55 deletions(-) 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); }