Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
advLigoRTS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CDS
software
advLigoRTS
Commits
ddca2818
Commit
ddca2818
authored
3 years ago
by
Ezekiel Dohmen
Browse files
Options
Downloads
Patches
Plain Diff
Adding interface that returns differing error codes to match error cases, also some cleanup
parent
0b29fa89
No related branches found
Branches containing commit
No related tags found
Tags containing commit
2 merge requests
!439
RCG 5.0 release fro deb 10
,
!318
mbuf_allocate_area upgrade
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/drv/mbuf/mbuf.c
+285
-290
285 additions, 290 deletions
src/drv/mbuf/mbuf.c
src/drv/mbuf/mbuf_kernel.h
+63
-6
63 additions, 6 deletions
src/drv/mbuf/mbuf_kernel.h
with
348 additions
and
296 deletions
src/drv/mbuf/mbuf.c
+
285
−
290
View file @
ddca2818
...
...
@@ -27,6 +27,7 @@
#endif
#include
<asm/io.h>
#include
"mbuf.h"
#include
"mbuf_kernel.h"
#include
"kvmem.c"
...
...
@@ -66,36 +67,56 @@ static struct file_operations mbuf_fops = {
.
owner
=
THIS_MODULE
,
};
// internal data
// How many memory areas we will support
#define MAX_AREAS 64
// pointer to the kmalloc'd area, rounded up to a page boundary
static
void
*
kmalloc_area
[
MAX_AREAS
];
// To be used by the IOP to store Dolphin memory state
int
iop_rfm_valid
;
EXPORT_SYMBOL
(
iop_rfm_valid
);
//
// Internal data
//
// Defines the max memory areas we will support
#define MAX_AREAS 64
// pointer to the kmalloc'd area, rounded up to a page boundary
static
void
*
kmalloc_area
[
MAX_AREAS
];
// Memory area tags (OM1, OM2, etc)
char
mtag
[
MAX_AREAS
][
MBUF_NAME_LEN
+
1
];
static
char
mtag
[
MAX_AREAS
][
MBUF_NAME_LEN
+
1
];
// Memory usage counters
unsigned
int
usage_cnt
[
MAX_AREAS
];
static
unsigned
int
usage_cnt
[
MAX_AREAS
];
// Memory area sizes
unsigned
int
kmalloc_area_size
[
MAX_AREAS
];
static
unsigned
int
kmalloc_area_size
[
MAX_AREAS
];
static
DEFINE_SPINLOCK
(
lock
);
/* character device open method */
static
int
mbuf_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
/// @brief Stores the error message mapping for each MBUF_KERNEL_CODE.
/// The number of entries here MUST match the number of MBUF_KERNEL_CODE
/// enums defined.
static
const
char
error_msgs
[][
MBUF_ERROR_MSG_ALLOC_LEN
]
=
{
return
0
;
}
{
""
},
{
"The mbuf module does not have any more free areas for the requested buffer"
},
{
"The buffer allocation failed"
},
{
"A buffer with the name already allocated, and the requested size does not match"
},
{
"A buffer with the requested name could not be found"
},
{
"Unsupported Error Code"
}
};
static
DEFINE_SPINLOCK
(
lock
);
static
int
find_mbuf
(
const
char
*
name
)
// Attempts to lookup an allocated buffer's index by name
// Returns the index in kmalloc_area where the buffer is located if found,
// and -1 if no buffer with the requested name was found.
// This is an internal helper function, the caller MUST
// acquire lock before calling this function
static
int
find_mbuf_index
(
const
char
*
name
)
{
int
i
=
0
;
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
...
...
@@ -106,225 +127,204 @@ static int find_mbuf(const char * name)
return
-
1
;
}
int
mbuf_release_area
(
char
*
name
,
struct
file
*
file
)
{
int
i
;
if
((
int
)
atomic_read
(
&
mbuf_verbosity
)
>
0
)
{
printk
(
KERN_INFO
" mbuf_release_area %s
\n
"
,
name
);
void
mbuf_lookup_error_msg
(
enum
MBUF_KERNEL_CODE
code
,
char
*
error_msg
)
{
int
err_indx
;
if
(
code
<
MBUF_KERNEL_CODE_OK
||
code
>=
MBUF_KERNEL_CODE_LAST
)
err_indx
=
MBUF_KERNEL_CODE_LAST
;
strncpy
(
error_msg
,
error_msgs
[
err_indx
],
MBUF_ERROR_MSG_MAX_LEN
);
return
;
}
EXPORT_SYMBOL
(
mbuf_lookup_error_msg
);
enum
MBUF_KERNEL_CODE
mbuf_release_area_file
(
const
char
*
name
,
struct
file
*
file
)
{
//Attempt to release the buffer
enum
MBUF_KERNEL_CODE
ret
=
mbuf_release_area
(
name
);
//If the release is good, clear out the file private data
if
(
ret
==
MBUF_KERNEL_CODE_OK
){
if
(
file
)
{
file
->
private_data
=
0
;
}
}
spin_lock
(
&
lock
);
// See if allocated
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
0
==
strcmp
(
mtag
[
i
],
name
))
{
// Found the area
usage_cnt
[
i
]
--
;
if
(
usage_cnt
[
i
]
<=
0
){
mtag
[
i
][
0
]
=
0
;
usage_cnt
[
i
]
=
0
;
if
(
file
)
file
->
private_data
=
0
;
rvfree
(
kmalloc_area
[
i
],
kmalloc_area_size
[
i
]);
kmalloc_area
[
i
]
=
0
;
kmalloc_area_size
[
i
]
=
0
;
}
spin_unlock
(
&
lock
);
return
0
;
}
}
spin_unlock
(
&
lock
);
return
-
1
;
return
ret
;
}
EXPORT_SYMBOL
(
mbuf_release_area
);
enum
MBUF_KERNEL_CODE
mbuf_release_area
(
const
char
*
name
)
{
int
i
;
// Returns index of allocated area
// -1 if no slots
// This is an internal helper function, the caller MUST
// acquire lock before calling this function
static
int
_mbuf_allocate_area_safe
(
char
*
name
,
int
size
)
{
int
i
,
s
;
if
((
int
)
atomic_read
(
&
mbuf_verbosity
)
>
0
)
{
printk
(
KERN_INFO
" mbuf_release_area %s
\n
"
,
name
);
}
// See if already allocated
spin_lock
(
&
lock
);
// See if allocated
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
0
==
strcmp
(
mtag
[
i
],
name
))
{
// Found the area, make sure it is big enough
if
(
kmalloc_area_size
[
i
]
<
size
)
{
return
-
1
;
// Found the area
usage_cnt
[
i
]
--
;
if
(
usage_cnt
[
i
]
<=
0
){
mtag
[
i
][
0
]
=
0
;
usage_cnt
[
i
]
=
0
;
rvfree
(
kmalloc_area
[
i
],
kmalloc_area_size
[
i
]);
kmalloc_area
[
i
]
=
0
;
kmalloc_area_size
[
i
]
=
0
;
}
usage_cnt
[
i
]
++
;
return
i
;
spin_unlock
(
&
lock
);
return
MBUF_KERNEL_CODE_OK
;
}
}
//We only get here if we don't find the buffer
spin_unlock
(
&
lock
);
return
MBUF_KERNEL_CODE_NAME_NOT_FOUND
;
}
EXPORT_SYMBOL
(
mbuf_release_area
);
int
mbuf_allocate_area_file
(
char
*
name
,
int
size
,
struct
file
*
file
)
{
enum
MBUF_KERNEL_CODE
ret
;
int
buffer_index
;
//Try to allocate buffer
ret
=
mbuf_allocate_area
(
name
,
size
,
0
);
if
(
ret
!=
MBUF_KERNEL_CODE_OK
)
return
-
1
;
//Get the index of the buffer
spin_lock
(
&
lock
);
buffer_index
=
find_mbuf_index
(
name
);
spin_unlock
(
&
lock
);
if
(
buffer_index
<
0
)
return
-
1
;
if
(
file
)
file
->
private_data
=
mtag
[
buffer_index
];
return
buffer_index
;
}
// Returns pointer to buffer allocated, or 0 (NULL) if there was an error.
// 0x0 if no slots
enum
MBUF_KERNEL_CODE
mbuf_allocate_area
(
const
char
*
name
,
const
int
size
,
volatile
void
**
buffer_ptr
)
{
int
i
;
spin_lock
(
&
lock
);
// See if we already have a buffer with the name
i
=
find_mbuf_index
(
name
);
if
(
i
>=
0
)
{
if
(
kmalloc_area_size
[
i
]
!=
size
)
{
*
buffer_ptr
=
NULL
;
spin_unlock
(
&
lock
);
return
MBUF_KERNEL_CODE_SZ_ERROR
;
}
++
usage_cnt
[
i
];
*
buffer_ptr
=
kmalloc_area
[
i
];
spin_unlock
(
&
lock
);
return
MBUF_KERNEL_CODE_OK
;
}
// Find first free slot
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
kmalloc_area
[
i
]
==
0
)
break
;
}
// Out of slots
if
(
i
>=
MAX_AREAS
)
{
return
-
1
;
spin_unlock
(
&
lock
);
return
MBUF_KERNEL_CODE_NO_BUFFERS
;
}
s
=
size
;
kmalloc_area
[
i
]
=
0
;
kmalloc_area
[
i
]
=
rvmalloc
(
size
);
//rkmalloc (&s, GFP_KERNEL);
kmalloc_area
[
i
]
=
rvmalloc
(
size
);
//printk("rvmalloc() returned %p\n", kmalloc_area[i]);
//printk("rkmalloc() returned %p %d\n", kmalloc_area[i], s);
//rkfree(kmalloc_area[i], s);
//kmalloc_area[i] = 0;
if
(
kmalloc_area
[
i
]
==
0
)
{
spin_unlock
(
&
lock
);
printk
(
"malloc() failed
\n
"
);
return
-
1
;
return
MBUF_KERNEL_CODE_ALLOC_FAILED
;
}
if
(
one_fill
)
memset
(
kmalloc_area
[
i
],
0xff
,
size
);
//1 fill if the allocation was good, and we are configured to do so
if
(
one_fill
)
memset
(
kmalloc_area
[
i
],
0xff
,
size
);
kmalloc_area_size
[
i
]
=
size
;
strncpy
(
mtag
[
i
],
name
,
MBUF_NAME_LEN
);
mtag
[
i
][
MBUF_NAME_LEN
]
=
0
;
usage_cnt
[
i
]
=
1
;
return
i
;
}
// Returns index of allocated area
// -1 if no slots
int
mbuf_allocate_area_safe
(
char
*
name
,
int
size
,
struct
file
*
file
)
{
int
result
=
-
1
;
if
(
!
name
||
size
<=
0
)
return
result
;
spin_lock
(
&
lock
);
result
=
_mbuf_allocate_area_safe
(
name
,
size
);
if
(
result
>=
0
&&
file
)
{
file
->
private_data
=
mtag
[
result
];
}
*
buffer_ptr
=
kmalloc_area
[
i
];
spin_unlock
(
&
lock
);
return
result
;
return
MBUF_KERNEL_CODE_OK
;
}
// Returns pointer to buffer allocated, or 0 (NULL) if there was an error.
// 0x0 if no slots
void
*
mbuf_allocate_area
(
char
*
name
,
int
size
,
struct
file
*
file
)
{
int
i
,
s
;
spin_lock
(
&
lock
);
EXPORT_SYMBOL
(
mbuf_allocate_area
);
// See if we already have a buffer with the name
i
=
find_mbuf
(
name
);
if
(
i
>=
0
)
{
++
usage_cnt
[
i
];
if
(
file
)
file
->
private_data
=
mtag
[
i
];
spin_unlock
(
&
lock
);
return
kmalloc_area
[
i
];
}
// Find first free slot
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
kmalloc_area
[
i
]
==
0
)
break
;
}
// Out of slots
if
(
i
>=
MAX_AREAS
)
{
spin_unlock
(
&
lock
);
return
0
;
}
s
=
size
;
kmalloc_area
[
i
]
=
0
;
kmalloc_area
[
i
]
=
rvmalloc
(
size
);
//rkmalloc (&s, GFP_KERNEL);
if
(
one_fill
)
memset
(
kmalloc_area
[
i
],
0xff
,
size
);
//printk("rvmalloc() returned %p\n", kmalloc_area[i]);
//printk("rkmalloc() returned %p %d\n", kmalloc_area[i], s);
//rkfree(kmalloc_area[i], s);
//kmalloc_area[i] = 0;
if
(
kmalloc_area
[
i
]
==
0
)
{
spin_unlock
(
&
lock
);
printk
(
"malloc() failed
\n
"
);
return
0
;
}
kmalloc_area_size
[
i
]
=
size
;
strncpy
(
mtag
[
i
],
name
,
MBUF_NAME_LEN
);
mtag
[
i
][
MBUF_NAME_LEN
]
=
0
;
usage_cnt
[
i
]
=
1
;
if
(
file
)
file
->
private_data
=
mtag
[
i
];
spin_unlock
(
&
lock
);
return
kmalloc_area
[
i
];
/* character device open method */
static
int
mbuf_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
return
0
;
}
EXPORT_SYMBOL
(
mbuf_allocate_area
);
/* character device last close method */
static
int
mbuf_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
char
*
name
;
if
(
filp
->
private_data
==
0
)
return
0
;
name
=
(
char
*
)
filp
->
private_data
;
mbuf_release_area
(
name
,
filp
);
return
0
;
char
*
name
;
if
(
filp
->
private_data
==
0
)
return
0
;
name
=
(
char
*
)
filp
->
private_data
;
mbuf_release_area
_file
(
name
,
filp
);
return
0
;
}
// helper function, mmap's the kmalloc'd area which is physically contiguous
int
mmap_kmem
(
unsigned
int
i
,
struct
vm_area_struct
*
vma
)
{
long
length
=
vma
->
vm_end
-
vma
->
vm_start
;
if
(
kmalloc_area_size
[
i
]
<
length
)
{
//printk("mbuf mmap() request to map 0x%lx bytes; allocated 0x%lx\n", length, kmalloc_area_size[i]);
return
-
EINVAL
;
}
//printk("mbuf mmap() length is 0x%lx\n", length);
long
length
=
vma
->
vm_end
-
vma
->
vm_start
;
return
rvmmap
(
kmalloc_area
[
i
],
length
,
vma
);
if
(
kmalloc_area_size
[
i
]
<
length
)
{
//printk("mbuf mmap() request to map 0x%lx bytes; allocated 0x%lx\n", length, kmalloc_area_size[i]);
return
-
EINVAL
;
}
//printk("mbuf mmap() length is 0x%lx\n", length);
#if 0
/* map the whole physically contiguous area in one piece */
if ((ret = remap_pfn_range(vma,
vma->vm_start,
((unsigned int )(kmalloc_area[i])) >> PAGE_SHIFT,
length,
vma->vm_page_prot)) < 0) {
return ret;
}
return 0;
#endif
return
rvmmap
(
kmalloc_area
[
i
],
length
,
vma
);
}
/* character device mmap method */
static
int
mbuf_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
int
i
;
char
*
name
;
int
i
;
char
*
name
;
if
(
file
->
private_data
==
0
)
return
-
EINVAL
;
name
=
(
char
*
)
file
->
private_data
;
// Find our memory area
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
0
==
strcmp
(
mtag
[
i
],
name
))
{
return
mmap_kmem
(
i
,
vma
);
}
}
return
-
EINVAL
;
if
(
file
->
private_data
==
0
)
return
-
EINVAL
;
name
=
(
char
*
)
file
->
private_data
;
// Find our memory area
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
0
==
strcmp
(
mtag
[
i
],
name
))
{
return
mmap_kmem
(
i
,
vma
);
}
}
return
-
EINVAL
;
}
static
long
mbuf_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
int
res
;
void
*
buf_ptr
;
int
mod
=
0
;
int
verbose
=
0
;
struct
mbuf_request_struct
req
;
void
__user
*
argp
=
(
void
__user
*
)
arg
;
int
res
;
int
mod
=
0
;
int
verbose
=
0
;
struct
mbuf_request_struct
req
;
void
__user
*
argp
=
(
void
__user
*
)
arg
;
verbose
=
(
int
)
atomic_read
(
&
mbuf_verbosity
);
...
...
@@ -334,83 +334,78 @@ static long mbuf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
switch
(
cmd
){
case
IOCTL_MBUF_ALLOCATE
:
{
if
(
copy_from_user
(
&
req
,
(
void
*
)
argp
,
sizeof
(
req
)))
{
return
-
EFAULT
;
}
// the size should be a multiple of page size
mod
=
req
.
size
%
PAGE_SIZE
;
if
(
mod
!=
0
)
{
req
.
size
+=
PAGE_SIZE
-
mod
;
}
if
(
verbose
>
0
)
{
printk
(
KERN_INFO
"mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p
\n
"
,
req
.
name
,
(
int
)
req
.
size
,
cmd
,
file
);
}
buf_ptr
=
mbuf_allocate_area
(
req
.
name
,
req
.
size
,
file
);
if
(
buf_ptr
!=
0
)
{
res
=
find_mbuf
(
req
.
name
);
if
(
res
<=
0
)
return
-
EINVAL
;
//If somehow we didn't find
return
kmalloc_area_size
[
res
];
}
else
{
return
-
EINVAL
;
}
}
break
;
{
if
(
copy_from_user
(
&
req
,
(
void
*
)
argp
,
sizeof
(
req
)))
{
return
-
EFAULT
;
}
// the size should be a multiple of page size
mod
=
req
.
size
%
PAGE_SIZE
;
if
(
mod
!=
0
)
{
req
.
size
+=
PAGE_SIZE
-
mod
;
}
if
(
verbose
>
0
)
{
printk
(
KERN_INFO
"mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p
\n
"
,
req
.
name
,
(
int
)
req
.
size
,
cmd
,
file
);
}
res
=
mbuf_allocate_area_file
(
req
.
name
,
req
.
size
,
file
);
if
(
res
<
0
)
return
-
EINVAL
;
//If there was an issue
return
kmalloc_area_size
[
res
];
}
break
;
case
IOCTL_MBUF_DEALLOCATE
:
{
if
(
copy_from_user
(
&
req
,
(
void
*
)
argp
,
sizeof
(
req
)))
{
return
-
EFAULT
;
}
//printk("mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p\n", req.name, req.size, cmd, file);
res
=
mbuf_release_area
(
req
.
name
,
file
);
if
(
res
>
=
0
)
{
return
0
;
}
else
{
return
-
EINVAL
;
}
}
break
;
{
if
(
copy_from_user
(
&
req
,
(
void
*
)
argp
,
sizeof
(
req
)))
{
return
-
EFAULT
;
}
//printk("mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p\n", req.name, req.size, cmd, file);
res
=
mbuf_release_area
_file
(
req
.
name
,
file
);
if
(
res
=
=
MBUF_KERNEL_CODE_OK
)
{
return
0
;
}
else
{
return
-
EINVAL
;
}
}
break
;
case
IOCTL_MBUF_INFO
:
#if 0
for (i = 0; i < MAX_AREAS; i++) {
if (kmalloc_area[i]) {
printk("mbuf %d: name:%.32s, size:%d, usage:%d\n",
i, mtag[i], kmalloc_area_size[i], usage_cnt[i]);
}
}
for (i = 0; i < MAX_AREAS; i++) {
if (kmalloc_area[i]) {
printk("mbuf %d: name:%.32s, size:%d, usage:%d\n",
i, mtag[i], kmalloc_area_size[i], usage_cnt[i]);
}
}
#endif
return
1
;
break
;
default:
return
-
EINVAL
;
break
;
default:
return
-
EINVAL
;
}
return
-
EINVAL
;
}
static
ssize_t
mbuf_sysfs_status
(
struct
kobject
*
kobj
,
struct
kobj_attribute
*
attr
,
char
*
buf
)
{
size_t
remaining
=
PAGE_SIZE
;
size_t
count
=
0
;
size_t
tmp
=
0
;
char
*
cur
=
buf
;
int
i
=
0
;
spin_lock
(
&
lock
);
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
kmalloc_area
[
i
]
==
0
)
continue
;
tmp
=
snprintf
(
cur
,
remaining
,
"%s: %d %d
\n
"
,
mtag
[
i
],
kmalloc_area_size
[
i
],
usage_cnt
[
i
]);
if
(
tmp
>
remaining
)
break
;
cur
+=
tmp
;
remaining
-=
tmp
;
count
+=
tmp
;
}
spin_unlock
(
&
lock
);
return
count
;
size_t
remaining
=
PAGE_SIZE
;
size_t
count
=
0
;
size_t
tmp
=
0
;
char
*
cur
=
buf
;
int
i
=
0
;
spin_lock
(
&
lock
);
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
if
(
kmalloc_area
[
i
]
==
0
)
continue
;
tmp
=
snprintf
(
cur
,
remaining
,
"%s: %d %d
\n
"
,
mtag
[
i
],
kmalloc_area_size
[
i
],
usage_cnt
[
i
]);
if
(
tmp
>
remaining
)
break
;
cur
+=
tmp
;
remaining
-=
tmp
;
count
+=
tmp
;
}
spin_unlock
(
&
lock
);
return
count
;
}
static
ssize_t
mbuf_sysfs_verbosity_store
(
struct
kobject
*
kobj
,
struct
kobj_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
...
...
@@ -449,68 +444,68 @@ static struct kobj_attribute sysfs_mbuf_verbosity_attr = __ATTR(verbosity, 0644,
/* group attributes together for bulk operations */
static
struct
attribute
*
mbuf_fields
[]
=
{
&
sysfs_mbuf_status_attr
.
attr
,
&
sysfs_mbuf_verbosity_attr
.
attr
,
NULL
,
&
sysfs_mbuf_status_attr
.
attr
,
&
sysfs_mbuf_verbosity_attr
.
attr
,
NULL
,
};
static
struct
attribute_group
mbuf_attr_group
=
{
.
attrs
=
mbuf_fields
,
.
attrs
=
mbuf_fields
,
};
/* module initialization - called at module load time */
static
int
__init
mbuf_init
(
void
)
{
int
i
;
int
ret
=
-
EINVAL
;
int
i
;
int
ret
=
-
EINVAL
;
/* get the major number of the character device */
if
((
ret
=
alloc_chrdev_region
(
&
mbuf_dev
,
0
,
1
,
"mbuf"
))
<
0
)
{
printk
(
KERN_ERR
"could not allocate major number for mbuf
\n
"
);
goto
out
;
}
/* get the major number of the character device */
if
((
ret
=
alloc_chrdev_region
(
&
mbuf_dev
,
0
,
1
,
"mbuf"
))
<
0
)
{
printk
(
KERN_ERR
"could not allocate major number for mbuf
\n
"
);
goto
out
;
}
if
(
IS_ERR
(
mbuf_class
=
class_create
(
THIS_MODULE
,
"ligo_mbuf"
)))
{
printk
(
KERN_ERR
"could not allocate device class for mbuf
\n
"
);
goto
out_unalloc_region
;
};
if
(
IS_ERR
(
mbuf_class
=
class_create
(
THIS_MODULE
,
"ligo_mbuf"
)))
{
printk
(
KERN_ERR
"could not allocate device class for mbuf
\n
"
);
goto
out_unalloc_region
;
};
if
(
IS_ERR
(
mbuf_device
=
device_create
(
mbuf_class
,
NULL
,
mbuf_dev
,
NULL
,
"mbuf"
)))
{
printk
(
KERN_ERR
"could not create device file for mbuf
\n
"
);
goto
out_cleanup_class
;
}
if
(
IS_ERR
(
mbuf_device
=
device_create
(
mbuf_class
,
NULL
,
mbuf_dev
,
NULL
,
"mbuf"
)))
{
printk
(
KERN_ERR
"could not create device file for mbuf
\n
"
);
goto
out_cleanup_class
;
}
/* initialize the device structure and register the device with the kernel */
cdev_init
(
&
mbuf_cdev
,
&
mbuf_fops
);
if
((
ret
=
cdev_add
(
&
mbuf_cdev
,
mbuf_dev
,
1
))
<
0
)
{
printk
(
KERN_ERR
"could not allocate chrdev for buf
\n
"
);
goto
out_cleanup_device
;
}
/* initialize the device structure and register the device with the kernel */
cdev_init
(
&
mbuf_cdev
,
&
mbuf_fops
);
if
((
ret
=
cdev_add
(
&
mbuf_cdev
,
mbuf_dev
,
1
))
<
0
)
{
printk
(
KERN_ERR
"could not allocate chrdev for buf
\n
"
);
goto
out_cleanup_device
;
}
mbuf_sysfs_dir
=
kobject_create_and_add
(
"mbuf"
,
kernel_kobj
);
if
(
mbuf_sysfs_dir
==
NULL
)
{
printk
(
KERN_ERR
"Could not create /sys/kernel/mbuf directory!
\n
"
);
goto
out_unalloc_region
;
}
mbuf_sysfs_dir
=
kobject_create_and_add
(
"mbuf"
,
kernel_kobj
);
if
(
mbuf_sysfs_dir
==
NULL
)
{
printk
(
KERN_ERR
"Could not create /sys/kernel/mbuf directory!
\n
"
);
goto
out_unalloc_region
;
}
if
(
sysfs_create_group
(
mbuf_sysfs_dir
,
&
mbuf_attr_group
)
!=
0
)
{
printk
(
KERN_ERR
"Could not create /sys/kernel/mbuf/... fields!
\n
"
);
goto
out_remove_sysfs
;
}
// Init local data structs
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
kmalloc_area
[
i
]
=
0
;
mtag
[
i
][
0
]
=
0
;
usage_cnt
[
i
]
=
0
;
}
ret
=
0
;
return
ret
;
if
(
sysfs_create_group
(
mbuf_sysfs_dir
,
&
mbuf_attr_group
)
!=
0
)
{
printk
(
KERN_ERR
"Could not create /sys/kernel/mbuf/... fields!
\n
"
);
goto
out_remove_sysfs
;
}
// Init local data structs
for
(
i
=
0
;
i
<
MAX_AREAS
;
i
++
)
{
kmalloc_area
[
i
]
=
0
;
mtag
[
i
][
0
]
=
0
;
usage_cnt
[
i
]
=
0
;
}
ret
=
0
;
return
ret
;
out_remove_sysfs:
kobject_del
(
mbuf_sysfs_dir
);
kobject_del
(
mbuf_sysfs_dir
);
out_cleanup_device:
device_destroy
(
mbuf_class
,
mbuf_dev
);
out_cleanup_class:
...
...
@@ -529,9 +524,9 @@ static void __exit mbuf_exit(void)
/* remove the character deivce */
cdev_del
(
&
mbuf_cdev
);
unregister_chrdev_region
(
mbuf_dev
,
1
);
if
(
mbuf_sysfs_dir
!=
NULL
)
{
kobject_del
(
mbuf_sysfs_dir
);
}
if
(
mbuf_sysfs_dir
!=
NULL
)
{
kobject_del
(
mbuf_sysfs_dir
);
}
}
module_init
(
mbuf_init
);
...
...
This diff is collapsed.
Click to expand it.
src/drv/mbuf/mbuf_kernel.h
+
63
−
6
View file @
ddca2818
#ifndef LIGO_MBUF_KERNEL_H
#define LIGO_MBUF_KERNEL_H
/
//
@brief This header is for the kernel module to mbuf, kernel
//
space interface. Mbuf exports the below symbols.
/
/
/
**
@brief This header is for the kernel module to mbuf, kernel
*
space interface. Mbuf exports the below symbols.
*
/
/
/
Used by the IOP to store Dolphin memory state
/
**
Used by the IOP to store Dolphin memory state
*/
extern
int
iop_rfm_valid
;
void
*
mbuf_allocate_area
(
char
*
name
,
int
size
,
struct
file
*
file
);
int
mbuf_release_area
(
char
*
name
,
struct
file
*
file
);
/** @brief This enum defines all possible error codes that can be
* returned by the kernel interface. You can use mbuf_lookup_error_msg()
* to retrieve a string version of the error code.
*/
enum
MBUF_KERNEL_CODE
{
MBUF_KERNEL_CODE_OK
=
0
,
MBUF_KERNEL_CODE_NO_BUFFERS
=
1
,
MBUF_KERNEL_CODE_ALLOC_FAILED
=
2
,
MBUF_KERNEL_CODE_SZ_ERROR
=
3
,
MBUF_KERNEL_CODE_NAME_NOT_FOUND
=
4
,
MBUF_KERNEL_CODE_LAST
};
/** A buffer of MBUF_ERROR_MSG_ALLOC_LEN must be passed as the second argument to mbuf_lookup_error_msg(...) */
#define MBUF_ERROR_MSG_MAX_LEN 128
#define MBUF_ERROR_MSG_ALLOC_LEN (MBUF_ERROR_MSG_MAX_LEN+1)
/** @brief Requests that a shared memory buffer be allocated with the name requested.
* If a buffer already exists with the requested name, then a pointer to that
* buffer is returned. If the buffer does not exist, it is allocated and
* a pointer to it returned.
*
* @param name The name of the shared memory buffer to create/lookup
*
* @param size The size (in bytes) of the buffer to create/lookup
*
* @param buffer_ptr The address of a pointer where the shared buffer's address
* should be written
*
* @return MBUF_KERNEL_CODE_OK : no errors were encountered
* MBUF_KERNEL_CODE_NO_BUFFERS : mbuf is out of shared buffer spaces and cannot you a new one
* MBUF_KERNEL_CODE_ALLOC_FAILED : The system call to allocate memory failed, check the size you
* are requesting, or the system might be out of memory
* MBUF_KERNEL_CODE_SZ_ERROR : Returned if the size used to lookup a buffer does not match
* the size used in the first allocation for the buffer of that name
*/
enum
MBUF_KERNEL_CODE
mbuf_allocate_area
(
const
char
*
name
,
const
int
size
,
volatile
void
**
buffer_ptr
);
/** @brief Releases the callers used of the shared memory. When all users of a shared buffer
* have released it, this function will free the memory on the last release.
*
* @param name The name of the shared memory buffer to release
*
* @return MBUF_KERNEL_CODE_OK : no errors were encountered
* MBUF_KERNEL_CODE_NAME_NOT_FOUND : A shared buffer with the given name was not found
*/
enum
MBUF_KERNEL_CODE
mbuf_release_area
(
const
char
*
name
);
/** @brief Allows callers to lookup error messages from their returned error codes
* Useful for error messages
*
* @param code The error code that should be looked up
*
* @param error_msg A buffer for the retrieved error code to be written. Should have at
* least MBUF_ERROR_MSG_ALLOC_LEN bytes allocated for it
*
* @return Void.
*/
void
mbuf_lookup_error_msg
(
const
enum
MBUF_KERNEL_CODE
code
,
char
*
error_msg
);
#endif // LIGO_MBUF_KERNEL_H
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment