freebsd compat. layer: a few more methods, preparing for pcnet
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21026 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e6bf88d435
commit
00212abe1c
@ -14,6 +14,7 @@
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <compat/machine/resource.h>
|
||||
#include <compat/dev/pci/pcivar.h>
|
||||
#include <compat/sys/bus.h>
|
||||
|
||||
@ -91,6 +92,34 @@ pci_enable_busmaster(device_t dev)
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
case SYS_RES_IOPORT:
|
||||
bit = PCI_command_io;
|
||||
break;
|
||||
case SYS_RES_MEMORY:
|
||||
bit = PCI_command_memory;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
pci_set_command_bit(dev, bit);
|
||||
if (pci_read_config(dev, PCI_command, 2) & bit)
|
||||
return 0;
|
||||
|
||||
device_printf(dev, "pci_enable_io(%d) failed.\n", space);
|
||||
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_printf(device_t dev, const char *format, ...)
|
||||
{
|
||||
@ -100,7 +129,7 @@ device_printf(device_t dev, const char *format, ...)
|
||||
vsnprintf(buf, sizeof(buf), format, vl);
|
||||
va_end(vl);
|
||||
|
||||
dprintf("[...] %s", buf);
|
||||
dprintf("[%s...] %s", gDriverName, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -165,6 +194,21 @@ printf(const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ffs(int value)
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
if (value == 0)
|
||||
return 0;
|
||||
|
||||
for (; !(value & 1); i++)
|
||||
value >>= 1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int resource_int_value(const char *name, int unit, const char *resname,
|
||||
int *result)
|
||||
{
|
||||
|
@ -11,4 +11,7 @@
|
||||
#define PCIM_CMD_MEMEN 0x0002
|
||||
#define PCIM_CMD_MWRICEN 0x0010
|
||||
|
||||
#define PCIR_BARS 0x10
|
||||
#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
|
||||
|
||||
#endif
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <sys/bus.h>
|
||||
|
||||
int pci_enable_busmaster(device_t dev);
|
||||
int pci_enable_io(device_t dev, int reg);
|
||||
|
||||
uint32_t pci_get_devid(device_t dev);
|
||||
void pci_set_intpin(device_t dev, uint8_t pin);
|
||||
|
@ -28,6 +28,14 @@
|
||||
#define IFF_LINK0 0x40000
|
||||
|
||||
|
||||
#define LINK_STATE_UNKNOWN 0
|
||||
#define LINK_STATE_DOWN 1
|
||||
#define LINK_STATE_UP 2
|
||||
|
||||
|
||||
#define IFQ_MAXLEN 50
|
||||
|
||||
|
||||
struct ifmediareq {
|
||||
char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
int ifm_current; /* current media options */
|
||||
|
@ -86,6 +86,8 @@ struct carp_if;
|
||||
|
||||
#include <altq/if_altq.h>
|
||||
|
||||
#include <net/if_dl.h> /* for sockaddr_dl */
|
||||
|
||||
TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */
|
||||
TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */
|
||||
TAILQ_HEAD(ifprefixhead, ifprefix);
|
||||
@ -180,6 +182,9 @@ struct ifnet {
|
||||
struct task if_starttask; /* task for IFF_NEEDSGIANT */
|
||||
struct task if_linktask; /* task for link change events */
|
||||
struct mtx if_addr_mtx; /* mutex to protect address lists */
|
||||
|
||||
/* Haiku additions */
|
||||
struct sockaddr_dl if_lladdr;
|
||||
};
|
||||
|
||||
typedef void if_init_f_t(void *);
|
||||
@ -657,8 +662,7 @@ typedef void if_com_free_t(void *com, u_char type);
|
||||
void if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
|
||||
void if_deregister_com_alloc(u_char type);
|
||||
|
||||
#define IF_LLADDR(ifp) \
|
||||
LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr)
|
||||
#define IF_LLADDR(ifp) LLADDR(&ifp->if_lladdr)
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS };
|
||||
|
@ -87,6 +87,20 @@ bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||
}
|
||||
|
||||
|
||||
#define BUS_SPACE_BARRIER_READ 1
|
||||
#define BUS_SPACE_BARRIER_WRITE 2
|
||||
|
||||
static inline void
|
||||
bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||
bus_size_t offset, bus_size_t len, int flags)
|
||||
{
|
||||
if (flags & BUS_SPACE_BARRIER_READ)
|
||||
__asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory");
|
||||
else
|
||||
__asm__ __volatile__ ("" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
enum intr_type {
|
||||
INTR_TYPE_NET = 4,
|
||||
INTR_MPSAFE = 512,
|
||||
|
@ -15,6 +15,12 @@ typedef struct devclass *devclass_t;
|
||||
|
||||
typedef int (*device_method_signature_t)(device_t dev);
|
||||
|
||||
typedef int device_probe_t(device_t dev);
|
||||
typedef int device_attach_t(device_t dev);
|
||||
typedef int device_detach_t(device_t dev);
|
||||
typedef int device_resume_t(device_t dev);
|
||||
typedef int device_suspend_t(device_t dev);
|
||||
|
||||
struct device_method {
|
||||
const char *name;
|
||||
device_method_signature_t method;
|
||||
@ -22,7 +28,7 @@ struct device_method {
|
||||
|
||||
typedef struct device_method device_method_t;
|
||||
|
||||
#define DEVMETHOD(name, func) { #name, (device_method_signature_t)func }
|
||||
#define DEVMETHOD(name, func) { #name, (device_method_signature_t)&func }
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
@ -30,6 +36,7 @@ typedef struct {
|
||||
size_t size;
|
||||
} driver_t;
|
||||
|
||||
#define BUS_PROBE_LOW_PRIORITY 10
|
||||
#define BUS_PROBE_DEFAULT 20
|
||||
|
||||
#define DRIVER_MODULE_NAME(name, busname) \
|
||||
@ -39,15 +46,18 @@ status_t _fbsd_init_hardware(driver_t *);
|
||||
status_t _fbsd_init_driver(driver_t *);
|
||||
void _fbsd_uninit_driver(driver_t *);
|
||||
|
||||
extern const char gDriverName[];
|
||||
|
||||
/* 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(name, busname) \
|
||||
#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() \
|
||||
{ \
|
||||
@ -64,6 +74,9 @@ void _fbsd_uninit_driver(driver_t *);
|
||||
const char **publish_devices() { return (const char **)gDevNameList; } \
|
||||
device_hooks *find_device(const char *name) { return &gDeviceHooks; }
|
||||
|
||||
#define DEFINE_CLASS_0(name, driver, methods, size) \
|
||||
driver_t driver = { #name, methods, size }
|
||||
|
||||
#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \
|
||||
driver_t *DRIVER_MODULE_NAME(name, busname) = &(driver)
|
||||
|
||||
|
@ -28,7 +28,8 @@ struct __system_init {
|
||||
#define SYSINIT(uniquifier, subsystem, order, func, ident) \
|
||||
struct __system_init __init_##uniquifier = { func }
|
||||
|
||||
#define __printflike(a, b) __attribute__ ((format (__printf__, a, b)))
|
||||
#define __packed __attribute__ ((packed))
|
||||
#define __printflike(a, b) __attribute__ ((format (__printf__, a, b)))
|
||||
|
||||
int printf(const char *format, ...) __printflike(1, 2);
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#define MLEN ((int)(MSIZE - sizeof(struct m_hdr)))
|
||||
#define MHLEN ((int)(MSIZE - sizeof(struct pkthdr)))
|
||||
|
||||
#define MINCLSIZE (MHLEN + 1)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct m_hdr {
|
||||
@ -82,6 +84,10 @@ struct mbuf {
|
||||
#define CSUM_PSEUDO_HDR 0x0800
|
||||
#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP)
|
||||
|
||||
#define MGET(m, how, type) ((m) = m_get((how), (type)))
|
||||
#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type)))
|
||||
#define MCLGET(m, how) m_clget((m), (how))
|
||||
|
||||
struct mbuf *m_getcl(int how, short type, int flags);
|
||||
void m_freem(struct mbuf *mbuf);
|
||||
struct mbuf *m_free(struct mbuf *m);
|
||||
@ -94,6 +100,7 @@ void m_copydata(const struct mbuf *m, int off, int len, caddr_t cp);
|
||||
|
||||
struct mbuf *m_get(int how, short type);
|
||||
struct mbuf *m_gethdr(int how, short type);
|
||||
void m_clget(struct mbuf *m, int how);
|
||||
|
||||
#define mtod(m, type) (type)((m)->m_data)
|
||||
|
||||
|
@ -43,6 +43,13 @@ static inline void mtx_unlock(struct mtx *mtx)
|
||||
}
|
||||
|
||||
|
||||
static inline int mtx_initialized(struct mtx *mtx)
|
||||
{
|
||||
/* XXX */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void mtx_init(struct mtx *m, const char *name, const char *type, int opts);
|
||||
void mtx_destroy(struct mtx *m);
|
||||
|
||||
|
@ -30,4 +30,7 @@
|
||||
|
||||
#define MCLBYTES (1 << MCLSHIFT)
|
||||
|
||||
#define ALIGN_BYTES (sizeof(int) - 1)
|
||||
#define ALIGN(x) ((((unsigned)x) + ALIGN_BYTES) & ~ALIGN_BYTES)
|
||||
|
||||
#endif
|
||||
|
@ -122,13 +122,18 @@ _fbsd_init_hardware(driver_t *driver)
|
||||
pci_info info;
|
||||
int i;
|
||||
|
||||
dprintf("%s: init_hardware(%p)\n", gDriverName, driver);
|
||||
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
for (i = 0; probe == NULL && driver->methods[i].name != NULL; i++) {
|
||||
if (strcmp(driver->methods[i].name, "device_probe") == 0)
|
||||
probe = driver->methods[i].method;
|
||||
}
|
||||
|
||||
if (probe == NULL) {
|
||||
dprintf("_fbsd_init_hardware: driver has no device_probe method.\n");
|
||||
dprintf("%s: driver has no device_probe method.\n", gDriverName);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -136,10 +141,17 @@ _fbsd_init_hardware(driver_t *driver)
|
||||
fakeDevice.pciInfo = &info;
|
||||
|
||||
for (i = 0; gPci->get_nth_pci_info(i, &info) == B_OK; i++) {
|
||||
if (probe(&fakeDevice) >= 0)
|
||||
if (probe(&fakeDevice) >= 0) {
|
||||
dprintf("%s, found %s at %i\n", gDriverName,
|
||||
fakeDevice.description, i);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
dprintf("%s: no hardware found.\n", gDriverName);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -147,6 +159,8 @@ _fbsd_init_hardware(driver_t *driver)
|
||||
status_t
|
||||
_fbsd_init_driver(driver_t *driver)
|
||||
{
|
||||
dprintf("%s: init_driver(%p)\n", gDriverName, driver);
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -154,4 +168,5 @@ _fbsd_init_driver(driver_t *driver)
|
||||
void
|
||||
_fbsd_uninit_driver(driver_t *driver)
|
||||
{
|
||||
dprintf("%s: uninit_driver(%p)\n", gDriverName, driver);
|
||||
}
|
||||
|
@ -85,6 +85,33 @@ if_start(struct ifnet *ifp)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
if_printf(struct ifnet *ifp, const char *format, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list vl;
|
||||
va_start(vl, format);
|
||||
vsnprintf(buf, sizeof(buf), format, vl);
|
||||
va_end(vl);
|
||||
|
||||
dprintf("[%s] %s", ifp->if_xname, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
if_link_state_change(struct ifnet *ifp, int link_state)
|
||||
{
|
||||
if (ifp->if_link_state == link_state)
|
||||
return;
|
||||
|
||||
ifp->if_link_state = link_state;
|
||||
|
||||
/* XXX */
|
||||
/* wake network stack's link state sem */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
struct rtentry *rt0)
|
||||
@ -116,6 +143,9 @@ ether_ifattach(struct ifnet *ifp, const uint8_t *mac_address)
|
||||
ifp->if_input = ether_input;
|
||||
ifp->if_resolvemulti = NULL; /* done in the stack */
|
||||
|
||||
ifp->if_lladdr.sdl_family = AF_LINK;
|
||||
memcpy(IF_LLADDR(ifp), mac_address, ETHER_ADDR_LEN);
|
||||
|
||||
ifp->if_init(ifp->if_softc);
|
||||
}
|
||||
|
||||
@ -127,6 +157,80 @@ ether_ifdetach(struct ifnet *ifp)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This is for reference. We have a table-driven version
|
||||
* of the little-endian crc32 generator, which is faster
|
||||
* than the double-loop.
|
||||
*/
|
||||
uint32_t
|
||||
ether_crc32_le(const uint8_t *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t crc;
|
||||
int bit;
|
||||
uint8_t data;
|
||||
|
||||
crc = 0xffffffff; /* initial value */
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1)
|
||||
carry = (crc ^ data) & 1;
|
||||
crc >>= 1;
|
||||
if (carry)
|
||||
crc = (crc ^ ETHER_CRC_POLY_LE);
|
||||
}
|
||||
|
||||
return (crc);
|
||||
}
|
||||
#else
|
||||
uint32_t
|
||||
ether_crc32_le(const uint8_t *buf, size_t len)
|
||||
{
|
||||
static const uint32_t crctab[] = {
|
||||
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
|
||||
};
|
||||
size_t i;
|
||||
uint32_t crc;
|
||||
|
||||
crc = 0xffffffff; /* initial value */
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
crc ^= buf[i];
|
||||
crc = (crc >> 4) ^ crctab[crc & 0xf];
|
||||
crc = (crc >> 4) ^ crctab[crc & 0xf];
|
||||
}
|
||||
|
||||
return (crc);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t
|
||||
ether_crc32_be(const uint8_t *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t crc, carry;
|
||||
int bit;
|
||||
uint8_t data;
|
||||
|
||||
crc = 0xffffffff; /* initial value */
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) {
|
||||
carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01);
|
||||
crc <<= 1;
|
||||
if (carry)
|
||||
crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
|
||||
}
|
||||
}
|
||||
|
||||
return (crc);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ether_ioctl(struct ifnet *ifp, int command, caddr_t data)
|
||||
{
|
||||
|
@ -146,6 +146,15 @@ m_gethdr(int how, short type)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
m_clget(struct mbuf *m, int how)
|
||||
{
|
||||
m->m_ext.ext_buf = NULL;
|
||||
/* called checks for errors by looking for M_EXT */
|
||||
construct_ext_mbuf(m, how);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
m_freem(struct mbuf *mb)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user