Add new drmOpenWithType function (v4)

v2: Add drmGetMinorBase, and call drmOpenWithType in drmOpen
v3: Pass 'type' to drmOpenByBusid and drmOpenDevice in drmOpenByName
v4: Renumber node type definitions, and return -1 for unsupported type

Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v3)
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
main
Jammy Zhou 2015-02-11 12:40:51 +08:00 committed by Alex Deucher
parent dd89e1efd0
commit f1adc4b375
2 changed files with 63 additions and 16 deletions

View File

@ -85,10 +85,6 @@
#define DRM_MSG_VERBOSITY 3 #define DRM_MSG_VERBOSITY 3
#define DRM_NODE_CONTROL 0
#define DRM_NODE_PRIMARY 1
#define DRM_NODE_RENDER 2
#define memclear(s) memset(&s, 0, sizeof(s)) #define memclear(s) memset(&s, 0, sizeof(s))
static drmServerInfoPtr drm_server_info; static drmServerInfoPtr drm_server_info;
@ -495,11 +491,25 @@ int drmAvailable(void)
return retval; return retval;
} }
static int drmGetMinorBase(int type)
{
switch (type) {
case DRM_NODE_PRIMARY:
return 0;
case DRM_NODE_CONTROL:
return 64;
case DRM_NODE_RENDER:
return 128;
default:
return -1;
};
}
/** /**
* Open the device by bus ID. * Open the device by bus ID.
* *
* \param busid bus ID. * \param busid bus ID.
* \param type device node type.
* *
* \return a file descriptor on success, or a negative value on error. * \return a file descriptor on success, or a negative value on error.
* *
@ -509,16 +519,20 @@ int drmAvailable(void)
* *
* \sa drmOpenMinor() and drmGetBusid(). * \sa drmOpenMinor() and drmGetBusid().
*/ */
static int drmOpenByBusid(const char *busid) static int drmOpenByBusid(const char *busid, int type)
{ {
int i, pci_domain_ok = 1; int i, pci_domain_ok = 1;
int fd; int fd;
const char *buf; const char *buf;
drmSetVersion sv; drmSetVersion sv;
int base = drmGetMinorBase(type);
if (base < 0)
return -1;
drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid); drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
for (i = 0; i < DRM_MAX_MINOR; i++) { for (i = base; i < base + DRM_MAX_MINOR; i++) {
fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY); fd = drmOpenMinor(i, 1, type);
drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
if (fd >= 0) { if (fd >= 0) {
/* We need to try for 1.4 first for proper PCI domain support /* We need to try for 1.4 first for proper PCI domain support
@ -558,6 +572,7 @@ static int drmOpenByBusid(const char *busid)
* Open the device by name. * Open the device by name.
* *
* \param name driver name. * \param name driver name.
* \param type the device node type.
* *
* \return a file descriptor on success, or a negative value on error. * \return a file descriptor on success, or a negative value on error.
* *
@ -568,19 +583,23 @@ static int drmOpenByBusid(const char *busid)
* *
* \sa drmOpenMinor(), drmGetVersion() and drmGetBusid(). * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
*/ */
static int drmOpenByName(const char *name) static int drmOpenByName(const char *name, int type)
{ {
int i; int i;
int fd; int fd;
drmVersionPtr version; drmVersionPtr version;
char * id; char * id;
int base = drmGetMinorBase(type);
if (base < 0)
return -1;
/* /*
* Open the first minor number that matches the driver name and isn't * Open the first minor number that matches the driver name and isn't
* already in use. If it's in use it will have a busid assigned already. * already in use. If it's in use it will have a busid assigned already.
*/ */
for (i = 0; i < DRM_MAX_MINOR; i++) { for (i = base; i < base + DRM_MAX_MINOR; i++) {
if ((fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY)) >= 0) { if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
if ((version = drmGetVersion(fd))) { if ((version = drmGetVersion(fd))) {
if (!strcmp(version->name, name)) { if (!strcmp(version->name, name)) {
drmFreeVersion(version); drmFreeVersion(version);
@ -622,9 +641,9 @@ static int drmOpenByName(const char *name)
for (devstring = ++pt; *pt && *pt != ' '; ++pt) for (devstring = ++pt; *pt && *pt != ' '; ++pt)
; ;
if (*pt) { /* Found busid */ if (*pt) { /* Found busid */
return drmOpenByBusid(++pt); return drmOpenByBusid(++pt, type);
} else { /* No busid */ } else { /* No busid */
return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_PRIMARY); return drmOpenDevice(strtol(devstring, NULL, 0),i, type);
} }
} }
} }
@ -653,9 +672,30 @@ static int drmOpenByName(const char *name)
* otherwise. * otherwise.
*/ */
int drmOpen(const char *name, const char *busid) int drmOpen(const char *name, const char *busid)
{
return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
}
/**
* Open the DRM device with specified type.
*
* Looks up the specified name and bus ID, and opens the device found. The
* entry in /dev/dri is created if necessary and if called by root.
*
* \param name driver name. Not referenced if bus ID is supplied.
* \param busid bus ID. Zero if not known.
* \param type the device node type to open, PRIMARY, CONTROL or RENDER
*
* \return a file descriptor on success, or a negative value on error.
*
* \internal
* It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
* otherwise.
*/
int drmOpenWithType(const char *name, const char *busid, int type)
{ {
if (!drmAvailable() && name != NULL && drm_server_info) { if (!drmAvailable() && name != NULL && drm_server_info) {
/* try to load the kernel */ /* try to load the kernel module */
if (!drm_server_info->load_module(name)) { if (!drm_server_info->load_module(name)) {
drmMsg("[drm] failed to load kernel module \"%s\"\n", name); drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
return -1; return -1;
@ -663,13 +703,13 @@ int drmOpen(const char *name, const char *busid)
} }
if (busid) { if (busid) {
int fd = drmOpenByBusid(busid); int fd = drmOpenByBusid(busid, type);
if (fd >= 0) if (fd >= 0)
return fd; return fd;
} }
if (name) if (name)
return drmOpenByName(name); return drmOpenByName(name, type);
return -1; return -1;
} }

View File

@ -552,7 +552,14 @@ do { register unsigned int __old __asm("o0"); \
/* General user-level programmer's API: unprivileged */ /* General user-level programmer's API: unprivileged */
extern int drmAvailable(void); extern int drmAvailable(void);
extern int drmOpen(const char *name, const char *busid); extern int drmOpen(const char *name, const char *busid);
extern int drmOpenControl(int minor);
#define DRM_NODE_PRIMARY 0
#define DRM_NODE_CONTROL 1
#define DRM_NODE_RENDER 2
extern int drmOpenWithType(const char *name, const char *busid,
int type);
extern int drmOpenControl(int minor);
extern int drmOpenRender(int minor); extern int drmOpenRender(int minor);
extern int drmClose(int fd); extern int drmClose(int fd);
extern drmVersionPtr drmGetVersion(int fd); extern drmVersionPtr drmGetVersion(int fd);