* 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:
Oliver Tappe
2006-08-04 19:34:43 +00:00
parent 78f9905a57
commit b07b33c4ec
@@ -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,42 +122,39 @@ 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];
} packetheader_t; } packetheader_t;
static status_t close_hook( void * ); static status_t close_hook(void *);
/* ----- /* -----
Here all platform dependant code is placed: this keeps the code clean Here all platform dependant code is placed: this keeps the code clean
----- */ ----- */
#ifdef __INTEL__ #ifdef __INTEL__
#define WRITE_8( offset , value) (gPCIModule->write_io_8 ((data->reg_base + (offset)), (value) ) ) #define WRITE_8( offset, value) (gPCIModule->write_io_8 ((data->reg_base + (offset)), (value)))
#define WRITE_16( offset , value) (gPCIModule->write_io_16((data->reg_base + (offset)), (value) ) ) #define WRITE_16(offset, value) (gPCIModule->write_io_16((data->reg_base + (offset)), (value)))
#define WRITE_32( offset , value) (gPCIModule->write_io_32((data->reg_base + (offset)), (value) ) ) #define WRITE_32(offset, value) (gPCIModule->write_io_32((data->reg_base + (offset)), (value)))
#define READ_8( offset ) (gPCIModule->read_io_8 ((data->reg_base + offset))) #define READ_8( offset) (gPCIModule->read_io_8 ((data->reg_base + offset)))
#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 */
#include <ByteOrder.h> #include <ByteOrder.h>
#define WRITE_8( offset , value) (*((volatile uint8 *)(data->reg_base + (offset))) = (value)) #define WRITE_8( offset, value) (*((volatile uint8 *)(data->reg_base + (offset))) = (value))
#define WRITE_16( offset , value) (*((volatile uint8 *)(data->reg_base + (offset))) = B_HOST_TO_LENDIAN_INT16(value)) #define WRITE_16(offset, value) (*((volatile uint8 *)(data->reg_base + (offset))) = B_HOST_TO_LENDIAN_INT16(value))
#define WRITE_32( offset , value) (*((volatile uint8 *)(data->reg_base + (offset))) = B_HOST_TO_LENDIAN_INT32(value)) #define WRITE_32(offset, value) (*((volatile uint8 *)(data->reg_base + (offset))) = B_HOST_TO_LENDIAN_INT32(value))
#define READ_8( offset ) (*((volatile uint8*)(data->reg_base + (offset)))) #define READ_8( offset) (*((volatile uint8*)(data->reg_base + (offset))))
#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++;
@@ -239,13 +230,12 @@ 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,15 +262,14 @@ 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]);
} }
put_module( B_PCI_MODULE_NAME ); put_module(B_PCI_MODULE_NAME);
} }
@@ -290,11 +278,10 @@ uninit_driver (void)
----- */ ----- */
//FWD declaration: //FWD declaration:
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,158 +312,152 @@ 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;
} }
//Clear memory //Clear memory
memset( data , 0 , sizeof( rtl8139_properties_t ) ); memset(data, 0, sizeof(rtl8139_properties_t));
//Set the ID //Set the ID
data->device_id = id; data->device_id = id;
// Create lock // Create lock
data->lock = create_sem( 1 , "rtl8139_nielx data protect" ); data->lock = create_sem(1, "rtl8139_nielx data protect");
set_sem_owner( data->lock , B_SYSTEM_TEAM ); set_sem_owner(data->lock, B_SYSTEM_TEAM);
data->input_wait = create_sem( 0 , "rtl8139_nielx read wait" ); data->input_wait = create_sem(0, "rtl8139_nielx read wait");
set_sem_owner( data->input_wait , B_SYSTEM_TEAM ); set_sem_owner(data->input_wait, B_SYSTEM_TEAM);
data->output_wait = create_sem( 1 , "rtl8139_nielx write wait" ); data->output_wait = create_sem(1, "rtl8139_nielx write wait");
set_sem_owner( data->output_wait , B_SYSTEM_TEAM ); set_sem_owner(data->output_wait, B_SYSTEM_TEAM);
//Set up the cookie //Set up the cookie
data->pcii = gFoundDevices[data->device_id]; data->pcii = gFoundDevices[data->device_id];
//Enable the registers //Enable the registers
rtl8139_init_registers( data ); rtl8139_init_registers(data);
/* enable pci address access */ /* enable pci address access */
cmd = gPCIModule->read_pci_config(data->pcii->bus, data->pcii->device, data->pcii->function, PCI_command, 2); cmd = gPCIModule->read_pci_config(data->pcii->bus, data->pcii->device, data->pcii->function, PCI_command, 2);
cmd = cmd | PCI_command_io | PCI_command_master | PCI_command_memory; cmd = cmd | PCI_command_io | PCI_command_master | PCI_command_memory;
gPCIModule->write_pci_config(data->pcii->bus, data->pcii->device, data->pcii->function, PCI_command, 2, cmd ); gPCIModule->write_pci_config(data->pcii->bus, data->pcii->device, data->pcii->function, PCI_command, 2, cmd);
// 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;
} }
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;
} }
/* TODO: Linux driver does power management here... */ /* TODO: Linux driver does power management here... */
/* Reset the chip -- command register;*/ /* Reset the chip -- command register;*/
WRITE_8 ( Command , Reset ); WRITE_8 (Command, Reset);
temp16 = 10000; temp16 = 10000;
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);
/* Since the reset was succesful, we can immediately open the transmit and receive registers */ /* Since the reset was succesful, we can immediately open the transmit and receive registers */
WRITE_8( Command , EnableReceive | EnableTransmit ); WRITE_8(Command, EnableReceive | EnableTransmit);
/* Reset Config1 register */ /* Reset Config1 register */
WRITE_8( Config1 , 0 ); WRITE_8(Config1, 0);
// Turn off lan-wake and set the driver-loaded bit // Turn off lan-wake and set the driver-loaded bit
WRITE_8( Config1, ( READ_8( Config1 )& ~0x30) | 0x20); WRITE_8(Config1, (READ_8(Config1)& ~0x30) | 0x20);
// Enable FIFO auto-clear // Enable FIFO auto-clear
WRITE_8( Config4, READ_8( Config4) | 0x80); WRITE_8(Config4, READ_8(Config4) | 0x80);
// Go to normal operation // Go to normal operation
WRITE_8( _9346CR , 0 ); WRITE_8(_9346CR, 0);
/* Reset Rx Missed counter*/ /* Reset Rx Missed counter*/
WRITE_16( MPC , 0 ); WRITE_16(MPC, 0);
/* Configure the Transmit Register */ /* Configure the Transmit Register */
//settings: Max DMA burst size per Tx DMA burst is 1024 ( = 110 ) //settings: Max DMA burst size per Tx DMA burst is 1024 (= 110)
//settings: Interframe GAP time according to IEEE standard ( = 11 ) //settings: Interframe GAP time according to IEEE standard (= 11)
WRITE_32( TxConfig , WRITE_32(TxConfig,
IFG_1 | IFG_0 | MXDMA_1 ); IFG_1 | IFG_0 | MXDMA_1);
/* Configure the Receive Register */ /* Configure the Receive Register */
//settings: Early Rx Treshold is 1024 kB ( = 110 ) DISABLED //settings: Early Rx Treshold is 1024 kB (= 110) DISABLED
//settings: Max DMA burst size per Rx DMA burst is 1024 ( = 110 ) //settings: Max DMA burst size per Rx DMA burst is 1024 (= 110)
//settings: The Rx Buffer length is 64k + 16 bytes ( = 11 ) //settings: The Rx Buffer length is 64k + 16 bytes (= 11)
//settings: continue last packet in memory if it exceeds buffer length. //settings: continue last packet in memory if it exceeds buffer length.
WRITE_32( RxConfig , /*RXFTH2 | RXFTH1 | */ WRITE_32(RxConfig, /*RXFTH2 | RXFTH1 | */
RBLEN_1 | RBLEN_0 | WRAP | MXDMA_2 | MXDMA_1 | APM | AB); RBLEN_1 | RBLEN_0 | WRAP | MXDMA_2 | MXDMA_1 | APM | AB);
//Disable blocking //Disable blocking
data->nonblocking = 0; data->nonblocking = 0;
//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);
data->receivebufferoffset = 0; //First packet starts at 0 data->receivebufferoffset = 0; //First packet starts at 0
//Disable all multi-interrupts //Disable all multi-interrupts
WRITE_16( MULINT , 0 ); WRITE_16(MULINT, 0);
//Allocate buffers for transmit (There can be two buffers in one page) //Allocate buffers for transmit (There can be two buffers in one page)
data->transmitbuffer[0] = alloc_mem( &(data->transmitbufferlog[0]) , &(data->transmitbufferphy[0]) , 4096 , "txbuffer01" ); data->transmitbuffer[0] = alloc_mem(&(data->transmitbufferlog[0]), &(data->transmitbufferphy[0]), 4096, "txbuffer01");
WRITE_32( TSAD0 , (int32)data->transmitbufferphy[0] ); WRITE_32(TSAD0, (int32)data->transmitbufferphy[0]);
data->transmitbuffer[1] = data->transmitbuffer[0]; data->transmitbuffer[1] = data->transmitbuffer[0];
data->transmitbufferlog[1] = (void *)( (uint32)data->transmitbufferlog[0] + 2048 ); data->transmitbufferlog[1] = (void *)((uint32)data->transmitbufferlog[0] + 2048);
data->transmitbufferphy[1] = (void *)( (uint32)data->transmitbufferphy[0] + 2048 ); data->transmitbufferphy[1] = (void *)((uint32)data->transmitbufferphy[0] + 2048);
WRITE_32( TSAD1 , (int32)data->transmitbufferphy[1] ); WRITE_32(TSAD1, (int32)data->transmitbufferphy[1]);
data->transmitbuffer[2] = alloc_mem( &(data->transmitbufferlog[2]) , &(data->transmitbufferphy[2]) , 4096 , "txbuffer23" ); data->transmitbuffer[2] = alloc_mem(&(data->transmitbufferlog[2]), &(data->transmitbufferphy[2]), 4096, "txbuffer23");
WRITE_32( TSAD2 , (int32)data->transmitbufferphy[2] ); WRITE_32(TSAD2, (int32)data->transmitbufferphy[2]);
data->transmitbuffer[3] = data->transmitbuffer[2]; data->transmitbuffer[3] = data->transmitbuffer[2];
data->transmitbufferlog[3] = (void *)( (uint32)data->transmitbufferlog[2] + 2048 ); data->transmitbufferlog[3] = (void *)((uint32)data->transmitbufferlog[2] + 2048);
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;
} }
@@ -484,47 +465,45 @@ open_hook(const char *name, uint32 flags, void** cookie)
data->finished_packets = 0; data->finished_packets = 0;
// Receive hardware MAC address // Receive hardware MAC address
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,
(READ_32( RxConfig )) | APM | AB ); (READ_32(RxConfig)) | APM | AB);
//Clear multicast mask //Clear multicast mask
WRITE_32( MAR0 , 0 ); WRITE_32(MAR0, 0);
WRITE_32( MAR0 + 4 , 0 ); WRITE_32(MAR0 + 4, 0);
/* 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;
} }
WRITE_16( IMR , WRITE_16(IMR,
ReceiveOk | ReceiveError | TransmitOk | TransmitError | ReceiveOk | ReceiveError | TransmitOk | TransmitError |
ReceiveOverflow | ReceiveUnderflow | ReceiveFIFOOverrun | ReceiveOverflow | ReceiveUnderflow | ReceiveFIFOOverrun |
TimeOut | SystemError ); TimeOut | SystemError);
/* Enable once more */ /* Enable once more */
WRITE_8( _9346CR , 0 ); WRITE_8(_9346CR, 0);
WRITE_8( Command , EnableReceive | EnableTransmit ); WRITE_8(Command, EnableReceive | EnableTransmit);
//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;
} }
@@ -534,25 +513,25 @@ open_hook(const char *name, uint32 flags, void** cookie)
rtl8139_reset - resets the card rtl8139_reset - resets the card
----- */ ----- */
static void rtl8139_reset( rtl8139_properties_t *data ) static void rtl8139_reset(rtl8139_properties_t *data)
{ {
// Stop everything and disable interrupts // Stop everything and disable interrupts
WRITE_8( Command , Reset ); WRITE_8(Command, Reset);
WRITE_16( IMR , 0 ); WRITE_16(IMR, 0);
//Reset the buffer pointers //Reset the buffer pointers
WRITE_16( CBR , 0 ); WRITE_16(CBR, 0);
WRITE_16( CAPR , 0 - 16 ); WRITE_16(CAPR, 0 - 16);
data->receivebufferoffset = 0; data->receivebufferoffset = 0;
//Re-enable interrupts //Re-enable interrupts
WRITE_16( IMR , WRITE_16(IMR,
ReceiveOk | ReceiveError | TransmitOk | TransmitError | ReceiveOk | ReceiveError | TransmitOk | TransmitError |
ReceiveOverflow | ReceiveUnderflow | ReceiveFIFOOverrun | ReceiveOverflow | ReceiveUnderflow | ReceiveFIFOOverrun |
TimeOut | SystemError ); TimeOut | SystemError);
//Start rx/tx //Start rx/tx
WRITE_8( Command , EnableReceive | EnableTransmit ); WRITE_8(Command, EnableReceive | EnableTransmit);
} }
/* ---------- /* ----------
@@ -566,64 +545,60 @@ 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);
restart: 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;
} }
// Retrieve the packet header // Retrieve the packet header
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
//Update the buffer -- 4 for the header length, plus 3 for the dword allignment //Update the buffer -- 4 for the header length, plus 3 for the dword allignment
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);
return packet_header->length - 4; return packet_header->length - 4;
} }
@@ -642,63 +617,61 @@ 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);
//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;
} }
// 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);
return B_IO_ERROR; return B_IO_ERROR;
} }
dprintf( "rtl8139_nielx write_hook(): TransmitID: %u Packagelen: %u Register: %lx\n" , transmitid , buflen , TSD0 + (sizeof(uint32) * transmitid ) ); dprintf("rtl8139_nielx write_hook(): TransmitID: %u Packagelen: %u Register: %lx\n", transmitid, buflen, TSD0 + (sizeof(uint32) * transmitid));
data->writes++; data->writes++;
// Set the buffer as used // Set the buffer as used
data->transmitstatus[transmitid] = 1; data->transmitstatus[transmitid] = 1;
//Copy the packet into the buffer //Copy the packet into the buffer
memcpy( data->transmitbufferlog[transmitid] , buffer , buflen ); memcpy(data->transmitbufferlog[transmitid], buffer, buflen);
if ( buflen < 60 ) if (buflen < 60)
buflen = 60; buflen = 60;
//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);
release_sem_etc( data->lock , 1 , B_DO_NOT_RESCHEDULE ); release_sem_etc(data->lock, 1, B_DO_NOT_RESCHEDULE);
//Done //Done
return B_OK; return B_OK;
@@ -714,56 +687,55 @@ 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;
case ETHER_ADDMULTI: case ETHER_ADDMULTI:
if (data == NULL ) if (data == NULL)
return B_ERROR; return B_ERROR;
//Check if the maximum of multicast addresses isn't reached //Check if the maximum of multicast addresses isn't reached
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;
} }
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -774,7 +746,7 @@ control_hook (void* cookie, uint32 op, void* arg, size_t len)
----- */ ----- */
static int32 static int32
rtl8139_interrupt( void *cookie ) rtl8139_interrupt(void *cookie)
{ {
rtl8139_properties_t *data = (rtl8139_properties_t *)cookie; rtl8139_properties_t *data = (rtl8139_properties_t *)cookie;
uint8 temp8; uint8 temp8;
@@ -784,65 +756,56 @@ 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
data->writes--; data->writes--;
data->finished_packets++; data->finished_packets++;
checks--; checks--;
release_sem_etc( data->output_wait , 1 , B_DO_NOT_RESCHEDULE ); release_sem_etc(data->output_wait, 1, B_DO_NOT_RESCHEDULE);
//update next transmitid //update next transmitid
continue; continue;
} }
@@ -851,49 +814,42 @@ 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) {
{
// //
; ;
} }
WRITE_16( ISR , isr_contents ); WRITE_16(ISR, isr_contents);
} }
unlock( status ); unlock(status);
return retval; return retval;
} }
@@ -907,8 +863,8 @@ close_hook (void* cookie)
{ {
rtl8139_properties_t * data = (rtl8139_properties_t *) cookie; rtl8139_properties_t * data = (rtl8139_properties_t *) cookie;
//Stop Rx and Tx process //Stop Rx and Tx process
WRITE_8( Command , 0 ); WRITE_8(Command, 0);
WRITE_16( IMR , 0 ); WRITE_16(IMR, 0);
return B_OK; return B_OK;
} }
@@ -923,26 +879,26 @@ 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,
rtl8139_interrupt , cookie ); rtl8139_interrupt, cookie);
//Free Rx and Tx buffers //Free Rx and Tx buffers
delete_area( data->receivebuffer ); delete_area(data->receivebuffer);
delete_area( data->transmitbuffer[0] ); delete_area(data->transmitbuffer[0]);
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);
return B_OK; return B_OK;
} }
@@ -955,9 +911,9 @@ free_hook (void* cookie)
device_hooks rtl8139_hooks = { device_hooks rtl8139_hooks = {
open_hook, /* -> open entry point */ open_hook, /* -> open entry point */
close_hook, /* -> close entry point */ close_hook, /* -> close entry point */
free_hook, /* -> free cookie */ free_hook, /* -> free cookie */
control_hook, /* -> control entry point */ control_hook, /* -> control entry point */
read_hook, /* -> read entry point */ read_hook, /* -> read entry point */
write_hook /* -> write entry point */ write_hook /* -> write entry point */
}; };