On Thu, 30 Sep 2004 21:47:02 +0200, [EMAIL PROTECTED]
<[EMAIL PROTECTED]> wrote:
> Send Eagleusb-dev mailing list submissions to
>         [email protected]
> 
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.gna.org/listinfo/eagleusb-dev
> or, via email, send a message with subject or body 'help' to
>         [EMAIL PROTECTED]
> 
> You can reach the person managing the list at
>         [EMAIL PROTECTED]
> 
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Eagleusb-dev digest..."
> 
> Today's Topics:
> 
>    1. ouh ouh... someone for testing ? (baud)
> 
> --__--__--
> 
> Message: 1
> From: baud <[EMAIL PROTECTED]>
> To: [email protected]
> Date: Thu, 30 Sep 2004 21:46:51 +0200
> Subject: [Eagleusb-dev] ouh ouh... someone for testing ?
> Reply-To: [email protected]
> 
> --=-qML6NwnTSh+fhTRn0KQs
> Content-Type: text/plain
> Content-Transfer-Encoding: 7bit
> 
> Hi,
> It seems this ML is quite dead :-( so that we may finally switch to
> english more easily than expected ;-)
> 
> We had in mind to get a version 2.0 out very soon now, unfortunately (?)
> we have all this remaining to be achieved :
> - test new eagle-usb.conf (better for new bnm), mostly for Fast 800
> E2L / E2T, no tester so far...
> - check that Oops are correctly handled with sl33p3r proposal (no answer
> to previous mail)
> - obtain updates for translations
> 
> I'm not sure it will be ready for Christmas at this rate :-( when we
> expected to ship the 2.0 version last thursday... well to get involved :
> 
> 0. Get the latest CVS version :
> cvs -d:pserver:[EMAIL PROTECTED] co eagleusb # press
> enter as you are logging as anonymous
> 
> 1. to test new eagle-usb.conf for pots, see attached file (change your
> VPI/VCI/encapsulation/ISP according to your ISP as defined in
> eagleconfig), unplug/plug your modem to take into account new
> configuration (you _must_ use latest bnm included in cvs & 1.9.9.1
> version)
> Please provide the following results :
> - eaglediag -sc
> - estimated time to synchronize (longer than before, the same,
> faster...)
> - any error in /var/log/messages (except warning about unknown
> option...)
> For ISDN, see fileW.2.0.31_fr/L1/CMV/cmvei.txt from
> http://www.sagem.com/support/site/driver/w_2_0_31_fr.zip
> If anyone finds *any* documentation, (s)he's welcome.
> 
> Who had a look at this new driver for linux ?
> http://www.sagem.com/support/site/driver/Fast8x0_2_0_32.tgz
> available from here :
> http://www.sagem.com/support/site/modele_fax.php?page=driver
> 
> 2. check sl33p3r message :
> https://mail.gna.org/public/eagleusb-dev/2004-09/msg00113.html
> to make it short : once cvs version downloaded, compile/install then
>    eaglectrl -x 0xFFFFFFFF
>    eaglectrl -d
>    rmmod eagle-usb
> you can do it many times (if not getting any Oops...) with an added depmod -a 
> or insmod eagle-usb
> Please report :
> - kernel / gcc / distribution used
> - messages obtained
> - anything I've forgotten to ask you
> 
> 3. For translation, see
> http://dev.eagle-usb.org/wakka.php?wiki=LocalizationScriptsUs
> and compare your eagleusb/utils/scripts/lang/en with the file in your 
> language (Tux has added new messages)
> 
> Thanks for your participation, it will help make it work better.
> 
> @++
> Ben'. aka baud123
> 
> --=-qML6NwnTSh+fhTRn0KQs
> Content-Disposition: attachment; filename=eagle-usb.conf
> Content-Type: text/plain; name=eagle-usb.conf; charset=ISO-8859-15
> Content-Transfer-Encoding: 7bit
> 
> <eaglectrl>
> # Options are set whith the following syntax:
> #
> # Name = Value
> #
> # where "Name" is the option name, and
> # "Value" is the option value, specified
> # in hexadecimal (without any prefix).
> # Option names are case sensitive.
> # Options that are commented out are specified
> # with their default values.
> #
> # Other than VPI, VCI and Encapsulation,
> # I really don't known what these options mean.
> 
> #POTS FOR EAGLE
> OPTN0=80008066
> OPTN0=00000994
> OPTN2=63600000
> OPTN3=00000028
> OPTN4=00600000
> OPTN5=00000500
> # OPTN6=00000000
> # OPTN7=02CD8044
> # OPTN15=09090909
> OPTN18=820200ff
> OPTN19=80000000
> OPTN20=11900002
> OPTN70=218280aa
> OPTN72=006f06eb
> OPTN73=00010060
> # NON TR-48 => interoperability ???
> #OPTN0=80008066
> #OPTN18=820200ff
> #OPTN19=00000000
> 
> # ignored, how to implement ???
> #cw diag 0 0x26870030
> #cw flag 0 0x00000820
> #CW cntl 0 2
> 
> VPI=00000008
> VCI=00000023
> 
> #The following values are valid for encapsulation :
> #MPOA_MODE_BRIDGED_ETH_LLC ----> 1
> #MPOA_MODE_BRIDGED_ETH_VC  ----> 2
> #MPOA_MODE_ROUTED_IP_LLC   ----> 3
> #MPOA_MODE_ROUTED_IP_VC    ----> 4
> #MPOA_MODE_PPPOA_LLC       ----> 5
> #MPOA_MODE_PPPOA_VC        ----> 6
> Encapsulation=00000006
> 
> Linetype=00000001
> RatePollFreq=00000009
> </eaglectrl>
> 
> --=-qML6NwnTSh+fhTRn0KQs
> Content-Disposition: attachment; filename=eu_types.h
> Content-Type: text/x-chdr; name=eu_types.h; charset=ISO-8859-15
> Content-Transfer-Encoding: 7bit
> 
> /*
>  *
>  * Copyright (c) 2003, Frederick Ros ([EMAIL PROTECTED])
>  *
>  * eu_types.h  - Types Declarations.
>  *
>  * This file is part of the eagle-usb driver package.
>  *
>  * eagle-usb driver package 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.
>  *
>  * "eagle-usb driver package" 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 "ADI USB ADSL Driver for Linux"; if not, write to the Free 
> Software
>  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>  *
>  * $Id: eu_types.h,v 1.4 2004/07/13 19:01:48 sleeper Exp $
>  */
> #ifndef __EU_TYPES_H__
> #define __EU_TYPES_H__
> 
> #include <linux/if_ether.h>
> #include <asm/bitops.h>
> #include <linux/types.h>
> 
> /**
>  * eu_ioctl_info  -  Used to exchange data between kernl and user space via
>  *                   ioctls
>  *
>  */
> struct eu_ioctl_info
> {
>     uint32_t  idma_start;
>     uint32_t  buffer_size;
>     uint8_t   *buffer;
> };
> 
> /*
>  * ioctl commands
>  */
> #define EU_IO_OPTIONS _IOW('U',  101, struct eu_ioctl_info)
> #define EU_IO_DSP     _IOW('U',  102, struct eu_ioctl_info)
> #define EU_IO_GETITF  _IOWR('U', 103, struct eu_ioctl_info)
> #define EU_IO_SYNC    _IO('U',   104)
> #define EU_IO_GETDBG  _IOWR('U', 105, struct eu_ioctl_info)
> #define EU_IO_SETDBG  _IOWR('U', 106, struct eu_ioctl_info)
> #if 0
> #define EU_IO_CMVS    _IOW('U',  107, struct eu_ioctl_info)
> #endif
> 
> /*
>  * Options description structure
>  */
> 
> #define MAX_OPTION_NAME_LENGTH      64
> 
> typedef struct
> {
>         char     name[MAX_OPTION_NAME_LENGTH];
>         uint32_t value;
> } eu_opt_t;
> 
> enum
> {
>     CFG_OPT_0 = 0,
>     CFG_OPT_2,
>     CFG_OPT_3,
>     CFG_OPT_4,
>     CFG_OPT_5,
>     CFG_OPT_6,
>     CFG_OPT_7,
>     CFG_OPT_15,
>     CFG_VPI,
>     CFG_VCI,
>     CFG_ENCAPS,
>     CFG_LINE,
>     CFG_RATE_POLL_FREQ,
>     CFG_OPT_COUNT
> };
> 
> #define NUM_DRV_OPTIONS CFG_OPT_COUNT
> typedef eu_opt_t eu_options_t[NUM_DRV_OPTIONS];
> 
> #ifdef __KERNEL__
> 
> #define TRANSMIT_TIMEOUT (HZ*5) /* 5 seconds */
> 
> #define ETHERTYPE_IP    0x0008
> #define ETHERTYPE_IPV6  0xdd86
> #define ETHERTYPE_ARP   0x0608
> 
> /*
>  * Custom ADI vendor control commands
>  */
> #define EU_CMD_GET_BLOCK      0x00
> #define EU_CMD_SET_BLOCK      0x01
> #define EU_CMD_GET_STAT       0x02
> #define EU_CMD_SET_MODE       0x03
> #define EU_CMD_SET_2183_DATA  0x04
> #define EU_CMD_GET_2183_DATA  0x05
> #define EU_CMD_GET_STAT_VAR   0x06
> #define EU_CMD_GET_INTERRUPT  0x07
> #define EU_CMD_SET_FPGA_DATA  0x0E
> #define EU_CMD_SET_TIMEOUT    0x11
> 
> /*
>  * Modes for EU_CMD_SET_MODE
>  */
> #define MODE_LOOPBACK_OFF      0x02
> #define MODE_LOOPBACK_ON       0x03
> #define MODE_BOOTMODE_IDMA     0x06
> #define MODE_START_RESET       0x07
> #define MODE_END_RESET         0x08
> 
> /*
>  * Mailbox addrs
>  */
> #define DSP_MP_TX_MAILBOX      0x3FD6
> #define DSP_MP_TX_START        0x3FCE
> #define DSP_MP_RX_MAILBOX      0x3FDF
> #define DSP_SWAP_MAILBOX       0x3FCD
> 
> /*
>  * Mailbox states
>  */
> #define MAILBOX_EMPTY          0
> #define MAILBOX_FULL           1
> 
> /*
>  * Maximums
>  */
> #define MAX_DSP_ALLOCS 128
> 
> /*
>  * MPOA Encapsulations
>  */
> #define MPOA_MODE_PPPOA_LLC         5
> #define MPOA_MODE_PPPOA_VC          6
> 
> /**
>  * eu_cdc_t - Comm Device Class notification buffer
>  *
>  * @req: request as defined but USB standard
>  * @data: 20 bytes array used to pass data to the modem
>  *
>  * This is an extended version of the USB standard CDC, as ADI modem
>  * use this to pass data.
>  */
> typedef struct
> {
>     uint8_t bRequestType;
>     uint8_t bRequest;
>     uint16_t wValue;
>     uint16_t wIndex;
>     uint16_t wLength;
>     uint8_t data[20];
> } eu_cdc_t __attribute__ ((packed));
> 
> /**
>  * eu_devint_t - returned by the modem on interrupt
>  */
> #define CMV_DATA_WORDS      8
> 
> typedef struct
> {
>     uint16_t intr;
>     union
>     {
>         uint16_t  swap_data;
>         uint16_t  cmv_data[CMV_DATA_WORDS];
>     } intr_info ;
>     uint16_t data_size;
> 
> } eu_devint_t;
> 
> /**
>  * ISO Frame
>  *
>  * @status  -  Status of this received frame
>  * @length  -  Actual Data Buffer Length (how much data we received)
>  * @data    -  Received Data
>  */
> #define FASTEST_ISO_RATE       1007
> 
> typedef struct eu_iso_frame
> {
>     int status;
>     int length;
>     char data[FASTEST_ISO_RATE];
> } eu_iso_frame_t;
> 
> /**
>  * ISO Receive Buffer
>  *
>  * @next   -  To link buffers in completed receive list
>  * @frames -  Frames for this receive buffer
>  *
>  */
> #define FRAMES_PER_ISO_URB     16
> typedef struct eu_iso_rb
> {
>     struct list_head next;
>     eu_iso_frame_t  frames[FRAMES_PER_ISO_URB];
> } eu_iso_rb_t;
> 
> /************************************************************************************/
> /* This will be the receiver buffer for incoming network data. We will queue  
>       */
> /* up a bunch of reads with USB with these buffers, then process them into    
>       */
> /* real ethernet packets as they come in. This enables us to support 
> situations     */
> /* where the entire ethernet packet does not come in in one USBBulkRead. We   
>       */
> /* do require that the data received into these buffers is an exact number    
>       */
> /* of ATM cells                                                               
>       */
> /* LINUX NOTE :                                                               
>       */
> /* In kernel 2.4.7-10 (the stock kernel with RedHat 7.2), the usb-uhci module 
>       */
> /* has a problem queuing multiple read bulk urbs). Therefore, we set this to 
> one so */
> /* we'll work with uhci or ohci. However, higher performance can be seen on 
> ohci    */
> /* if you allow multiple read urbs. So, if you're on an ohci-based machine,   
>       */
> /* set INCOMING_Q_SIZE to > 1 to achieve greater performance.                 
>       */
> /************************************************************************************/
> /* FIXME */
> #ifdef USEBULK
> #define INCOMING_Q_SIZE 1
> #else
> /*We'll set it to 6 when we're dealing with ISOCHRONOUS data.*/
> #define INCOMING_Q_SIZE 6
> #endif
> 
> #define OUTGOING_Q_SIZE    64
> #define OUTGOING_DATA_SIZE 1802 /* same logic as for INCOMING_DATA_SIZE */
> 
> /************************************************************************************/
> /* Here's how I got this - Max ethernet   = 1500 bytes +                      
>       */
> /*          possible Ethernet FCS         = 4 bytes +                         
>       */
> /*          possible MPOA encapsulation   = 10 bytes +                        
>       */
> /*          CPCS PDU trailer              = 8 bytes +                         
>       */
> /*          at most 2 ATM payloads of pad = 96 bytes                          
>       */
> /*                                       ----------                           
>       */
> /*                                         1618 bytes                         
>       */
> /*          Divided among ATM cells = 34 ATM cells * 53 bytes                 
>       */
> /*                      Grand total = 1802                                    
>       */
> /* NOTE NOTE NOTE NOTE                                                        
>       */
> /* This logic all makes sense IF the device received data in ATM cell sized 
> chunks, */
> /* however, it doesn't. The USB pipes receive 64bytes at a time, so we have   
>       */
> /* to have space for a size that is the LCM of 64 and 53, which is 64*53      
>       */
> /************************************************************************************/
> /* FIXME */
> #define INCOMING_DATA_SIZE (64 * 53)
> 
> /**
>  * BULK Receive Buffer
>  *
>  * @next   -  To link buffers in completed receive list
>  * length  - Received Data Length
>  * data    - Received Data
>  */
> typedef struct eu_bulk_rb
> {
>     struct list_head next;
>     int length;
>     char data[INCOMING_DATA_SIZE];
> } eu_bulk_rb_t;
> 
> /*
>  * To ease code ...
>  */
> 
> #ifdef USEBULK
> typedef eu_bulk_rb_t eu_rb_t;
> #else
> typedef eu_iso_rb_t eu_rb_t;
> #endif /* USEBULK */
> 
> /*
>  * Queued Control Urb
>  */
> #define CTRL_URB_Q_SIZE 16
> 
> typedef struct
> {
>     struct list_head list;
>     struct urb *urb;
>     void *dev;
> } queued_urb_t;
> 
> /**
>  * eu_msg_t  - Decoded modem messages
>  *
>  * @preamble     Message preamble
>  * @type         Function type
>  * @subtype      Function Sub Type
>  * @sender_id    ID of the Sender   (unused)
>  * @receiver_id  ID of the receiver (unused)
>  * @index        message index      (unused)
>  * @symb_addr    Symbolic addr      (unused)
>  * @offset_addr  Offset             (unused)
>  * @data         Data from modem
>  *
>  * Field marked with (unused) tag are only used to check message is not
>  * corrupted
>  */
> typedef struct
> {
>     uint16_t preamble;
>     uint16_t type;
>     uint16_t subtype;
>     uint16_t sender_id;
>     uint16_t receiver_id;
>     uint16_t index;
>     uint8_t  saddr[4];
>     uint32_t offset_addr;
>     uint32_t data;
> } eu_msg_t;
> 
> typedef struct
> {
>     uint16_t preamble;
>     uint16_t function;
>     uint16_t idx;
>     uint8_t  saddr_hihi;
>     uint8_t  saddr_hilo;
>     uint8_t  saddr_lohi;
>     uint8_t  saddr_lolo;
>     uint16_t offset;
>     uint32_t data;
> } eu_cmv_msg_t;
> 
> /* FIXME */
> #define MAX_CMV_MESSAGES    20
> 
> typedef struct
> {
>     union
>     {
>         eu_cmv_msg_t *Msgs[ MAX_CMV_MESSAGES ];
>         uint16_t *RawCmd[ MAX_CMV_MESSAGES ];
>     } MsgMax;
>     uint32_t MsgCount;
> } MsgSequence;
> 
> /*  State machine control structure*/
> /* FIXME */
> typedef struct
> {
>     /* state machine flags and options*/
>     uint32_t   ADPT0;
>     uint32_t   ADPT1;
>     uint32_t   ADPT2;
>     uint32_t   INFO9;
>     uint32_t   CNTL0;
>     uint32_t   OPTN0;
>     uint32_t   OPTN2;
>     uint32_t   OPTN4;
>     uint32_t   OPTN7;
>     uint32_t   OPTN3;
>     uint32_t   OPTN5;
>     uint32_t   OPTN6;
>     uint32_t   OPTN15;
>     uint32_t   PFCL1;
>     uint32_t   MASK8;
>     uint32_t   MASK9;
> 
>     uint32_t   INFO8;
>     uint32_t   PSDM0;
>     uint32_t   UNH;
>     uint32_t   ISDN;
>     uint32_t   FLAG0;
> 
>     /* OPERATIONAL values*/
>     uint32_t   sw_status;
>     uint32_t   crc_status;
>     uint32_t   flags;
> 
>     /* statistics*/
>     uint32_t   stats_ES_count;
>     uint32_t   stats_Cur_Atten;
>     uint32_t   stats_Cur_SNR;
>     uint32_t   stats_Rx_Blks;
>     uint32_t   stats_Tx_Blks;
>     uint32_t   stats_Corr_Blks;
>     uint32_t   stats_Uncorr_Blks;
> 
>     uint32_t   stats_Rx_Blks_Delta;
>     uint32_t   stats_Corr_Blks_Delta;
>     uint32_t   stats_Uncorr_Blks_Delta;
> 
>     /* transfer rate*/
>     uint32_t   XferRate0;
>     uint32_t   DownRate;
>     uint32_t   UpRate;
>     uint32_t   FwRxTimeout;
> 
>     /* miscell*/
>     uint32_t   DIAG03;
>     uint32_t   DIAG47;
>     uint32_t   DIAG49;
>     uint32_t   INFO10;
>     uint32_t   PSDM01;
>     uint32_t   INFO08;
>     uint32_t   INFO14;
> 
>     /* following counters work in single digits before reset is tridgerred*/
>     uint8_t    LOS_count;
>     uint8_t    CRC_count;
> 
>     uint8_t    Block_CRC90;
>     uint8_t    Block_CRC97;
> 
>     uint32_t  stats_Ne_Fast_Lod_Failure;
>     uint32_t  stats_Ne_Fast_Hec_Failure;
> 
>     /* -------- status variables ------------------------*/
>     uint8_t    LineType;
> 
>     uint16_t   ModemReplyExpected;
>     uint16_t   CurrentAdiState;
>     uint16_t   PrevAdiState;
> 
>     uint16_t   MsgStage;
>     uint16_t   ReTrain;
>     uint16_t   RetryCount;
> 
>     uint32_t   HeartbeatCounter;
> 
>     /* pre-composed messages used for fast retrain sequence*/
>     MsgSequence MsgSeq_Retrainer;
>     MsgSequence MsgSeq_SoftReset;
>     MsgSequence MsgSeq_OpStat;
>     MsgSequence MsgSeq_Stat;
>     MsgSequence MsgSeq_ModemEna;
>     MsgSequence MsgSeq_EnaFR;
> 
>     struct timer_list timerSM;
> 
>     /* flags and handles*/
>     uint32_t   CurrentExpirationTime;
>     uint32_t   SwapPageRequiredTime;
> 
>     uint32_t  OutboundPending;
>     uint32_t  InboundAsyncPending;
>     uint32_t  InboundSyncPending;
> 
>     uint32_t  watchBadBlocks;
> }  AdiMSM;
> 
> /*
>  * Boot states: they are copied over the value of the modem internal states
>  */
> typedef enum {
>     PRE_BOOT = 0,
>     STAGE_1  = 1,
>     STAGE_2  = 2,
>     STAGE_3  = 3,
>     REBOOT   = 4,
>     UPLOAD_P = 5,
>     STATE_MAX
> } boot_state_t;
> 
> /* Represents a block of IDMA memory, either Program or Data Memory (PM or 
> DM)*/
> /* FIXME */
> typedef struct
> {
>     uint8_t  *MemOffset;
>     uint32_t  DSPAddr;
>     uint32_t  DSPSize;
>     uint32_t  DSPExtendedSize;
> } IDMABlock;
> 
> /* Represents a page of IDMA memory, either a Main page or a Swap page*/
> /* FIXME */
> typedef struct
> {
>     uint32_t  BlockCount;
>     uint32_t  PageOffset;
>     IDMABlock *Blocks;
> } IDMAPage;
> 
> /**
>  * eu_sar_r_t  - Sar Reassembly structure
>  *
>  *  @skb                  -  Pointer to the used skb
>  *  @pdu_len_from_trailer -  Length as reported by cell trailer
>  *  @running_crc          -  CRC in the process to be calculated
>  *  @cell_count           -  Number of prcessed cells for this frame.
>  */
> typedef struct
> {
>     struct sk_buff *skb;
>     uint32_t        pdu_len_from_trailer;
>     uint32_t        running_crc;
>     uint32_t        cell_count;
> } eu_sar_r_t;
> 
> /**
>  * eu_sar_s_t  -  Sar Segmentation structure
>  *
>  * @out_buff   -   Buffer used to segemnt data
>  * @size -
>  *
>  */
> typedef struct
> {
>     uint8_t  *out_buff;
>     uint32_t  size;
>     uint8_t  *cell_hdr;
>     uint32_t  raw_pdu_length;
>     uint32_t  padding_len;
>     uint32_t  bytes_left_in_curr_cell;
>     uint32_t  cell_count;
>     uint32_t  running_crc;
> } eu_sar_s_t;
> 
> /**
>  * eu_aal5_trailer_t - AAL5 Trailer
>  *
>  *  @cpcs_uu  -
>  *  @cpi      -
>  *  @pdu_len  -  PDU Length for this frame
>  *  @crc      -  CRC for this frame
>  *
>  */
> 
> typedef struct
> {
>     uint8_t  cpcs_uu;
>     uint8_t  cpi;
>     uint16_t pdu_len;
>     uint32_t crc;
> }
> eu_aal5_trailer_t;
> 
> /**
>  * eu_atm_vc_t  -  ATM Virtual Channel descriptor
>  *
>  * @reassembler        -   SAR Reassembler
>  * @vpi                -   Virtual Path Identifier
>  * @vci                -   Virtual Channel Identifier
>  * @vpi_vci            -   Agregated VPI/VCI
>  * @max_sdu_size       -   Maximum Data User Size
>  * @reassembly_ipg     -   uint32_t : Is a Reassembly I ProGress ?
>  * @encaps_size        -   Encapsulation size on segmentation ( RFC 2684 )
>  * @encaps_hdr         -   Encapsulation Header
>  * @cell_hdr           -   Header of current cell
>  * @cpcs_uu            -
>  * @cpi                -
>  *
>  */
> 
> #define ATM_CELL_HEADER_SIZE                5
> 
> typedef struct
> {
>     eu_sar_r_t  reassembler;
>     eu_sar_s_t  segmenter;
>     uint32_t     vpi;
>     uint32_t     vci;
>     uint32_t     vpi_vci;
>     uint32_t     max_sdu_size;
>     uint32_t     reassembly_ipg;
>     uint32_t     encaps_size;
>     uint8_t     *encaps_hdr;
>     uint8_t      cell_hdr[ATM_CELL_HEADER_SIZE];
>     uint8_t      cpcs_uu;
>     uint8_t      cpi;
> } eu_atm_vc_t;
> 
> /*
>  * Encapsulation modes
>  */
> #define MPOA_MODE_BRIDGED_ETH_LLC   1
> #define MPOA_MODE_BRIDGED_ETH_VC    2
> #define MPOA_MODE_ROUTED_IP_LLC     3
> #define MPOA_MODE_ROUTED_IP_VC      4
> 
> /**
>  * Instance flags
>  */
> #define EU_OPEN            0
> #define EU_WRITING         1
> #define EU_HAS_INT         2
> #define EU_READING         3
> #define EU_MSG_INITIALIZED 4
> #define EU_UNPLUG          5
> #define EU_LOW_RATE        6
> #define EU_DSP_IPG         7
> #define EU_DSP_LOADED      8
> #define EU_ETH_REGISTERED  9    /* Successfully registered */
> #define EU_ETH_REGISTERING 10   /* Registration in progress */
> 
> #define EU_SET_FLAG(i,f)    set_bit((f), &(i)->flags)
> #define EU_CLEAR_FLAG(i,f)  clear_bit((f),&(i)->flags)
> #define EU_TEST_FLAG(i,f)   test_bit((f),&(i)->flags)
> 
> #define STAT_COUNT        0x0015
> #define ATM_CELL_SIZE     53
> 
> /* ---------------------------- Stats Counters ----------------------------- 
> */
> 
> /*
>  * Received ATM Cells
>  */
> #define STAT_CELLS_RX               0x0000
> /*
>  * Transmited ATM Cells
>  */
> #define STAT_CELLS_TX               0x0001
> 
> /*
>  * Number of cells drop because of CRC error
>  */
> #define STAT_CELLS_LOST_CRC         0x0002
> /*
>  * Stats Lost because of invalid VPI/VCI
>  */
> #define STAT_CELLS_LOST_VPIVCI      0x0003
> /*
>  * Number of cells lost because reassembly buffer is to short
>  */
> #define STAT_CELLS_LOST_OTHER       0x0004
> 
> /*
>  * Received Ethernet/IP Packets
>  */
> #define STAT_PAKTS_RX               0x0005
> /*
>  * Transmited Ethernet/IP Packets
>  */
> #define STAT_PAKTS_TX               0x0006
> /*
>  * Packets lost because over-sized
>  */
> #define STAT_PAKTS_LOST_OSIZE       0x0007
> /*
>  * Nb Packets droped after filter
>  */
> #define STAT_PAKTS_FILTERED         0x0008
> 
> #define STAT_ATMVCI                 0x0009
> #define STAT_ATMVPI                 0x000A
> #define STAT_ATMHEC                 0x000B
> #define STAT_ATMDELIN               0x000C
> 
> #define STAT_DSLMARGIN              0x000D
> #define STAT_DSLATTEN               0x000E
> #define STAT_DSLFEC                 0x000F
> #define STAT_DSLVIDCPE              0x0010
> #define STAT_DSLVIDCO               0x0011
> #define STAT_DSLTXRATE              0x0012
> #define STAT_DSLRXRATE              0x0013
> /*
>  * Number of OAM cells received
>  */
> #define STAT_CELLS_OAM_RCVD         0x0014
> 
> typedef struct eu_instance_s
> {
>     /*
>      * To count the number of interfaces linked to this structure ...
>      */
>     uint32_t users;
> 
>     /*
>      * To protect accesses to this structure.
>      */
>     spinlock_t lock;
> 
>     /*
>      * To link all of our instances
>      */
>     struct list_head list;
> 
>     /*
>      * Holds USB device information (dev, interfaces, pipes, etc.)
>      */
>     struct usb_device *usbdev;
> 
>     /*
>      * URBs allocated for this device
>      */
>     struct urb  *urb_int;
>     struct urb  *urb_write;
>     struct urb  *urb_oam_write;
>     struct urb  *read_urb[INCOMING_Q_SIZE];      /* Array of receive urbs  */
> 
>     /*
>      * Device's endpoints
>      */
>     uint32_t pipe_int_in;
>     uint32_t pipe_bulk_idma_out;
>     uint32_t pipe_bulk_data_out;
>     uint32_t pipe_bulk_data_in;
>     uint32_t pipe_iso_data_in;
> 
>     /*
>      * Data returned on interrupt by modem
>      */
>     eu_cdc_t *intr_data;
> 
>     /*
>      * Cache used to allocate read buffers
>      */
>     kmem_cache_t *rb_cache;
> 
>     /*
>      * Maximum Receive Unit - depends on the encapsulation
>      */
>     unsigned int mru;
> 
>     /*
>      * Size of the header to prepend in front of inbound data
>      */
>     unsigned int eth_hdr;
> 
>     /*
>      * To hold outbound data
>      */
>     uint8_t   *segmentation_buffer;
> 
>     /*
>      * Modem state machine info
>      */
>     AdiMSM            AdiModemSm;
>     wait_queue_head_t sync_q;
> 
>     eu_cmv_msg_t   *pDriverCMVs;
> 
>     /*DSP code info*/
>     IDMAPage  MainPage;
>     IDMAPage *pSwapPages;
>     uint32_t    SwapPageCount;
> 
>     /*URB queues*/
>     struct list_head ctrl_urb_free_q;  /* Free queued_urb_t queue */
>     struct list_head ctrl_urb_ipg_q;  /* In-progress control urb queue */
>     struct urb      *ctrl_urb_failed;
>     spinlock_t       ctrl_q_lock;
> 
>     /*Kernel timer(s)*/
>     struct timer_list ctrl_urb_q_timer;
>     struct timer_list ctrl_urb_retry;
> 
>     /*
>      * Tasklets
>      */
>     struct tasklet_struct rcv_complete_tasklet;
> 
> #ifdef LINUX_2_6
>     /*
>      * Work queue for eth creation
>      */
>     struct work_struct   create_eth;
> #endif
> 
>     /*
>      * Boot queue / task
>      */
> #ifdef LINUX_2_6
>     struct work_struct   boot_sm;
> #elif defined(LINUX_2_4)
>     struct tq_struct boot_sm;
> #endif
> 
>     boot_state_t boot_state;
>     uint16_t  swap_data;
> 
>     /*
>      * Wait Queue
>      */
>     wait_queue_head_t thr_wait;
> 
>     /*
>      * Completed Read Queue: data to be treated by kernel
>      */
>     struct list_head  comp_read_q;
> 
>     /*
>      * Associated spinlock
>      */
>     spinlock_t       comp_read_q_lock;
> 
>     /*
>      * Misc data
>      */
>     volatile unsigned long flags;
> 
> #ifdef DELAY_ISO_STARTUP
>     uint32_t          IsReadPipeStarted;
> #endif
>     uint32_t           MpoaMode;
>     uint8_t            mac[ETH_ALEN];
> 
>     /*
>      * Ethernet interface data
>      */
>     uint32_t                 out_pkt_size;
>     struct net_device       *eth;
>     struct net_device_stats  LinuxStats;
>     char                     if_name[IFNAMSIZ];
> 
>     /*
>      * Statistics
>      */
>     uint32_t Statistics[STAT_COUNT];
> 
>     /*
>      * ATM data
>      */
>     eu_atm_vc_t Vc;
> 
>     /*
>      * State variables used for OAM stuff
>      */
>     uint32_t           OAMState_TimerOn;
>     uint32_t           OAMState_SendingCC;
>     uint32_t           OAMState_ReceiveCC;
>     uint32_t           OAMState_AIS;
>     uint32_t           OAMState_CCSink;
>     uint8_t            OAMCell[ATM_CELL_SIZE*2];
>     uint8_t           *pOAMCell;
>     uint8_t            OAMCellHeader[ATM_CELL_HEADER_SIZE*2];
>     struct timer_list  OAMTimer;
> 
> } eu_instance_t;
> 
> #endif /* __KERNEL__ */
> 
> #endif /* __EU_TYPES_H__ */
> 
> --=-qML6NwnTSh+fhTRn0KQs
> Content-Disposition: attachment; filename=eu_main.c
> Content-Type: text/x-csrc; name=eu_main.c; charset=ISO-8859-15
> Content-Transfer-Encoding: 7bit
> 
> /*
>  *
>  * Copyright (c) 2003, Frederick Ros ([EMAIL PROTECTED])
>  * Forked from ADI Linux driver from Analog Devices Inc.,
>  * User space interface rewritten by C.Casteyde ([EMAIL PROTECTED])
>  * Multi-modem support added by Renaud Guerin ([EMAIL PROTECTED])
>  * Other stuff : Frederick Ros ([EMAIL PROTECTED])
>  *
>  * eagle-usb.c
>  *
>  * 
> ----------------------------------------------------------------------------
>  *
>  * This file is part of the eagle-usb driver package.
>  *
>  * "eagle-usb driver package" 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.
>  *
>  * "eagle-usb driver package" 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 "eagle-usb driver package"; if not, write to the Free Software
>  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>  *
>  *
>  * $Id: eu_main.c,v 1.15 2004/08/26 20:06:34 sleeper Exp $
>  */
> 
> #include "Adiutil.h"
> #include <linux/module.h>
> #include <linux/init.h>
> #include <linux/proc_fs.h>
> #include <linux/list.h>
> #include <asm/uaccess.h>
> #include <linux/if_arp.h>
> #include "eagle-usb.h"
> #include "macros.h"
> #include "Dsp.h"
> #include "eu_msg.h"
> #include "Pipes.h"
> #include "eu_utils.h"
> #include "eu_sm.h"
> #include "Oam.h"
> #include "Mpoa.h"
> #include "Me.h"
> #include "Uni.h"
> #include "debug.h"
> #include "eu_eth.h"
> #include "eu_boot_sm.h"
> 
> /* ------------------------------- Private Macros 
> ------------------------------- */
> 
> #define CASE_PREFIRM    EAGLE_I_PID_PREFIRM:    \
>     case MILLER_A_PID_PREFIRM:                  \
>     case MILLER_B_PID_PREFIRM:                  \
>     case HEINEKEN_A_PID_PREFIRM:                \
>     case HEINEKEN_B_PID_PREFIRM:                \
>     case EAGLE_IIC_PID_PREFIRM:                 \
>     case EAGLE_II_PID_PREFIRM
> 
> #define CASE_POSTFIRM   EAGLE_I_PID_PSTFIRM:    \
>     case MILLER_A_PID_PSTFIRM:                  \
>     case MILLER_B_PID_PSTFIRM:                  \
>     case HEINEKEN_A_PID_PSTFIRM:                \
>     case HEINEKEN_B_PID_PSTFIRM:                \
>     case EAGLE_II_PID_PSTFIRM:                  \
>     case EAGLE_IIC_PID_PSTFIRM
> 
> #define ISPREFIRM(c) ( EAGLE_I_PID_PREFIRM == (c)                             
>         ||        \
>                        MILLER_A_PID_PREFIRM   == (c) || MILLER_B_PID_PREFIRM 
> == (c)   ||        \
>                        HEINEKEN_A_PID_PREFIRM == (c) || 
> HEINEKEN_B_PID_PREFIRM == (c) ||        \
>                        EAGLE_II_PID_PREFIRM   == (c) || EAGLE_IIC_PID_PREFIRM 
> == (c)            \
>                      )
> 
> #define ISPOSTFIRM(c) ( EAGLE_I_PID_PSTFIRM == (c)                            
>          ||       \
>                         MILLER_A_PID_PSTFIRM   == (c) || MILLER_B_PID_PSTFIRM 
> == (c)   ||       \
>                         HEINEKEN_A_PID_PSTFIRM == (c) || 
> HEINEKEN_B_PID_PSTFIRM == (c) ||       \
>                         EAGLE_II_PID_PSTFIRM   == (c) || 
> EAGLE_IIC_PID_PSTFIRM == (c)           \
>                       )
> 
> /*
>  * Hardcoded endpoint addresses
>  */
> #define EP_BULK_IDMA_OUT       0x04
> #define EP_BULK_DATA_OUT       0x02
> #define EP_BULK_DATA_IN        0x82
> #define EP_ISOC_DATA_IN        0x88
> #define EP_INT_IN              0x84
> 
> #define USB_INTF_IN            0x02
> #define FASTEST_ISO_INTF       0x08
> 
> /*
>  * Interrupts
>  */
> #define EU_INT_LOADSWAPPAGE   0x01
> #define EU_INT_INCOMINGCMV    0x02
> 
> /* ----------------------- Private Function Declarations 
> ------------------------ */
> 
> /*
>  * USB related
>  */
> #ifdef LINUX_2_4
> static void *eu_probe(struct usb_device *usb, unsigned int ifnum, const 
> struct usb_device_id *id);
> static void eu_disconnect(struct usb_device *usb, void *ptr);
> static int eu_user(struct usb_device *dev, unsigned int code, void *buf);
> #elif defined (LINUX_2_6)
> static int eu_probe ( struct usb_interface *intf, const struct usb_device_id 
> *id);
> static void eu_disconnect(struct usb_interface *intf);
> static int eu_user(struct usb_interface *intf, unsigned int code, void *buf);
> #endif
> 
> static USB_COMPLETION_PROTO (eu_irq,urb,regs);
> 
> static int eu_read_proc(char *page, char **start, off_t off, int count, int 
> *eof, void *data);
> 
> /*
>  * Ethernet device related
>  */
> static eu_instance_t *eu_init_prefirm ( struct usb_device *usb );
> #ifdef LINUX_2_6
> static eu_instance_t * eu_init_postfirm ( struct usb_device *usb, struct 
> usb_interface *intf );
> #else
> static eu_instance_t * eu_init_postfirm ( struct usb_device *usb );
> #endif
> static void eu_disconnect_postfirm ( eu_instance_t *ins , struct usb_device 
> *usb );
> static void eu_process_rcv ( unsigned long data );
> static int eu_check_options ( const eu_options_t opt );
> 
> /* ----------------------------- Private Variables 
> ------------------------------ */
> 
> /*
>  * List of supported VID/PID
>  */
> static const struct usb_device_id eu_ids[] =
> {
>     {  USB_DEVICE (EAGLE_VID, EAGLE_I_PID_PREFIRM) },
>     {  USB_DEVICE (EAGLE_VID, EAGLE_I_PID_PSTFIRM) },
>     {  USB_DEVICE (EAGLE_VID, EAGLE_II_PID_PREFIRM) },
>     {  USB_DEVICE (EAGLE_VID, EAGLE_II_PID_PSTFIRM) },
>     {  USB_DEVICE (EAGLE_VID, EAGLE_IIC_PID_PREFIRM) },
>     {  USB_DEVICE (EAGLE_VID, EAGLE_IIC_PID_PSTFIRM) },
>     {  USB_DEVICE (USR_VID, MILLER_A_PID_PREFIRM) },
>     {  USB_DEVICE (USR_VID, MILLER_A_PID_PSTFIRM) },
>     {  USB_DEVICE (USR_VID, MILLER_B_PID_PREFIRM) },
>     {  USB_DEVICE (USR_VID, MILLER_B_PID_PSTFIRM) },
>     {  USB_DEVICE (USR_VID, HEINEKEN_A_PID_PREFIRM) },
>     {  USB_DEVICE (USR_VID, HEINEKEN_A_PID_PSTFIRM) },
>     {  USB_DEVICE (USR_VID, HEINEKEN_B_PID_PREFIRM) },
>     {  USB_DEVICE (USR_VID, HEINEKEN_B_PID_PSTFIRM) },
>     { }
> };
> 
> /*
>  * USB driver descriptor
>  */
> static struct usb_driver eu_driver =
> {
> #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19)
>     .owner      = THIS_MODULE,
> #endif
>     .name       = "eagle-usb",
>     .id_table   = eu_ids,
>     .probe      = eu_probe,
>     .disconnect = eu_disconnect,
>     .ioctl      = eu_user
> };
> 
> /*
>  * Linked list of modem eu_instance_t structs
>  */
> LIST_HEAD(modem_list);
> 
> /*
>  * Our /proc dir entry
>  */
> struct proc_dir_entry* eu_procdir;
> 
> #define DEFAULT_OPTN0    0x80020066
> #define DEFAULT_OPTN2    0x23700000
> #define DEFAULT_OPTN3    0x00000000
> #define DEFAULT_OPTN4    0x00000000
> #define DEFAULT_OPTN5    0x00000000
> #define DEFAULT_OPTN6    0x00000000
> #define DEFAULT_OPTN7    0x02CD8044
> #define DEFAULT_OPTN15   0x00000000
> #define DEFAULT_VPI      0x00000008
> #define DEFAULT_VCI      0x00000023
> #define DEFAULT_ENCAPS   MPOA_MODE_PPPOA_VC
> #define DEFAULT_LINETYPE 0x00000001
> #define DEFAULT_POLLFREQ 0x0000000A
> 
> /*
>  * Default driver options
>  */
> static const eu_options_t default_options =
> {
>     { "OPTN0", DEFAULT_OPTN0 },
>     { "OPTN2", DEFAULT_OPTN2 },
>     { "OPTN3", DEFAULT_OPTN3 },
>     { "OPTN4", DEFAULT_OPTN4 },
>     { "OPTN5", DEFAULT_OPTN5 },
>     { "OPTN6", DEFAULT_OPTN6 },
>     { "OPTN7", DEFAULT_OPTN7 },
>     { "OPTN15", DEFAULT_OPTN15 },
>     { "VPI", DEFAULT_VPI },
>     { "VCI", DEFAULT_VCI },
>     { "Encapsulation", DEFAULT_ENCAPS },
>     { "Linetype", DEFAULT_LINETYPE },
>     { "RatePollFreq", DEFAULT_POLLFREQ },
> };
> 
> /*
>  * User supplied name for ethernet interface
>  */
> static char *if_name = NULL;
> 
> /*
>  * User supplied debug level
>  */
> unsigned int module_dbg_mask = 0x0;
> 
> /* -------------------------------- Module Stuff 
> -------------------------------- */
> 
> MODULE_AUTHOR ("Anoosh Naderi <[EMAIL PROTECTED]>/Frederick Ros ([EMAIL 
> PROTECTED])");
> MODULE_DESCRIPTION ("Eagle USB ADSL Modem driver");
> MODULE_DEVICE_TABLE (usb, eu_ids);
> MODULE_LICENSE("GPL");
> MODULE_PARM (if_name,"s");
> MODULE_PARM_DESC (if_name,"Exported ethernet interface name");
> MODULE_PARM (module_dbg_mask,"i");
> MODULE_PARM_DESC (module_dbg_mask,"Module Debug mask");
> 
> EXPORT_NO_SYMBOLS;
> 
> /* -----------------------  INITIALIZATION / DESTRUCTION 
> ------------------------ */
> 
> /**
>  * eu_init - Initialize the module.
>  *      Generates CRC table
>  *      Creates /proc/driver/eagle-usb directory
>  *      Register to USB subsystem
>  *
>  */
> static int __init eu_init (void)
> {
>     int result = 0;
> 
>     eu_enters (DBG_INIT);
> 
>     eu_report ("driver V"EAGLEUSBVERSION" loaded\n");
> 
>     eu_crc_generate();
> 
>     eu_procdir = proc_mkdir("driver/eagle-usb",NULL);
> 
>     if ( eu_procdir )
>     {
>        eu_procdir->owner = THIS_MODULE;
>     }
>     else
>     {
>         eu_report ("could not create /proc/driver/eagle-usb/\n");
>         result = -ENOMEM;
>     }
> 
>     usb_register(&eu_driver);
> 
>     eu_leaves (DBG_INIT);
> 
>     return 0;
> }
> 
> module_init (eu_init);
> 
> /**
>  * eu_exit  -  Finalize module
>  *
>  *    Deregister with USB subsystem
>  *    Remove /proc/drivers/eagle-usb directory
>  *
>  */
> static void __exit eu_exit (void)
> {
>     eu_enters (DBG_INIT);
> 
>     /*
>      * This calls automatically the eu_disconnect method if necessary:
>      */
>     usb_deregister (&eu_driver);
> 
>     eu_report ("driver unloaded\n");
>     remove_proc_entry("driver/eagle-usb",NULL);
> 
>     eu_leaves (DBG_INIT);
> 
> }
> 
> module_exit (eu_exit);
> 
> /**
>  * eu_probe  -  Ask driver to probe this device
>  *
>  */
> #ifdef LINUX_2_4
> static void *eu_probe (
>                        struct usb_device *usb,
>                        unsigned int ifnum,
>                        const struct usb_device_id *id
>                       )
> #elif defined(LINUX_2_6)
> static int eu_probe (
>                      struct usb_interface *intf,
>                      const struct usb_device_id *id
>                     )
> #endif
> 
> {
>     void     *ins = NULL;
> #ifdef LINUX_2_6
>     struct usb_device *usb = interface_to_usbdev (intf);
> #endif
>     uint32_t  pid  = usb->descriptor.idProduct;
> 
>     eu_enters (DBG_INIT);
> 
>     eu_dbg (DBG_INIT,"vid (%#X) pid (%#X) \n",
>              usb->descriptor.idVendor, usb->descriptor.idProduct);
> 
>     /*
>      * This driver knows only pre and postfirmware devices.
>      */
>     if ( !ISPREFIRM(pid) && !ISPOSTFIRM(pid) )
>     {
>         eu_dbg (DBG_INIT," Not a supported modem\n");
>         goto byebye;
>     }
> 
>     switch ( pid )
>     {
>         case CASE_PREFIRM:
> 
>             ins = eu_init_prefirm ( usb );
>             break;
> 
>         case CASE_POSTFIRM:
> #ifdef LINUX_2_6
>             ins = eu_init_postfirm ( usb, intf );
> #else
>             ins = eu_init_postfirm ( usb );
> #endif
> 
>             break;
>     }
> 
>     eu_leaves (DBG_INIT);
> 
>   byebye:
> #ifdef LINUX_2_6
>     if (ins)
>     {
> 
>         usb_set_intfdata (intf, ins);
> 
>         return (0);
>     }
>     else
>     {
>         return -ENODEV;
>     }
> #else
>     return (ins);
> #endif
> }
> 
> /*
>  * eu_init_prefirm - Initialize pre-firmware device
>  *
>  * @usb  -  USB device to init.
>  */
> static eu_instance_t *eu_init_prefirm ( struct usb_device *usb )
> {
>     eu_instance_t *ins    = NULL;
>     int            ret;
>     uint32_t       pid    = usb->descriptor.idProduct;
> 
>     eu_enters (DBG_INIT);
> 
>     /*
>      * Create a new pre-firmware device:
>      */
>     ins = GET_KBUFFER (sizeof(eu_instance_t));
>     if ( !ins )
>     {
>         eu_err ("Not enough memory to get new driver structure..\n");
>         goto byebye;
>     }
> 
>     eu_report ("New pre-firmware modem detected\n");
> 
>     /*
>      * Reinitialize the modem structure:
>      */
>     memset (ins, 0, sizeof(eu_instance_t));
>     ins->usbdev = usb;
> 
>     EU_CLEAR_FLAG (ins, EU_MSG_INITIALIZED);
>     EU_CLEAR_FLAG (ins, EU_UNPLUG);
> 
>     eu_report ("Uploading firmware..\n");
> 
>     ret = eu_load_firmware ( ins, pid );
>     if ( ret < 0 )
>     {
>         eu_err ("Can't upload firmware to modem...\n");
>         FREE_KBUFFER (ins);
>         ins = NULL;
>         goto byebye;
>     }
> 
>     eu_report ("Binding eu_instance_t to USB %03d/%03d\n",
>                usb->bus->busnum, usb->devnum);
> 
>     list_add (&ins->list,&modem_list);
> 
>   byebye:
>     eu_leaves ( DBG_INIT);
> 
>     return(ins);
> 
> }
> 
> /**
>  * eu_init_postfirm  - Initialize post firmware device
>  *
>  * @usb  -  USB device to init
>  */
> #ifdef LINUX_2_6
> static eu_instance_t * eu_init_postfirm ( struct usb_device *usb, struct 
> usb_interface *intf )
> #else
> static eu_instance_t * eu_init_postfirm ( struct usb_device *usb )
> #endif
> {
>     int                             i;
>     eu_instance_t                  *ins = NULL;
>     char                            path[32];
>     struct proc_dir_entry*          procfile;
>     int                             ret = 0;
>     unsigned int                    nb_frames;
>     int tmp;
> 
>     eu_enters (DBG_INIT);
> 
>     /*
>      * Create a new post-firmware device:
>      */
>     ins = GET_KBUFFER (sizeof (eu_instance_t));
> 
>     if ( !ins )
>     {
>         eu_err ("eu_init_postfirm: Not enough memory !\n");
>         goto byebye;
>     }
> 
>     /*
>      * Initialize our instance
>      */
>     memset ( ins, 0, sizeof(eu_instance_t) );
>     ins->usbdev = usb;
> 
>     EU_CLEAR_FLAG ( ins, EU_MSG_INITIALIZED);
>     EU_CLEAR_FLAG ( ins, EU_UNPLUG);
> 
>     init_waitqueue_head (&ins->sync_q);
>     ins->lock = SPIN_LOCK_UNLOCKED;
> 
>     /*
>      * Add our new device's list hook to the modem_list
>      */
>     list_add ( &ins->list,&modem_list );
> 
>     eu_report ("New USB ADSL device detected, waiting for DSP code...\n");
> #ifdef LINUX_2_6
>     eu_report ("Interface %d 
> accepted.\n",intf->altsetting[0].desc.bInterfaceNumber);
> #endif
> 
> #ifdef USEBULK
>     EU_CLEAR_FLAG (ins, EU_LOW_RATE);
> #else
>     EU_SET_FLAG (ins, EU_LOW_RATE);
> #endif
> 
>     /*
>      * Use constants for endpoint addresses - It saves us from parsing through
>      * descriptors ..
>      */
>     ins->pipe_bulk_idma_out = usb_sndbulkpipe(usb, EP_BULK_IDMA_OUT);
>     ins->pipe_bulk_data_out = usb_sndbulkpipe(usb, EP_BULK_DATA_OUT);
>     ins->pipe_bulk_data_in  = usb_rcvbulkpipe(usb, EP_BULK_DATA_IN);
>     ins->pipe_iso_data_in  = usb_rcvisocpipe(usb, EP_ISOC_DATA_IN);
>     ins->pipe_int_in     = usb_rcvintpipe(usb, EP_INT_IN);
> 
>     /*
>      * Make sure we can get all the memory we need
>      */
>     ins->intr_data = GET_KBUFFER (sizeof (eu_cdc_t));
> 
>     if ( !ins->intr_data )
>     {
>         eu_err ("Can't allocate interrupt buffer\n");
>         goto free_instance;
>     }
> 
>     ins->segmentation_buffer  = GET_KBUFFER(OUTGOING_DATA_SIZE);
> 
>     if ( !ins->segmentation_buffer )
>     {
>         eu_err ("Can't allocate segmentation buffer\n");
>         goto free_int_buff;
>     }
> 
>     INIT_LIST_HEAD ( &ins->comp_read_q );
>     ins->comp_read_q_lock = SPIN_LOCK_UNLOCKED;
> 
> #ifdef USEBULK
>     nb_frames     = 0;
> #else
>     nb_frames     =  FRAMES_PER_ISO_URB;
> #endif /* USEBULK */
> 
>     /*
>      * Get a lookaside cache
>      */
>     ins->rb_cache = kmem_cache_create ( "eagle-usb",
>                                         sizeof(eu_rb_t),
>                                         0,0, NULL,NULL);
> 
>     if ( !ins->rb_cache )
>     {
>         eu_err ("eu_init_postfirm : Can't get lookaside cache.\n");
>         goto free_seg_buff;
>     }
> 
>     for ( i=0; i < INCOMING_Q_SIZE; i++ )
>     {
>         ins->read_urb[i]   = USB_ALLOC_URB ( nb_frames, GFP_ATOMIC );
> 
>         if ( !ins->read_urb[i] )
>         {
>             eu_err ("eu_init_postfirm : Can't allocate URB \n");
>             goto free_urbs;
>         }
> 
>         ins->read_urb[i]->transfer_buffer = NULL;
> 
>     }
> 
>     ins->pOAMCell = GET_KBUFFER(128);
>     if (ins->pOAMCell == 0 )
>     {
>         eu_err ("eu_init_postfirm : Can't allocate memory\n");
>         goto free_urbs;
>     }
> 
>     ins->mru = 0;
> 
>     /*
>      * Initialize the CTRL URB queue
>      */
>     ret = alloc_queued_urb_ctrl ( ins, CTRL_URB_Q_SIZE );
> 
>     if (ret != 0)
>     {
>         eu_err ("eu_init_postfirm : alloc_queued_urb_ctrl out of memory\n");
>         goto free_oam_cell;
>     }
> 
>     INIT_LIST_HEAD(&ins->ctrl_urb_ipg_q);
>     ins->ctrl_q_lock = SPIN_LOCK_UNLOCKED;
>     ins->ctrl_urb_failed= FALSE;
> 
>     /*
>      * Initialize needed kernel timers.
>      * WatchdogTimer is the "management entity", responsible for initiating a 
> regular
>      * status check of the modem
>      */
>     init_timer(&ins->AdiModemSm.timerSM);
>     ins->AdiModemSm.timerSM.function = WatchdogTimer;
>     ins->AdiModemSm.timerSM.data     = (unsigned long) ins;
> 
>     /*
>      * As UHCI does not allow to queue control urbs, we make our own queueing
>      */
>     init_timer(&ins->ctrl_urb_q_timer);
>     ins->ctrl_urb_q_timer.function  = ctrl_urb_q_watcher;
>     ins->ctrl_urb_q_timer.data      = (unsigned long) ins;
> 
>     init_timer (&ins->ctrl_urb_retry);
>     ins->ctrl_urb_retry.function = ctrl_urb_retry_send;
>     ins->ctrl_urb_retry.data = (unsigned long) ins;
>     ins->ctrl_urb_failed = NULL;
> 
>     /*
>      * Get interrupt urb
>      */
>     ins->urb_int   = USB_ALLOC_URB ( 0, GFP_ATOMIC );
> 
>     if ( !ins->urb_int )
>     {
>         eu_err ("eu_init_postfirm : Can't allocate INT URB \n");
>         goto free_oam_cell;
>     }
> 
>     /*
>      * Get write urb
>      */
>     ins->urb_write   = USB_ALLOC_URB ( 0, GFP_ATOMIC );
> 
>     if ( !ins->urb_write )
>     {
>         eu_err ("eu_init_postfirm : Can't allocate WRITE URB \n");
>         goto free_urb_int;
>     }
> 
>     /*
>      * Get oam_write urb
>      */
>     ins->urb_oam_write   = USB_ALLOC_URB ( 0, GFP_ATOMIC );
> 
>     if ( !ins->urb_oam_write )
>     {
>         eu_err ("eu_init_postfirm : Can't allocate OAM WRITE URB \n");
>         goto free_urb_write;
>     }
> 
>     /*
>      * Other init stuff
>      */
>     ins->AdiModemSm.HeartbeatCounter = 0;
>     ins->AdiModemSm.CurrentAdiState  = STATE_JUST_PLUGGED_IN;
> 
>     init_timer(&ins->OAMTimer);
>     ins->OAMTimer.function  = OAMTimerFunction;
>     ins->OAMTimer.data      = (unsigned long)ins;
> 
>     /*
>      * Interface 1 is for outbound traffic
>      */
>     tmp = USB_DRIVER_CLAIM_INTERFACE(&eu_driver, GET_INTF_PTR(usb,1), ins);
>     if ( tmp != 0 )
>     {
>         eu_report ("Failed to claim interface 1 (%d)\n",-tmp);
>         goto free_oam_timer;
>     }
> 
>     /*
>      * Interface 2 is for inbound traffic
>      */
>     tmp = USB_DRIVER_CLAIM_INTERFACE(&eu_driver, GET_INTF_PTR(usb,2), ins);
>     if ( tmp != 0 )
>     {
>         eu_report ("Failed to claim interface 2 (%d)\n",-tmp);
>         goto release_intf_1;
>     }
> 
>     ins->users = 3;
> 
> #ifndef USEBULK
> 
>     /*
>      * Set alternate interface to 8, which is ISO transport
>      * with the max. packet size ( about 1007 bytes)
>      */
>     if (usb_set_interface(usb, USB_INTF_IN, FASTEST_ISO_INTF) < 0)
>     {
>         eu_err ("usb_set_interface failed on iso alt 8\n");
>     }
> #endif /* USEBULK */
> 
>     /*
>      * Setup our /proc interface
>      */
>     snprintf ( path,32,"%03d-%03d",ins->usbdev->bus->busnum, 
> ins->usbdev->devnum);
> 
>     procfile=create_proc_read_entry(path,0, eu_procdir, eu_read_proc, ins);
> 
>     if (procfile)
>     {
>         procfile->owner=THIS_MODULE;
>         eu_report ("created proc entry at : /proc/driver/eagle-usb/%s\n",
>                    path);
>     }
>     else
>     {
>         eu_err ("failed to create proc entry at : /proc/driver/%s !\n",
>                 path);
>     }
> 
>     /*
>      * Get MAC address
>      */
>     eu_get_mac_addr ( ins );
> 
>     /*
>      * Initialize wait queue
>      */
>     init_waitqueue_head (&ins->thr_wait);
> 
>     if ( if_name )
>     {
>         strncpy ( ins->if_name, if_name, IFNAMSIZ-1);
>         ins->if_name[IFNAMSIZ-1] = '\0';
>     }
> 
>     /*
>      * Initialize tasklets
>      */
>     tasklet_init ( &ins->rcv_complete_tasklet,
>                    eu_process_rcv,
>                    (unsigned long) ins );
> #ifdef LINUX_2_6
>     /*
>      * And work
>      */
>     INIT_WORK (&ins->create_eth,eu_eth_create, ins);
> #endif
> 
>     /*
>      * And boot SM
>      */
> #ifdef LINUX_2_6
>     INIT_WORK (&ins->boot_sm, eu_boot_sm, ins);
> #elif defined(LINUX_2_4)
>     INIT_TQUEUE (&ins->boot_sm, eu_boot_sm, ins);
> #endif
> 
>     /*
>      * And boot state
>      */
>     ins->boot_state = PRE_BOOT;
> 
>     /*
>      * We're successfull !!!!
>      */
>     eu_dbg (DBG_INIT,"nb of users: %u\n",ins->users);
>     goto byebye;
> 
>   release_intf_1:
>     usb_driver_release_interface(&eu_driver, GET_INTF_PTR(usb,1));
> 
>   free_oam_timer:
>     if ( timer_pending ( &ins->OAMTimer ) )
>     {
>         del_timer ( &ins->OAMTimer );
>     }
> 
>   free_urb_write:
>     usb_free_urb ( ins->urb_write );
>     ins->urb_write = NULL;
> 
>   free_urb_int:
>     usb_free_urb ( ins->urb_int );
>     ins->urb_int = NULL;
> 
>   free_oam_cell:
>     FREE_KBUFFER (ins->pOAMCell );
> 
>   free_urbs:
> 
>     for ( i=0; i < INCOMING_Q_SIZE; i++ )
>     {
>         if ( ins->read_urb[i] ) {
>             usb_free_urb ( ins->read_urb[i] );
>             ins->read_urb[i] = NULL;
>         }
>         else
>         {
>             break;
>         }
>     }
> 
>     kmem_cache_destroy ( ins->rb_cache );
> 
>   free_seg_buff:
>     FREE_KBUFFER ( ins->segmentation_buffer );
> 
>   free_int_buff:
>     FREE_KBUFFER ( ins->intr_data );
> 
>   free_instance:
>     FREE_KBUFFER (ins);
>     ins = NULL;
> 
>   byebye:
>     eu_leaves ( DBG_INIT);
>    return (ins);
> 
> }
> 
> /**
>  * eu_disconnect  -  Disconnect an USB device from the system
>  *
>  * @usb   -   USB Device to disconnect
>  * @ptr   -   User Data ( pointer to associated instance )
>  *
>  */
> #ifdef LINUX_2_4
> static void eu_disconnect ( struct usb_device *usb, void *ptr )
> #elif defined(LINUX_2_6)
> static void eu_disconnect ( struct usb_interface *intf )
> #endif
> {
> #ifdef LINUX_2_4
>     eu_instance_t *ins = (eu_instance_t *)ptr;
> #elif defined (LINUX_2_6)
>     eu_instance_t *ins = usb_get_intfdata (intf);
>     struct usb_device *usb = interface_to_usbdev (intf);
> #endif
> 
>     uint32_t pid = usb->descriptor.idProduct;
> 
>     eu_enters (DBG_INIT);
> 
>     /*
>      * We can't do anything if we don't have a valid eu_instance_t pointer
>      */
>     if (ins == NULL)
>     {
>         eu_err ("eu_disconnect : No device.\n");
>         goto dis_done;
>     }
> 
>     eu_dbg (DBG_INIT,"intf=0x%p intfdate=0x%p ins = 0x%p\n",
>             intf,usb_get_intfdata (intf),ins);
> 
>     /*
>      * Do nothing if you also have no usbdev associated
>      */
>     if (ins->usbdev == NULL )
>     {
>         eu_dbg (DBG_INIT,"No usb dev associated.\n");
>         goto dis_done;
>     }
> 
>     eu_dbg (DBG_INIT,"ins->usbdev = 0x%p\n",ins->usbdev);
> 
>     EU_SET_FLAG (ins, EU_UNPLUG);
> 
>     eu_dbg (DBG_INIT,"Let check PID\n");
> 
>     switch (pid)
>     {
>     case CASE_PREFIRM:
> 
>         list_del(&ins->list);
> 
>         FREE_KBUFFER(ins);
> 
>         eu_report ("Pre-firmware modem removed\n");
>         break;
> 
>     case CASE_POSTFIRM:
> 
> /*         ins->usbdev = NULL; */
> 
> #ifdef LINUX_2_6
>     usb_set_intfdata (intf, NULL);
> #endif
>         eu_disconnect_postfirm (ins,usb);
> 
>         ins = NULL;
>         break;
>     }
> 
>     eu_dbg (DBG_INIT,"intf=0x%p intfdata=0x%p 
> ins=0x%p\n",intf,usb_get_intfdata (intf),ins);
> 
> dis_done:
>     eu_leaves (DBG_INIT);
> }
> 
> /**
>  * eu_disconnect_postfirm  -  Perform destruction of a postfirmware device
>  *
>  * @ins  -  Instance to destroy
>  *
>  */
> static void eu_disconnect_postfirm ( eu_instance_t *ins , struct usb_device 
> *usb )
> {
>     int i;
>     char path[32];
> 
>     /*
>      * Unlink pending interrupt URBs
>      */
>     if ( EU_TEST_FLAG ( ins, EU_HAS_INT ) )
>     {
>         eu_dbg (DBG_INIT,"Stop interrupt URB\n");
>         ins->urb_int->transfer_flags &= ~URB_ASYNC_UNLINK;
>         usb_unlink_urb(ins->urb_int);
>         usb_free_urb (ins->urb_int);
>         EU_CLEAR_FLAG (ins, EU_HAS_INT);
>     }
> 
>     /*
>      * Decrement the number of user, and destroy this instance only if this
>      * number reaches 0
>      */
>     ins->users --;
> 
>     eu_dbg (DBG_INIT,"nb of users: %u\n",ins->users);
> 
>     if ( ins->users > 0 )
>     {
>         eu_dbg (DBG_INIT,"Still %u user(s).. Do nothing\n",ins->users);
>         return;
>     }
> 
>     /*
>      * If timers are currently running, delete them:
>      */
>     if ( timer_pending (&ins->AdiModemSm.timerSM) )
>     {
>         del_timer ( &ins->AdiModemSm.timerSM );
>     }
> 
>     if ( timer_pending (&ins->ctrl_urb_q_timer) )
>     {
>         del_timer ( &ins->ctrl_urb_q_timer );
>     }
> 
>     if ( timer_pending (&ins->ctrl_urb_retry) )
>     {
>         del_timer ( &ins->ctrl_urb_retry );
>     }
> 
>     /*
>      * Flush all pending task ...
>      */
>     EU_FLUSH (eu_>boot_sm);
> 
>     /*
>      * Free the DSP code:
>      */
> 
>     /*
>      * FIXME : don't duplicate DSP code for every modem ?
>      */
>     FreeDspData ( &ins->MainPage, &ins->pSwapPages, &ins->SwapPageCount );
> 
>     if ( timer_pending ( &ins->OAMTimer ) )
>     {
>         del_timer ( &ins->OAMTimer );
>     }
> 
>     /*
>      * Remove our network interface from the kernel:
>      */
> 
>     if ( ins->eth )
>     {
>         /*
>          * This will call the eu_close method:
>          */
>         unregister_netdev ( ins->eth );
>         kfree ( ins->eth );
>         ins->eth = NULL;
>     }
> 
>     EU_CLEAR_FLAG (ins, EU_ETH_REGISTERED);
> 
>     /*
>      * Free memory we alloced
>      */
>     FREE_KBUFFER ( ins->intr_data );
> 
>     for ( i=0; i<INCOMING_Q_SIZE; i++ )
>     {
> 
>         if ( ( ins->read_urb[i] ) &&
>              ( ins->read_urb[i]->transfer_buffer ) )
>         {
>             kmem_cache_free ( ins->rb_cache,
>                               GET_RBUF (ins->read_urb[i]) );
>         }
> 
>         if ( ins->read_urb[i] )
>         {
>             ins->read_urb[i]->transfer_flags &= ~URB_ASYNC_UNLINK;
>             usb_unlink_urb ( ins->read_urb[i] );
>             usb_free_urb ( ins->read_urb[i] );
>             ins->read_urb[i] = NULL;
>         }
>     }
> 
>     kmem_cache_destroy ( ins->rb_cache );
> 
>     tasklet_kill ( &ins->rcv_complete_tasklet);
> 
>     FREE_KBUFFER ( ins->pOAMCell );
> 
>     unlink_ipg_ctrl_urb ( ins );
>     free_queued_urb_ctrl (&ins->ctrl_urb_free_q);
>     free_queued_urb_ctrl (&ins->ctrl_urb_ipg_q);
> 
>     /*
>      * Free write urb: it has been unlinked in eu_eth_close
>      */
>     ins->urb_write->transfer_flags &= ~URB_ASYNC_UNLINK;
>     usb_unlink_urb ( ins->urb_write );
>     usb_free_urb ( ins->urb_write );
> 
>     /*
>      * Free urb_oam_write
>      */
>     ins->urb_oam_write->transfer_flags &= ~URB_ASYNC_UNLINK;
>     usb_unlink_urb(ins->urb_oam_write);
>     usb_free_urb ( ins->urb_oam_write );
> 
>     /*
>      * Tell usb that we no longer claim these interfaces as our property
>      */
> 
> #if 0
>     /*
>      * Release interrupt interface
>      */
>     usb_driver_release_interface ( &eu_driver, GET_INTF_PTR (usb,0) );
> 
>     /*
>      * Release outbound interface
>      */
>     usb_driver_release_interface ( &eu_driver, GET_INTF_PTR (usb,1) );
> 
>     /*
>      * Release inbound interface
>      */
>     usb_driver_release_interface ( &eu_driver, GET_INTF_PTR (usb,2) );
> #endif
> 
> #if 0
>     if ( ins->pDriverCMVs )
>     {
>         FREE_VBUFFER ( ins->pDriverCMVs );
>     }
> #endif
> 
>     list_del ( &ins->list );
> 
>     snprintf ( path,32,"%03d-%03d",usb->bus->busnum, usb->devnum );
>     remove_proc_entry ( path, eu_procdir );
> 
>     FREE_KBUFFER ( ins );
> 
>     eu_report ("ADSL device removed\n");
> }
> 
> /*******************************************************************************/
> /* eu_irq                                                                     
>  */
> /*******************************************************************************/
> static USB_COMPLETION_PROTO (eu_irq,urb,regs)
> {
>     eu_instance_t *ins;
> 
>     eu_enters (DBG_INTS);
> 
>     /*
>      * Instance is in the URB context.
>      */
>     ins = (eu_instance_t *)urb->context;
> 
>     if ( NULL == ins )
>     {
>         eu_err ("eu_irq : No device.\n");
>         goto irq_done;
>     }
> 
>     if ( !EU_TEST_FLAG(ins, EU_HAS_INT) )
>     {
>         eu_err ("eu_irq : Callback on unregistered interrupt handler!\n");
>         goto irq_done;
>     }
> 
>     if  (
>          ( urb->status ==  -ENOENT ) ||
>          ( urb->status == -ECONNRESET ) ||
>          ( urb->status == -ESHUTDOWN )
>         )
>     {
>         /*
>          *  User cancelled this URB : do nothing, and don't reset status to 0,
>          *  or the URB will be re-used
>          */
>         eu_report ("eu_irq : URB canceled by user.\n");
>         EU_CLEAR_FLAG (ins, EU_HAS_INT);
> 
>         goto irq_done;
>     }
> 
>     /*
>      * Lets check the status first, to make sure this was succesfull
>      */
>     if ( urb->status < 0 )
>     {
>         eu_err ("eu_irq : URB status indicates error (%d)\n",
>                 urb->status);
>         urb->status = 0;
>         goto resubmit;
>     }
> 
>     /*
>      * All is well, we can process the data!
>      */
>     if ( ins->intr_data->bRequestType == 0x08 ) /* device-to-host interrupt */
>     {
>         eu_devint_t *pintr;
> 
>         pintr = (eu_devint_t *) (&(ins->intr_data->data[0]));
> 
>         switch ( cpu_to_le16 (pintr->intr) )
>         {
>             case EU_INT_LOADSWAPPAGE:
>             {
>                 ins->swap_data = cpu_to_le16 (pintr->intr_info.swap_data);
> 
>                 eu_dbg (DBG_INTS,"interrupt = EU_INT_LOADSWAPPAGE\n");
> 
>                 if ( ins->AdiModemSm.CurrentAdiState != 
> STATE_HARD_RESET_INITIATE )
>                 {
>                     ins->boot_state = UPLOAD_P;
>                     EU_SCHEDULE ( &ins->boot_sm ) ;
>                 }
>             }
>             break;
> 
>             case EU_INT_INCOMINGCMV:
>             {
>                 eu_dbg (DBG_INTS,"interrupt = EU_INT_INCOMINGCMV\n");
> 
>                 ProcessIncomingCmv ( ins, pintr->intr_info.cmv_data );
>             }
>             break;
> 
>             default:
>                 eu_dbg (DBG_INTS,"interrupt = unsupported(%d)\n", 
> pintr->intr);
> 
>                 break;
>         }
>     }
> 
>   resubmit:
> 
> #ifdef LINUX_2_6
>     {
>         int ret;
> 
>         ret = USB_SUBMIT_URB ( urb, GFP_ATOMIC );
>         if ( ret )
>         {
>             eu_err ("eu_irq: URB submission failure (%d)\n",ret);
>         }
>     }
> 
> #endif
> 
>   irq_done:
>     eu_leaves (DBG_INTS);
> 
> }
> 
> /**
>  * find_hardware - Look for the given hardware in instance list
>  *
>  */
> static eu_instance_t *find_hardware ( struct usb_device *dev )
> {
>     struct list_head *ptr;
>     eu_instance_t         *ins = NULL;
> 
>     for ( ptr = modem_list.next; ptr != &modem_list; ptr = ptr->next )
>     {
>         eu_instance_t *entry;
>         entry=list_entry (ptr, eu_instance_t, list);
>         if ( entry->usbdev == dev )
>         {
>             ins=entry;
>             break;
>         }
>     }
> 
>     return ins;
> }
> 
> /**
>  * eu_user  -  ioctl handler for ioctl emited on the USB device file. Ioctls 
> emited
>  *             on the network device will be treated by eu_eth_ioctl
>  */
> #ifdef LINUX_2_4
> static int eu_user ( struct usb_device *dev, unsigned int code, void *buf )
> #elif defined (LINUX_2_6)
> static int eu_user ( struct usb_interface *intf, unsigned int code, void *buf 
> )
> #endif
> {
> #ifdef LINUX_2_6
>     struct usb_device *dev = interface_to_usbdev (intf);
> #endif
>     eu_instance_t *ins;
>     int retval = -ENOTTY;
>     uint32_t pid = dev->descriptor.idProduct;
> 
>     /*
>      * USB automatically transfers user ioctl structure in kernel
>      * address space (the size is already encoded in the ioctl code):
>      */
>     struct eu_ioctl_info *pIOCTLinfo = (struct eu_ioctl_info *) buf;
> 
>     MODULE_USER_GET;
> 
>     if ( !(ins = find_hardware(dev)) )
>     {
>         eu_report ("Could not find eu_instance_t for USB device %03d/%03d\n",
>                     dev->bus->busnum, dev->devnum);
>         MODULE_USER_RELEASE;
> 
>         return -ENOTTY;
>     }
> 
>     /*
>      * Set/Get debug flags works for pre/post firmwares.
>      */
>     if ( code == EU_IO_SETDBG )
>     {
>         if ( NULL == pIOCTLinfo )
>         {
>             eu_err ("EU_IO_SETDBG : No data\n");
>             retval = -EINVAL;
>             goto byebye;
>         }
> 
>         module_dbg_mask = pIOCTLinfo->idma_start;
>         eu_report ("Debug mask set to 0x%x\n",module_dbg_mask);
>         retval = 0;
>         goto byebye;
>     }
> 
>     if ( code == EU_IO_GETDBG )
>     {
>         if ( NULL == pIOCTLinfo )
>         {
>             eu_err ("EU_IO_GETDBG : No data\n");
>             retval = -EINVAL;
>             goto byebye;
>         }
> 
>         pIOCTLinfo->idma_start = module_dbg_mask;
>         retval = 0;
>         goto byebye;
>     }
> 
>     /* Check this ioctl if for one of our devices: */
>     switch (pid)
>     {
>         case CASE_PREFIRM:
>             eu_err ("In pre-firmware mode only get/set debug ioctl is 
> permitted.\n");
>             retval = -EINVAL;
>             break;
>         case CASE_POSTFIRM:
>             switch (code)
>             {
> #if 0
>                 case EU_IO_CMVS:
>                     retval = -ERESTARTSYS;
>                     if ( !spin_trylock ( &ins->net_lock ) )
>                     {
>                         eu_err ("EU_IO_CMVS : Can't lock\n");
>                         break;
>                     }
> 
>                     if ( ins->flags & EU_OPEN )
>                     {
>                         retval = -EBUSY;
>                         eu_err ("EU_IO_CMVS : Eth device already open.\n");
>                         goto end_set_cmvs;
>                     }
> 
>                     if (NULL == pIOCTLinfo)
>                     {
>                         eu_err ("EU_IO_CMVS : No data.\n");
>                         retval = -EFAULT;
>                         goto end_set_cmvs;
>                     }
> 
>                     if (pIOCTLinfo->buffer == NULL )
>                     {
>                         eu_err ("EU_IO_CMVS: Null input buffer\n");
>                         retval = -EINVAL;
>                         goto end_set_cmvs;
>                     }
> 
>                     if ( pIOCTLinfo->buffer_size == 0 )
>                     {
>                         eu_err ("EU_IO_CMVS: Invalid Buffersize\n");
>                         retval = -EINVAL;
>                         goto end_set_cmvs;
>                     }
> 
>                     /* Get a buffer for CMVs */
>                     eu_dbg (DBG_INIT,"Allocating %d bytes for 
> CMVs\n",pIOCTLinfo->buffer_size);
> 
>                     ins->pDriverCMVs = GET_VBUFFER (pIOCTLinfo->buffer_size);
>                     if ( ins->pDriverCMVs == NULL )
>                     {
>                         eu_err ("EU_IO_CMVS: Not enough memory to get %d 
> bytes\n",
>                                  pIOCTLinfo->buffer_size);
>                         retval = -ENOMEM;
>                         goto end_set_cmvs;
>                     }
> 
>                     if (copy_from_user(ins->pDriverCMVs, pIOCTLinfo->buffer, 
> pIOCTLinfo->buffer_size))
>                     {
>                         retval = -EFAULT;
>                         FREE_VBUFFER (ins->pDriverCMVs);
>                         eu_err ("EU_IO_CMVS : copy from user failed.\n");
>                         goto end_set_cmvs;
>                     }
> 
>                     eu_report ("ioctl EU_IO_CMVS received and treated.\n");
>                     retval = 0;
> 
>               end_set_cmvs:
>                     spin_unlock ( &ins->net_lock);
> 
>                     break;
> #endif
> 
>                 case EU_IO_OPTIONS:             /* Set driver options */
>                     /*
>                      * Option cannot be set while network interface is up
>                      */
> 
> #if 0
>                     if ( ins->pDriverCMVs == NULL )
>                     {
>                         /* User as not yet sent EU_IO_CMVS */
>                         eu_err ("EU_IO_OPTIONS: CMVs not yet sent.\n");
>                         retval = -ERESTARTSYS;
>                         goto end_set_options;
>                     }
> #endif
> 
>                     if (!( EU_TEST_FLAG (ins, EU_OPEN ) ) )
>                     {
>                         eu_options_t opt;
> 
>                         memcpy(&opt, &default_options, sizeof(eu_options_t));
> 
>                         if (NULL == pIOCTLinfo)
>                         {
>                             eu_err ("EU_IO_OPTIONS : No data.\n");
>                             retval = -EFAULT;
>                             break;
>                         }
> 
>                         /* Check the option array size: */
>                         if (sizeof(opt) != pIOCTLinfo->buffer_size)
>                         {
>                             eu_err ("EU_IO_OPTIONS : Invalid Data size\n");
>                             retval = -EINVAL;
>                             break;
>                         }
> 
>                         if (copy_from_user(&opt, pIOCTLinfo->buffer, 
> sizeof(opt)))
>                         {
>                             retval = -EFAULT;
>                             eu_err ("EU_IO_OPTIONS : copy from user 
> failed.\n");
>                             break;
>                         }
> 
>                         /* Options retrieved, check them: */
>                         if ( eu_check_options ( opt ) )
>                         {
>                             /* OK, initialize Mpoa and Msg: */
>                             eu_report ("ioctl EU_IO_OPTIONS received\n");
> 
>                             /*
>                              * Initialize the message handling
>                              */
>                             if ( !spin_trylock ( &ins->lock ) )
>                             {
>                                 eu_err ("EU_IO_OPTIONS : Can't lock\n");
>                                 retval = -ERESTARTSYS;
>                                 break;
>                             }
> 
>                             eu_msg_initialize ( ins, opt );
>                             MpoaInitialize(ins, opt);
> 
>                             EU_SET_FLAG (ins, EU_MSG_INITIALIZED);
> 
>                             spin_unlock ( &ins->lock );
> 
>                             retval = 0;
>                         }
>                     }
>                     else
>                     {
>                         retval = -EBUSY;
>                         eu_err ("EU_IO_OPTIONS : Eth device already open.\n");
>                     }
> 
>                     break;
> 
>                 case EU_IO_DSP:
>                     /*
>                      * Load DSP code
>                      */
> 
>                     if ( !EU_TEST_FLAG (ins, EU_MSG_INITIALIZED) )
>                     {
>                         eu_err ("Message handling not initialized."
>                                  " Please send options.\n");
>                         retval = -EINVAL;
>                         break;
>                     }
> 
>                     if ( !EU_TEST_FLAG( ins, EU_OPEN ) )
>                     {
>                         uint8_t *pBuf = NULL;
>                         IDMAPage MainPage;
>                         IDMAPage *pSwapPages;
>                         uint32_t   SwapPageCount;
> 
>                         if (NULL == pIOCTLinfo)
>                         {
>                             eu_err ("EU_IO_DSP : No data.\n");
>                             retval = -EFAULT;
>                             break;
>                         }
> 
>                         if (pIOCTLinfo->idma_start >= pIOCTLinfo->buffer_size)
>                         {
>                             eu_err ("EU_IO_DSP : Invalid Data Size\n");
>                             retval = -EFAULT;
>                             break;
>                         }
> 
>                         pBuf = GET_VBUFFER(pIOCTLinfo->buffer_size);
> 
>                         if (NULL == pBuf)
>                         {
>                             eu_err ("EU_IO_DSP : No memory.\n");
>                             retval = -ENOMEM;
>                             break;
>                         }
> 
>                         if (copy_from_user(pBuf, pIOCTLinfo->buffer, 
> pIOCTLinfo->buffer_size))
>                         {
>                             eu_err ("EU_IO_DSP : copy from user failed.\n");
>                             retval = -EFAULT;
>                             goto free_adsl_dsp;
>                         }
> 
>                         /*
>                          * Get our DSP code ready for IDMA booting
>                          */
>                         eu_report ("ioctl EU_IO_DSP received\n");
> 
>                         if ( EU_TEST_FLAG( ins, EU_DSP_IPG ) )
>                         {
>                             retval = -ERESTARTSYS;
>                             goto free_adsl_dsp;
>                         }
> 
>                         EU_SET_FLAG (ins, EU_DSP_IPG);
> 
>                         retval = ProcessDSPCode ( ins,
>                                                   pBuf,
>                                                   pIOCTLinfo->idma_start,
>                                                   pIOCTLinfo->buffer_size,
>                                                   &MainPage,
>                                                   &pSwapPages,
>                                                   &SwapPageCount
>                                                 );
> 
>                         if (retval != 0)
>                         {
>                             eu_err ("EU_IO_DSP : ProcessDSPCode failed 
> (%d)\n",
>                                      retval);
>                             FreeDspData ( &MainPage, &pSwapPages, 
> &SwapPageCount );
>                             goto free_adsl_dsp;
>                         }
> 
>                         EU_SET_FLAG (ins, EU_DSP_LOADED);
> 
>                         /*
>                          * Flush all pending task ...
>                          */
>                         EU_FLUSH (eu_>boot_sm);
> 
>                         /*
>                          * Ok, we got our DSP code, replace the old DSP code 
> by
>                          * the new one:
>                          */
> 
>                         FreeDspData ( &ins->MainPage, &ins->pSwapPages, 
> &ins->SwapPageCount );
> 
>                         ins->MainPage.BlockCount = MainPage.BlockCount;
>                         ins->MainPage.Blocks = MainPage.Blocks;
>                         ins->pSwapPages = pSwapPages;
>                         ins->SwapPageCount = SwapPageCount;
> 
>                         /*
>                          * Load the DSP code if necessary:
>                          */
>                         eu_report ("Loading DSP code to device...\n");
> 
>                         if ( !EU_TEST_FLAG(ins, EU_HAS_INT) )
>                         {
>                             /*
>                              * Get the USB endpoint for IDMA uploading:
>                              */
> #ifdef LINUX_2_4
>                             struct usb_endpoint_descriptor *epint =
>                                 GET_INTF_PTR (dev,0)->altsetting[0].endpoint 
> + 0;
>                             uint8_t interval = epint->bInterval;
> #elif defined(LINUX_2_6)
>                             uint8_t interval =
>                                 GET_INTF_PTR 
> (dev,0)->altsetting[0].endpoint[0].desc.bInterval;
> #endif
>                             /*
>                              * Install the interrupt handler to send IDMA 
> pages to the modem
>                              * and handle further incoming data
>                              */
>                             usb_fill_int_urb ( ins->urb_int, dev, 
> ins->pipe_int_in, ins->intr_data,
>                                                sizeof(eu_cdc_t), eu_irq, ins, 
> interval );
> 
>                             EU_SET_FLAG (ins, EU_HAS_INT);
> 
>                             if ( USB_SUBMIT_URB ( ins->urb_int , GFP_KERNEL ) 
> < 0 )
>                             {
>                                 eu_err ("Unable to submit interrupt URB!\n");
>                                 retval = -EIO;
>                                 EU_CLEAR_FLAG (ins, EU_HAS_INT);
>                                 goto free_adsl_dsp;
>                             }
> 
>                         }
> 
>                         EU_CLEAR_FLAG (ins, EU_DSP_IPG);
> 
>                         /*
>                          * Send the DSP code to the modem:
>                          */
>                         ins->boot_state = PRE_BOOT;
>                         if ( !EU_TEST_FLAG(ins,EU_HAS_INT) || boot_the_modem 
> (ins) != 0)
>                         {
>                             eu_err ("Unable to load DSP code to device!\n");
> 
>                             goto free_adsl_dsp;
>                         }
>                         else
>                         {
>                             eu_report ("DSP code successfully loaded to 
> device\n");
>                         }
> 
>                         retval = 0;
> 
>                       free_adsl_dsp:
>                         FREE_VBUFFER(pBuf);
>                     }
>                     else
>                     {
>                         retval = -EBUSY;
>                         eu_err ("EU_IO_DSP : Eth device already open\n");
>                     }
>                     break;
> 
>                 case EU_IO_GETITF:              /* Get the network interface 
> name */
>                 {
>                     uint32_t length;
> 
>                     if (NULL == pIOCTLinfo)
>                     {
>                         eu_err ("EU_IO_GETITF : No data.\n");
>                         retval = -EFAULT;
>                         break;
>                     }
> 
>                     if ( !ins->eth )
>                     {
>                         eu_err ("EU_IO_GETIF: eth not yet created !!\n");
>                         retval = -EFAULT;
>                         break;
>                     }
> 
>                     length = strlen(ins->eth->name) + sizeof(char);
>                     if ( NULL == pIOCTLinfo->buffer )
>                     {
>                         /* Get the requested size */
>                         pIOCTLinfo->buffer_size = length;
>                         retval = 0;
>                     }
>                     else
>                     {
>                         /* Get the interface name */
>                         if ( pIOCTLinfo->buffer_size < length )
>                         {
>                             eu_err ("EU_IO_GETITF : Invalid Buffer size\n");
>                             retval = -EINVAL;
>                             break;
>                         }
> 
>                         if ( copy_to_user ( pIOCTLinfo->buffer, 
> ins->eth->name, length ) != 0 )
>                         {
>                             eu_err ("EU_IO_GETITF : copy to user failed\n");
>                             retval = -EFAULT;
>                             break;
>                         }
>                         retval = 0;
>                     }
>                     break;
>                 }
>                 break;
> 
>                 case EU_IO_SYNC:                /* Wait for modem 
> "operational" state */
>                     if (wait_event_interruptible(ins->sync_q,
>                                                  
> ((ins->AdiModemSm.CurrentAdiState & STATE_OPERATIONAL) == STATE_OPERATIONAL)))
>                         retval = -EINTR;
>                     else
>                         retval = 0;
>                     break;
> 
>                 default:
>                     /* Bad ioctl */
>                     break;
>             }
>             break;
>         default:
>             /* Bad device */
>             break;
>     }
> 
>   byebye:
>     MODULE_USER_RELEASE;
>     return retval;
> }
> 
> /**
>  * eu_read_proc  - /proc interface.
>  *
>  */
> static int eu_read_proc ( char *page,
>                           char **start,
>                           off_t off,
>                           int count,
>                           int *eof,
>                           void *data
>                         )
> {
>     eu_instance_t *ins = (eu_instance_t *)data;
>     int size;
>     char *p = page;
>     /*
>      * If this output needs to be larger than 4K (PAGE_SIZE), we need to do 
> this
>      * differently
>      */
>     p += sprintf(p, "eagle-usb status display\n");
>     p += sprintf(p, 
> "-------------------------------------------------------------\n");
>     p += sprintf(p, "Driver version %s\n",EAGLEUSBVERSION);
>     p += sprintf(p, "USB Bus : %03d\t USB Device : %03d\t Dbg mask: 0x%x\n",
>                  ins->usbdev->bus->busnum, ins->usbdev->devnum, 
> module_dbg_mask);
>     if (ins->eth->name)
>     {
>         p += sprintf(p, "Ethernet Interface : %s\n",ins->eth->name);
>     }
>     else
>     {
>         p += sprintf(p, "Ethernet Interface : none\n");
>     }
>     p += sprintf(p, "MAC: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
>                  ins->mac[0],ins->mac[1],ins->mac[2],ins->mac[3],ins->mac[4],
>                  ins->mac[5]);
> 
>     p += sprintf(p, "Tx Rate  %10.10d  Rx Rate  %10.10d  Crc      %10.10d\n",
>                  ins->AdiModemSm.UpRate / 1024,
>                  ins->AdiModemSm.DownRate / 1024,
>                  ins->Statistics[STAT_CELLS_LOST_CRC]);
>     p += sprintf(p, "FEC      %10.10d  Margin   %10.10d  Atten    %10.10d 
> dB\n",
>                  ins->AdiModemSm.stats_Uncorr_Blks,
>                  ins->AdiModemSm.stats_Cur_SNR & 0xFF,
>                  (ins->AdiModemSm.stats_Cur_Atten & 0xFF)/2);
>     p += sprintf(p, "VID-CPE  %10.10d  VID-CO   %10.10d  HEC      %10.10d\n",
>                  ins->AdiModemSm.INFO14,
>                  ins->AdiModemSm.INFO08,
>                  ins->AdiModemSm.DIAG03);
> 
>     p += sprintf(p, "VPI      %10.10d  VCI      %10.10d  Delin         ",
>                  ins->Vc.vpi, ins->Vc.vci);
> 
>     /*Delineation is the only one where we print a string instead of a 
> number*/
>     if (ins->AdiModemSm.flags & 0x0C00)
>         p += sprintf(p, "ERROR\n");
>     else
>         if (ins->AdiModemSm.flags & 0x0030)
>             p += sprintf(p, " LOSS\n");
>         else
>             p += sprintf(p, " GOOD\n");
>     p += sprintf(p, "Cells Rx %10.10d  Cells Tx %10.10d\n",
>                  ins->Statistics[STAT_CELLS_RX],
>                  ins->Statistics[STAT_CELLS_TX]);
>     p += sprintf(p, "Pkts Rx  %10.10d  Pkts Tx  %10.10d\n",
>                  ins->Statistics[STAT_PAKTS_RX],
>                  ins->Statistics[STAT_PAKTS_TX]);
>     p += sprintf(p, "OAM      %10.10d  Bad VPI  %10.10d  Bad CRC  %10.10d\n",
>                   ins->Statistics[STAT_CELLS_OAM_RCVD],
>                   ins->Statistics[STAT_CELLS_LOST_VPIVCI],
>                   ins->Statistics[STAT_CELLS_LOST_CRC]
>                   );
>     p += sprintf(p, "Oversiz. %10.10d\n\n",
>                 ins->Statistics[STAT_CELLS_LOST_OTHER] );
> 
>     switch (ins->AdiModemSm.CurrentAdiState)
>     {
>         case STATE_UNDEFINED:
>             p += sprintf(p, "Modem is unplugged from USB.\n");
>             break;
>         case STATE_JUST_PLUGGED_IN:
>             p += sprintf(p, "Modem waiting for driver response.\n");
>             p += sprintf (p,"Please send DSP (eaglectrl -d)\n");
>             break;
>         case STATE_UNTRAIN:
>         case STATE_UNTRAIN_TX:
>         case STATE_UNTRAIN_RX:
>             p += sprintf(p, "Modem is initializing(UNTRAIN)\n");
>             break;
>         case STATE_INITIALIZING:
>         case STATE_INITIALIZING_TX:
>         case STATE_INITIALIZING_RX:
>             p += sprintf(p, "Modem is initializing(INITIALIZING)\n");
>             break;
>         case STATE_HARD_RESET_INITIATE:
>         case STATE_HARD_RESET_END:
>         case STATE_BOOT_WAIT:
>         case STATE_BOOT_STAGE_1:
>         case STATE_BOOT_STAGE_2:
>         case STATE_BOOT_STAGE_3:
>             p += sprintf(p, "Modem is booting\n");
>             break;
>         case STATE_OPERATIONAL:
>         case STATE_OPERATIONAL_TX:
>         case STATE_OPERATIONAL_RX:
>             p += sprintf(p, "Modem is operational\n");
>             break;
>         case STATE_STALLED_FOREVER:
>             p += sprintf(p, "Modem cannot boot. Unplug other devices and 
> retry.\n");
>             break;
>         default:
>             p += sprintf(p, "Unhandled state\n");
>             eu_report ("eu_read_proc: unhandled state 0x%X\n", 
> ins->AdiModemSm.CurrentAdiState);
>             break;
>     }
>     p += sprintf(p, "\n");
>     /*
>      * Figure out how much of the page we used
>      */
>     size  = p - page;
>     size -= off;
> 
>     if (size < count)
>     {
>         *eof = 1;
>         if (size <= 0)
>             return 0;
>     }
>     else
>         size = count;
>     /*
>      * Fool caller into thinking we started where he told us to in the page
>      */
>     *start = page + off;
>     return size;
> }
> 
> /**
>  * eu_process_rcv  -  Process completed receive queue
>  *                    Called as a tasklet
>  *
>  */
> static void eu_process_rcv ( unsigned long data )
> {
>     eu_instance_t *ins = (eu_instance_t *) data;
>     unsigned long flags;
> /*     uint8_t *pbuf; */
>     eu_rb_t *pbuf;
> #ifdef USEBULK
>     eu_bulk_rb_t *pbulk;
> #else
>     int i;
>     eu_iso_rb_t *piso;
>     eu_iso_frame_t *pf;
> #endif
>     int result;
>     int count = 0;
> 
>     eu_enters( DBG_READ );
> 
>     if ( ins == NULL )
>     {
>         eu_err ("eu_process_rcv: Null instance !\n");
>         return;
>     }
> 
>     /*
>      * Treat all messages in the list
>      */
>     while ( !list_empty ( &ins->comp_read_q ) )
>     {
>         /*
>          * Remove head of the list
>          */
>         spin_lock_irqsave (&ins->comp_read_q_lock, flags);
>         /*
>          * FIXME : we should use a list function ...
>          * if list field position change .. we must be able to find it again 
> ...
>          *
>          */
>         pbuf = list_entry (ins->comp_read_q.next, eu_rb_t, next);
>         list_del(ins->comp_read_q.next);
> 
>         spin_unlock_irqrestore (&ins->comp_read_q_lock, flags);
> 
> #ifdef USEBULK
> 
>         pbulk = (eu_bulk_rb_t *) pbuf;
> 
>         count ++;
> 
>         result = eu_uni_process_in_data ( ins, &pbulk->data[0], pbulk->length 
> );
>         if (result)
>         {
>             eu_dbg (DBG_READ,"Error %d from eu_uni_process_in_data\n", 
> result);
>         }
> 
> #else
>         /*
>          * Now process each frame
>          */
>         piso = (eu_iso_rb_t *) pbuf;
>         pf = &piso->frames[0];
> 
>         for ( i=0 ; i<FRAMES_PER_ISO_URB; i++ )
>         {
> 
>             if ( pf->status == 0 )
>             {
>                 count ++;
> 
>                 result = eu_uni_process_in_data ( ins,
>                                                   &pf->data[0],
>                                                   pf->length
>                                                 );
>                 if ( result != 0 )
>                 {
>                     eu_dbg (DBG_READ,"Error %d from eu_uni_process_in_data\n",
>                              result);
>                 }
>             }
> 
>             pf ++;
>         }
> #endif /* USEBULK */
> 
>         /*
>          * And free the transfer buffer
>          */
>         kmem_cache_free ( ins->rb_cache, pbuf );
> 
>     }
>     eu_dbg( DBG_READ ," %d frames processed.\n",count);
> 
>     eu_leaves ( DBG_READ );
> 
> }
> 
> /* ------------------------------------ Misc 
> ------------------------------------ */
> 
> /**
>  * eu_check_options - Check given options are accepted
>  */
> static int eu_check_options ( const eu_options_t opt )
> {
>     int result = 1;
>     if (opt[CFG_ENCAPS].value != MPOA_MODE_BRIDGED_ETH_LLC &&
>         opt[CFG_ENCAPS].value != MPOA_MODE_BRIDGED_ETH_VC &&
>         opt[CFG_ENCAPS].value != MPOA_MODE_ROUTED_IP_LLC &&
>         opt[CFG_ENCAPS].value != MPOA_MODE_ROUTED_IP_VC &&
>         opt[CFG_ENCAPS].value != MPOA_MODE_PPPOA_LLC &&
>         opt[CFG_ENCAPS].value != MPOA_MODE_PPPOA_VC)
>         result = 0;
>     return result;
> }
> 
> --=-qML6NwnTSh+fhTRn0KQs--
> 
> --__--__--
> 
> _______________________________________________
> Eagleusb-dev mailing list
> [email protected]
> https://mail.gna.org/listinfo/eagleusb-dev
> 
> End of Eagleusb-dev Digest
>

Reply via email to