rsrcdbmgr_attach()
Reserve a system resource for a process
Synopsis:
#include <sys/rsrcdbmgr.h> #include <sys/rsrcdbmsg.h> int rsrcdbmgr_attach( rsrc_request_t * list, int count );
Arguments:
- list
- An array of rsrc_request_t structures that describe the resources that you want to reserve; see below.
- count
- The number of entries in the array.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The resource database manager allocates and keeps track of system resources i.e. it manages these resources. The system resources currently tracked are:
- memory
- IRQs
- DMA channels
- I/O ports
- PCI memory
You can also track and access arbitrarily defined resources by using a string name as an identifier.
Major and minor device numbers are handled with separate rsrcdbmgr_devno_attach() and rsrcdbmgr_devno_detach() functions.
There are two main functions that drivers can use to communicate with the resource database:
- rsrcdbmgr_attach()
- rsrcdbmgr_detach()
The rsrcdbmgr_attach() function reserves a resource range(s) from the database of available resources for a process. Other processes can't reserve this resource range until the resource is returned to the system (usually with the rsrcdbmgr_detach() call). The requested resources are returned in a list of rsrc_request_t structures with the start and end fields filled in. The number of resources requested is specified in count.
- In order to successfully use the rsrcdbmgr_attach and rsrcdbmgr_detach() functions, your process must have the PROCMGR_AID_RSRCDBMGR ability enabled. For more information, see procmgr_ability() .
- Reserving the resources doesn't give you access to them; you still have to use mmap() , InterruptAttach() , or another means.
When you're finished with the resource, you must return it to the system. The easiest way to return the resource is to call rsrcdbmgr_detach() with the same start, end, and type (via the flags field) that were issued for the resource.
rsrc_request_t structure
The resource requests structure looks like this:
typedef struct _rsrc_request { uint64_t length; uint64_t align; uint64_t start; uint64_t end; uint32_t flags; uint32_t zero[2]; const char *name; } rsrc_request_t;
The members include:
- length
- The length of the resource that you want to reserve. You must set this member.
- align
- The alignment of the resource.
- start, end
- The range of resource that you want to reserve.
- flags
- The type of the resource, as well as flags that affect the request.
You must either set this member to be one of the following resource types
(defined in <sys/rsrcdbmgr.h>), or set it to
RSRCDBMGR_FLAG_NAME and fill in the name field:
- RSRCDBMGR_DMA_CHANNEL — DMA channel
- RSRCDBMGR_IO_PORT — I/O port address
- RSRCDBMGR_IRQ — Interrupt address
- RSRCDBMGR_MEMORY — Memory address
- RSRCDBMGR_PCI_MEMORY — PCI memory address
You can OR in the following flags (also defined in <sys/rsrcdbmgr.h>):
- RSRCDBMGR_FLAG_ALIGN — the contents of the align field are valid, and the requested resource starts with the given alignment.
- RSRCDBMGR_FLAG_LIST — this is one item in a list to search.
- RSRCDBMGR_FLAG_NAME — the name field is valid, and is a system name.
- RSRCDBMGR_FLAG_RANGE — the contents of the start and end fields are valid, and the requested resource is in the range start to end, inclusive.
- RSRCDBMGR_FLAG_SHARE — other processes can have access to an allocated resource.
- RSRCDBMGR_FLAG_TOPDOWN — start the search for a free resource block from end. If you also set RSRCDBMGR_FLAG_RANGE, this flag makes the search start from the end of the available range.
- name
- A pointer to the name of the resource class (NULL by
default).
This field is used only if you set RSRCDBMGR_FLAG_NAME
in the flags field.
The name must not start with a leading slash (/) and should be
in the form:
type[/ subtype[/ subsubtype]].
The numeric constants map to the string-based resource names as follows:
Flag Name RSRCDBMGR_MEMORY memory RSRCDBMGR_IRQ irq RSRCDBMGR_IO_PORT io RSRCDBMGR_DMA_CHANNEL dma RSRCDBMGR_PCI_MEMORY pcimemory For example, normal I/O Ports (RSRCDBMGR_IO_PORT) are mapped to the string io. If you had a special class of io ports, you could access it with the name io/myspecialio. The subtype components are specific instances of the hierarchy, and as such, requests that are made higher up (e.g. a request for io) attempt to give out resources that aren't part of these specific instances.
Returns:
EOK, or -1 if an error occurred (errno is set).
Errors:
- EAGAIN
- The resource request can't be filled.
- EINVAL
- Invalid argument.
- ENOMEM
- Insufficient memory to allocate internal data structures.
- EPERM
- The calling process doesn't have the required permission; see procmgr_ability() .
Examples:
Example 1
/* * Request one DMA Channel, with length 1, from the * entire range of available DMA channel resources. */ #include <stdio.h> #include <sys/rsrcdbmgr.h> #include <sys/rsrcdbmsg.h> int main(int argc, char **argv) { int count; rsrc_request_t req; memset(&req, 0, sizeof(req)); req.length = 1; req.flags = RSRCDBMGR_DMA_CHANNEL; count = 1; if (rsrcdbmgr_attach( &req, count) == -1) { perror("Problem attaching to resource "); exit(1); } printf("You can use DMA channel 0x%llx \n", req.start); … /* Do something with the acquired resource */ … /* To return the resource to the database: */ if (rsrcdbmgr_detach( &req, count) == -1) { perror("Problem detaching resource \n"); exit(1); } return(0); }
Example 2
/* * Request memory that's 4-byte aligned * and has a length of 50. */ #include <stdio.h> #include <sys/rsrcdbmgr.h> #include <sys/rsrcdbmsg.h> int main(int argc, char **argv) { int count; rsrc_request_t req; memset(&req, 0, sizeof(req)); req.align = 4; req.length = 50; req.flags = RSRCDBMGR_FLAG_ALIGN | RSRCDBMGR_MEMORY; count = 1; if (rsrcdbmgr_attach(&req, count) == -1) { perror("Problem attaching to resource "); exit(1); } printf("You can use memory from 0x%llx 0x%llx inclusive. \n", req.start, req.end ); … /* Do something with the acquired resource */ … /* To return the resource to the database: */ if (rsrcdbmgr_detach( &req, count) == -1) { perror("Problem detaching resource \n"); exit(1); } return(0); }
Example 3
/* * Request two resources: * I/O port 0 and an IRQ in the range 10-12 * from the available resources. */ #include <stdio.h> #include <sys/rsrcdbmgr.h> #include <sys/rsrcdbmsg.h> int main(int argc, char **argv) { int count; rsrc_request_t req[2]; memset(req, 0, 2*sizeof(*req)); req[0].start = 0; req[0].end = 0; req[0].length = 1; req[0].flags = RSRCDBMGR_FLAG_RANGE | RSRCDBMGR_IO_PORT; req[1].start = 10; req[1].end = 12; req[1].length = 1; req[1].flags = RSRCDBMGR_FLAG_RANGE | RSRCDBMGR_IRQ; count = 2; if (rsrcdbmgr_attach(req, count) == -1) { perror("Problem attaching to resource "); exit(1); } printf("You can use io-port 0x%llx \n", req[0].start); printf("You can use irq 0x%llx \n", req[1].start); … /* Do something with the acquired resource */ … /* To return the resource to the database: */ if (rsrcdbmgr_detach(req, count) == -1) { perror("Problem detaching resource \n"); exit(1); } return(0); }
Example 4
This example uses names instead of the constants for the resource type:
rsrc_alloc_t alloc; rsrc_request_t ralloc; //Create a new resource memset(&alloc, 0, sizeof(alloc)); alloc.start = 0x20000000; alloc.end = 0x27ffffff; alloc.flags = RSRCDBMGR_FLAG_NAME; alloc.name = "io/Port_S0"; printf("Allocing %p %p %p \n", &alloc, &alloc.name, alloc.name); if (rsrcdbmgr_create (&alloc, 1) == -1) { perror("create() 1 failed \n"); return 1; } // Attach to the new resource, any range with 32 length memset( &ralloc, 0, sizeof(ralloc)); ralloc.start = ralloc.end = 0; ralloc.length = 32; ralloc.flags = RSRCDBMGR_FLAG_NAME; ralloc.name = "io/Port_S0"; if (rsrcdbmgr_attach (&ralloc, 1) == -1) { perror("attach() 2 failed \n");; return 1; } // Do something with the resource
Classification:
Safety: | |
---|---|
Cancellation point | Yes |
Interrupt handler | No |
Signal handler | Yes |
Thread | Yes |