* Reworked firmware loading. This gets rid of the need for the settings files.
Name mapping is now defined in the glue code. * Adding two macros for handling firmware name mapping completely in the glue code: - HAIKU_FIRMWARE_NAME_MAP(firmwarePartsCount) is used when mapping is required. Have a look to iprowifi2100's glue code for an example. - NO_HAIKU_FIRMWARE_NAME_MAP() is used when the firmware names don't need to be mapped. For example: broadcom43xx * Discard usage of vm_map_file() and use the previously read() method again. After Axel and Ingo agree that both methods are fine in this particular use case, using read() looks easier on the eye. It needs only 3 parameters, where vm_map_file() takes 10. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35170 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
bf365f13aa
commit
d3806c1b62
@ -173,11 +173,36 @@ enum {
|
||||
|
||||
#define HAIKU_DRIVER_REQUIRES(flag) (__haiku_driver_requirements & (flag))
|
||||
|
||||
|
||||
/* #pragma mark - firmware loading */
|
||||
|
||||
|
||||
/*
|
||||
* Only needed to be specified in the glue code of drivers which actually need
|
||||
* to load firmware. See iprowifi2100 for an example.
|
||||
*/
|
||||
|
||||
extern const uint __haiku_firmware_version;
|
||||
|
||||
/* Use 0 if driver doesn't care about firmware version. */
|
||||
#define HAIKU_FIRMWARE_VERSION(version) \
|
||||
const uint __haiku_firmware_version = (version)
|
||||
|
||||
extern const uint __haiku_firmware_parts_count;
|
||||
extern const char* __haiku_firmware_name_map[][2];
|
||||
|
||||
#define HAIKU_FIRMWARE_NAME_MAP(firmwarePartsCount) \
|
||||
const uint __haiku_firmware_parts_count = firmwarePartsCount; \
|
||||
const char* __haiku_firmware_name_map[firmwarePartsCount][2]
|
||||
|
||||
#define NO_HAIKU_FIRMWARE_NAME_MAP() \
|
||||
const uint __haiku_firmware_parts_count = 0; \
|
||||
const char* __haiku_firmware_name_map[0][2] = {NULL}
|
||||
|
||||
|
||||
/* #pragma mark - synchronization */
|
||||
|
||||
|
||||
#define HAIKU_INTR_REGISTER_STATE \
|
||||
cpu_status __haiku_cpu_state = 0
|
||||
|
||||
|
@ -18,46 +18,44 @@
|
||||
#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.
|
||||
|
||||
|
||||
static const char*
|
||||
getHaikuFirmwareName(const char* fbsdFirmwareName,
|
||||
const char* unknownFirmwareName)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (__haiku_firmware_name_map == NULL)
|
||||
return unknownFirmwareName;
|
||||
|
||||
for (i = 0; i < __haiku_firmware_parts_count; i++) {
|
||||
if (strcmp(__haiku_firmware_name_map[i][0], fbsdFirmwareName) == 0)
|
||||
return __haiku_firmware_name_map[i][1];
|
||||
}
|
||||
return unknownFirmwareName;
|
||||
}
|
||||
|
||||
|
||||
const struct firmware*
|
||||
firmware_get(const char* fbsdFirmwareName)
|
||||
{
|
||||
area_id area;
|
||||
void* driverSettings = NULL;
|
||||
char* fbsdFirmwareNameCopy = NULL;
|
||||
int fileDescriptor = 0;
|
||||
struct firmware* firmware = NULL;
|
||||
int32 firmwareFileSize;
|
||||
char* firmwarePath = NULL;
|
||||
const char* haikuFirmwareName = NULL;
|
||||
ssize_t readCount = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
haikuFirmwareName = getHaikuFirmwareName(fbsdFirmwareName,
|
||||
fbsdFirmwareName);
|
||||
|
||||
firmwarePath = (char*)malloc(B_PATH_NAME_LENGTH);
|
||||
if (firmwarePath == NULL)
|
||||
@ -88,20 +86,22 @@ firmware_get(const char* fbsdFirmwareName)
|
||||
if (firmware == NULL)
|
||||
goto cleanup;
|
||||
|
||||
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)
|
||||
firmware->data = malloc(firmwareFileSize);
|
||||
if (firmware->data == NULL)
|
||||
goto cleanup;
|
||||
|
||||
readCount = read(fileDescriptor, (void*)firmware->data, firmwareFileSize);
|
||||
if (readCount == -1 || readCount < firmwareFileSize) {
|
||||
free((void*)firmware->data);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
firmware->datasize = firmwareFileSize;
|
||||
firmware->name = fbsdFirmwareNameCopy;
|
||||
firmware->version = __haiku_firmware_version;
|
||||
|
||||
close(fileDescriptor);
|
||||
free(firmwarePath);
|
||||
unload_driver_settings(driverSettings);
|
||||
return firmware;
|
||||
|
||||
cleanup:
|
||||
@ -113,8 +113,6 @@ cleanup:
|
||||
free(firmwarePath);
|
||||
if (fileDescriptor)
|
||||
close(fileDescriptor);
|
||||
if (driverSettings)
|
||||
unload_driver_settings(driverSettings);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -125,7 +123,8 @@ firmware_put(const struct firmware* firmware, int flags)
|
||||
if (firmware == NULL)
|
||||
return;
|
||||
|
||||
_user_unmap_memory((void*)firmware->data, firmware->datasize);
|
||||
if (firmware->data)
|
||||
free((void*)firmware->data);
|
||||
if (firmware->name)
|
||||
free((void*)firmware->name);
|
||||
free((void*)firmware);
|
||||
|
Loading…
Reference in New Issue
Block a user