[haiku-commits] r35156 - in haiku/trunk/src/libs/compat/freebsd_network: . compat/sys

  • From: coling@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 19 Jan 2010 10:08:53 +0100 (CET)

Author: colin
Date: 2010-01-19 10:08:52 +0100 (Tue, 19 Jan 2010)
New Revision: 35156
Changeset: http://dev.haiku-os.org/changeset/35156/haiku

Modified:
   haiku/trunk/src/libs/compat/freebsd_network/compat/sys/cdefs.h
   haiku/trunk/src/libs/compat/freebsd_network/compat/sys/firmware.h
   haiku/trunk/src/libs/compat/freebsd_network/compat/sys/libkern.h
   haiku/trunk/src/libs/compat/freebsd_network/firmware.c
Log:
* 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.


Modified: haiku/trunk/src/libs/compat/freebsd_network/compat/sys/cdefs.h
===================================================================
--- haiku/trunk/src/libs/compat/freebsd_network/compat/sys/cdefs.h      
2010-01-19 08:34:14 UTC (rev 35155)
+++ haiku/trunk/src/libs/compat/freebsd_network/compat/sys/cdefs.h      
2010-01-19 09:08:52 UTC (rev 35156)
@@ -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 */

Modified: haiku/trunk/src/libs/compat/freebsd_network/compat/sys/firmware.h
===================================================================
--- haiku/trunk/src/libs/compat/freebsd_network/compat/sys/firmware.h   
2010-01-19 08:34:14 UTC (rev 35155)
+++ haiku/trunk/src/libs/compat/freebsd_network/compat/sys/firmware.h   
2010-01-19 09:08:52 UTC (rev 35156)
@@ -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_ */

Modified: haiku/trunk/src/libs/compat/freebsd_network/compat/sys/libkern.h
===================================================================
--- haiku/trunk/src/libs/compat/freebsd_network/compat/sys/libkern.h    
2010-01-19 08:34:14 UTC (rev 35155)
+++ haiku/trunk/src/libs/compat/freebsd_network/compat/sys/libkern.h    
2010-01-19 09:08:52 UTC (rev 35156)
@@ -16,6 +16,6 @@
 
 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_ */

Modified: haiku/trunk/src/libs/compat/freebsd_network/firmware.c
===================================================================
--- haiku/trunk/src/libs/compat/freebsd_network/firmware.c      2010-01-19 
08:34:14 UTC (rev 35155)
+++ haiku/trunk/src/libs/compat/freebsd_network/firmware.c      2010-01-19 
09:08:52 UTC (rev 35156)
@@ -1,10 +1,12 @@
 /*
- * Copyright 2009, Colin Günther, coling@xxxxxxx
+ * Copyright 2009-2010, Colin Günther, coling@xxxxxxx
  * 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;
+       fbsdFirmwareNameCopy = strndup(fbsdFirmwareName,
+               MAX_FBSD_FIRMWARE_NAME_CHARS);
+       if (fbsdFirmwareNameCopy == NULL)
+               goto cleanup;
 
-       strncpy(firmwareName, imageName, strlen(imageName) + 1);
-
        firmware = (struct firmware*)malloc(sizeof(struct firmware));
        if (firmware == NULL)
-               goto cleanup3;
+               goto cleanup;
 
-       firmware->data = malloc(firmwareFileSize);
-       if (firmware->data == NULL)
-               goto cleanup4;
+       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;
 
-       readCount = read(fileDescriptor, (void*)firmware->data, 
firmwareFileSize);
-       if (readCount == -1)
-               goto cleanup5;
-
        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);
 }


Other related posts: