* fixed access of deleted value in free_hook() that I introduced myself a couple
of months ago * cleanup, improved styleguide conformance at least to some extent... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18393 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -47,12 +47,11 @@
|
|||||||
|
|
||||||
#define RTL_MAX_CARDS 4
|
#define RTL_MAX_CARDS 4
|
||||||
|
|
||||||
#define RTL_NODEBUG
|
#define TRACE_RTL8139
|
||||||
#ifdef RTL_NODEBUG
|
#ifdef TRACE_RTL8139
|
||||||
#define TRACE no_printf
|
# define TRACE(x) dprintf x
|
||||||
static void no_printf( const char *useless , ... ) {};
|
|
||||||
#else
|
#else
|
||||||
#define TRACE TRACE
|
# define TRACE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct supported_device {
|
typedef struct supported_device {
|
||||||
@@ -95,8 +94,7 @@ static int32 rtl8139_interrupt(void *data); /* interrupt handler */
|
|||||||
structure that stores internal data
|
structure that stores internal data
|
||||||
---- */
|
---- */
|
||||||
|
|
||||||
typedef struct rtl8139_properties
|
typedef struct rtl8139_properties {
|
||||||
{
|
|
||||||
pci_info *pcii; /* Pointer to PCI Info for the device */
|
pci_info *pcii; /* Pointer to PCI Info for the device */
|
||||||
uint32 reg_base; /* Base address for registers */
|
uint32 reg_base; /* Base address for registers */
|
||||||
area_id ioarea; /* PPC: Area where the mmaped registers are */
|
area_id ioarea; /* PPC: Area where the mmaped registers are */
|
||||||
@@ -124,8 +122,7 @@ typedef struct rtl8139_properties
|
|||||||
uint8 nonblocking; /* determines if the card blocks on read requests */
|
uint8 nonblocking; /* determines if the card blocks on read requests */
|
||||||
} rtl8139_properties_t;
|
} rtl8139_properties_t;
|
||||||
|
|
||||||
typedef struct packetheader
|
typedef struct packetheader {
|
||||||
{
|
|
||||||
volatile uint16 bits; /* Status bits of the packet header */
|
volatile uint16 bits; /* Status bits of the packet header */
|
||||||
volatile uint16 length; /* Length of the packet including header + CRC */
|
volatile uint16 length; /* Length of the packet including header + CRC */
|
||||||
volatile uint8 data[1];
|
volatile uint8 data[1];
|
||||||
@@ -144,8 +141,7 @@ static status_t close_hook( void * );
|
|||||||
#define READ_16(offset) (gPCIModule->read_io_16((data->reg_base + offset)))
|
#define READ_16(offset) (gPCIModule->read_io_16((data->reg_base + offset)))
|
||||||
#define READ_32(offset) (gPCIModule->read_io_32((data->reg_base + offset)))
|
#define READ_32(offset) (gPCIModule->read_io_32((data->reg_base + offset)))
|
||||||
|
|
||||||
static void rtl8139_init_registers( rtl8139_properties_t *data )
|
static void rtl8139_init_registers(rtl8139_properties_t *data) {
|
||||||
{
|
|
||||||
data->reg_base = data->pcii->u.h0.base_registers[0];
|
data->reg_base = data->pcii->u.h0.base_registers[0];
|
||||||
}
|
}
|
||||||
#else /* PPC */
|
#else /* PPC */
|
||||||
@@ -158,8 +154,7 @@ static status_t close_hook( void * );
|
|||||||
#define READ_16(offset) B_LENDIAN_TO_HOST_INT16(*((volatile uint16*)(data->reg_base + (offset))))
|
#define READ_16(offset) B_LENDIAN_TO_HOST_INT16(*((volatile uint16*)(data->reg_base + (offset))))
|
||||||
#define READ_32(offset) B_LENDIAN_TO_HOST_INT32(*((volatile uint32*)(data->reg_base + (offset))))
|
#define READ_32(offset) B_LENDIAN_TO_HOST_INT32(*((volatile uint32*)(data->reg_base + (offset))))
|
||||||
|
|
||||||
static void rtl8139_init_registers( rtl8139_properties_t *data )
|
static void rtl8139_init_registers(rtl8139_properties_t *data) {
|
||||||
{
|
|
||||||
int32 base, size, offset;
|
int32 base, size, offset;
|
||||||
base = data->pcii->u.h0.base_registers[0];
|
base = data->pcii->u.h0.base_registers[0];
|
||||||
size = data->pcii->u.h0.base_register_sizes[0];
|
size = data->pcii->u.h0.base_register_sizes[0];
|
||||||
@@ -172,7 +167,7 @@ static status_t close_hook( void * );
|
|||||||
size += offset;
|
size += offset;
|
||||||
size = (size +(B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
|
size = (size +(B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
|
||||||
|
|
||||||
TRACE("rtl8139_nielx _open_hook(): PCI base=%lx size=%lx offset=%lx\n", base, size, offset);
|
TRACE(("rtl8139_nielx _open_hook(): PCI base=%lx size=%lx offset=%lx\n", base, size, offset));
|
||||||
|
|
||||||
data->ioarea = map_physical_memory("rtl8139_regs", (void *)base, size, B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, (void **)&data->reg_base);
|
data->ioarea = map_physical_memory("rtl8139_regs", (void *)base, size, B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, (void **)&data->reg_base);
|
||||||
|
|
||||||
@@ -188,7 +183,7 @@ status_t
|
|||||||
init_hardware (void)
|
init_hardware (void)
|
||||||
{
|
{
|
||||||
// Nielx: no special requirements here...
|
// Nielx: no special requirements here...
|
||||||
TRACE( "rtl8139_nielx: init_hardware\n" );
|
TRACE(("rtl8139_nielx: init_hardware\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,34 +199,30 @@ init_driver (void)
|
|||||||
pci_info *item; //Storage used while looking through pci
|
pci_info *item; //Storage used while looking through pci
|
||||||
int32 i, found; //Counter
|
int32 i, found; //Counter
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx: init_driver()\n" );
|
TRACE(("rtl8139_nielx: init_driver()\n"));
|
||||||
|
|
||||||
// Try if the PCI module is loaded (it would be weird if it wouldn't, but alas)
|
// Try if the PCI module is loaded (it would be weird if it wouldn't, but alas)
|
||||||
if( ( status = get_module( B_PCI_MODULE_NAME, (module_info **)&gPCIModule )) != B_OK)
|
if((status = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCIModule)) != B_OK) {
|
||||||
{
|
TRACE(("rtl8139_nielx init_driver(): Get PCI module failed! %lu \n", status));
|
||||||
TRACE( "rtl8139_nielx init_driver(): Get PCI module failed! %lu \n", status);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
i = 0;
|
i = 0;
|
||||||
item = (pci_info *)malloc(sizeof(pci_info));
|
item = (pci_info *)malloc(sizeof(pci_info));
|
||||||
for ( i = found = 0 ; gPCIModule->get_nth_pci_info(i, item) == B_OK ; i++ )
|
for (i = found = 0 ; gPCIModule->get_nth_pci_info(i, item) == B_OK ; i++) {
|
||||||
{
|
|
||||||
supported_device_t *supported;
|
supported_device_t *supported;
|
||||||
|
|
||||||
for (supported = m_supported_devices; supported->name; supported++) {
|
for (supported = m_supported_devices; supported->name; supported++) {
|
||||||
if ((item->vendor_id == supported->vendor_id) &&
|
if ((item->vendor_id == supported->vendor_id) &&
|
||||||
(item->device_id == supported->device_id) )
|
(item->device_id == supported->device_id)) {
|
||||||
{
|
|
||||||
//Also done in etherpci sample code
|
//Also done in etherpci sample code
|
||||||
if ((item->u.h0.interrupt_line == 0) || (item->u.h0.interrupt_line == 0xFF))
|
if ((item->u.h0.interrupt_line == 0) || (item->u.h0.interrupt_line == 0xFF)) {
|
||||||
{
|
TRACE(("rtl8139_nielx init_driver(): found %s with invalid IRQ - check IRQ assignement\n", supported->name));
|
||||||
TRACE( "rtl8139_nielx init_driver(): found %s with invalid IRQ - check IRQ assignement\n", supported->name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("rtl8139_nielx init_driver(): found %s at IRQ %u \n", supported->name, item->u.h0.interrupt_line);
|
TRACE(("rtl8139_nielx init_driver(): found %s at IRQ %u \n", supported->name, item->u.h0.interrupt_line));
|
||||||
gFoundDevices[found] = item;
|
gFoundDevices[found] = item;
|
||||||
item = (pci_info *)malloc(sizeof(pci_info));
|
item = (pci_info *)malloc(sizeof(pci_info));
|
||||||
found++;
|
found++;
|
||||||
@@ -242,9 +233,8 @@ init_driver (void)
|
|||||||
free(item);
|
free(item);
|
||||||
|
|
||||||
//Check if we have found any devices:
|
//Check if we have found any devices:
|
||||||
if ( found == 0 )
|
if (found == 0) {
|
||||||
{
|
TRACE(("rtl8139_nielx init_driver(): no device found\n"));
|
||||||
TRACE( "rtl8139_nielx init_driver(): no device found\n" );
|
|
||||||
put_module(B_PCI_MODULE_NAME); //dereference module
|
put_module(B_PCI_MODULE_NAME); //dereference module
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
@@ -253,8 +243,7 @@ init_driver (void)
|
|||||||
{
|
{
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|
||||||
for (i = 0; i < found; i++)
|
for (i = 0; i < found; i++) {
|
||||||
{
|
|
||||||
sprintf(name, "net/rtl8139/%ld", i);
|
sprintf(name, "net/rtl8139/%ld", i);
|
||||||
gDeviceNames[i] = strdup(name);
|
gDeviceNames[i] = strdup(name);
|
||||||
}
|
}
|
||||||
@@ -273,10 +262,9 @@ uninit_driver (void)
|
|||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
void *item;
|
void *item;
|
||||||
TRACE( "rtl8139_nielx: uninit_driver()\n" );
|
TRACE(("rtl8139_nielx: uninit_driver()\n"));
|
||||||
|
|
||||||
for (index = 0; (item = gDeviceNames[index]) != NULL; index++)
|
for (index = 0; (item = gDeviceNames[index]) != NULL; index++) {
|
||||||
{
|
|
||||||
free(item);
|
free(item);
|
||||||
free(gFoundDevices[index]);
|
free(gFoundDevices[index]);
|
||||||
}
|
}
|
||||||
@@ -293,8 +281,7 @@ uninit_driver (void)
|
|||||||
static status_t free_hook(void *cookie);
|
static status_t free_hook(void *cookie);
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
open_hook(const char *name, uint32 flags, void** cookie)
|
open_hook(const char *name, uint32 flags, void** cookie) {
|
||||||
{
|
|
||||||
|
|
||||||
rtl8139_properties_t *data;
|
rtl8139_properties_t *data;
|
||||||
uint8 id;
|
uint8 id;
|
||||||
@@ -303,7 +290,7 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
uint32 temp32;
|
uint32 temp32;
|
||||||
unsigned char cmd;
|
unsigned char cmd;
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx open_hook()\n" );
|
TRACE(("rtl8139_nielx open_hook()\n"));
|
||||||
|
|
||||||
// verify device access
|
// verify device access
|
||||||
{
|
{
|
||||||
@@ -325,9 +312,8 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create a structure that contains the internals
|
//Create a structure that contains the internals
|
||||||
if (!(*cookie = data = (rtl8139_properties_t *)malloc(sizeof(rtl8139_properties_t))))
|
if (!(*cookie = data = (rtl8139_properties_t *)malloc(sizeof(rtl8139_properties_t)))) {
|
||||||
{
|
TRACE(("rtl8139_nielx open_hook(): Out of memory\n"));
|
||||||
TRACE( "rtl8139_nielx open_hook(): Out of memory\n" );
|
|
||||||
gDeviceOpenMask &= ~(1L << id);
|
gDeviceOpenMask &= ~(1L << id);
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
@@ -360,9 +346,8 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
// Check for the chipversion -- The version bits are bits 31-27 and 24-23
|
// Check for the chipversion -- The version bits are bits 31-27 and 24-23
|
||||||
temp32 = READ_32(TxConfig);
|
temp32 = READ_32(TxConfig);
|
||||||
|
|
||||||
if ( temp32 == 0xFFFFFF )
|
if (temp32 == 0xFFFFFF) {
|
||||||
{
|
TRACE(("rtl8139_nielx open_hook(): Faulty chip\n"));
|
||||||
TRACE( "rtl8139_nielx open_hook(): Faulty chip\n" );
|
|
||||||
free_hook(cookie);
|
free_hook(cookie);
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
return EIO;
|
return EIO;
|
||||||
@@ -370,25 +355,24 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
|
|
||||||
temp32 = temp32 & 0x7cc00000;
|
temp32 = temp32 & 0x7cc00000;
|
||||||
|
|
||||||
switch( temp32 )
|
switch(temp32) {
|
||||||
{
|
|
||||||
case 0x74000000:
|
case 0x74000000:
|
||||||
TRACE( "rtl8139_nielx open_hook(): Chip is the 8139 C\n" );
|
TRACE(("rtl8139_nielx open_hook(): Chip is the 8139 C\n"));
|
||||||
data->chip_type = RTL_8139_C;
|
data->chip_type = RTL_8139_C;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x74400000:
|
case 0x74400000:
|
||||||
TRACE( "rtl8139_niels open_hook(): Chip is the 8139 D\n" );
|
TRACE(("rtl8139_niels open_hook(): Chip is the 8139 D\n"));
|
||||||
data->chip_type = RTL_8139_D;
|
data->chip_type = RTL_8139_D;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x74C00000:
|
case 0x74C00000:
|
||||||
TRACE( "rtl8139_nielx open_hook(): Chip is the 8101L\n" );
|
TRACE(("rtl8139_nielx open_hook(): Chip is the 8101L\n"));
|
||||||
data->chip_type = RTL_8101_L;
|
data->chip_type = RTL_8101_L;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TRACE( "rtl8139_nielx open_hook(): Unknown chip, assuming 8139 C\n" );
|
TRACE(("rtl8139_nielx open_hook(): Unknown chip, assuming 8139 C\n"));
|
||||||
data->chip_type = RTL_8139_C;
|
data->chip_type = RTL_8139_C;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,13 +384,12 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
while ((READ_8(Command) & Reset) && temp16 > 0)
|
while ((READ_8(Command) & Reset) && temp16 > 0)
|
||||||
temp16--;
|
temp16--;
|
||||||
|
|
||||||
if ( temp16 == 0 )
|
if (temp16 == 0) {
|
||||||
{
|
TRACE(("rtl8139_nielx open_hook(): Reset failed... Bailing out\n"));
|
||||||
TRACE( "rtl8139_nielx open_hook(): Reset failed... Bailing out\n" );
|
|
||||||
free_hook(cookie);
|
free_hook(cookie);
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
TRACE( "rtl8139_nielx open_hook(): Chip reset: %u \n" , temp16 );
|
TRACE(("rtl8139_nielx open_hook(): Chip reset: %u \n", temp16));
|
||||||
|
|
||||||
/* Enable writing to the configuration registers */
|
/* Enable writing to the configuration registers */
|
||||||
WRITE_8(_9346CR, 0xc0);
|
WRITE_8(_9346CR, 0xc0);
|
||||||
@@ -448,9 +431,8 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
//Allocate the ring buffer for the receiver.
|
//Allocate the ring buffer for the receiver.
|
||||||
// Size is set above: as 16k + 16 bytes + 1.5 kB--- 16 bytes for last CRC (a
|
// Size is set above: as 16k + 16 bytes + 1.5 kB--- 16 bytes for last CRC (a
|
||||||
data->receivebuffer = alloc_mem(&(data->receivebufferlog), &(data->receivebufferphy), 1024 * 64 + 16, "rx buffer");
|
data->receivebuffer = alloc_mem(&(data->receivebufferlog), &(data->receivebufferphy), 1024 * 64 + 16, "rx buffer");
|
||||||
if( data->receivebuffer == B_ERROR )
|
if(data->receivebuffer == B_ERROR) {
|
||||||
{
|
TRACE(("rtl8139_nielx open_hook(): memory allocation for ringbuffer failed\n"));
|
||||||
TRACE( "rtl8139_nielx open_hook(): memory allocation for ringbuffer failed\n" );
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
WRITE_32(RBSTART, (int32) data->receivebufferphy);
|
WRITE_32(RBSTART, (int32) data->receivebufferphy);
|
||||||
@@ -474,9 +456,8 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
data->transmitbufferphy[3] = (void *)((uint32)data->transmitbufferphy[2] + 2048);
|
data->transmitbufferphy[3] = (void *)((uint32)data->transmitbufferphy[2] + 2048);
|
||||||
WRITE_32(TSAD3, (int32)data->transmitbufferphy[3]);
|
WRITE_32(TSAD3, (int32)data->transmitbufferphy[3]);
|
||||||
|
|
||||||
if( data->transmitbuffer[0] == B_ERROR || data->transmitbuffer[2] == B_ERROR )
|
if(data->transmitbuffer[0] == B_ERROR || data->transmitbuffer[2] == B_ERROR) {
|
||||||
{
|
TRACE(("rtl8139_nielx open_hook(): memory allocation for transmitbuffer failed\n"));
|
||||||
TRACE( "rtl8139_nielx open_hook(): memory allocation for transmitbuffer failed\n" );
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,9 +468,9 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
for(temp8 = 0 ; temp8 < 6; temp8++)
|
for(temp8 = 0 ; temp8 < 6; temp8++)
|
||||||
data->address.ebyte[ temp8 ] = READ_8(IDR0 + temp8 );
|
data->address.ebyte[ temp8 ] = READ_8(IDR0 + temp8 );
|
||||||
|
|
||||||
TRACE( "rlt8139_nielx open_hook(): MAC address: %x:%x:%x:%x:%x:%x\n",
|
TRACE(("rlt8139_nielx open_hook(): MAC address: %x:%x:%x:%x:%x:%x\n",
|
||||||
data->address.ebyte[0], data->address.ebyte[1], data->address.ebyte[2],
|
data->address.ebyte[0], data->address.ebyte[1], data->address.ebyte[2],
|
||||||
data->address.ebyte[3] , data->address.ebyte[4] , data->address.ebyte[5] );
|
data->address.ebyte[3], data->address.ebyte[4], data->address.ebyte[5]));
|
||||||
|
|
||||||
/* Receive physical match packets and broadcast packets */
|
/* Receive physical match packets and broadcast packets */
|
||||||
WRITE_32(RxConfig,
|
WRITE_32(RxConfig,
|
||||||
@@ -501,9 +482,8 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
|
|
||||||
|
|
||||||
/* We want interrupts! */
|
/* We want interrupts! */
|
||||||
if ( install_io_interrupt_handler( data->pcii->u.h0.interrupt_line , rtl8139_interrupt , data , 0 ) != B_OK )
|
if (install_io_interrupt_handler(data->pcii->u.h0.interrupt_line, rtl8139_interrupt, data, 0) != B_OK) {
|
||||||
{
|
TRACE(("rtl8139_nielx open_hook(): Error installing interrupt handler\n"));
|
||||||
TRACE( "rtl8139_nielx open_hook(): Error installing interrupt handler\n" );
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,13 +498,12 @@ open_hook(const char *name, uint32 flags, void** cookie)
|
|||||||
|
|
||||||
//Check if Tx and Rx are enabled
|
//Check if Tx and Rx are enabled
|
||||||
if(!(READ_8(Command) & EnableReceive) || !(READ_8(Command) & EnableTransmit))
|
if(!(READ_8(Command) & EnableReceive) || !(READ_8(Command) & EnableTransmit))
|
||||||
TRACE( "TRANSMIT AND RECEIVE NOT ENABLED!!!\n" );
|
TRACE(("TRANSMIT AND RECEIVE NOT ENABLED!!!\n"));
|
||||||
else
|
else
|
||||||
TRACE( "TRANSMIT AND RECEIVE ENABLED!!!\n" );
|
TRACE(("TRANSMIT AND RECEIVE ENABLED!!!\n"));
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx open_hook(): Basic Mode Status Register: 0x%x ESRS: 0x%x\n" ,
|
TRACE(("rtl8139_nielx open_hook(): Basic Mode Status Register: 0x%x ESRS: 0x%x\n",
|
||||||
READ_16( BMSR ) ,
|
READ_16(BMSR), READ_8(ESRS)));
|
||||||
READ_8( ESRS ) );
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -566,7 +545,7 @@ read_hook (void* cookie, off_t position, void *buf, size_t* num_bytes)
|
|||||||
packetheader_t *packet_header;
|
packetheader_t *packet_header;
|
||||||
cpu_status former;
|
cpu_status former;
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx: read_hook()\n" );
|
TRACE(("rtl8139_nielx: read_hook()\n"));
|
||||||
|
|
||||||
//if(!data->nonblocking)
|
//if(!data->nonblocking)
|
||||||
acquire_sem_etc(data->input_wait, 1, B_CAN_INTERRUPT, 0);
|
acquire_sem_etc(data->input_wait, 1, B_CAN_INTERRUPT, 0);
|
||||||
@@ -575,9 +554,8 @@ restart:
|
|||||||
former = lock();
|
former = lock();
|
||||||
|
|
||||||
//Next: check in command register if there's actually anything to be read
|
//Next: check in command register if there's actually anything to be read
|
||||||
if ( READ_8( Command ) & BUFE )
|
if (READ_8(Command) & BUFE ) {
|
||||||
{
|
TRACE(("rtl8139_nielx read_hook: Nothing to read!!!\n"));
|
||||||
TRACE( "rtl8139_nielx read_hook: Nothing to read!!!\n" );
|
|
||||||
unlock(former);
|
unlock(former);
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -586,33 +564,30 @@ restart:
|
|||||||
packet_header = (packetheader_t *) ((uint8 *)data->receivebufferlog + data->receivebufferoffset);
|
packet_header = (packetheader_t *) ((uint8 *)data->receivebufferlog + data->receivebufferoffset);
|
||||||
|
|
||||||
// Check if the transfer is already done: EarlyRX
|
// Check if the transfer is already done: EarlyRX
|
||||||
if ( packet_header->length == 0xfff0 )
|
if (packet_header->length == 0xfff0) {
|
||||||
{
|
TRACE(("rtl8139_nielx read_hook: The transfer is not yet finished!!!\n"));
|
||||||
TRACE( "rtl8139_nielx read_hook: The transfer is not yet finished!!!\n" );
|
|
||||||
unlock(former);
|
unlock(former);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check for an error: if needed: resetrx, length may not be bigger than 1514 + 4 CRC
|
//Check for an error: if needed: resetrx, length may not be bigger than 1514 + 4 CRC
|
||||||
if ( !( packet_header->bits & 0x1 ) || packet_header->length > 1518 )
|
if (!(packet_header->bits & 0x1) || packet_header->length > 1518) {
|
||||||
{
|
TRACE(("rtl8139_nielx read_hook: Error in package reception: bits: %u length %u!!!\n", packet_header->bits, packet_header->length));
|
||||||
TRACE( "rtl8139_nielx read_hook: Error in package reception: bits: %u length %u!!!\n" , packet_header->bits , packet_header->length);
|
|
||||||
unlock (former);
|
unlock (former);
|
||||||
rtl8139_reset(data);
|
rtl8139_reset(data);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx read_hook(): Packet size: %u Receiveheader: %u Buffer size: %lu\n" , packet_header->length , packet_header->bits , *num_bytes );
|
TRACE(("rtl8139_nielx read_hook(): Packet size: %u Receiveheader: %u Buffer size: %lu\n", packet_header->length, packet_header->bits, *num_bytes));
|
||||||
|
|
||||||
//Copy the packet
|
//Copy the packet
|
||||||
*num_bytes = packet_header->length - 4;
|
*num_bytes = packet_header->length - 4;
|
||||||
if ( data->receivebufferoffset + *num_bytes > 65536 )
|
if (data->receivebufferoffset + *num_bytes > 65536) {
|
||||||
{
|
|
||||||
//Packet wraps around, copy last bits except header (= +4)
|
//Packet wraps around, copy last bits except header (= +4)
|
||||||
memcpy(buf, (void *)((uint32)data->receivebufferlog + data->receivebufferoffset + 4), 0x10000 - (data->receivebufferoffset + 4));
|
memcpy(buf, (void *)((uint32)data->receivebufferlog + data->receivebufferoffset + 4), 0x10000 - (data->receivebufferoffset + 4));
|
||||||
//copy remaining bytes from the beginning
|
//copy remaining bytes from the beginning
|
||||||
memcpy((void *) ((uint32)buf + 0x10000 - (data->receivebufferoffset + 4)), data->receivebufferlog, *num_bytes - (0x10000 - (data->receivebufferoffset + 4)));
|
memcpy((void *) ((uint32)buf + 0x10000 - (data->receivebufferoffset + 4)), data->receivebufferlog, *num_bytes - (0x10000 - (data->receivebufferoffset + 4)));
|
||||||
TRACE( "rtl8139_nielx read_hook: Wrapping around end of buffer\n" );
|
TRACE(("rtl8139_nielx read_hook: Wrapping around end of buffer\n"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
memcpy(buf, (void *) ((uint32)data->receivebufferlog + data->receivebufferoffset + 4), packet_header->length - 4); //length-4 because we don't want to copy the 4 bytes CRC
|
memcpy(buf, (void *) ((uint32)data->receivebufferlog + data->receivebufferoffset + 4), packet_header->length - 4); //length-4 because we don't want to copy the 4 bytes CRC
|
||||||
@@ -621,7 +596,7 @@ restart:
|
|||||||
data->receivebufferoffset = (data->receivebufferoffset + packet_header->length + 4 + 3) & ~3;
|
data->receivebufferoffset = (data->receivebufferoffset + packet_header->length + 4 + 3) & ~3;
|
||||||
|
|
||||||
WRITE_16(CAPR, data->receivebufferoffset - 16); //-16, avoid overflow
|
WRITE_16(CAPR, data->receivebufferoffset - 16); //-16, avoid overflow
|
||||||
TRACE( "rtl8139_nielx read_hook(): CBP %u CAPR %u \n" , READ_16( CBR ) , READ_16( CAPR ) );
|
TRACE(("rtl8139_nielx read_hook(): CBP %u CAPR %u \n", READ_16(CBR), READ_16(CAPR)));
|
||||||
|
|
||||||
unlock(former);
|
unlock(former);
|
||||||
|
|
||||||
@@ -642,7 +617,7 @@ write_hook (void* cookie, off_t position, const void* buffer, size_t* num_bytes)
|
|||||||
uint32 transmitdescription = 0;
|
uint32 transmitdescription = 0;
|
||||||
cpu_status former;
|
cpu_status former;
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx write_hook()\n" );
|
TRACE(("rtl8139_nielx write_hook()\n"));
|
||||||
|
|
||||||
acquire_sem(data->lock);
|
acquire_sem(data->lock);
|
||||||
acquire_sem_etc(data->output_wait, 1, B_CAN_INTERRUPT, 0);
|
acquire_sem_etc(data->output_wait, 1, B_CAN_INTERRUPT, 0);
|
||||||
@@ -650,17 +625,16 @@ write_hook (void* cookie, off_t position, const void* buffer, size_t* num_bytes)
|
|||||||
//Get spinlock
|
//Get spinlock
|
||||||
former = lock();
|
former = lock();
|
||||||
|
|
||||||
if ( data->writes == 4 )
|
if (data->writes == 4) {
|
||||||
{
|
|
||||||
dprintf("rtl8139_nielx write_hook(): already doing four writes\n");
|
dprintf("rtl8139_nielx write_hook(): already doing four writes\n");
|
||||||
unlock(former);
|
unlock(former);
|
||||||
release_sem_etc(data->lock, 1, B_DO_NOT_RESCHEDULE);
|
release_sem_etc(data->lock, 1, B_DO_NOT_RESCHEDULE);
|
||||||
return B_INTERRUPTED;
|
return B_INTERRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( buflen > 1792 ) //Maximum of 1792 bytes
|
if (buflen > 1792) {
|
||||||
{
|
// Maximum of 1792 bytes
|
||||||
TRACE( "rtl8139_nielx write_hook(): packet is too long\n" );
|
TRACE(("rtl8139_nielx write_hook(): packet is too long\n"));
|
||||||
unlock(former);
|
unlock(former);
|
||||||
release_sem_etc(data->lock, 1, B_DO_NOT_RESCHEDULE);
|
release_sem_etc(data->lock, 1, B_DO_NOT_RESCHEDULE);
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
@@ -668,8 +642,7 @@ write_hook (void* cookie, off_t position, const void* buffer, size_t* num_bytes)
|
|||||||
|
|
||||||
// We need to determine a free transmit descriptor
|
// We need to determine a free transmit descriptor
|
||||||
transmitid = data->queued_packets % 4;
|
transmitid = data->queued_packets % 4;
|
||||||
if ( data->transmitstatus[ transmitid ] == 1 )
|
if (data->transmitstatus[ transmitid ] == 1) {
|
||||||
{
|
|
||||||
//No free descriptor]
|
//No free descriptor]
|
||||||
unlock(former);
|
unlock(former);
|
||||||
release_sem_etc(data->lock, 1, B_DO_NOT_RESCHEDULE);
|
release_sem_etc(data->lock, 1, B_DO_NOT_RESCHEDULE);
|
||||||
@@ -690,10 +663,10 @@ write_hook (void* cookie, off_t position, const void* buffer, size_t* num_bytes)
|
|||||||
|
|
||||||
//Clear OWN and start transfer Create transmit description with early Tx FIFO, size
|
//Clear OWN and start transfer Create transmit description with early Tx FIFO, size
|
||||||
transmitdescription = (buflen | 0x80000 | transmitdescription) ^OWN; //0x80000 = early tx treshold
|
transmitdescription = (buflen | 0x80000 | transmitdescription) ^OWN; //0x80000 = early tx treshold
|
||||||
TRACE( "rtl8139_nielx write: transmitdescription = %lu\n" , transmitdescription );
|
TRACE(("rtl8139_nielx write: transmitdescription = %lu\n", transmitdescription));
|
||||||
WRITE_32(TSD0 + (sizeof(uint32) * transmitid), transmitdescription);
|
WRITE_32(TSD0 + (sizeof(uint32) * transmitid), transmitdescription);
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx write: TSAD: %u\n" , READ_16( TSAD ) );
|
TRACE(("rtl8139_nielx write: TSAD: %u\n", READ_16(TSAD)));
|
||||||
data->queued_packets++;
|
data->queued_packets++;
|
||||||
|
|
||||||
unlock(former);
|
unlock(former);
|
||||||
@@ -714,20 +687,19 @@ control_hook (void* cookie, uint32 op, void* arg, size_t len)
|
|||||||
{
|
{
|
||||||
rtl8139_properties_t *data = (rtl8139_properties_t *)cookie;
|
rtl8139_properties_t *data = (rtl8139_properties_t *)cookie;
|
||||||
ether_address_t address;
|
ether_address_t address;
|
||||||
TRACE( "rtl8139_nielx control_hook()\n" );
|
TRACE(("rtl8139_nielx control_hook()\n"));
|
||||||
|
|
||||||
|
|
||||||
switch ( op )
|
switch (op) {
|
||||||
{
|
|
||||||
case ETHER_INIT:
|
case ETHER_INIT:
|
||||||
TRACE( "rtl8139_nielx control_hook(): Wants us to init... ;-)\n" );
|
TRACE(("rtl8139_nielx control_hook(): Wants us to init... ;-)\n"));
|
||||||
return B_NO_ERROR;
|
return B_NO_ERROR;
|
||||||
|
|
||||||
case ETHER_GETADDR:
|
case ETHER_GETADDR:
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx control_hook(): Wants our address...\n" );
|
TRACE(("rtl8139_nielx control_hook(): Wants our address...\n"));
|
||||||
memcpy(arg, (void *) &(data->address), sizeof(ether_address_t));
|
memcpy(arg, (void *) &(data->address), sizeof(ether_address_t));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
@@ -738,31 +710,31 @@ control_hook (void* cookie, uint32 op, void* arg, size_t len)
|
|||||||
if (data->multiset == 8)
|
if (data->multiset == 8)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx control_hook(): Add multicast...\n" );
|
TRACE(("rtl8139_nielx control_hook(): Add multicast...\n"));
|
||||||
memcpy(&address, arg, sizeof(address));
|
memcpy(&address, arg, sizeof(address));
|
||||||
TRACE( "Multicast address: %i %i %i %i %i %i \n" , address.ebyte[0] ,
|
TRACE(("Multicast address: %i %i %i %i %i %i \n", address.ebyte[0],
|
||||||
address.ebyte[1], address.ebyte[2], address.ebyte[3], address.ebyte[4],
|
address.ebyte[1], address.ebyte[2], address.ebyte[3], address.ebyte[4],
|
||||||
address.ebyte[5] );
|
address.ebyte[5]));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case ETHER_NONBLOCK:
|
case ETHER_NONBLOCK:
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx control_hook(): Wants to set block/nonblock\n" );
|
TRACE(("rtl8139_nielx control_hook(): Wants to set block/nonblock\n"));
|
||||||
memcpy(&data->nonblocking, arg, sizeof(data->nonblocking));
|
memcpy(&data->nonblocking, arg, sizeof(data->nonblocking));
|
||||||
return B_NO_ERROR;
|
return B_NO_ERROR;
|
||||||
|
|
||||||
case ETHER_REMMULTI:
|
case ETHER_REMMULTI:
|
||||||
TRACE( "rtl8139_nielx control_hook(): Wants REMMULTI\n" );
|
TRACE(("rtl8139_nielx control_hook(): Wants REMMULTI\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case ETHER_SETPROMISC:
|
case ETHER_SETPROMISC:
|
||||||
TRACE("rtl8139_nielx control_hook(): Wants PROMISC\n" );
|
TRACE(("rtl8139_nielx control_hook(): Wants PROMISC\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case ETHER_GETFRAMESIZE:
|
case ETHER_GETFRAMESIZE:
|
||||||
TRACE("rtl8139_nielx control_hook(): Wants GETFRAMESIZE\n" ) ;
|
TRACE(("rtl8139_nielx control_hook(): Wants GETFRAMESIZE\n"));
|
||||||
*((unsigned int *)arg) = 1514;
|
*((unsigned int *)arg) = 1514;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -784,58 +756,49 @@ rtl8139_interrupt( void *cookie )
|
|||||||
|
|
||||||
status = lock();
|
status = lock();
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
isr_contents = READ_16(ISR);
|
isr_contents = READ_16(ISR);
|
||||||
if (isr_contents == 0)
|
if (isr_contents == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
TRACE( "NIELX INTERRUPT: %u \n" , isr_contents );
|
TRACE(("NIELX INTERRUPT: %u \n", isr_contents));
|
||||||
if( isr_contents & ReceiveOk )
|
if(isr_contents & ReceiveOk) {
|
||||||
{
|
TRACE(("rtl8139_nielx interrupt ReceiveOk\n"));
|
||||||
TRACE( "rtl8139_nielx interrupt ReceiveOk\n" );
|
|
||||||
release_sem_etc(data->input_wait, 1, B_DO_NOT_RESCHEDULE);
|
release_sem_etc(data->input_wait, 1, B_DO_NOT_RESCHEDULE);
|
||||||
retval = B_INVOKE_SCHEDULER;
|
retval = B_INVOKE_SCHEDULER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isr_contents & ReceiveError )
|
if (isr_contents & ReceiveError) {
|
||||||
{
|
|
||||||
//Do something
|
//Do something
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isr_contents & TransmitOk )
|
if (isr_contents & TransmitOk) {
|
||||||
{
|
|
||||||
uint32 checks = data->queued_packets - data->finished_packets;
|
uint32 checks = data->queued_packets - data->finished_packets;
|
||||||
uint32 txstatus;
|
uint32 txstatus;
|
||||||
// Check each status descriptor
|
// Check each status descriptor
|
||||||
while( checks > 0 )
|
while(checks > 0) {
|
||||||
{
|
|
||||||
// If a register isn't used, continue next run
|
// If a register isn't used, continue next run
|
||||||
temp8 = data->finished_packets % 4 ;
|
temp8 = data->finished_packets % 4 ;
|
||||||
txstatus = READ_32(TSD0 + temp8 * sizeof(int32));
|
txstatus = READ_32(TSD0 + temp8 * sizeof(int32));
|
||||||
dprintf("run: %u txstatus: %lu Register: %lx\n", temp8, txstatus, TSD0 + temp8 * sizeof(int32));
|
dprintf("run: %u txstatus: %lu Register: %lx\n", temp8, txstatus, TSD0 + temp8 * sizeof(int32));
|
||||||
|
|
||||||
if ( !( txstatus & ( TOK | TUN | TABT ) ) )
|
if (!(txstatus & (TOK | TUN | TABT))) {
|
||||||
{
|
|
||||||
dprintf("NOT FINISHED\n");
|
dprintf("NOT FINISHED\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( txstatus & ( TABT | OWC ) )
|
if (txstatus & (TABT | OWC)) {
|
||||||
{
|
|
||||||
dprintf("MAJOR ERROR\n");
|
dprintf("MAJOR ERROR\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( txstatus &( TUN ) )
|
if (txstatus &(TUN)) {
|
||||||
{
|
|
||||||
dprintf("TRANSMIT UNDERRUN\n");
|
dprintf("TRANSMIT UNDERRUN\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( txstatus & TOK ) )
|
if ((txstatus & TOK)) {
|
||||||
{
|
|
||||||
//this one is the one!
|
//this one is the one!
|
||||||
dprintf("NIELX INTERRUPT: TXOK, clearing register %u\n", temp8);
|
dprintf("NIELX INTERRUPT: TXOK, clearing register %u\n", temp8);
|
||||||
data->transmitstatus[temp8] = 0; //That's all there is to it
|
data->transmitstatus[temp8] = 0; //That's all there is to it
|
||||||
@@ -851,42 +814,35 @@ rtl8139_interrupt( void *cookie )
|
|||||||
retval = B_HANDLED_INTERRUPT;
|
retval = B_HANDLED_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isr_contents & TransmitError )
|
if(isr_contents & TransmitError) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isr_contents & ReceiveOverflow )
|
if(isr_contents & ReceiveOverflow) {
|
||||||
{
|
|
||||||
// Discard all the current packages to be processed -- newos driver
|
// Discard all the current packages to be processed -- newos driver
|
||||||
WRITE_16(CAPR, (READ_16(CBR) + 16) % 0x1000);
|
WRITE_16(CAPR, (READ_16(CBR) + 16) % 0x1000);
|
||||||
retval = B_HANDLED_INTERRUPT;
|
retval = B_HANDLED_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isr_contents & ReceiveUnderflow )
|
if(isr_contents & ReceiveUnderflow) {
|
||||||
{
|
|
||||||
// Most probably a link change -> TODO CHECK!
|
// Most probably a link change -> TODO CHECK!
|
||||||
TRACE( "rtl8139_nielx interrupt(): BMCR: 0x%x BMSR: 0x%x\n" ,
|
TRACE(("rtl8139_nielx interrupt(): BMCR: 0x%x BMSR: 0x%x\n",
|
||||||
READ_16( BMCR ) ,
|
READ_16(BMCR), READ_16(BMSR)));
|
||||||
READ_16( BMSR ) );
|
|
||||||
retval = B_HANDLED_INTERRUPT;
|
retval = B_HANDLED_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isr_contents & ReceiveFIFOOverrun )
|
if (isr_contents & ReceiveFIFOOverrun) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isr_contents & TimeOut )
|
if (isr_contents & TimeOut) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isr_contents & SystemError )
|
if (isr_contents & SystemError) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -923,7 +879,7 @@ free_hook (void* cookie)
|
|||||||
{
|
{
|
||||||
rtl8139_properties_t *data = (rtl8139_properties_t *) cookie;
|
rtl8139_properties_t *data = (rtl8139_properties_t *) cookie;
|
||||||
|
|
||||||
TRACE( "rtl8139_nielx free_hook()\n" );
|
TRACE(("rtl8139_nielx free_hook()\n"));
|
||||||
|
|
||||||
//Remove interrupt handler
|
//Remove interrupt handler
|
||||||
remove_io_interrupt_handler(data->pcii->u.h0.interrupt_line,
|
remove_io_interrupt_handler(data->pcii->u.h0.interrupt_line,
|
||||||
@@ -935,12 +891,12 @@ free_hook (void* cookie)
|
|||||||
delete_area(data->transmitbuffer[2]);
|
delete_area(data->transmitbuffer[2]);
|
||||||
delete_area(data->ioarea); //Only does something on ppc
|
delete_area(data->ioarea); //Only does something on ppc
|
||||||
|
|
||||||
//Finally, free the cookie
|
|
||||||
free( data );
|
|
||||||
|
|
||||||
// mark this device as closed
|
// mark this device as closed
|
||||||
gDeviceOpenMask &= ~(1L << data->device_id);
|
gDeviceOpenMask &= ~(1L << data->device_id);
|
||||||
|
|
||||||
|
//Finally, free the cookie
|
||||||
|
free(data);
|
||||||
|
|
||||||
//Put the pci module
|
//Put the pci module
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user