stand/ofw: Subclass devnet to cope with ofw's unique needs
We need to match devices in a slightly special way: We have to look up the path and see if the device is a 'network' device in order to use it. Sponsored by: Netflix Tested by: grehan@ (with tweaks to my original patch) Differential Revision: https://reviews.freebsd.org/D37557
This commit is contained in:
parent
ed3cc2f248
commit
b8ff248f65
@ -48,6 +48,7 @@ extern int ofw_getdev(void **vdev, const char *devspec, const char **path);
|
|||||||
extern ev_sethook_t ofw_setcurrdev;
|
extern ev_sethook_t ofw_setcurrdev;
|
||||||
|
|
||||||
extern struct devsw ofwdisk;
|
extern struct devsw ofwdisk;
|
||||||
|
extern struct devsw ofw_netdev;
|
||||||
extern struct netif_driver ofwnet;
|
extern struct netif_driver ofwnet;
|
||||||
|
|
||||||
int ofwn_getunit(const char *);
|
int ofwn_getunit(const char *);
|
||||||
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <netif.h>
|
#include <netif.h>
|
||||||
|
|
||||||
|
#include "libofw.h"
|
||||||
#include "openfirm.h"
|
#include "openfirm.h"
|
||||||
|
|
||||||
static int ofwn_probe(struct netif *, void *);
|
static int ofwn_probe(struct netif *, void *);
|
||||||
@ -267,3 +268,77 @@ ofwn_getunit(const char *path)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To properly match network devices, we have to subclass the netdev device.
|
||||||
|
* It has a different devdesc than a normal network device (which is fine:
|
||||||
|
* it's a struct superset) and different matching criteria (since it has to
|
||||||
|
* look at the path, find a handle and see if that handle is a network node
|
||||||
|
* or not).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int ofwnd_init(void);
|
||||||
|
static int ofwnd_parsedev(struct devdesc **, const char *, const char **);
|
||||||
|
static bool ofwnd_match(struct devsw *, const char *);
|
||||||
|
static char *ofwnd_fmtdev(struct devdesc *);
|
||||||
|
|
||||||
|
struct devsw ofw_netdev = {
|
||||||
|
.dv_name = "network",
|
||||||
|
.dv_type = DEVT_NET,
|
||||||
|
.dv_init = ofwnd_init,
|
||||||
|
.dv_match = ofwnd_match,
|
||||||
|
.dv_fmtdev = ofwnd_fmtdev,
|
||||||
|
.dv_parsedev = ofwnd_parsedev,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ofwnd_init(void)
|
||||||
|
{
|
||||||
|
netdev.dv_init();
|
||||||
|
ofw_netdev.dv_strategy = netdev.dv_strategy;
|
||||||
|
ofw_netdev.dv_open = netdev.dv_open;
|
||||||
|
ofw_netdev.dv_close = netdev.dv_close;
|
||||||
|
ofw_netdev.dv_ioctl = netdev.dv_ioctl;
|
||||||
|
ofw_netdev.dv_print = netdev.dv_print;
|
||||||
|
ofw_netdev.dv_fmtdev = netdev.dv_fmtdev;
|
||||||
|
/* parsedev is unique to ofwnd */
|
||||||
|
/* match is unique to ofwnd */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ofwnd_parsedev(struct devdesc **dev, const char *devspec, const char **path)
|
||||||
|
{
|
||||||
|
const char *rem_path;
|
||||||
|
struct ofw_devdesc *idev;
|
||||||
|
|
||||||
|
if (ofw_path_to_handle(devspec, ofw_netdev.dv_name, &rem_path) == -1)
|
||||||
|
return (ENOENT);
|
||||||
|
idev = malloc(sizeof(struct ofw_devdesc));
|
||||||
|
if (idev == NULL) {
|
||||||
|
printf("ofw_parsedev: malloc failed\n");
|
||||||
|
return ENOMEM;
|
||||||
|
};
|
||||||
|
strlcpy(idev->d_path, devspec, min(rem_path - devspec + 1,
|
||||||
|
sizeof(idev->d_path)));
|
||||||
|
if (dev != NULL)
|
||||||
|
*dev = &idev->dd;
|
||||||
|
if (path != NULL)
|
||||||
|
*path = rem_path;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ofwnd_match(struct devsw *devsw, const char *devspec)
|
||||||
|
{
|
||||||
|
const char *path;
|
||||||
|
|
||||||
|
return (ofw_path_to_handle(devspec, devsw->dv_name, &path) != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ofwnd_fmtdev(struct devdesc *idev)
|
||||||
|
{
|
||||||
|
struct ofw_devdesc *dev = (struct ofw_devdesc *)idev;
|
||||||
|
|
||||||
|
return (dev->d_path);
|
||||||
|
}
|
||||||
|
@ -54,7 +54,7 @@ struct devsw *devsw[] = {
|
|||||||
&ofwdisk,
|
&ofwdisk,
|
||||||
#endif
|
#endif
|
||||||
#if defined(LOADER_NET_SUPPORT)
|
#if defined(LOADER_NET_SUPPORT)
|
||||||
&netdev,
|
&ofw_netdev,
|
||||||
#endif
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user