* 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
This commit is contained in:
@@ -35,6 +35,10 @@
|
|||||||
#ifndef _FBSD_COMPAT_SYS_CDEFS_H_
|
#ifndef _FBSD_COMPAT_SYS_CDEFS_H_
|
||||||
#define _FBSD_COMPAT_SYS_CDEFS_H_
|
#define _FBSD_COMPAT_SYS_CDEFS_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <posix/sys/cdefs.h>
|
||||||
|
|
||||||
|
|
||||||
#define __FBSDID(str) static const char __fbsdid[] = str
|
#define __FBSDID(str) static const char __fbsdid[] = str
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -174,7 +178,6 @@
|
|||||||
* a feature that we cannot live without.
|
* a feature that we cannot live without.
|
||||||
*/
|
*/
|
||||||
#ifdef lint
|
#ifdef lint
|
||||||
#define __dead2
|
|
||||||
#define __pure2
|
#define __pure2
|
||||||
#define __unused
|
#define __unused
|
||||||
#define __packed
|
#define __packed
|
||||||
@@ -182,18 +185,15 @@
|
|||||||
#define __section(x)
|
#define __section(x)
|
||||||
#else
|
#else
|
||||||
#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
|
#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
|
||||||
#define __dead2
|
|
||||||
#define __pure2
|
#define __pure2
|
||||||
#define __unused
|
#define __unused
|
||||||
#endif
|
#endif
|
||||||
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
|
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
|
||||||
#define __dead2 __attribute__((__noreturn__))
|
|
||||||
#define __pure2 __attribute__((__const__))
|
#define __pure2 __attribute__((__const__))
|
||||||
#define __unused
|
#define __unused
|
||||||
/* XXX Find out what to do for __packed, __aligned and __section */
|
/* XXX Find out what to do for __packed, __aligned and __section */
|
||||||
#endif
|
#endif
|
||||||
#if __GNUC_PREREQ__(2, 7)
|
#if __GNUC_PREREQ__(2, 7)
|
||||||
#define __dead2 __attribute__((__noreturn__))
|
|
||||||
#define __pure2 __attribute__((__const__))
|
#define __pure2 __attribute__((__const__))
|
||||||
#define __unused __attribute__((__unused__))
|
#define __unused __attribute__((__unused__))
|
||||||
#define __packed __attribute__((__packed__))
|
#define __packed __attribute__((__packed__))
|
||||||
@@ -210,7 +210,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER)
|
#if defined(__INTEL_COMPILER)
|
||||||
#define __dead2 __attribute__((__noreturn__))
|
|
||||||
#define __pure2 __attribute__((__const__))
|
#define __pure2 __attribute__((__const__))
|
||||||
#define __unused __attribute__((__unused__))
|
#define __unused __attribute__((__unused__))
|
||||||
#define __used __attribute__((__used__))
|
#define __used __attribute__((__used__))
|
||||||
@@ -263,10 +262,6 @@
|
|||||||
* first. It is only available with ANSI C.
|
* first. It is only available with ANSI C.
|
||||||
*/
|
*/
|
||||||
#if defined(__STDC__) || defined(__cplusplus)
|
#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 __XSTRING(x) __STRING(x) /* expand x, then stringify */
|
||||||
|
|
||||||
#define __const const /* define reserved names to standard */
|
#define __const const /* define reserved names to standard */
|
||||||
@@ -281,9 +276,6 @@
|
|||||||
#endif /* !__cplusplus */
|
#endif /* !__cplusplus */
|
||||||
|
|
||||||
#else /* !(__STDC__ || __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)
|
#if !defined(__CC_SUPPORTS___INLINE)
|
||||||
#define __const /* delete pseudo-ANSI C keywords */
|
#define __const /* delete pseudo-ANSI C keywords */
|
||||||
|
|||||||
@@ -6,16 +6,18 @@
|
|||||||
#define _FBSD_COMPAT_SYS_FIRMWARE_H_
|
#define _FBSD_COMPAT_SYS_FIRMWARE_H_
|
||||||
|
|
||||||
|
|
||||||
|
#define FIRMWARE_UNLOAD 0x0001
|
||||||
|
|
||||||
|
|
||||||
struct firmware {
|
struct firmware {
|
||||||
const char* name; /* system-wide name */
|
const char* name; // system-wide name
|
||||||
const void* data; /* location of image */
|
const void* data; // location of image
|
||||||
size_t datasize; /* size of image in bytes */
|
size_t datasize; // size of image in bytes
|
||||||
unsigned int version; /* version of the image */
|
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);
|
void firmware_put(const struct firmware*, int);
|
||||||
|
|
||||||
#endif /* _FBSD_COMPAT_SYS_FIRMWARE_H_ */
|
#endif /* _FBSD_COMPAT_SYS_FIRMWARE_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 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_ */
|
#endif /* _FBSD_COMPAT_SYS_LIBKERN_H_ */
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Colin Günther, [email protected].
|
* Copyright 2009-2010, Colin Günther, [email protected].
|
||||||
* All Rights Reserved. Distributed under the terms of the MIT License.
|
* All Rights Reserved. Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <posix/sys/mman.h>
|
||||||
|
|
||||||
#include <compat/sys/param.h>
|
#include <compat/sys/param.h>
|
||||||
#include <compat/sys/firmware.h>
|
#include <compat/sys/firmware.h>
|
||||||
#include <compat/sys/haiku-module.h>
|
#include <compat/sys/haiku-module.h>
|
||||||
@@ -16,78 +18,115 @@
|
|||||||
#include <StorageDefs.h>
|
#include <StorageDefs.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include <driver_settings.h>
|
||||||
|
#include <kernel/vm/vm.h>
|
||||||
|
#include <syscalls.h>
|
||||||
|
#include <vm_defs.h>
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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*
|
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;
|
struct firmware* firmware = NULL;
|
||||||
int32 firmwareFileSize;
|
int32 firmwareFileSize;
|
||||||
char* firmwareName;
|
char* firmwarePath = NULL;
|
||||||
char* firmwarePath;
|
const char* haikuFirmwareName = NULL;
|
||||||
ssize_t readCount;
|
|
||||||
|
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);
|
firmwarePath = (char*)malloc(B_PATH_NAME_LENGTH);
|
||||||
if (firmwarePath == NULL)
|
if (firmwarePath == NULL)
|
||||||
goto cleanup0;
|
goto cleanup;
|
||||||
|
|
||||||
if (find_directory(B_SYSTEM_DATA_DIRECTORY, -1, false,
|
if (find_directory(B_SYSTEM_DATA_DIRECTORY, -1, false,
|
||||||
firmwarePath, B_PATH_NAME_LENGTH) != B_OK)
|
firmwarePath, B_PATH_NAME_LENGTH) != B_OK)
|
||||||
goto cleanup1;
|
goto cleanup;
|
||||||
|
|
||||||
strlcat(firmwarePath, "/firmware/", B_PATH_NAME_LENGTH);
|
strlcat(firmwarePath, "/firmware/", B_PATH_NAME_LENGTH);
|
||||||
strlcat(firmwarePath, gDriverName, B_PATH_NAME_LENGTH);
|
strlcat(firmwarePath, gDriverName, B_PATH_NAME_LENGTH);
|
||||||
strlcat(firmwarePath, "/", 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);
|
fileDescriptor = open(firmwarePath, B_READ_ONLY);
|
||||||
if (fileDescriptor == -1)
|
if (fileDescriptor == -1)
|
||||||
goto cleanup1;
|
goto cleanup;
|
||||||
|
|
||||||
firmwareFileSize = lseek(fileDescriptor, 0, SEEK_END);
|
firmwareFileSize = lseek(fileDescriptor, 0, SEEK_END);
|
||||||
lseek(fileDescriptor, 0, SEEK_SET);
|
lseek(fileDescriptor, 0, SEEK_SET);
|
||||||
|
|
||||||
firmwareName = (char*)malloc(strlen(imageName) + 1);
|
fbsdFirmwareNameCopy = strndup(fbsdFirmwareName,
|
||||||
if (firmwareName == NULL)
|
MAX_FBSD_FIRMWARE_NAME_CHARS);
|
||||||
goto cleanup2;
|
if (fbsdFirmwareNameCopy == NULL)
|
||||||
|
goto cleanup;
|
||||||
strncpy(firmwareName, imageName, strlen(imageName) + 1);
|
|
||||||
|
|
||||||
firmware = (struct firmware*)malloc(sizeof(struct firmware));
|
firmware = (struct firmware*)malloc(sizeof(struct firmware));
|
||||||
if (firmware == NULL)
|
if (firmware == NULL)
|
||||||
goto cleanup3;
|
goto cleanup;
|
||||||
|
|
||||||
firmware->data = malloc(firmwareFileSize);
|
firmware->data = NULL;
|
||||||
if (firmware->data == NULL)
|
area = _user_map_file("mmap area", (void*)&firmware->data, B_ANY_ADDRESS,
|
||||||
goto cleanup4;
|
firmwareFileSize, B_READ_AREA, REGION_PRIVATE_MAP, true, fileDescriptor,
|
||||||
|
0);
|
||||||
readCount = read(fileDescriptor, (void*)firmware->data, firmwareFileSize);
|
if (area < 0)
|
||||||
if (readCount == -1)
|
goto cleanup;
|
||||||
goto cleanup5;
|
|
||||||
|
|
||||||
firmware->datasize = firmwareFileSize;
|
firmware->datasize = firmwareFileSize;
|
||||||
firmware->name = firmwareName;
|
firmware->name = fbsdFirmwareNameCopy;
|
||||||
firmware->version = __haiku_firmware_version;
|
firmware->version = __haiku_firmware_version;
|
||||||
goto cleanup2;
|
|
||||||
|
|
||||||
cleanup5:
|
|
||||||
free(&firmware->data);
|
|
||||||
cleanup4:
|
|
||||||
free(firmware);
|
|
||||||
firmware = NULL;
|
|
||||||
cleanup3:
|
|
||||||
free(firmwareName);
|
|
||||||
cleanup2:
|
|
||||||
close(fileDescriptor);
|
close(fileDescriptor);
|
||||||
cleanup1:
|
|
||||||
free(firmwarePath);
|
free(firmwarePath);
|
||||||
cleanup0:
|
unload_driver_settings(driverSettings);
|
||||||
return firmware;
|
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
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user