freebsd compat. layer: split device structure to handle for miibus devices, added a new network_device.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21094 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-05-09 19:35:38 +00:00
parent a300c4e4e1
commit b650951128
6 changed files with 150 additions and 90 deletions

View File

@ -36,8 +36,9 @@ pci_module_info *gPci;
uint32_t
pci_read_config(device_t dev, int offset, int size)
{
uint32_t value = gPci->read_pci_config(dev->pci_info.bus,
dev->pci_info.device, dev->pci_info.function, offset, size);
uint32_t value = gPci->read_pci_config(NETDEV(dev)->pci_info.bus,
NETDEV(dev)->pci_info.device, NETDEV(dev)->pci_info.function,
offset, size);
TRACE_PCI(dev, "pci_read_config(%i, %i) = 0x%lx\n", offset, size, value);
return value;
}
@ -48,8 +49,9 @@ pci_write_config(device_t dev, int offset, uint32_t value, int size)
{
TRACE_PCI(dev, "pci_write_config(%i, 0x%lx, %i)\n", offset, value, size);
gPci->write_pci_config(dev->pci_info.bus, dev->pci_info.device,
dev->pci_info.function, offset, size, value);
gPci->write_pci_config(NETDEV(dev)->pci_info.bus,
NETDEV(dev)->pci_info.device, NETDEV(dev)->pci_info.function,
offset, size, value);
}
@ -164,14 +166,10 @@ driver_vprintf(const char *format, va_list vl)
int
device_printf(device_t dev, const char *format, ...)
{
char devDesc[32];
va_list vl;
snprintf(devDesc, sizeof(devDesc), "%i:%i:%i", (int)dev->pci_info.bus,
(int)dev->pci_info.device, (int)dev->pci_info.function);
va_start(vl, format);
driver_vprintf_etc(devDesc, format, vl);
driver_vprintf_etc(dev->dev_name, format, vl);
va_end(vl);
return 0;
}
@ -192,6 +190,23 @@ device_set_desc_copy(device_t dev, const char *desc)
}
const char *
device_get_desc(device_t dev)
{
return dev->description;
}
void
device_sprintf_name(device_t dev, const char *format, ...)
{
va_list vl;
va_start(vl, format);
vsnprintf(dev->dev_name, sizeof(dev->dev_name), format, vl);
va_end(vl);
}
const char *
device_get_name(device_t dev)
{

View File

@ -93,6 +93,7 @@ void *device_get_softc(device_t dev);
int device_printf(device_t dev, const char *, ...) __printflike(2, 3);
void device_set_desc(device_t dev, const char *desc);
void device_set_desc_copy(device_t dev, const char *desc);
const char *device_get_desc(device_t dev);
device_t device_add_child(device_t dev, const char *name, int unit);
int device_delete_child(device_t dev, device_t child);

View File

@ -52,32 +52,41 @@ status_t _fbsd_init_driver(driver_t *);
void _fbsd_uninit_driver(driver_t *);
extern const char gDriverName[];
driver_t *__haiku_get_miibus_driver(void);
/* we define the driver methods with HAIKU_FBSD_DRIVER_GLUE to
* force the rest of the stuff to be linked back with the driver.
* While gcc 2.95 packs everything from the static library onto
* the final binary, gcc 4.x rightfuly doesn't. */
#define HAIKU_FBSD_DRIVER_GLUE(publicname, name, busname) \
extern char *gDevNameList[]; \
extern device_hooks gDeviceHooks; \
extern driver_t *DRIVER_MODULE_NAME(name, busname); \
const char gDriverName[] = #publicname; \
int32 api_version = B_CUR_DRIVER_API_VERSION; \
status_t init_hardware() \
{ \
return _fbsd_init_hardware(DRIVER_MODULE_NAME(name, busname)); \
} \
status_t init_driver() \
{ \
return _fbsd_init_driver(DRIVER_MODULE_NAME(name, busname)); \
} \
void uninit_driver() \
{ \
_fbsd_uninit_driver(DRIVER_MODULE_NAME(name, busname)); \
} \
const char **publish_devices() { return (const char **)gDevNameList; } \
device_hooks *find_device(const char *name) { return &gDeviceHooks; }
#define HAIKU_FBSD_DRIVER_GLUE(publicname, name, busname) \
extern const char *gDevNameList[]; \
extern device_hooks gDeviceHooks; \
extern driver_t *DRIVER_MODULE_NAME(name, busname); \
const char gDriverName[] = #publicname; \
int32 api_version = B_CUR_DRIVER_API_VERSION; \
status_t init_hardware() \
{ \
return _fbsd_init_hardware(DRIVER_MODULE_NAME(name, busname)); \
} \
status_t init_driver() \
{ \
return _fbsd_init_driver(DRIVER_MODULE_NAME(name, busname)); \
} \
void uninit_driver() \
{ _fbsd_uninit_driver(DRIVER_MODULE_NAME(name, busname)); } \
const char **publish_devices() \
{ return gDevNameList; } \
device_hooks *find_device(const char *name) \
{ return &gDeviceHooks; }
#define HAIKU_FBSD_MII_DRIVER(name) \
driver_t *__haiku_get_miibus_driver(device_t dev) \
{ return DRIVER_MODULE_NAME(name, miibus); }
#define HAIKU_NO_FBSD_MII_DRIVER() \
driver_t *__haiku_get_miibus_driver(device_t dev) \
{ return NULL; }
extern spinlock __haiku_intr_spinlock;
extern int __haiku_disable_interrupts(device_t dev);

View File

@ -26,8 +26,8 @@
#define MAX_DEVICES 8
device_t gDevices[MAX_DEVICES];
char *gDevNameList[MAX_DEVICES + 1];
struct network_device *gDevices[MAX_DEVICES];
const char *gDevNameList[MAX_DEVICES + 1];
static device_probe_t *sDeviceProbe;
@ -36,28 +36,47 @@ static device_detach_t *sDeviceDetach;
static device_t
init_device(device_t dev, driver_t *driver)
{
dev->driver = driver;
dev->softc = malloc(driver->softc_size);
if (dev->softc == NULL)
return NULL;
return dev;
}
static void
uninit_device(device_t dev)
{
if (dev->flags & DEVICE_DESC_ALLOCED)
free((char *)dev->description);
free(dev->softc);
}
static struct network_device *
allocate_device(driver_t *driver)
{
char semName[64];
device_t dev = (device_t)malloc(sizeof(struct device));
struct network_device *dev = malloc(sizeof(struct network_device));
if (dev == NULL)
return NULL;
memset(dev, 0, sizeof(struct device));
snprintf(semName, sizeof(semName), "%s rcv", gDriverName);
dev->softc_size = driver->softc_size;
dev->softc = malloc(driver->softc_size);
if (dev->softc == NULL) {
if (init_device(DEVNET(dev), driver) == NULL) {
free(dev);
return NULL;
}
snprintf(semName, sizeof(semName), "%s rcv", gDriverName);
dev->receive_sem = create_sem(0, semName);
if (dev->receive_sem < 0) {
free(dev->softc);
uninit_device(DEVNET(dev));
free(dev);
return NULL;
}
@ -71,13 +90,11 @@ allocate_device(driver_t *driver)
static void
free_device(device_t dev)
free_device(struct network_device *dev)
{
delete_sem(dev->receive_sem);
ifq_uninit(&dev->receive_queue);
free(dev->softc);
if (dev->flags & DEVICE_DESC_ALLOCED)
free((char *)dev->description);
uninit_device(DEVNET(dev));
free(dev);
}
@ -100,8 +117,8 @@ _resolve_method(driver_t *driver, const char *name)
static status_t
compat_open(const char *name, uint32 flags, void **cookie)
{
struct network_device *dev;
status_t status;
device_t dev;
int i;
driver_printf("compat_open(%s, 0x%lx)\n", name, flags);
@ -124,11 +141,11 @@ compat_open(const char *name, uint32 flags, void **cookie)
return B_BUSY;
/* some drivers expect the softc to be zero'ed out */
memset(dev->softc, 0, dev->softc_size);
memset(dev->base.softc, 0, dev->base.driver->softc_size);
status = sDeviceAttach(dev);
status = sDeviceAttach(DEVNET(dev));
if (status != 0)
dev->flags = 0;
atomic_and(&dev->open, 0);
driver_printf(" ... status = 0x%ld\n", status);
@ -155,11 +172,11 @@ compat_open(const char *name, uint32 flags, void **cookie)
static status_t
compat_close(void *cookie)
{
device_t dev = cookie;
struct network_device *dev = cookie;
device_printf(dev, "compat_close()\n");
device_printf(DEVNET(dev), "compat_close()\n");
atomic_or(&dev->flags, DEVICE_CLOSED);
atomic_or(&DEVNET(dev)->flags, DEVICE_CLOSED);
/* do we need a memory barrier in read() or is the atomic_or
* (and the implicit 'lock') enough? */
@ -173,11 +190,11 @@ compat_close(void *cookie)
static status_t
compat_free(void *cookie)
{
device_t dev = cookie;
struct network_device *dev = cookie;
device_printf(dev, "compat_free()\n");
device_printf(DEVNET(dev), "compat_free()\n");
sDeviceDetach(dev);
sDeviceDetach(DEVNET(dev));
/* XXX empty out the send queue */
@ -191,24 +208,24 @@ compat_free(void *cookie)
static status_t
compat_read(void *cookie, off_t position, void *buf, size_t *numBytes)
{
struct network_device *dev = cookie;
uint32 semFlags = B_CAN_INTERRUPT;
device_t dev = cookie;
status_t status;
struct mbuf *mb;
size_t len;
driver_printf("compat_read(%p, %lld, %p, [%lu])\n", cookie, position, buf,
device_printf(DEVNET(dev), "compat_read(%lld, %p, [%lu])\n", position, buf,
*numBytes);
if (dev->flags & DEVICE_CLOSED)
if (DEVNET(dev)->flags & DEVICE_CLOSED)
return B_INTERRUPTED;
if (dev->flags & DEVICE_NON_BLOCK)
if (DEVNET(dev)->flags & DEVICE_NON_BLOCK)
semFlags |= B_RELATIVE_TIMEOUT;
do {
status = acquire_sem_etc(dev->receive_sem, 1, semFlags, 0);
if (dev->flags & DEVICE_CLOSED)
if (DEVNET(dev)->flags & DEVICE_CLOSED)
return B_INTERRUPTED;
if (status == B_WOULD_BLOCK) {
@ -242,10 +259,10 @@ static status_t
compat_write(void *cookie, off_t position, const void *buffer,
size_t *numBytes)
{
device_t dev = cookie;
struct network_device *dev = cookie;
struct mbuf *mb;
driver_printf("compat_write(%p, %lld, %p, [%lu])\n", cookie, position,
device_printf(DEVNET(dev), "compat_write(%lld, %p, [%lu])\n", position,
buffer, *numBytes);
mb = m_getcl(0, MT_DATA, 0);
@ -264,7 +281,7 @@ compat_write(void *cookie, off_t position, const void *buffer,
static status_t
compat_control(void *cookie, uint32 op, void *arg, size_t len)
{
device_t dev = cookie;
struct network_device *dev = cookie;
struct ifnet *ifp = dev->ifp;
switch (op) {
@ -282,9 +299,9 @@ compat_control(void *cookie, uint32 op, void *arg, size_t len)
if (user_memcpy(&value, arg, sizeof(int32)) < B_OK)
return B_BAD_ADDRESS;
if (value)
dev->flags |= DEVICE_NON_BLOCK;
DEVNET(dev)->flags |= DEVICE_NON_BLOCK;
else
dev->flags &= ~DEVICE_NON_BLOCK;
DEVNET(dev)->flags &= ~DEVICE_NON_BLOCK;
return B_OK;
}
@ -378,7 +395,7 @@ device_hooks gDeviceHooks = {
status_t
_fbsd_init_hardware(driver_t *driver)
{
struct device fakeDevice;
struct network_device fakeDevice;
device_probe_t *probe;
int i;
@ -397,12 +414,12 @@ _fbsd_init_hardware(driver_t *driver)
for (i = 0; gPci->get_nth_pci_info(i, &fakeDevice.pci_info) == B_OK; i++) {
int result;
result = probe(&fakeDevice);
result = probe(DEVNET(&fakeDevice));
if (result >= 0) {
dprintf("%s, found %s at %d\n", gDriverName,
fakeDevice.description, i);
if (fakeDevice.flags & DEVICE_DESC_ALLOCED)
free((char *)fakeDevice.description);
device_get_desc(DEVNET(&fakeDevice)), i);
if (DEVNET(&fakeDevice)->flags & DEVICE_DESC_ALLOCED)
free((char *)DEVNET(&fakeDevice)->description);
put_module(B_PCI_MODULE_NAME);
return B_OK;
}
@ -420,7 +437,7 @@ _fbsd_init_driver(driver_t *driver)
{
int i, ncards = 0;
status_t status;
device_t dev;
struct network_device *dev;
dprintf("%s: init_driver(%p)\n", gDriverName, driver);
@ -460,14 +477,15 @@ _fbsd_init_driver(driver_t *driver)
for (i = 0; dev != NULL
&& gPci->get_nth_pci_info(i, &dev->pci_info) == B_OK; i++) {
if (sDeviceProbe(dev) >= 0) {
snprintf(dev->dev_name, sizeof(dev->dev_name), "net/%s/%i",
gDriverName, ncards);
dprintf("%s, adding %s @%d -> /dev/%s\n", gDriverName, dev->description,
i, dev->dev_name);
device_t base = DEVNET(dev);
if (sDeviceProbe(base) >= 0) {
device_sprintf_name(base, "net/%s/%i", gDriverName, ncards);
dprintf("%s, adding %s @%d -> /dev/%s\n", gDriverName,
device_get_desc(base), i, device_get_name(base));
gDevices[ncards] = dev;
gDevNameList[ncards] = dev->dev_name;
gDevNameList[ncards] = device_get_name(base);
ncards++;
if (ncards < MAX_DEVICES)

View File

@ -25,27 +25,39 @@
struct ifnet;
struct device {
pci_info pci_info;
char dev_name[128];
int32 open;
driver_t *driver;
int32 flags;
int unit;
char nameunit[64];
const char * description;
void * softc;
};
struct network_device {
struct device base;
pci_info pci_info;
int32 open;
struct ifqueue receive_queue;
sem_id receive_sem;
sem_id link_state_sem;
struct ifnet * ifp;
int unit;
char nameunit[64];
const char * description;
void * softc;
size_t softc_size;
};
#define DEVNET(dev) ((device_t)(&(dev)->base))
#define NETDEV(base) ((struct network_device *)(base))
enum {
DEVICE_OPEN = 1 << 0,
DEVICE_CLOSED = 1 << 1,
@ -80,16 +92,20 @@ void uninit_taskqueues(void);
void init_bounce_pages(void);
void uninit_bounce_pages(void);
void driver_printf(const char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
void driver_printf(const char *format, ...)
__attribute__ ((format (__printf__, 1, 2)));
void driver_vprintf(const char *format, va_list vl);
void device_sprintf_name(device_t dev, const char *format, ...)
__attribute__ ((format (__printf__, 2, 3)));
void ifq_init(struct ifqueue *ifq, const char *name);
void ifq_uninit(struct ifqueue *ifq);
extern struct net_stack_module_info *gStack;
extern pci_module_info *gPci;
extern char *gDevNameList[];
extern struct device *gDevices[];
extern const char *gDevNameList[];
extern struct network_device *gDevices[];
#endif

View File

@ -67,8 +67,8 @@ if_initname(struct ifnet *ifp, const char *name, int unit)
if (gDevNameList[i] == NULL)
panic("unknown interface");
ifp->if_dev = gDevices[i];
ifp->if_dev->ifp = ifp;
ifp->if_dev = DEVNET(gDevices[i]);
gDevices[i]->ifp = ifp;
}
@ -146,7 +146,8 @@ if_link_state_change(struct ifnet *ifp, int link_state)
ifp->if_link_state = link_state;
release_sem_etc(ifp->if_dev->link_state_sem, 1, B_DO_NOT_RESCHEDULE);
release_sem_etc(NETDEV(ifp->if_dev)->link_state_sem, 1,
B_DO_NOT_RESCHEDULE);
}
@ -269,8 +270,8 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
{
device_t dev = ifp->if_dev;
IF_ENQUEUE(&dev->receive_queue, m);
release_sem_etc(dev->receive_sem, 1, B_DO_NOT_RESCHEDULE);
IF_ENQUEUE(&NETDEV(dev)->receive_queue, m);
release_sem_etc(NETDEV(dev)->receive_sem, 1, B_DO_NOT_RESCHEDULE);
}