# RUN make command means what



## iinfi (Dec 3, 2008)

i have a USB to ethernet device which i want to use in linux.
i downloaded the driver files from the net for the same but am unable to understand the instructions.
the instructions in the readme go as follows.



> DAVICOM Semiconductor Inc.				11/24/2006
> 
> A Davicom DM9601 USB Fast Ethernet driver for Linux.
> Copyright (C) 1997  Sten Wang
> ...



contents of the file named "Makefile"

```
##================================================================
##     Davicom Semiconductor Inc.  	For DM9601 V0.00
##   --------------------------------------------------------
## Description:
##              Compile driver dm9601.c to dm9601.o
##
## Modification List:
## 09/05/2000	Fixed SMPFALGS wrong on smp & smp_mod
## 08/02/2000	Changed some description string & include file path
## 07/25/2000	Append smp_mod and changed some descriptions
## 01/25/2000	by Sten Wang
##================================================================
# Comment/uncomment the following line to disable/enable debugging
#DEBUG = y

# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
  DEBFLAGS = -O -g # "-O" is needed to expand inlines
else
  DEBFLAGS = -O2
endif

CFLAGS += $(DEBFLAGS) -I$(LDDINCDIR)

ifneq ($(KERNELRELEASE),)
# call from kernel build system

obj-m	:= dm9601.o

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINCDIR=$(PWD)/../include modules

endif



clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

depend .depend dep:
	$(CC) $(CFLAGS) -M *.c > .depend


ifeq (.depend,$(wildcard .depend))
include .depend
endif
```

contents of the file named "dm9601.c"

