freebsd compat. layer: use a thread for deferred interrupt handling. fixed a issue with bus_space_write_N. init the receive queue on device creation.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21041 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -8,9 +8,9 @@
|
|||||||
* Some of this code is based on previous work by Marcus Overhagen.
|
* Some of this code is based on previous work by Marcus Overhagen.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <malloc.h>
|
#include "device.h"
|
||||||
|
|
||||||
#include <drivers/PCI.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include <compat/dev/pci/pcivar.h>
|
#include <compat/dev/pci/pcivar.h>
|
||||||
#include <compat/machine/resource.h>
|
#include <compat/machine/resource.h>
|
||||||
@@ -34,9 +34,17 @@ struct internal_intr {
|
|||||||
driver_intr_t handler;
|
driver_intr_t handler;
|
||||||
void *arg;
|
void *arg;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
|
void *context;
|
||||||
|
|
||||||
|
thread_id thread;
|
||||||
|
sem_id sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int32 intr_wrapper(void *data);
|
||||||
|
|
||||||
|
|
||||||
static area_id
|
static area_id
|
||||||
map_mem(void **virtualAddr, void *_phy, size_t size, uint32 protection,
|
map_mem(void **virtualAddr, void *_phy, size_t size, uint32 protection,
|
||||||
const char *name)
|
const char *name)
|
||||||
@@ -111,6 +119,9 @@ bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,
|
|||||||
&& type != SYS_RES_IOPORT)
|
&& type != SYS_RES_IOPORT)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
device_printf(dev, "bus_alloc_resource(%i, [%i], 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
|
||||||
|
type, *rid, start, end, count, flags);
|
||||||
|
|
||||||
// maybe a local array of resources is enough
|
// maybe a local array of resources is enough
|
||||||
res = malloc(sizeof(struct resource));
|
res = malloc(sizeof(struct resource));
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
@@ -165,19 +176,66 @@ static int32
|
|||||||
intr_wrapper(void *data)
|
intr_wrapper(void *data)
|
||||||
{
|
{
|
||||||
struct internal_intr *intr = data;
|
struct internal_intr *intr = data;
|
||||||
intr->handler(intr->arg);
|
driver_printf("in interrupt handler.\n");
|
||||||
|
|
||||||
|
disable_io_interrupt_handler(intr->context, B_IN_INTERRUPT_CONTEXT);
|
||||||
|
release_sem_etc(intr->sem, 1, B_DO_NOT_RESCHEDULE);
|
||||||
|
|
||||||
|
return B_INVOKE_SCHEDULER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
intr_handler(void *data)
|
||||||
|
{
|
||||||
|
struct internal_intr *intr = data;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
enable_io_interrupt_handler(intr->context);
|
||||||
|
|
||||||
|
status = acquire_sem(intr->sem);
|
||||||
|
if (status < B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
driver_printf("in soft interrupt handler.\n");
|
||||||
|
|
||||||
|
intr->handler(intr->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
disable_io_interrupt_handler(intr->context, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_internal_intr(struct internal_intr *intr)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
delete_sem(intr->sem);
|
||||||
|
wait_for_thread(intr->thread, &status);
|
||||||
|
|
||||||
|
if (intr->context)
|
||||||
|
delete_io_interrupt_handler(intr->context);
|
||||||
|
|
||||||
|
free(intr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
bus_setup_intr(device_t dev, struct resource *res, int flags,
|
bus_setup_intr(device_t dev, struct resource *res, int flags,
|
||||||
driver_intr_t handler, void *arg, void **cookiep)
|
driver_intr_t handler, void *arg, void **cookiep)
|
||||||
{
|
{
|
||||||
|
/* TODO check MPSAFE etc */
|
||||||
|
|
||||||
struct internal_intr *intr = (struct internal_intr *)malloc(
|
struct internal_intr *intr = (struct internal_intr *)malloc(
|
||||||
sizeof(struct internal_intr));
|
sizeof(struct internal_intr));
|
||||||
|
char semName[64];
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
|
/* status_t status; */
|
||||||
|
|
||||||
if (intr == NULL)
|
if (intr == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -185,12 +243,34 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
|
|||||||
intr->arg = arg;
|
intr->arg = arg;
|
||||||
intr->irq = res->handle;
|
intr->irq = res->handle;
|
||||||
|
|
||||||
status = install_io_interrupt_handler(intr->irq, intr_wrapper, intr, 0);
|
snprintf(semName, sizeof(semName), "%s intr", dev->dev_name);
|
||||||
if (status < B_OK) {
|
|
||||||
|
intr->sem = create_sem(0, semName);
|
||||||
|
if (intr->sem < B_OK) {
|
||||||
free(intr);
|
free(intr);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(semName, sizeof(semName), "%s intr handler", dev->dev_name);
|
||||||
|
|
||||||
|
intr->thread = spawn_kernel_thread(intr_handler, semName,
|
||||||
|
B_REAL_TIME_DISPLAY_PRIORITY, intr);
|
||||||
|
if (intr->thread < B_OK) {
|
||||||
|
delete_sem(intr->sem);
|
||||||
|
free(intr);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
intr->context = NULL;
|
||||||
|
status = create_io_interrupt_handler(intr->irq, intr_wrapper, intr,
|
||||||
|
&intr->context);
|
||||||
|
if (status < B_OK) {
|
||||||
|
free_internal_intr(intr);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resume_thread(intr->thread);
|
||||||
|
|
||||||
*cookiep = intr;
|
*cookiep = intr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -201,8 +281,8 @@ int
|
|||||||
bus_teardown_intr(device_t dev, struct resource *res, void *arg)
|
bus_teardown_intr(device_t dev, struct resource *res, void *arg)
|
||||||
{
|
{
|
||||||
struct internal_intr *intr = arg;
|
struct internal_intr *intr = arg;
|
||||||
remove_io_interrupt_handler(intr->irq, intr_wrapper, intr);
|
/* remove_io_interrupt_handler(intr->irq, intr_wrapper, intr); */
|
||||||
free(intr);
|
free_internal_intr(intr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,3 +295,33 @@ bus_generic_detach(device_t dev)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define BUS_SPACE_READ(size, type, fun) \
|
||||||
|
type bus_space_read_##size(bus_space_tag_t tag, \
|
||||||
|
bus_space_handle_t handle, bus_size_t offset) \
|
||||||
|
{ \
|
||||||
|
type value; \
|
||||||
|
if (tag == I386_BUS_SPACE_IO) \
|
||||||
|
value = fun(handle + offset); \
|
||||||
|
else \
|
||||||
|
value = *(volatile type *)(handle + offset); \
|
||||||
|
return value; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BUS_SPACE_WRITE(size, type, fun) \
|
||||||
|
void bus_space_write_##size(bus_space_tag_t tag, \
|
||||||
|
bus_space_handle_t handle, bus_size_t offset, type value) \
|
||||||
|
{ \
|
||||||
|
if (tag == I386_BUS_SPACE_IO) \
|
||||||
|
fun(value, handle + offset); \
|
||||||
|
else \
|
||||||
|
*(volatile type *)(handle + offset) = value; \
|
||||||
|
}
|
||||||
|
|
||||||
|
BUS_SPACE_READ(1, uint8_t, in8)
|
||||||
|
BUS_SPACE_READ(2, uint16_t, in16)
|
||||||
|
BUS_SPACE_READ(4, uint32_t, in32)
|
||||||
|
|
||||||
|
BUS_SPACE_WRITE(1, uint8_t, out8)
|
||||||
|
BUS_SPACE_WRITE(2, uint16_t, out16)
|
||||||
|
BUS_SPACE_WRITE(4, uint32_t, out32)
|
||||||
|
|||||||
@@ -20,6 +20,14 @@
|
|||||||
|
|
||||||
// TODO a lot.
|
// TODO a lot.
|
||||||
|
|
||||||
|
#define DEBUG_PCI
|
||||||
|
|
||||||
|
#ifdef DEBUG_PCI
|
||||||
|
#define TRACE_PCI(dev, format, args...) device_printf(dev, format , ##args)
|
||||||
|
#else
|
||||||
|
#define TRACE_PCI(dev, format, args...) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
status_t init_compat_layer(void);
|
status_t init_compat_layer(void);
|
||||||
|
|
||||||
struct net_stack_module_info *gStack;
|
struct net_stack_module_info *gStack;
|
||||||
@@ -28,14 +36,18 @@ pci_module_info *gPci;
|
|||||||
uint32_t
|
uint32_t
|
||||||
pci_read_config(device_t dev, int offset, int size)
|
pci_read_config(device_t dev, int offset, int size)
|
||||||
{
|
{
|
||||||
return gPci->read_pci_config(dev->pci_info.bus, dev->pci_info.device,
|
uint32_t value = gPci->read_pci_config(dev->pci_info.bus,
|
||||||
dev->pci_info.function, offset, size);
|
dev->pci_info.device, dev->pci_info.function, offset, size);
|
||||||
|
TRACE_PCI(dev, "pci_read_config(%i, %i) = 0x%lx\n", offset, size, value);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pci_write_config(device_t dev, int offset, uint32_t value, int size)
|
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,
|
gPci->write_pci_config(dev->pci_info.bus, dev->pci_info.device,
|
||||||
dev->pci_info.function, offset, size, value);
|
dev->pci_info.function, offset, size, value);
|
||||||
}
|
}
|
||||||
@@ -119,16 +131,48 @@ pci_enable_io(device_t dev, int space)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
driver_printf(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, format);
|
||||||
|
driver_vprintf(format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
driver_vprintf_etc(const char *extra, const char *format, va_list vl)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
vsnprintf(buf, sizeof(buf), format, vl);
|
||||||
|
|
||||||
|
if (extra)
|
||||||
|
dprintf("[%s] (%s) %s", gDriverName, extra, buf);
|
||||||
|
else
|
||||||
|
dprintf("[%s] %s", gDriverName, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
driver_vprintf(const char *format, va_list vl)
|
||||||
|
{
|
||||||
|
driver_vprintf_etc(NULL, format, vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
device_printf(device_t dev, const char *format, ...)
|
device_printf(device_t dev, const char *format, ...)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char devDesc[32];
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, format);
|
|
||||||
vsnprintf(buf, sizeof(buf), format, vl);
|
|
||||||
va_end(vl);
|
|
||||||
|
|
||||||
dprintf("[%s...] %s", gDriverName, buf);
|
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);
|
||||||
|
va_end(vl);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,13 +224,11 @@ device_delete_child(device_t dev, device_t child)
|
|||||||
int
|
int
|
||||||
printf(const char *format, ...)
|
printf(const char *format, ...)
|
||||||
{
|
{
|
||||||
char buf[256];
|
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, format);
|
va_start(vl, format);
|
||||||
vsnprintf(buf, sizeof(buf), format, vl);
|
driver_vprintf(format, vl);
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
|
||||||
dprintf(buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#define IFF_DRV_RUNNING 0x10000
|
#define IFF_DRV_RUNNING 0x10000
|
||||||
#define IFF_DRV_OACTIVE 0x20000
|
#define IFF_DRV_OACTIVE 0x20000
|
||||||
#define IFF_LINK0 0x40000
|
#define IFF_LINK0 0x40000
|
||||||
|
#define IFF_DEBUG 0x80000
|
||||||
|
|
||||||
|
|
||||||
#define LINK_STATE_UNKNOWN 0
|
#define LINK_STATE_UNKNOWN 0
|
||||||
|
|||||||
@@ -24,67 +24,18 @@ typedef unsigned int bus_space_handle_t;
|
|||||||
#define BUS_SPACE_MAXSIZE_32BIT 0xffffffff
|
#define BUS_SPACE_MAXSIZE_32BIT 0xffffffff
|
||||||
#define BUS_SPACE_MAXSIZE 0xffffffff
|
#define BUS_SPACE_MAXSIZE 0xffffffff
|
||||||
|
|
||||||
static inline uint8_t
|
uint8_t bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||||
bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
|
bus_size_t offset);
|
||||||
bus_size_t offset)
|
void bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||||
{
|
bus_size_t offset, uint8_t value);
|
||||||
if (tag == I386_BUS_SPACE_IO)
|
uint16_t bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||||
return in8(handle + offset);
|
bus_size_t offset);
|
||||||
return *(volatile uint8_t *)(handle + offset);
|
void bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||||
}
|
bus_size_t offset, uint16_t value);
|
||||||
|
uint32_t bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||||
|
bus_size_t offset);
|
||||||
static inline void
|
void bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||||
bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t handle,
|
bus_size_t offset, uint32_t value);
|
||||||
bus_size_t offset, uint8_t value)
|
|
||||||
{
|
|
||||||
if (tag == I386_BUS_SPACE_IO)
|
|
||||||
out8(handle + offset, value);
|
|
||||||
else
|
|
||||||
*(volatile uint8_t *)(handle + offset) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint16_t
|
|
||||||
bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
|
|
||||||
bus_size_t offset)
|
|
||||||
{
|
|
||||||
if (tag == I386_BUS_SPACE_IO)
|
|
||||||
return in16(handle + offset);
|
|
||||||
return *(volatile uint16_t *)(handle + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t handle,
|
|
||||||
bus_size_t offset, uint16_t value)
|
|
||||||
{
|
|
||||||
if (tag == I386_BUS_SPACE_IO)
|
|
||||||
out16(handle + offset, value);
|
|
||||||
else
|
|
||||||
*(volatile uint16_t *)(handle + offset) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
|
|
||||||
bus_size_t offset)
|
|
||||||
{
|
|
||||||
if (tag == I386_BUS_SPACE_IO)
|
|
||||||
return in32(handle + offset);
|
|
||||||
return *(volatile uint32_t *)(handle + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle,
|
|
||||||
bus_size_t offset, uint32_t value)
|
|
||||||
{
|
|
||||||
if (tag == I386_BUS_SPACE_IO)
|
|
||||||
out32(handle + offset, value);
|
|
||||||
else
|
|
||||||
*(volatile uint32_t *)(handle + offset) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define BUS_SPACE_BARRIER_READ 1
|
#define BUS_SPACE_BARRIER_READ 1
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ allocate_device(driver_t *driver)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ifq_init(&dev->receive_queue, semName);
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ static void
|
|||||||
free_device(device_t dev)
|
free_device(device_t dev)
|
||||||
{
|
{
|
||||||
delete_sem(dev->receive_sem);
|
delete_sem(dev->receive_sem);
|
||||||
|
ifq_uninit(&dev->receive_queue);
|
||||||
free(dev->softc);
|
free(dev->softc);
|
||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
@@ -93,7 +96,7 @@ compat_open(const char *name, uint32 flags, void **cookie)
|
|||||||
device_t dev;
|
device_t dev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dprintf("%s, compat_open(%s, 0x%lx)\n", gDriverName, name, flags);
|
driver_printf("compat_open(%s, 0x%lx)\n", name, flags);
|
||||||
|
|
||||||
for (i = 0; gDevNameList[i] != NULL; i++) {
|
for (i = 0; gDevNameList[i] != NULL; i++) {
|
||||||
if (strcmp(gDevNameList[i], name) == 0)
|
if (strcmp(gDevNameList[i], name) == 0)
|
||||||
@@ -112,6 +115,8 @@ compat_open(const char *name, uint32 flags, void **cookie)
|
|||||||
if (status != 0)
|
if (status != 0)
|
||||||
dev->flags = 0;
|
dev->flags = 0;
|
||||||
|
|
||||||
|
driver_printf(" ... status = 0x%ld\n", status);
|
||||||
|
|
||||||
*cookie = dev;
|
*cookie = dev;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -123,7 +128,7 @@ compat_close(void *cookie)
|
|||||||
{
|
{
|
||||||
device_t dev = cookie;
|
device_t dev = cookie;
|
||||||
|
|
||||||
dprintf("%s, compat_close(%p)\n", gDriverName, dev);
|
device_printf(dev, "compat_close()\n");
|
||||||
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -134,7 +139,7 @@ compat_free(void *cookie)
|
|||||||
{
|
{
|
||||||
device_t dev = cookie;
|
device_t dev = cookie;
|
||||||
|
|
||||||
dprintf("%s, compat_free(%p)\n", gDriverName, dev);
|
device_printf(dev, "compat_free()\n");
|
||||||
|
|
||||||
free_device(dev);
|
free_device(dev);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -150,6 +155,9 @@ compat_read(void *cookie, off_t position, void *buf, size_t *numBytes)
|
|||||||
struct mbuf *mb;
|
struct mbuf *mb;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
driver_printf("compat_read(%p, %lld, %p, [%lu])\n", cookie, position, buf,
|
||||||
|
*numBytes);
|
||||||
|
|
||||||
if (dev->flags & DEVICE_CLOSED)
|
if (dev->flags & DEVICE_CLOSED)
|
||||||
return B_INTERRUPTED;
|
return B_INTERRUPTED;
|
||||||
|
|
||||||
@@ -193,6 +201,9 @@ compat_write(void *cookie, off_t position, const void *buffer,
|
|||||||
device_t dev = cookie;
|
device_t dev = cookie;
|
||||||
struct mbuf *mb;
|
struct mbuf *mb;
|
||||||
|
|
||||||
|
driver_printf("compat_write(%p, %lld, %p, [%lu])\n", cookie, position,
|
||||||
|
buffer, *numBytes);
|
||||||
|
|
||||||
mb = m_getcl(0, MT_DATA, 0);
|
mb = m_getcl(0, MT_DATA, 0);
|
||||||
if (mb == NULL)
|
if (mb == NULL)
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
|
|||||||
@@ -58,6 +58,12 @@ void uninit_mutexes(void);
|
|||||||
void init_bounce_pages(void);
|
void init_bounce_pages(void);
|
||||||
void uninit_bounce_pages(void);
|
void uninit_bounce_pages(void);
|
||||||
|
|
||||||
|
void driver_printf(const char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
|
||||||
|
void driver_vprintf(const char *format, va_list vl);
|
||||||
|
|
||||||
|
void ifq_init(struct ifqueue *ifq, const char *name);
|
||||||
|
void ifq_uninit(struct ifqueue *ifq);
|
||||||
|
|
||||||
extern struct net_stack_module_info *gStack;
|
extern struct net_stack_module_info *gStack;
|
||||||
extern pci_module_info *gPci;
|
extern pci_module_info *gPci;
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,26 @@ if_initname(struct ifnet *ifp, const char *name, int unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ifq_init(struct ifqueue *ifq, const char *name)
|
||||||
|
{
|
||||||
|
ifq->ifq_head = NULL;
|
||||||
|
ifq->ifq_tail = NULL;
|
||||||
|
ifq->ifq_len = 0;
|
||||||
|
ifq->ifq_maxlen = IFQ_MAXLEN;
|
||||||
|
ifq->ifq_drops = 0;
|
||||||
|
|
||||||
|
mtx_init(&ifq->ifq_mtx, name, NULL, MTX_DEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ifq_uninit(struct ifqueue *ifq)
|
||||||
|
{
|
||||||
|
mtx_destroy(&ifq->ifq_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
if_attach(struct ifnet *ifp)
|
if_attach(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
@@ -79,14 +99,14 @@ if_attach(struct ifnet *ifp)
|
|||||||
TAILQ_INIT(&ifp->if_prefixhead);
|
TAILQ_INIT(&ifp->if_prefixhead);
|
||||||
TAILQ_INIT(&ifp->if_multiaddrs);
|
TAILQ_INIT(&ifp->if_multiaddrs);
|
||||||
|
|
||||||
mtx_init(&ifp->if_snd.ifq_mtx, ifp->if_xname, NULL, MTX_DEF);
|
ifq_init((struct ifqueue *)&ifp->if_snd, ifp->if_xname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
if_detach(struct ifnet *ifp)
|
if_detach(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
mtx_destroy(&ifp->if_snd.ifq_mtx);
|
ifq_uninit((struct ifqueue *)&ifp->if_snd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +117,6 @@ if_start(struct ifnet *ifp)
|
|||||||
if (ifp->if_flags & IFF_NEEDSGIANT)
|
if (ifp->if_flags & IFF_NEEDSGIANT)
|
||||||
panic("freebsd compat.: unsupported giant requirement");
|
panic("freebsd compat.: unsupported giant requirement");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ifp->if_start(ifp);
|
ifp->if_start(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +152,7 @@ int
|
|||||||
ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||||
struct rtentry *rt0)
|
struct rtentry *rt0)
|
||||||
{
|
{
|
||||||
int error;
|
int error = 0;
|
||||||
IFQ_HANDOFF(ifp, m, error);
|
IFQ_HANDOFF(ifp, m, error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -270,3 +289,13 @@ ether_ioctl(struct ifnet *ifp, int command, caddr_t data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
ether_sprintf(const u_char *ap)
|
||||||
|
{
|
||||||
|
static char etherbuf[18];
|
||||||
|
snprintf(etherbuf, sizeof (etherbuf),
|
||||||
|
"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
|
||||||
|
ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]);
|
||||||
|
return (etherbuf);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user