freebsd compat. layer: added open(), which calls into the driver's attach. when testing with PCNET, a interface is already presented to the stack, it is even able to obtain the MAC address from the device, but still more work to do.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21030 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -183,7 +183,7 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
|
||||
|
||||
intr->handler = handler;
|
||||
intr->arg = arg;
|
||||
intr->irq = (int)res;
|
||||
intr->irq = res->handle;
|
||||
|
||||
status = install_io_interrupt_handler(intr->irq, intr_wrapper, intr, 0);
|
||||
if (status < B_OK) {
|
||||
@@ -193,7 +193,7 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
|
||||
|
||||
*cookiep = intr;
|
||||
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ int
|
||||
pci_enable_io(device_t dev, int space)
|
||||
{
|
||||
/* adapted from FreeBSD's pci_enable_io_method */
|
||||
uint16_t command;
|
||||
int bit = 0;
|
||||
|
||||
switch (space) {
|
||||
@@ -144,10 +143,8 @@ device_set_desc(device_t dev, const char *desc)
|
||||
const char *
|
||||
device_get_name(device_t dev)
|
||||
{
|
||||
/*
|
||||
* if (dev != NULL && dev->devclass)
|
||||
* return devclass_get_name(dev->devclass);
|
||||
*/
|
||||
if (dev)
|
||||
return dev->dev_name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,8 @@ struct ifqueue {
|
||||
struct mtx ifq_mtx;
|
||||
};
|
||||
|
||||
struct device;
|
||||
|
||||
/*
|
||||
* Structure defining a network interface.
|
||||
*
|
||||
@@ -185,6 +187,7 @@ struct ifnet {
|
||||
|
||||
/* Haiku additions */
|
||||
struct sockaddr_dl if_lladdr;
|
||||
struct device *if_dev;
|
||||
};
|
||||
|
||||
typedef void if_init_f_t(void *);
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef struct device_method device_method_t;
|
||||
typedef struct {
|
||||
const char *name;
|
||||
device_method_t *methods;
|
||||
size_t size;
|
||||
size_t softc_size;
|
||||
} driver_t;
|
||||
|
||||
#define BUS_PROBE_LOW_PRIORITY 10
|
||||
|
||||
@@ -27,8 +27,13 @@ device_t gDevices[MAX_DEVICES];
|
||||
char *gDevNameList[MAX_DEVICES + 1];
|
||||
|
||||
|
||||
static device_probe_t *sDeviceProbe;
|
||||
static device_attach_t *sDeviceAttach;
|
||||
static device_detach_t *sDeviceDetach;
|
||||
|
||||
|
||||
static device_t
|
||||
allocate_device()
|
||||
allocate_device(driver_t *driver)
|
||||
{
|
||||
char semName[64];
|
||||
|
||||
@@ -40,8 +45,15 @@ allocate_device()
|
||||
|
||||
snprintf(semName, sizeof(semName), "%s rcv", gDriverName);
|
||||
|
||||
dev->softc = malloc(driver->softc_size);
|
||||
if (dev->softc == NULL) {
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev->receive_sem = create_sem(0, semName);
|
||||
if (dev->receive_sem < 0) {
|
||||
free(dev->softc);
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -54,15 +66,55 @@ static void
|
||||
free_device(device_t dev)
|
||||
{
|
||||
delete_sem(dev->receive_sem);
|
||||
free(dev->softc);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static device_method_signature_t
|
||||
_resolve_method(driver_t *driver, const char *name)
|
||||
{
|
||||
device_method_signature_t method = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; method == NULL && driver->methods[i].name != NULL; i++) {
|
||||
if (strcmp(driver->methods[i].name, name) == 0)
|
||||
method = driver->methods[i].method;
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
compat_open(const char *name, uint32 flags, void **cookie)
|
||||
{
|
||||
status_t status;
|
||||
device_t dev;
|
||||
int i;
|
||||
|
||||
dprintf("%s, compat_open(%s, 0x%lx)\n", gDriverName, name, flags);
|
||||
return B_ERROR;
|
||||
|
||||
for (i = 0; gDevNameList[i] != NULL; i++) {
|
||||
if (strcmp(gDevNameList[i], name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (gDevNameList[i] == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
dev = gDevices[i];
|
||||
|
||||
if (atomic_or(&dev->flags, DEVICE_OPEN) & DEVICE_OPEN)
|
||||
return B_BUSY;
|
||||
|
||||
status = sDeviceAttach(dev);
|
||||
if (status != 0)
|
||||
dev->flags = 0;
|
||||
|
||||
*cookie = dev;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,21 +262,6 @@ device_hooks gDeviceHooks = {
|
||||
};
|
||||
|
||||
|
||||
static device_method_signature_t
|
||||
_resolve_method(driver_t *driver, const char *name)
|
||||
{
|
||||
device_method_signature_t method = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; method == NULL && driver->methods[i].name != NULL; i++) {
|
||||
if (strcmp(driver->methods[i].name, name) == 0)
|
||||
method = driver->methods[i].method;
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_fbsd_init_hardware(driver_t *driver)
|
||||
{
|
||||
@@ -264,16 +301,17 @@ _fbsd_init_hardware(driver_t *driver)
|
||||
status_t
|
||||
_fbsd_init_driver(driver_t *driver)
|
||||
{
|
||||
device_probe_t *probe;
|
||||
int i, ncards = 0;
|
||||
status_t status;
|
||||
device_t dev;
|
||||
|
||||
dprintf("%s: init_driver(%p)\n", gDriverName, driver);
|
||||
|
||||
probe = (device_probe_t *)_resolve_method(driver, "device_probe");
|
||||
sDeviceProbe = (device_probe_t *)_resolve_method(driver, "device_probe");
|
||||
sDeviceAttach = (device_attach_t *)_resolve_method(driver, "device_attach");
|
||||
sDeviceDetach = (device_detach_t *)_resolve_method(driver, "device_detach");
|
||||
|
||||
dev = allocate_device();
|
||||
dev = allocate_device(driver);
|
||||
if (dev == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@@ -294,10 +332,10 @@ _fbsd_init_driver(driver_t *driver)
|
||||
|
||||
for (i = 0; dev != NULL
|
||||
&& gPci->get_nth_pci_info(i, &dev->pci_info) == B_OK; i++) {
|
||||
if (probe(dev) >= 0) {
|
||||
snprintf(dev->dev_name, sizeof(dev->dev_name), "/dev/net/%s/%i",
|
||||
if (sDeviceProbe(dev) >= 0) {
|
||||
snprintf(dev->dev_name, sizeof(dev->dev_name), "net/%s/%i",
|
||||
gDriverName, ncards);
|
||||
dprintf("%s, adding %s @%d -> %s\n", gDriverName, dev->description,
|
||||
dprintf("%s, adding %s @%d -> /dev/%s\n", gDriverName, dev->description,
|
||||
i, dev->dev_name);
|
||||
|
||||
gDevices[ncards] = dev;
|
||||
@@ -305,7 +343,7 @@ _fbsd_init_driver(driver_t *driver)
|
||||
|
||||
ncards++;
|
||||
if (ncards < MAX_DEVICES)
|
||||
dev = allocate_device();
|
||||
dev = allocate_device(driver);
|
||||
else
|
||||
dev = NULL;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,9 @@ struct device {
|
||||
|
||||
|
||||
enum {
|
||||
DEVICE_CLOSED = 1 << 0,
|
||||
DEVICE_NON_BLOCK = 1 << 1,
|
||||
DEVICE_OPEN = 1 << 0,
|
||||
DEVICE_CLOSED = 1 << 1,
|
||||
DEVICE_NON_BLOCK = 1 << 2,
|
||||
};
|
||||
|
||||
|
||||
@@ -60,4 +61,7 @@ void uninit_bounce_pages(void);
|
||||
extern struct net_stack_module_info *gStack;
|
||||
extern pci_module_info *gPci;
|
||||
|
||||
extern char *gDevNameList[];
|
||||
extern struct device *gDevices[];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,11 +47,28 @@ if_free(struct ifnet *ifp)
|
||||
void
|
||||
if_initname(struct ifnet *ifp, const char *name, int unit)
|
||||
{
|
||||
int i;
|
||||
|
||||
dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit);
|
||||
|
||||
if (name == NULL)
|
||||
panic("interface goes unamed");
|
||||
|
||||
ifp->if_dname = name;
|
||||
ifp->if_dunit = unit;
|
||||
|
||||
/* XXX use a more Haiku friendly name here? */
|
||||
snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", name, unit);
|
||||
strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
|
||||
|
||||
for (i = 0; gDevNameList[i] != NULL; i++) {
|
||||
if (strcmp(gDevNameList[i], name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (gDevNameList[i] == NULL)
|
||||
panic("unknown interface");
|
||||
|
||||
ifp->if_dev = gDevices[i];
|
||||
ifp->if_dev->ifp = ifp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user