```
/*
**	DM9601: USB 10/100Mbps/HomePNA (1Mbps) Fast Ethernet
**
**	Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg)
**	
**
**	ChangeLog:
**	v0.01		 Work for DM9601 now.
**	v0.02		 rename to dm9601.
**	v0.03		 Debug TX full to cause TX hang problem.
**	v0.04		 Support MAC/Hash address
**			 REG5 get better RX performance when bit4=0
**			 Power-Down PHY when driver close
**	v0.05		 Support dynamic reset
**			 Support automatically switch IntPHY/EXT MII
**			 Support REG_8, REG_9, REG_A for flow control
**	V0.06   06/14/01 Dynamic select INT/EXT MII by REG1 bit 4
**			 Support Force and Auto mode
**	V0.07	06/14/01 Program HPNA chip E3/E4/E5
**	V0.08	06/15/01 Enable REG_F4 bit5 to force "INT always return"
**	V0.09	06/19/01 Default set REG_0A bit3 to enable BP with DA match
**		06/22/01 Modify DM9801 progrmming	
**			 E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
**			 E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
**			     R17 = (R17 & 0xfff0) | NF + 3
**			 E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
**			     R17 = (R17 & 0xfff0) | NF
**
**      V1.00   03/05/03 Weilun Huang <weilun_huang@davicom.com.tw>:
**			 Added semaphore mechanism to solve the problem. 
**			 While device is being plugged, it makes kernel 
**			 hang on VIA chipset. Removed the devrequest typedef 
**			 use "struct usb_ctrlrequest".
**	v1.01   06/01/12 Michael shen <michaelshen@davicom.com.cn>:
**			 modify argument of try_module_get and module_put
**			 to be THIS_MODULE to pass compiling for kernel 2.6.9
*/

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/config.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/crc32.h>
#include "dm9601.h"
extern int usb_set_configuration(struct usb_device *dev, int configuration);


#define	DM9601_USE_INTR

static const char *version = __FILE__ ": v0.0.6 2001/05/24 (C) 1999-2000 Petko Manolov (petkan@dce.bg)";

static struct usb_eth_dev usb_dev_id[] = {
#define	DM9601_DEV(pn, vid, pid, flags)	\
	{name:pn, vendor:vid, device:pid, private:flags},
#include "dm9601.h"
#undef	DM9601_DEV
	{NULL, 0, 0, 0}
};

static struct usb_device_id dm9601_ids[] = {
#define	DM9601_DEV(pn, vid, pid, flags) \
	{match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor:vid, idProduct:pid},
#include "dm9601.h"
#undef	DM9601_DEV
	{ }
};

/* For module input parameter */
static int mode = DM9601_AUTO, dm9601_mode;
static 	u8 reg5 = DM9601_REG5, reg8 = DM9601_REG8, reg9 = DM9601_REG9, 
	rega = DM9601_REGA, nfloor = 0;

MODULE_AUTHOR("Petko Manolov <petkan@dce.bg>");
MODULE_DESCRIPTION("DAVICOM DM9601 USB Fast Ethernet driver");
MODULE_LICENSE("Dual BSD/GPL");

/*
 * USB-status codes: not defined in 2.6
 * USB_ST* maps to -E* and should go away in the future
 */

#define USB_ST_NOERROR		0
#define USB_ST_CRC		(-EILSEQ)
#define USB_ST_BITSTUFF		(-EPROTO)
#define USB_ST_NORESPONSE	(-ETIMEDOUT)			/* device not responding/handshaking */
#define USB_ST_DATAOVERRUN	(-EOVERFLOW)
#define USB_ST_DATAUNDERRUN	(-EREMOTEIO)
#define USB_ST_BUFFEROVERRUN	(-ECOMM)
#define USB_ST_BUFFERUNDERRUN	(-ENOSR)
#define USB_ST_INTERNALERROR	(-EPROTO) 			/* unknown error */
#define USB_ST_SHORT_PACKET    	(-EREMOTEIO)
#define USB_ST_PARTIAL_ERROR  	(-EXDEV)			/* ISO transfer only partially completed */
#define USB_ST_URB_KILLED     	(-ENOENT)			/* URB canceled by user */
#define USB_ST_URB_PENDING       (-EINPROGRESS)
#define USB_ST_REMOVED		(-ENODEV) 			/* device not existing or removed */
#define USB_ST_TIMEOUT		(-ETIMEDOUT)			/* communication timed out, also in urb->status**/
#define USB_ST_NOTSUPPORTED	(-ENOSYS)			
#define USB_ST_BANDWIDTH_ERROR	(-ENOSPC)			/* too much bandwidth used */
#define USB_ST_URB_INVALID_ERROR  (-EINVAL)			/* invalid value/transfer type */
#define USB_ST_URB_REQUEST_ERROR  (-ENXIO)			/* invalid endpoint */
#define USB_ST_STALL		(-EPIPE) 			/* pipe stalled, also in urb->status*/

module_param(mode, int,0644);
module_param(reg5,int,0644);
module_param(reg8,int,0644);
module_param(reg9,int,0644);
module_param(rega,int,0644);
module_param(nfloor,int,0644);

MODULE_PARM_DESC(mode, "Media mode select: 0:10MH 1:100MHF 4:10MF 5:100MF 8:AUTO");

MODULE_DEVICE_TABLE (usb, dm9601_ids);

static int write_eprom_word(dm9601_board_info_t *, __u8, __u16);
static int update_eth_regs_async(dm9601_board_info_t *);

/* Aargh!!! I _really_ hate such tweaks */
static void ctrl_callback(struct urb *urb, struct pt_regs* regs)
{
	dm9601_board_info_t	*dbi = urb->context;

	if (!dbi)
		return;

	switch (urb->status & 0xff) {
		case USB_ST_NOERROR:
		case 0x92:
			if (dbi->flags & ALL_REGS_CHANGE) {
				update_eth_regs_async(dbi);
				return;
			}
			break;
		case USB_ST_URB_PENDING:
		case 0x8d:
			return;
		case USB_ST_URB_KILLED:
			break;
		default:
			warn("%s: status %x",__FUNCTION__, urb->status);
	}

	dbi->flags &= ~ALL_REGS_CHANGED;
	
	if (dbi->flags & CTRL_URB_SLEEP) {
		dbi->flags &= ~CTRL_URB_SLEEP;
		wake_up_interruptible(&dbi->ctrl_wait);
	}
}


static int get_registers(dm9601_board_info_t *dbi, __u16 indx, __u16 size, void *data)
{
	int	ret;
	DECLARE_WAITQUEUE(wait, current);

	while ( dbi->flags & ALL_REGS_CHANGED ) {
		dbi->flags |= CTRL_URB_SLEEP;
		interruptible_sleep_on( &dbi->ctrl_wait );
	}
	
	dbi->dr.bRequestType = DM9601_REQT_READ;
	dbi->dr.bRequest     = DM9601_REQ_GET_REGS;
	dbi->dr.wValue       = cpu_to_le16 (0);
	dbi->dr.wIndex       = cpu_to_le16p(&indx);
	dbi->dr.wLength      = cpu_to_le16p(&size);
	dbi->ctrl_urb.transfer_buffer_length = size;

	usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
			  usb_rcvctrlpipe(dbi->usb,0),
			  (char *)&dbi->dr,
			  data, size, ctrl_callback, dbi );

	add_wait_queue( &dbi->ctrl_wait, &wait );
	set_current_state( TASK_INTERRUPTIBLE );
	dbi->flags |= CTRL_URB_SLEEP;

	if ( (ret = usb_submit_urb( &dbi->ctrl_urb ,GFP_ATOMIC)) ) {
		err("%s: BAD CTRLs %d",__FUNCTION__,ret);
		goto out;
	}

	schedule();
	remove_wait_queue( &dbi->ctrl_wait, &wait );
out:
	return	ret;
}


static int set_registers(dm9601_board_info_t *dbi, __u16 indx, __u16 size, void *data)
{
	int	ret;
	DECLARE_WAITQUEUE(wait, current);

	while (dbi->flags & ALL_REGS_CHANGED) {
		dbi->flags |= CTRL_URB_SLEEP ;
		interruptible_sleep_on(&dbi->ctrl_wait);
	}
	
	dbi->dr.bRequestType = DM9601_REQT_WRITE;
	dbi->dr.bRequest     = DM9601_REQ_SET_REGS;
	dbi->dr.wValue       = cpu_to_le16(0);
	dbi->dr.wIndex       = cpu_to_le16p(&indx);
	dbi->dr.wLength      = cpu_to_le16p(&size);
	dbi->ctrl_urb.transfer_buffer_length = size;

	usb_fill_control_urb(&dbi->ctrl_urb, dbi->usb,
			  usb_sndctrlpipe(dbi->usb, 0),
			  (char *)&dbi->dr,
			  data, size, ctrl_callback, dbi);
			  
	add_wait_queue(&dbi->ctrl_wait, &wait);
	set_current_state(TASK_INTERRUPTIBLE);
	dbi->flags |= CTRL_URB_SLEEP;

	if ( (ret = usb_submit_urb(&dbi->ctrl_urb,GFP_ATOMIC)) ) {
		err("%s: BAD CTRL %d",__FUNCTION__,ret);
		return	ret;
	}

	schedule();
	remove_wait_queue( &dbi->ctrl_wait, &wait );

	return	ret;
}


static int set_register( dm9601_board_info_t *dbi, __u16 indx, __u8 data )
{
	int	ret;
	__u16 dat = data;
	DECLARE_WAITQUEUE(wait, current);
	
	while ( dbi->flags & ALL_REGS_CHANGED ) {
		dbi->flags |= CTRL_URB_SLEEP;
		interruptible_sleep_on( &dbi->ctrl_wait );
	}
	
	dbi->dr.bRequestType = DM9601_REQT_WRITE;
	dbi->dr.bRequest     = DM9601_REQ_SET_REG;
	dbi->dr.wValue 	     = cpu_to_le16p( &dat);
	dbi->dr.wIndex 	     = cpu_to_le16p( &indx );
	dbi->dr.wLength      = cpu_to_le16( 0 );
	dbi->ctrl_urb.transfer_buffer_length = 0;

	usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
			  usb_sndctrlpipe(dbi->usb,0),
			  (char *)&dbi->dr,
			  &data, 0, ctrl_callback, dbi );

	add_wait_queue( &dbi->ctrl_wait, &wait );
	set_current_state( TASK_INTERRUPTIBLE );
	dbi->flags |= CTRL_URB_SLEEP;

	if ( (ret = usb_submit_urb( &dbi->ctrl_urb ,GFP_ATOMIC)) ) {
		err("%s: BAD CTRL %d",__FUNCTION__,ret);
		return	ret;
	}

	schedule();
	remove_wait_queue( &dbi->ctrl_wait, &wait );

	return	ret;
}

static int update_eth_regs_async( dm9601_board_info_t *dbi )
{
	int	ret;

	if (dbi->flags & HASH_REGS_CHANGE) {
		dbi->flags &= ~HASH_REGS_CHANGE;
		dbi->flags |= HASH_REGS_CHANGED;
		dbi->dr.bRequestType = DM9601_REQT_WRITE;
		dbi->dr.bRequest     = DM9601_REQ_SET_REGS;
		dbi->dr.wValue       = cpu_to_le16(0);
		dbi->dr.wIndex       = cpu_to_le16(0x16);
		dbi->dr.wLength      = cpu_to_le16(8);
		dbi->ctrl_urb.transfer_buffer_length = 8;

		usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
			  usb_sndctrlpipe(dbi->usb,0),
			  (char *)&dbi->dr,
			  dbi->hash_table, 8, ctrl_callback, dbi );
	} else if (dbi->flags & RX_CTRL_CHANGE) {
		dbi->flags &= ~RX_CTRL_CHANGE;
		dbi->flags |= RX_CTRL_CHANGED;
		dbi->dr.bRequestType = DM9601_REQT_WRITE;
		dbi->dr.bRequest     = DM9601_REQ_SET_REG;
		dbi->dr.wValue       = cpu_to_le16(dbi->rx_ctrl_reg);
		dbi->dr.wIndex       = cpu_to_le16(0x5);
		dbi->dr.wLength       = cpu_to_le16(0);
		dbi->ctrl_urb.transfer_buffer_length = 0;

		usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
			  usb_sndctrlpipe(dbi->usb,0),
			  (char *)&dbi->dr,
			  &dbi->rx_ctrl_reg, 0, ctrl_callback, dbi );
	} else {
		dbi->flags &= ~NET_CTRL_CHANGE;
		dbi->flags |= NET_CTRL_CHANGED;
		dbi->dr.bRequestType = DM9601_REQT_WRITE;
		dbi->dr.bRequest     = DM9601_REQ_SET_REG;
		dbi->dr.wValue       = cpu_to_le16(dbi->net_ctrl_reg);
		dbi->dr.wIndex       =  cpu_to_le16(0x0);
		dbi->dr.wLength      = cpu_to_le16(0);
		dbi->ctrl_urb.transfer_buffer_length = 0;

		usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
			  usb_sndctrlpipe(dbi->usb,0),
			  (char *)&dbi->dr,
			  &dbi->net_ctrl_reg, 0, ctrl_callback, dbi );
	}

	if ( (ret = usb_submit_urb( &dbi->ctrl_urb ,GFP_KERNEL)) )
		err("%s: BAD CTRL %d, flags %x",__FUNCTION__,ret,dbi->flags );

	return	ret;
}

static int read_mii_word( dm9601_board_info_t *dbi, __u8 phy, __u8 index, __u16 *regd )
{
	set_register( dbi, 0x0c, index | 0x40 );
	set_register( dbi, 0x0b, 0x0c );
	udelay(100);
	set_register( dbi, 0x0b, 0x0 );
	get_registers( dbi, 0xd, 2, regd);

	return 0;
}


static int write_mii_word( dm9601_board_info_t *dbi, __u8 phy, __u8 index, __u16 regd )
{
	set_register( dbi, 0x0c, index | 0x40 );
	set_registers( dbi, 0xd, 2, &regd);
	set_register( dbi, 0x0b, 0x0a );
	udelay(100);
	set_register( dbi, 0x0b, 0x0 );

	return 0;
}


static int read_eprom_word( dm9601_board_info_t *dbi, __u8 index, __u16 *retdata )
{
	set_register( dbi, 0x0c, index );
	set_register( dbi, 0x0b, 0x4 );
	udelay(100);
	set_register( dbi, 0x0b, 0x0 );
	get_registers( dbi, 0xd, 2, retdata);

	return 0;
}

static int write_eprom_word( dm9601_board_info_t *dbi, __u8 index, __u16 data )
{
	set_register(dbi, 0x0c, index);
	set_registers(dbi, 0x0d, 2, &data);
	set_register(dbi, 0x0b, 0x12);
	udelay(100);
	set_register(dbi, 0x0b, 0x0);
	return 0;
}

static void read_bulk_callback( struct urb *urb, struct pt_regs* reg )
{
	dm9601_board_info_t *dbi = urb->context;
	struct net_device *net = dbi->net;
	int count = urb->actual_length, res;
	__u8 rx_status;
	struct sk_buff	*skb;
	__u16 pkt_len;
	unsigned char * bufptr;

	if ( !dbi || !(dbi->flags & DM9601_RUNNING) )
		return;

	if ( !netif_device_present(net) )
		return;

	if ( dbi->flags & DM9601_RX_BUSY ) {
		dbi->stats.rx_errors++;
		dbg("DM9601 Rx busy");
		return;
	}
	dbi->flags |= DM9601_RX_BUSY;

	switch ( urb->status ) {
		case USB_ST_NOERROR:
			break;
		case USB_ST_NORESPONSE:
			dbg( "reset MAC" );
			dbi->flags &= ~DM9601_RX_BUSY;
			break;
		default:
#ifdef RX_IMPROVE
			dbg("%s: RX status %d",net->name, urb->status );
			goto goon;
#endif
		;
	}

/* For RX improve ---------------------------*/
#ifdef RX_IMPROVE
	if (dbi->rx_buf_flag) {
		bufptr = dbi->rx_buff;
		usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
				usb_rcvbulkpipe(dbi->usb, 1),
				dbi->rx_buff2, DM9601_MAX_MTU, 
				read_bulk_callback, dbi );
	} else {
		bufptr = dbi->rx_buff2;
		usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
				usb_rcvbulkpipe(dbi->usb, 1),
				dbi->rx_buff, DM9601_MAX_MTU, 
				read_bulk_callback, dbi );
	}

	if ( (res = usb_submit_urb(&dbi->rx_urb,GFP_ATOMIC)) )
		warn("%s: failed submint rx_urb %d",__FUNCTION__,res);

	dbi->flags &= ~DM9601_RX_BUSY;
	dbi->rx_buf_flag = dbi->rx_buf_flag ? 0:1;
#else
	bufptr = dbi->rx_buff;
#endif
/* ----------------------------------------------------------*/

	if ( !count )
		goto goon;

	rx_status = *(__u8 *)(bufptr);
	pkt_len = *(__u16 *)(bufptr + 1) - 4;

	dbi->stats.rx_bytes += pkt_len;
	if ( (rx_status & 0xbf) || (pkt_len > 1518) ) {
		dbi->stats.rx_errors++;
		if (pkt_len > 1518) dbi->rx_longf_errors++;
		if (rx_status & 0x80) dbi->rx_runtf_errors++;
		if (rx_status & 0x20) dbi->rx_lc_errors++;
		if (rx_status & 0x10) dbi->rx_wdt_errors++;
		if (rx_status & 0x08) dbi->rx_ple_errors++;
		if (rx_status & 0x04) dbi->stats.rx_frame_errors++;
		if (rx_status & 0x02) dbi->stats.rx_crc_errors++;
		if (rx_status & 0x1) dbi->stats.rx_fifo_errors++;
		goto goon;
	}

	if ( !(skb = dev_alloc_skb(pkt_len + 2)) )
		goto goon;

	skb->dev = net;
	skb_reserve(skb, 2);
	memcpy(skb_put(skb, pkt_len), bufptr + 3, pkt_len);

	skb->protocol = eth_type_trans(skb, net);
	netif_rx(skb);
	dbi->stats.rx_packets++;
	dbi->stats.rx_bytes += pkt_len;

goon:
#ifndef RX_IMPROVE
	usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
			usb_rcvbulkpipe(dbi->usb, 1),
			dbi->rx_buff, DM9601_MAX_MTU, 
			read_bulk_callback, dbi );
	if ( (res = usb_submit_urb(&dbi->rx_urb,GFP_ATOMIC)) )
		warn("%s: failed submint rx_urb %d",__FUNCTION__,res);
	dbi->flags &= ~DM9601_RX_BUSY;
#endif
}


static void write_bulk_callback( struct urb *urb, struct pt_regs* reg )
{
	dm9601_board_info_t *dbi = urb->context;

	if ( !dbi || !(dbi->flags & DM9601_RUNNING) )
		return;

	if ( !netif_device_present(dbi->net) )
		return;
		
	if ( urb->status )
		info("%s: TX status %d", dbi->net->name, urb->status);

	dbi->net->trans_start = jiffies;
	netif_wake_queue( dbi->net );
}

#ifdef	DM9601_USE_INTR
static void intr_callback( struct urb *urb ,struct pt_regs* pt)
{
	dm9601_board_info_t *dbi = urb->context;
	struct net_device *net;
	__u8	*d;

	if ( !dbi )
		return;
		
	switch ( urb->status ) {
		case USB_ST_NOERROR:
			break;
		case USB_ST_URB_KILLED:
			return;
		default:
			info("intr status %d", urb->status);
	}

	d = urb->transfer_buffer;
	net = dbi->net;

	if ( !(d[6] & 0x04) && (d[0] & 0x10) ) { 
		printk("<WARN> TX FULL %x %x\n", d[0], d[6]); 
		dbi->flags |= DM9601_RESET_WAIT;
	}

	/* Auto Sense Media Policy:
		Fast EtherNet NIC: don't need to do.
		Force media mode: don't need to do.
		HomeRun/LongRun NIC and AUTO_Mode:
			INT_MII not link, select EXT_MII
			EXT_MII not link, select INT_MII
	*/
	if ( 	!(d[0] & 0x40) && 
		(dbi->nic_type != FASTETHER_NIC) &&
		(dbi->op_mode == DM9601_AUTO) ) {
		dbi->net_ctrl_reg ^= 0x80;
		netif_stop_queue(net);
		dbi->flags |= NET_CTRL_CHANGE;
		ctrl_callback(&dbi->ctrl_urb, NULL);
		netif_wake_queue(net);
	}

	if ( (d[1] | d[2]) & 0xf4 ) {
		dbi->stats.tx_errors++;
		if ( (d[0] | d[1]) & 0x84) 	/* EXEC & JABBER */
			dbi->stats.tx_aborted_errors++;
		if ( (d[0] | d[1]) & 0x10 )	/* LATE COL */
			dbi->stats.tx_window_errors++;
		if ( (d[0] | d[1]) & 0x60 )	/* NO or LOST CARRIER */
			dbi->stats.tx_carrier_errors++;
	}
}
#endif

static void dm9601_tx_timeout( struct net_device *net )
{
	dm9601_board_info_t *dbi = net->priv;

	if ( !dbi )
		return;
		
	warn("%s: Tx timed out.", net->name);
	dbi->tx_urb.transfer_flags |= URB_NO_FSBR;//USB_ASYNC_UNLINK;
	usb_unlink_urb( &dbi->tx_urb );
	dbi->stats.tx_errors++;
}
//#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,48)
//#endif


static int dm9601_start_xmit( struct sk_buff *skb, struct net_device *net )
{
	dm9601_board_info_t	*dbi = net->priv;
	int 	count = skb->len + 2;
	int 	res;
	__u16 l16 = skb->len;
	
	netif_stop_queue( net );

	if (!(count & 0x3f)) { count++; l16++; }

	((__u16 *)dbi->tx_buff)[0] = cpu_to_le16(l16);
	memcpy(dbi->tx_buff + 2, skb->data, skb->len);
#if 0
	FILL_BULK_URB_TO( &dbi->tx_urb, dbi->usb,
			usb_sndbulkpipe(dbi->usb, 2),
			dbi->tx_buff, count, 
			write_bulk_callback, dbi, jiffies + HZ );
#else
	usb_fill_bulk_urb( &dbi->tx_urb, dbi->usb,
			usb_sndbulkpipe(dbi->usb, 2),
			dbi->tx_buff, count, 
			write_bulk_callback, dbi);

#endif
	if ((res = usb_submit_urb(&dbi->tx_urb,GFP_KERNEL))) {
		warn("failed tx_urb %d", res);
		dbi->stats.tx_errors++;
		netif_start_queue( net );
	} else {
		dbi->stats.tx_packets++;
		dbi->stats.tx_bytes += skb->len;
		net->trans_start = jiffies;
	}

	dev_kfree_skb(skb);

	return 0;
}


static struct net_device_stats *dm9601_netdev_stats( struct net_device *dev )
{
	return &((dm9601_board_info_t *)dev->priv)->stats;
}


static inline void disable_net_traffic( dm9601_board_info_t *dbi )
{
	__u8 reg5;

	write_mii_word(dbi, 1, 0, 0x8000);	/* RESET PHY */

	get_registers(dbi, 0x5, 1, &reg5);
	reg5 &= 0xfe;
	set_register(dbi, 0x5, reg5);		/* RX disable */
	set_register(dbi, 0x1f, 0x01);		/* PHY power down */
}

static void set_phy_mode(dm9601_board_info_t *dbi)
{
	__u16	phy_reg0 = 0x1000, phy_reg4 = 0x01e1;

	/* PHY media mode setting */
	if ( !(dbi->op_mode & DM9601_AUTO) ) {	
		switch(dbi->op_mode) {
			case DM9601_10MHF:  
				phy_reg4 = 0x0021; break;
			case DM9601_10MFD:  
				phy_reg4 = 0x0041; break;
			case DM9601_100MHF: 
				phy_reg4 = 0x0081; break;
			case DM9601_100MFD: 
				phy_reg4 = 0x0101; break;
			default: 
				phy_reg0 = 0x8000; break;
		}
		write_mii_word(dbi, 1, 4, phy_reg4); /* Set PHY capability */
		write_mii_word(dbi, 1, 0, phy_reg0);
	}

	/* Active PHY */
	set_register( dbi, 0x1e, 0x01 );	/* Let GPIO0 output */
	set_register( dbi, 0x1f, 0x00 );	/* Power_on PHY */
}

/*
	Init HomeRun DM9801
*/
static void program_dm9801(dm9601_board_info_t *dbi, u16 HPNA_rev)
{
	__u16 reg16, reg17, reg24, reg25;

	if ( !nfloor ) nfloor = DM9801_NOISE_FLOOR;

	read_mii_word(dbi, 1, 16, &reg16);
	read_mii_word(dbi, 1, 17, &reg17);
	read_mii_word(dbi, 1, 24, &reg24);
	read_mii_word(dbi, 1, 25, &reg25);

	switch(HPNA_rev) {
	case 0xb900: /* DM9801 E3 */
		reg16 |= 0x1000;
		reg25 = ( (reg24 + nfloor) & 0x00ff) | 0xf000;
		break;
	case 0xb901: /* DM9801 E4 */
		reg25 = ( (reg24 + nfloor) & 0x00ff) | 0xc200;
		reg17 = (reg17 & 0xfff0) + nfloor + 3;
		break;
	case 0xb902: /* DM9801 E5 */
	case 0xb903: /* DM9801 E6 */
	default:
		reg16 |= 0x1000;
		reg25 = ( (reg24 + nfloor - 3) & 0x00ff) | 0xc200;
		reg17 = (reg17 & 0xfff0) + nfloor;
		break;
	}

	write_mii_word(dbi, 1, 16, reg16);
	write_mii_word(dbi, 1, 17, reg17);
	write_mii_word(dbi, 1, 25, reg25);
}

/*
	Init LongRun DM9802
*/
static void program_dm9802(dm9601_board_info_t *dbi)
{
	__u16 reg25;

	if ( !nfloor ) nfloor = DM9802_NOISE_FLOOR;

	read_mii_word(dbi, 1, 25, &reg25);
	reg25 = (reg25 & 0xff00) + nfloor;
	write_mii_word(dbi, 1, 25, reg25);
}

/*
	Identify NIC type
*/
static void identify_nic(dm9601_board_info_t* dbi)
{
	__u16	phy_tmp;

	/* Select EXT_MII */
	dbi->net_ctrl_reg |= 0x80;
	set_register(dbi, 0x00, dbi->net_ctrl_reg);	/* EXT-MII */

	read_mii_word(dbi, 1, 3, &phy_tmp);
	switch(phy_tmp & 0xfff0) {
	case 0xb900:
		read_mii_word(dbi, 1, 31, &phy_tmp);
		if (phy_tmp == 0x4404) { 
			dbi->nic_type =  HOMERUN_NIC;
			program_dm9801(dbi, phy_tmp);
		} else {
			dbi->nic_type = LONGRUN_NIC;
			program_dm9802(dbi);
		}
		break;
	default:
		dbi->nic_type = FASTETHER_NIC;
	}

	/* Select INT_MII */
	dbi->net_ctrl_reg &= ~0x80;
	set_register(dbi, 0x00, dbi->net_ctrl_reg);
}

static void init_dm9601(struct net_device *net)
{
	dm9601_board_info_t *dbi = (dm9601_board_info_t *)net->priv;

	/* User passed argument */
	dbi->rx_ctrl_reg = reg5 | 0x01;
	dbi->net_ctrl_reg = 0x00;
	dbi->reg08 = reg8;
	dbi->reg09 = reg9;
	dbi->reg0a = rega;

	/* RESET device */
	set_register(dbi, 0x00, 0x01);	/* Reset */
	udelay(100);

	/* NIC type: FASTETHER, HOMERUN, LONGRUN */
	identify_nic(dbi);

	/* Set PHY */
	dbi->op_mode = dm9601_mode;
	set_phy_mode(dbi);

	/* MII selection */
	if ( 	(dbi->nic_type != FASTETHER_NIC) && 
		(dbi->op_mode == DM9601_1M_HPNA) 	)
		dbi->net_ctrl_reg |= 0x80;

	/* Program operating register */
	set_register(dbi, 0x00, dbi->net_ctrl_reg);
	set_register(dbi, 0x08, dbi->reg08);
	set_register(dbi, 0x09, dbi->reg09);
	set_register(dbi, 0x0a, dbi->reg0a);
	set_register(dbi, 0xf4, 0x26);	/* Reset EP1/EP2, INT always return */
	set_registers(dbi, 0x10, 0x06, net->dev_addr); /*  MAC addr */
	dbi->hash_table[3] = 0x8000;	/* Broadcast Address */
	set_registers(dbi, 0x16, 0x08, dbi->hash_table); /*  Hash Table */
	set_register(dbi, 0x05, dbi->rx_ctrl_reg); /* Active RX */
}


static int dm9601_open(struct net_device *net)
{
	dm9601_board_info_t *dbi = (dm9601_board_info_t *)net->priv;
	int	res;
	int owner;

	down(&dbi->ctrl_sem);
//	MOD_INC_USE_COUNT;
	owner = try_module_get(THIS_MODULE); 
	usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
			usb_rcvbulkpipe(dbi->usb, 1),
			dbi->rx_buff, DM9601_MAX_MTU, 
			read_bulk_callback, dbi );
	if ( (res = usb_submit_urb(&dbi->rx_urb,GFP_ATOMIC)) )
		warn("%s: failed rx_urb %d",__FUNCTION__,res);
	dbi->rx_buf_flag = 1;

#ifdef	DM9601_USE_INTR
	usb_fill_int_urb( &dbi->intr_urb, dbi->usb,
			usb_rcvintpipe(dbi->usb, 3),
			dbi->intr_buff, sizeof(dbi->intr_buff),
			intr_callback, dbi, dbi->intr_interval );
	if ( (res = usb_submit_urb(&dbi->intr_urb,GFP_ATOMIC)) )
		warn("%s: failed intr_urb %d",__FUNCTION__,res);
#endif

	init_dm9601(net);

	netif_start_queue( net );
	dbi->flags |= DM9601_RUNNING;
	up(&dbi->ctrl_sem);

	return 0;
}


static int dm9601_close( struct net_device *net )
{
	dm9601_board_info_t	*dbi = net->priv;

	dbi->flags &= ~DM9601_RUNNING;
	netif_stop_queue(net);
	if ( !(dbi->flags & DM9601_UNPLUG) )
		disable_net_traffic(dbi);

	usb_unlink_urb(&dbi->rx_urb);
	usb_unlink_urb(&dbi->tx_urb);
	usb_unlink_urb(&dbi->ctrl_urb);
#ifdef	DM9601_USE_INTR
	usb_unlink_urb(&dbi->intr_urb);
#endif
	//MOD_DEC_USE_COUNT;
	module_put(THIS_MODULE);
#ifdef STS_DBUG
	printk("<DM9601> rx errors: %lx \n", dbi->stats.rx_errors);
	printk("<DM9601> fifo over errors: %lx \n", dbi->stats.rx_fifo_errors);
	printk("<DM9601> crc errors: %lx \n", dbi->stats.rx_crc_errors);
	printk("<DM9601> alignment errors: %lx \n", dbi->stats.rx_frame_errors);
	printk("<DM9601> physical layer errors: %lx \n", dbi->rx_ple_errors);
	printk("<DM9601> watchdog errors: %lx \n", dbi->rx_wdt_errors);
	printk("<DM9601> late collision errors: %lx \n", dbi->rx_lc_errors);
	printk("<DM9601> runt frame errors: %lx \n", dbi->rx_runtf_errors);
	printk("<DM9601> long frame errors: %lx \n", dbi->rx_longf_errors);
#endif
	return 0;
}


static int dm9601_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
{
	__u16 *data = (__u16 *)&rq->ifr_data;
	dm9601_board_info_t	*dbi = net->priv;

	switch(cmd) {
		case SIOCDEVPRIVATE:
			data[0] = dbi->phy;
		case SIOCDEVPRIVATE+1:
			read_mii_word(dbi, data[0], data[1]&0x1f, &data[3]);
			return 0;
		case SIOCDEVPRIVATE+2:
			if ( !capable(CAP_NET_ADMIN) )
				return -EPERM;
			write_mii_word(dbi, dbi->phy, data[1] & 0x1f, data[2]);
			return 0;
		default:
			return -EOPNOTSUPP;
	}
}

/*
  Calculate the CRC valude of the Rx packet
  flag = 1 : return the reverse CRC (for the received packet CRC)
         0 : return the normal CRC (for Hash Table index)
*/
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
{

   u32 crc = ether_crc_le(Len, Data);
   
   if (flag) 
	   return ~crc;
   
   return crc;
}

static void dm9601_set_multicast( struct net_device *net )
{
	dm9601_board_info_t *dbi = net->priv;
	struct dev_mc_list *mcptr = net->mc_list;
	int count = net->mc_count, i, hash_val;

	netif_stop_queue(net);

	if (net->flags & IFF_PROMISC) {
		dbi->rx_ctrl_reg |= RX_PROMISCUOUS;
		info("%s: Promiscuous mode enabled", net->name);
	} else if (net->flags & IFF_ALLMULTI) {
		dbi->rx_ctrl_reg |= RX_PASS_MULTICAST;
		dbi->rx_ctrl_reg &= ~RX_PROMISCUOUS;
		info("%s set allmulti", net->name);
	} else {
		dbi->rx_ctrl_reg &= ~RX_PASS_MULTICAST;
		dbi->rx_ctrl_reg &= ~RX_PROMISCUOUS;
		/* Clear Hash Table */
		for (i = 0; i < 4; i++) dbi->hash_table[i] = 0;
		/* Set Broadcast Address */
		dbi->hash_table[3] = 0x8000;
		/* the multicast address in Hash Table : 64 bits */
		for (i = 0; i < count; i++, mcptr = mcptr->next) {
			hash_val = cal_CRC((char *)mcptr->dmi_addr, 6, 0) & 0x3f; 
			dbi->hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
		}
		info("%s: set Rx mode", net->name);
	}

	dbi->flags |= HASH_REGS_CHANGE | RX_CTRL_CHANGE;
	ctrl_callback(&dbi->ctrl_urb, NULL);

	netif_wake_queue(net);
}


static int dm9601_probe( struct usb_interface *udev, const struct usb_device_id *id)
{
	struct net_device	*net;
	dm9601_board_info_t	*dbi;
	int dev_index = id - dm9601_ids;
	struct usb_device *dev = interface_to_usbdev (udev);	
	int status;
	
#if 0	
	if (usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue)) {
		err("usb_set_configuration() failed");
		return -ENODEV;
	}
#endif
	if(!(dbi = kmalloc(sizeof(dm9601_board_info_t), GFP_KERNEL))) {
		err("out of memory allocating device structure");
		return -ENOMEM;
	}
//	usb_inc_dev_use( dev );
//	printk("dev_index %d dbi %x\n",dev_index,dbi);
	usb_get_dev(dev);
	memset(dbi, 0, sizeof(dm9601_board_info_t));
	// initialize dbi struct
	{
		usb_init_urb(&dbi->ctrl_urb);
		usb_init_urb(&dbi->rx_urb);
		usb_init_urb(&dbi->tx_urb);
		usb_init_urb(&dbi->intr_urb);
		usb_init_urb(&dbi->dump_urb);

	}
	dbi->dev_index = dev_index;
	init_waitqueue_head( &dbi->ctrl_wait );

//	net = init_etherdev( NULL, 0 );
	net = alloc_etherdev(0);
	if ( !net ) {
		kfree( dbi );
		return	-ENOMEM;
	}
	
	init_MUTEX(&dbi->ctrl_sem);
	down(&dbi->ctrl_sem);
	dbi->usb = dev;
	dbi->net = net;
	net->priv = dbi;
	net->open = dm9601_open;
	net->stop = dm9601_close;
	net->watchdog_timeo = DM9601_TX_TIMEOUT;
	net->tx_timeout = dm9601_tx_timeout;
	net->do_ioctl = dm9601_ioctl;
	net->hard_start_xmit = dm9601_start_xmit;
	net->set_multicast_list = dm9601_set_multicast;
	net->get_stats = dm9601_netdev_stats;
	net->mtu = DM9601_MTU;
	dbi->intr_interval = 0xff;	/* Default is 0x80 */

	/* Get Node Address */
	read_eprom_word(dbi, 0, (__u16 *)net->dev_addr);
	read_eprom_word(dbi, 1, (__u16 *)(net->dev_addr + 2));
	read_eprom_word(dbi, 2, (__u16 *)(net->dev_addr + 4));

	dbi->features = usb_dev_id[dev_index].private;
	info( "%s: %s", net->name, usb_dev_id[dev_index].name );
	
	usb_set_intfdata (udev, dbi);
	SET_NETDEV_DEV(net, &udev->dev);
	status = register_netdev (net);
	up(&dbi->ctrl_sem);
	if (status)
		return status;

	// start as if the link is up
	netif_device_attach (net);
		
	return 0;
	
}


static void dm9601_disconnect( struct usb_interface *intf/*struct usb_device *dev, void *ptr*/ )
{
	struct usb_device *dev = interface_to_usbdev (intf);;
	dm9601_board_info_t *dbi = usb_get_intfdata(intf);

	if ( !dbi ) {
		warn("unregistering non-existant device");
		return;
	}

	dbi->flags |= DM9601_UNPLUG;
	unregister_netdev( dbi->net );
//	usb_dec_dev_use( dev );
	usb_put_dev(dev);

	kfree( dbi );
	dbi = NULL;
}


static struct usb_driver dm9601_driver = {
	name:		"dm9601",
	probe:		dm9601_probe,
	disconnect:	dm9601_disconnect,
	id_table:	dm9601_ids,
};

int __init dm9601_init(void)
{
	info( "%s", version );

 	switch(mode) {
   		case DM9601_10MHF:
		case DM9601_100MHF:
		case DM9601_10MFD:
		case DM9601_100MFD:
		case DM9601_1M_HPNA:
			dm9601_mode = mode;
			break;
		default:
			dm9601_mode = DM9601_AUTO;
	}

	nfloor = (nfloor > 15) ? 0:nfloor;

	return usb_register( &dm9601_driver );
}

void __exit dm9601_exit(void)
{
	usb_deregister( &dm9601_driver );
}

module_init( dm9601_init );
module_exit( dm9601_exit );
```

contents of the file named "dm9601.h"


```
/*
 *  Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */


#ifndef	DM9601_DEV

#define	HAS_HOME_PNA		0x40000000

#define	DM9601_MTU		1500
#define	DM9601_MAX_MTU		1536

#define	EPROM_WRITE		0x01
#define	EPROM_READ		0x02
#define	EPROM_LOAD		0x20

#define	MII_BMCR		0x00
#define	MII_BMSR		0x01
#define	PHY_READ		0x40
#define	PHY_WRITE		0x20

#define	DM9601_PRESENT		0x00000001
#define	DM9601_RUNNING		0x00000002
#define	DM9601_TX_BUSY		0x00000004
#define	DM9601_RX_BUSY		0x00000008
#define	CTRL_URB_RUNNING	0x00000010
#define	CTRL_URB_SLEEP		0x00000020
#define	DM9601_UNPLUG		0x00000040
#define	DM9601_RESET_WAIT	0x00800000
#define	NET_CTRL_CHANGE		0x04000000
#define	NET_CTRL_CHANGED	0x08000000
#define	RX_CTRL_CHANGE		0x10000000
#define	RX_CTRL_CHANGED		0x20000000
#define	HASH_REGS_CHANGE	0x40000000
#define	HASH_REGS_CHANGED	0x80000000
#define ALL_REGS_CHANGE		(NET_CTRL_CHANGE | RX_CTRL_CHANGE | HASH_REGS_CHANGE)
#define ALL_REGS_CHANGED	(NET_CTRL_CHANGED | RX_CTRL_CHANGED | HASH_REGS_CHANGED)
#define	DEFAULT_GPIO_RESET	0x24
#define	LINKSYS_GPIO_RESET	0x24
#define	DEFAULT_GPIO_SET	0x26

#define	RX_PASS_MULTICAST	8
#define	RX_PROMISCUOUS		2

#define	REG_TIMEOUT		(HZ)
#define	DM9601_TX_TIMEOUT	(HZ*10)

#define	TX_UNDERRUN		0x80
#define	EXCESSIVE_COL		0x40
#define	LATE_COL		0x20
#define	NO_CARRIER		0x10
#define	LOSS_CARRIER		0x08
#define	JABBER_TIMEOUT		0x04

#define	DM9601_REQT_READ	0xc0
#define	DM9601_REQ_GET_REGS	0x00
#define	DM9601_REQ_GET_MEMS	0x02

#define	DM9601_REQT_WRITE	0x40
#define	DM9601_REQ_SET_REGS	0x01
#define	DM9601_REQ_SET_REG	0x03
#define	DM9601_REQ_SET_MEMS	0x05
#define	DM9601_REQ_SET_MEM	0x07

#define DM9601_10MHF		0
#define DM9601_100MHF		1
#define DM9601_10MFD		4
#define DM9601_100MFD		5
#define DM9601_AUTO		8
#define DM9601_1M_HPNA		0x10

#define DM9601_REG5		0x30
#define DM9601_REG8		0x27
#define DM9601_REG9		0x38
#define DM9601_REGA		0xff

#define DM9801_NOISE_FLOOR	0x08
#define DM9802_NOISE_FLOOR	0x05

enum DM9601_NIC_TYPE {
	FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2 };

enum DM9601_MII_TYPE {
	MII_TYPE_INT = 0, MII_TYPE_EXT = 1 };

#define	ALIGN(x)		x __attribute__((aligned(L1_CACHE_BYTES)))

typedef struct dm9601_board_info {
	struct usb_device	*usb;
	struct net_device	*net;
	struct net_device_stats	stats;
	unsigned long		rx_longf_errors, rx_runtf_errors, rx_lc_errors,
				rx_wdt_errors, rx_ple_errors;
	unsigned		flags;
	unsigned		features;
	int			dev_index;
	int			intr_interval;
	struct urb		ctrl_urb, rx_urb, tx_urb, intr_urb, dump_urb;
	struct usb_ctrlrequest	dr;
	wait_queue_head_t	ctrl_wait;
	struct semaphore	ctrl_sem;
	unsigned char		ALIGN(rx_buff[DM9601_MAX_MTU]);
	unsigned char		ALIGN(rx_buff2[DM9601_MAX_MTU]);
	unsigned char		ALIGN(tx_buff[DM9601_MAX_MTU]);
	unsigned char		ALIGN(intr_buff[8]);
	unsigned char		ALIGN(dump_buff[8]);
	__u16			hash_table[4];
	__u8			rx_ctrl_reg, net_ctrl_reg, reg08, reg09, reg0a;
	__u8			phy;
	__u8			gpio_res;
	__u8			rx_buf_flag;
	__u8			nic_type;
	__u8			op_mode;
} dm9601_board_info_t;


struct usb_eth_dev {
	char	*name;
	__u16	vendor;
	__u16	device;
	__u32	private; /* LSB is gpio reset value */
};


#define VENDOR_ACCTON           0x083a
#define VENDOR_ADMTEK           0x07a6
#define VENDOR_BILLIONTON       0x08dd
#define VENDOR_COREGA           0x07aa
#define VENDOR_DLINK1           0x2001
#define VENDOR_DLINK2           0x07b8
#define VENDOR_IODATA           0x04bb
#define VENDOR_LANEED           0x056e
#define VENDOR_LINKSYS          0x066b
#define VENDOR_MELCO            0x0411
#define VENDOR_SMC              0x0707
#define VENDOR_SOHOWARE         0x15e8


#else	/* DM9601_DEV */


DM9601_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)",
		VENDOR_ADMTEK, 0x0986,
		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "Davicom USB-100", 0x0a46, 0x9601,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "Davicom USB-100", 0x3334, 0x1701,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "Corega FEter USB-TXC", VENDOR_COREGA, 0x9601, 
		DEFAULT_GPIO_RESET )
DM9601_DEV( "D-Link DSB-650TX", VENDOR_DLINK1, 0x4001,
		LINKSYS_GPIO_RESET )
DM9601_DEV( "D-Link DSB-650TX", VENDOR_DLINK1, 0x4002,
		LINKSYS_GPIO_RESET )
DM9601_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK1, 0x4003,
		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "D-Link DSB-650", VENDOR_DLINK1, 0xabc1,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "D-Link DU-E10", VENDOR_DLINK2, 0xabc1,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "D-Link DU-E100", VENDOR_DLINK2, 0x4002,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
		LINKSYS_GPIO_RESET )
DM9601_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
		LINKSYS_GPIO_RESET )
DM9601_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
		LINKSYS_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "Linksys USB Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
		LINKSYS_GPIO_RESET )
DM9601_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
		DEFAULT_GPIO_RESET )
DM9601_DEV( "SOHOware NUB100 Ethernet", 0x0a46, 0x9601,
		DEFAULT_GPIO_RESET )


#endif	/* _DEV */
```


*
do the above code make any sense ??
atleast i dont understand the instructions.
1st step RUN make command!! how do i do this???

*


----------



## Faun (Dec 3, 2008)

Run these commands one by one !



> ./configure
> 
> make
> 
> sudo make install



if u are using other linux(in which sudo is not installed) then in third step first 


> su -



and then



> make install


----------



## iinfi (Dec 3, 2008)

thanks ... will try this tomorrow n post the results.
added:
i m sorry wat u told me doesnt work
i m logging in as root user only. the 3 files r in a directory in /root location
now from where sud i run this command??
i did the following ... greek n latin to me.

```
[root@localhost dm9601-2.6]# pwd
/root/dm9601-2.6
[root@localhost dm9601-2.6]# ./configure
bash: ./configure: No such file or directory
```


----------



## Hitboxx (Dec 4, 2008)

Looking at that read me, I don't think it requires ./configure.

Just do make., (from inside the same directory)

[root@localhost dm9601-2.6]#make

If it says make not found, you have to install the make package from the repo, depending on your distro. What distro are you using by the way?


----------



## iinfi (Dec 5, 2008)

i didnt understand the read me.
will try wat u said....
added:
btw wat does ./configure do??

this is the error i get if i run make.... i m running RHCE 5

```
[root@linux dm9601-2.6]# make
make -C /lib/modules/2.6.18-53.el5/build M=/root/dm9601-2.6 LDDINCDIR=/root/dm9601-2.6/../include modules
make[1]: Entering directory `/lib/modules/2.6.18-53.el5/build'
make[1]: *** No rule to make target `modules'.  Stop.
make[1]: Leaving directory `/lib/modules/2.6.18-53.el5/build'
make: *** [default] Error 2
```
where is the trouble??


----------



## Hitboxx (Dec 5, 2008)

1) Looks like you are missing kernel sources. How did you acquire RHEL5? Bought it, got it from a friend, Certification course? If you bought it, then you should contact Redhat support because you are entitled to it and they will provide the necessary solution(s). Same goes for Certification.

2) If you are using RHEL 5, then why are you compiling it? Start from Appendix B-2.

./configure - ./configure is a bash script that generates a Makefile after analyzing your system. The configure script is built by the autoconf program given a configure.ac or configure.in template file. A Makefile is like saying setup.exe on Windows, ./configure readies the app in question to be installed.


----------



## iinfi (Dec 5, 2008)

hi ... i got RHEL 5 from my training center. yea certification.


			
				Hitboxx said:
			
		

> 2) If you are using RHEL 5, then why are you compiling it? Start from Appendix B-2.


the second line in b-2 says
2. copy dm9601.ko into /lib/modules/2.6.x/kernel/drivers/net/

i dont have the .ko file.
i only have these files.
Makefile
dm9601.c
dm9601.h

sry i m not too familiar with this stuff.


----------



## Hitboxx (Dec 5, 2008)

Try locate dm9601 in the terminal,

For eg., I have it here


> [hitboxx@Mothership ~]$ locate dm9601
> /lib/modules/2.6.27.4-68.fc10.x86_64/kernel/drivers/net/usb/dm9601.ko
> /lib/modules/2.6.27.5-109.fc10.x86_64/kernel/drivers/net/usb/dm9601.ko
> /lib/modules/2.6.27.5-117.fc10.x86_64/kernel/drivers/net/usb/dm9601.ko


----------



## iinfi (Dec 7, 2008)

i m afraid there arent any .ko files in my system with that name...


----------



## mediator (Dec 8, 2008)

Here!
1. Edit your "dm9601.c" and change '#include <linux/config.h>' to '#include <linux/configfs.h>'
2. If necessary change the 'CFLAGS' TO 'EXTRA_CFLAGS'  in the Makefile.
3. and then try with 'make'!

I suggest you use fedora if you are doing RHCE and install Redhat on virtual machine to pass the exam.


----------

