* 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:
Colin Günther 2010-01-19 09:08:52 +00:00
parent 6379e53e2d
commit 865639deac
4 changed files with 88 additions and 55 deletions

View File

@ -35,6 +35,10 @@
#ifndef _FBSD_COMPAT_SYS_CDEFS_H_
#define _FBSD_COMPAT_SYS_CDEFS_H_
#include <posix/sys/cdefs.h>
#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 */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 <posix/sys/mman.h>
#include <compat/sys/param.h>
#include <compat/sys/firmware.h>
#include <compat/sys/haiku-module.h>
@ -16,78 +18,115 @@
#include <StorageDefs.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*
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);
}