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:
Hugo Santos 2007-05-05 00:47:20 +00:00
parent e6bf88d435
commit 00212abe1c
14 changed files with 241 additions and 8 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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 };

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -30,4 +30,7 @@
#define MCLBYTES (1 << MCLSHIFT)
#define ALIGN_BYTES (sizeof(int) - 1)
#define ALIGN(x) ((((unsigned)x) + ALIGN_BYTES) & ~ALIGN_BYTES)
#endif

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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)
{