⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bclient.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  @(#) pSOSystem PowerPC/V2.2.2: drivers/bclient.c (&U&) 2.7 97/11/04 17:08:09 */
/***********************************************************************/
/*                                                                     */
/*   MODULE:  drivers/bootp/bclient.c                                  */
/*   DATE:    97/11/04                                                 */
/*   PURPOSE: Contains routines that implement the BOOTP protocol.     */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*           Copyright 1991 - 1996, Integrated Systems, Inc.           */
/*                      ALL RIGHTS RESERVED                            */
/*                                                                     */
/*   Permission is hereby granted to licensees of Integrated Systems,  */
/*   Inc. products to use or abstract this computer program for the    */
/*   sole purpose of implementing a product based on Integrated        */
/*   Systems, Inc. products.   No other rights to reproduce, use,      */
/*   or disseminate this computer program, whether in part or in       */
/*   whole, are granted.                                               */
/*                                                                     */
/*   Integrated Systems, Inc. makes no representation or warranties    */
/*   with respect to the performance of this computer program, and     */
/*   specifically disclaims any responsibility for any damages,        */
/*   special or consequential, connected with the use of this program. */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/
#include <psos.h>
#include "bsp.h"
#include <pna.h>
#include <pna_mib.h>
#include <bspfuncs.h>
#include <ip_udp.h>
#include <bootp.h>
#include <configs.h>
#include <types.h>
 
/*---------------------------------------------------------------------*/
/* The node anchor address is a pointer to the node configuration      */
/* table, which in turn points to the pSOS+ configuration table.  This */
/* driver will look in the pSOS+ configuration table to see how many   */
/* ticks per second are specified, and thus how many interrupts per    */
/* second to generate.                                                 */
/*---------------------------------------------------------------------*/
extern NODE_CT *anchor;

/*---------------------------------------------------------------------*/
/* This code can be compiled for use with either a zero-copy LAN       */
/* driver or a non-zero-copy LAN driver.                               */
/*---------------------------------------------------------------------*/
#define NI_RAWMEM (BSP_LAN1_FLAGS & IFF_RAWMEM)

/***********************************************************************/
/* NI interface for Bootp                                              */
/***********************************************************************/
#define BOOTP_IFNUM 188

/***********************************************************************/
/* IP header for BOOTP packet                                          */
/***********************************************************************/
static USHORT ip_id = 1000000 & 0xFFFF;      /* IP header id */

/***********************************************************************/
/* Initial transaction ID for BOOTP packet                             */
/***********************************************************************/
static ULONG InitialXid = -1000000;            

/***********************************************************************/
/* PsosUp indicates if pSOS is up when get_bootp_params is called      */
/***********************************************************************/
static ULONG PsosUp;                         

/***********************************************************************/
/* Seconds elapsed since first BOOTP packet was sent out               */
/***********************************************************************/
static USHORT SecsSinceStart;               

static char Bootp_Replied;
static UCHAR *EthAddrPtr;
static bootppkt_t BootpReplyPkt;
static char BootpServerName[64];
static char BootpFileName[128];
static char BootpBuf[IP_SZ + UDP_SZ + BOOTP_SZ];
static ULONG BootpXid;
static long (*MyNiLan)(ULONG, union nientry *);

/***********************************************************************/
/* Functions used                                                      */
/***********************************************************************/
static ULONG process_bootp(int type, char *buff_addr);
static ULONG broadcast_bootp(long (*NiLanPtr)());
static ULONG extract_bootpkt(bootppkt_t *bootp, bootpparms_t *retp);
static USHORT in_cksum(UCHAR *addr, int count);
static void bootp_ip_packet(char *bootpbuf); 
static void strcpy(UCHAR *src, UCHAR *dst);
static void bmemset(UCHAR *ptr, register UCHAR fill, register ULONG count);
static void bmemcpy(UCHAR *src, UCHAR *dest, ULONG nbytes);
static void sleep(int count);

extern char *strncpy(char *, const char *, unsigned char);

#if NI_RAWMEM
#define NR_MBLKS 20

/*---------------------------------------------------------------------*/
/* We will maintain a list of mblks which will be allocated and freed  */
/* by besballoc() and bfreemsg().                                      */
/*---------------------------------------------------------------------*/
static mblk_t *bm_freelist; /* head of free list of message blocks */
static mblk_t bm[NR_MBLKS]; /* message blocks */
static dblk_t db[NR_MBLKS]; /* associated data blocks */

/***********************************************************************/
/*     ballocb: Allocate a message block                               */
/*      bfreeb: Free a message block                                   */
/*                                                                     */
/*        NOTE: These are unimplemented                                */
/*                                                                     */
/***********************************************************************/
static mblk_t *ballocb(long size, long pri) {return NULL;}
static void bfreeb(mblk_t *bp) {}


/***********************************************************************/
/*  init_bmbuf: Initialize the mblk free list                          */
/*                                                                     */
/*        NOTE: Each mblk gets a data block attached to it.  The mblks */
/*              are linked together in the "free" list, using the      */
/*              b_next field.                                          */
/***********************************************************************/
static void init_bmbuf(void)
{
int i;
 
for (i = 0; i < NR_MBLKS; i++) 
    {
    bmemset((unsigned char *)&bm[i], 0, sizeof(mblk_t));
    bmemset((unsigned char *)&db[i], 0, sizeof(dblk_t));
    bm[i].b_datap = &db[i];           /* attach data block */
    bm[i].b_next = &bm[i+1];
    }
bm[NR_MBLKS - 1].b_next = 0;

bm_freelist = &bm[0];
}

/***********************************************************************/
/*   besballoc: Attach a message block to a buffer                     */
/*                                                                     */
/*      INPUTS: base: ptr to buffer                                    */
/*              size: length of buffer in bytes                        */
/*              pri: ignored                                           */
/*              frtn: ptr to struct describing routine to be called    */
/*                    when buffer is to be freed                       */
/*                                                                     */
/*     RETURNS: ptr to msg block                                       */
/*                                                                     */
/***********************************************************************/
static mblk_t *besballoc(UCHAR *base, int size, int pri, frtn_t *frtn)
{
register mblk_t *pmblk;
register unsigned long om;
 
if (base == NULL || frtn == NULL)
    return(NULL);
 
/*---------------------------------------------------------------------*/
/* Get a msg block from the free list (if one is available)            */
/*---------------------------------------------------------------------*/
om = splx(MAX_ILEV);
if (pmblk = bm_freelist) 
    {
    bm_freelist = bm_freelist->b_next;
    pmblk->b_next = 0;
    }
else 
    {
    splx(om);
    return(NULL);
    }
splx(om);
 
/*---------------------------------------------------------------------*/
/* Fill in the msg block and its associated data block                 */
/*---------------------------------------------------------------------*/
pmblk->b_rptr = base;
pmblk->b_wptr = base;
pmblk->b_datap->db_base = base;
pmblk->b_datap->db_lim = (UCHAR *)(base + size + 1);
pmblk->b_datap->db_ref = 1;
pmblk->b_datap->db_frtn = *frtn;

return(pmblk);
}
 
/***********************************************************************/
/*    bfreemsg: Free a message block and its associated buffer, if     */
/*              there is one.                                          */
/*                                                                     */
/*      INPUTS: mp: ptr to message block triplet                       */
/*                                                                     */
/*     RETURNS:                                                        */
/*     OUTPUTS:                                                        */
/*     NOTE(S):                                                        */
/*                                                                     */
/***********************************************************************/
static void bfreemsg(mblk_t *mp)
{
unsigned long om;
 
om = splx(MAX_ILEV);
if (mp->b_datap->db_frtn.free_func)
    (mp->b_datap->db_frtn.free_func)(mp->b_datap->db_frtn.free_arg);
mp->b_next = bm_freelist;
bm_freelist = mp;
splx(om);
}

#endif /* NI_RAWMEM */

/***********************************************************************/
/*                                                                     */
/*   get_bootp_params: Obtain BOOTP reply packet for a specified       */
/*                     NI interface.                                   */
/*                                                                     */
/***********************************************************************/
ULONG get_bootp_params(long (*ni_entry)(ULONG, union nientry *),
                       char *bootp_file_name,
                       char *bootp_server_name,
                       int num_retries,
                       int flags,
                       char *ret_params)
{
union nientry init_ni, poll_ni;
int wait_count;               
int next_retry = 1;
struct ni_funcs NiFuncs;
unsigned long retval;

/*---------------------------------------------------------------------*/
/* Initialize the "mbuf manager"                                       */
/*---------------------------------------------------------------------*/
#if NI_RAWMEM
init_bmbuf();
#endif

/*---------------------------------------------------------------------*/
/* Get Pointer to NI interface used to RARP and initialize that NI.    */
/*---------------------------------------------------------------------*/
MyNiLan = (long (*)())ni_entry;

/*---------------------------------------------------------------------*/
/* Set niinit.ap_addr to "process_rarp" the function that the network  */
/* interface (driver) will call to process incoming packets.           */
/*---------------------------------------------------------------------*/
init_ni.niinit.ap_addr = (long(*)()) process_bootp;
init_ni.niinit.if_num = BOOTP_IFNUM;   /* My interface number */
init_ni.niinit.ip_addr = 0;            /* Redundant but needed */

#if NI_RAWMEM
init_ni.niinit.funcs = &NiFuncs;
NiFuncs.allocb = ballocb;
NiFuncs.freeb = bfreeb;
NiFuncs.freemsg = bfreemsg;
NiFuncs.esballoc = besballoc;
#endif

/*---------------------------------------------------------------------*/
/* Call network interface initialization function.  It will return the */
/* hardware address of this interface.                                 */
/*---------------------------------------------------------------------*/
EthAddrPtr = (UCHAR *)(*ni_entry)(NI_INIT, &init_ni);

/*---------------------------------------------------------------------*/
/* Check to see if the NI init failed, don't continue if it has.       */
/*---------------------------------------------------------------------*/
if (EthAddrPtr == (UCHAR *)-1)
    return 0xffffffff;

poll_ni.nipoll.if_num = BOOTP_IFNUM;
if (num_retries == 0)
    num_retries = BOOTP_RETRIES;
Bootp_Replied = FALSE;
bmemset((UCHAR *)BootpServerName, 0, sizeof(BootpServerName));
bmemset((UCHAR *)BootpFileName, 0, sizeof(BootpFileName));

if (bootp_server_name)
    strcpy((UCHAR *)bootp_server_name, (UCHAR *)BootpServerName); 
if (bootp_file_name)
    strcpy((UCHAR *)bootp_file_name, (UCHAR *)BootpFileName);

SecsSinceStart = 0;

if ((flags & PSOSUP) == PSOSUP)
    PsosUp = 1;
else
    PsosUp = 0;

#if NI_RAWMEM
bootp_ip_packet(BootpBuf);
#endif
/*---------------------------------------------------------------------*/
/* Send a BOOTP request, poll the NI, and check if the poll caused a   */
/* RARP response to occur. This sequence is repeated "retry" times.    */
/* During each retry, two NI polls are done, 1 second apart to give    */
/* the RARP server a chance to reply.                                  */
/*---------------------------------------------------------------------*/
while (num_retries && !Bootp_Replied)
    {

    if (broadcast_bootp((long (*)())ni_entry) != 0)
        return (0xffffffff);
    wait_count = next_retry;
    while (!Bootp_Replied && wait_count) {
        (*ni_entry)(NI_POLL, &poll_ni);
        --wait_count;
        sleep(1);
        };

    SecsSinceStart += next_retry;
    if (next_retry < 60) 
        next_retry *= 2;
        --num_retries;
    };

/*---------------------------------------------------------------------*/
/* We've fallen through the loop, if there was BOOTP reply then return */
/* the IP address for this board, else return a 0.  The LanStop()      */
/* routine is always called to prevent further BOOTP responses from    */
/* being delivered (and DMAed into memory).                            */
/*---------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -